@@ -1134,6 +1134,14 @@ namespace ts {
1134
1134
return token === t && tryParse ( nextTokenCanFollowModifier ) ;
1135
1135
}
1136
1136
1137
+ function nextTokenIsOnSameLineAndCanFollowModifier ( ) {
1138
+ nextToken ( ) ;
1139
+ if ( scanner . hasPrecedingLineBreak ( ) ) {
1140
+ return false ;
1141
+ }
1142
+ return canFollowModifier ( ) ;
1143
+ }
1144
+
1137
1145
function nextTokenCanFollowModifier ( ) {
1138
1146
if ( token === SyntaxKind . ConstKeyword ) {
1139
1147
// 'const' is only a modifier if followed by 'enum'.
@@ -1154,11 +1162,7 @@ namespace ts {
1154
1162
return canFollowModifier ( ) ;
1155
1163
}
1156
1164
1157
- nextToken ( ) ;
1158
- if ( scanner . hasPrecedingLineBreak ( ) ) {
1159
- return false ;
1160
- }
1161
- return canFollowModifier ( ) ;
1165
+ return nextTokenIsOnSameLineAndCanFollowModifier ( ) ;
1162
1166
}
1163
1167
1164
1168
function parseAnyContextualModifier ( ) : boolean {
@@ -4923,15 +4927,31 @@ namespace ts {
4923
4927
return decorators ;
4924
4928
}
4925
4929
4926
- function parseModifiers ( ) : ModifiersArray {
4930
+ /*
4931
+ * There are situations in which a modifier like 'const' will appear unexpectedly, such as on a class member.
4932
+ * In those situations, if we are entirely sure that 'const' is not valid on its own (such as when ASI takes effect
4933
+ * and turns it into a standalone declaration), then it is better to parse it and report an error later.
4934
+ *
4935
+ * In such situations, 'permitInvalidConstAsModifier' should be set to true.
4936
+ */
4937
+ function parseModifiers ( permitInvalidConstAsModifier ?: boolean ) : ModifiersArray {
4927
4938
let flags = 0 ;
4928
4939
let modifiers : ModifiersArray ;
4929
4940
while ( true ) {
4930
4941
const modifierStart = scanner . getStartPos ( ) ;
4931
4942
const modifierKind = token ;
4932
4943
4933
- if ( ! parseAnyContextualModifier ( ) ) {
4934
- break ;
4944
+ if ( token === SyntaxKind . ConstKeyword && permitInvalidConstAsModifier ) {
4945
+ // We need to ensure that any subsequent modifiers appear on the same line
4946
+ // so that when 'const' is a standalone declaration, we don't issue an error.
4947
+ if ( ! tryParse ( nextTokenIsOnSameLineAndCanFollowModifier ) ) {
4948
+ break ;
4949
+ }
4950
+ }
4951
+ else {
4952
+ if ( ! parseAnyContextualModifier ( ) ) {
4953
+ break ;
4954
+ }
4935
4955
}
4936
4956
4937
4957
if ( ! modifiers ) {
@@ -4976,7 +4996,7 @@ namespace ts {
4976
4996
4977
4997
const fullStart = getNodePos ( ) ;
4978
4998
const decorators = parseDecorators ( ) ;
4979
- const modifiers = parseModifiers ( ) ;
4999
+ const modifiers = parseModifiers ( /*permitInvalidConstAsModifier*/ true ) ;
4980
5000
4981
5001
const accessor = tryParseAccessorDeclaration ( fullStart , decorators , modifiers ) ;
4982
5002
if ( accessor ) {
0 commit comments