@@ -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 {
@@ -4903,15 +4907,31 @@ namespace ts {
4903
4907
return decorators ;
4904
4908
}
4905
4909
4906
- function parseModifiers ( ) : ModifiersArray {
4910
+ /*
4911
+ * There are situations in which a modifier like 'const' will appear unexpectedly, such as on a class member.
4912
+ * In those situations, if we are entirely sure that 'const' is not valid on its own (such as when ASI takes effect
4913
+ * and turns it into a standalone declaration), then it is better to parse it and report an error later.
4914
+ *
4915
+ * In such situations, 'permitInvalidConstAsModifier' should be set to true.
4916
+ */
4917
+ function parseModifiers ( permitInvalidConstAsModifier ?: boolean ) : ModifiersArray {
4907
4918
let flags = 0 ;
4908
4919
let modifiers : ModifiersArray ;
4909
4920
while ( true ) {
4910
4921
const modifierStart = scanner . getStartPos ( ) ;
4911
4922
const modifierKind = token ;
4912
4923
4913
- if ( ! parseAnyContextualModifier ( ) ) {
4914
- break ;
4924
+ if ( token === SyntaxKind . ConstKeyword && permitInvalidConstAsModifier ) {
4925
+ // We need to ensure that any subsequent modifiers appear on the same line
4926
+ // so that when 'const' is a standalone declaration, we don't issue an error.
4927
+ if ( ! tryParse ( nextTokenIsOnSameLineAndCanFollowModifier ) ) {
4928
+ break ;
4929
+ }
4930
+ }
4931
+ else {
4932
+ if ( ! parseAnyContextualModifier ( ) ) {
4933
+ break ;
4934
+ }
4915
4935
}
4916
4936
4917
4937
if ( ! modifiers ) {
@@ -4956,7 +4976,7 @@ namespace ts {
4956
4976
4957
4977
const fullStart = getNodePos ( ) ;
4958
4978
const decorators = parseDecorators ( ) ;
4959
- const modifiers = parseModifiers ( ) ;
4979
+ const modifiers = parseModifiers ( /*permitInvalidConstAsModifier*/ true ) ;
4960
4980
4961
4981
const accessor = tryParseAccessorDeclaration ( fullStart , decorators , modifiers ) ;
4962
4982
if ( accessor ) {
0 commit comments