@@ -1927,37 +1927,47 @@ export class Parser extends DiagnosticEmitter {
1927
1927
1928
1928
var state = tn . mark ( ) ;
1929
1929
var token = tn . next ( ) ;
1930
+ var statement : Statement | null = null ;
1930
1931
switch ( token ) {
1931
1932
case Token . BREAK : {
1932
- return this . parseBreak ( tn ) ;
1933
+ statement = this . parseBreak ( tn ) ;
1934
+ break ;
1933
1935
}
1934
1936
case Token . CONST : {
1935
- return this . parseVariable ( tn , [
1937
+ statement = this . parseVariable ( tn , [
1936
1938
Node . createModifier ( ModifierKind . CONST , tn . range ( ) )
1937
1939
] , null ) ;
1940
+ break ;
1938
1941
}
1939
1942
case Token . CONTINUE : {
1940
- return this . parseContinue ( tn ) ;
1943
+ statement = this . parseContinue ( tn ) ;
1944
+ break ;
1941
1945
}
1942
1946
case Token . DO : {
1943
- return this . parseDoStatement ( tn ) ;
1947
+ statement = this . parseDoStatement ( tn ) ;
1948
+ break ;
1944
1949
}
1945
1950
case Token . FOR : {
1946
- return this . parseForStatement ( tn ) ;
1951
+ statement = this . parseForStatement ( tn ) ;
1952
+ break ;
1947
1953
}
1948
1954
case Token . IF : {
1949
- return this . parseIfStatement ( tn ) ;
1955
+ statement = this . parseIfStatement ( tn ) ;
1956
+ break ;
1950
1957
}
1951
1958
case Token . LET : {
1952
- return this . parseVariable ( tn , [
1959
+ statement = this . parseVariable ( tn , [
1953
1960
Node . createModifier ( ModifierKind . LET , tn . range ( ) )
1954
1961
] , null ) ;
1962
+ break ;
1955
1963
}
1956
1964
case Token . VAR : {
1957
- return this . parseVariable ( tn , null , null ) ;
1965
+ statement = this . parseVariable ( tn , null , null ) ;
1966
+ break ;
1958
1967
}
1959
1968
case Token . OPENBRACE : {
1960
- return this . parseBlockStatement ( tn , topLevel ) ;
1969
+ statement = this . parseBlockStatement ( tn , topLevel ) ;
1970
+ break ;
1961
1971
}
1962
1972
case Token . RETURN : {
1963
1973
if ( topLevel ) {
@@ -1966,34 +1976,49 @@ export class Parser extends DiagnosticEmitter {
1966
1976
tn . range ( )
1967
1977
) ; // recoverable
1968
1978
}
1969
- return this . parseReturn ( tn ) ;
1979
+ statement = this . parseReturn ( tn ) ;
1980
+ break ;
1970
1981
}
1971
1982
case Token . SEMICOLON : {
1972
1983
return Node . createEmptyStatement ( tn . range ( tn . tokenPos ) ) ;
1973
1984
}
1974
1985
case Token . SWITCH : {
1975
- return this . parseSwitchStatement ( tn ) ;
1986
+ statement = this . parseSwitchStatement ( tn ) ;
1987
+ break ;
1976
1988
}
1977
1989
case Token . THROW : {
1978
- return this . parseThrowStatement ( tn ) ;
1990
+ statement = this . parseThrowStatement ( tn ) ;
1991
+ break ;
1979
1992
}
1980
1993
case Token . TRY : {
1981
- return this . parseTryStatement ( tn ) ;
1994
+ statement = this . parseTryStatement ( tn ) ;
1995
+ break ;
1982
1996
}
1983
1997
case Token . TYPE : {
1984
- return this . parseTypeDeclaration ( tn ) ;
1998
+ statement = this . parseTypeDeclaration ( tn ) ;
1999
+ break ;
1985
2000
}
1986
2001
case Token . VOID : {
1987
- return this . parseVoidStatement ( tn ) ;
2002
+ statement = this . parseVoidStatement ( tn ) ;
2003
+ break ;
1988
2004
}
1989
2005
case Token . WHILE : {
1990
- return this . parseWhileStatement ( tn ) ;
2006
+ statement = this . parseWhileStatement ( tn ) ;
2007
+ break ;
1991
2008
}
1992
2009
default : {
1993
2010
tn . reset ( state ) ;
1994
- return this . parseExpressionStatement ( tn ) ;
2011
+ statement = this . parseExpressionStatement ( tn ) ;
2012
+ break ;
1995
2013
}
1996
2014
}
2015
+ if ( ! statement ) { // has been reported
2016
+ tn . reset ( state ) ;
2017
+ this . skipStatement ( tn ) ;
2018
+ } else {
2019
+ tn . discard ( state ) ;
2020
+ }
2021
+ return statement ;
1997
2022
}
1998
2023
1999
2024
parseBlockStatement (
@@ -2006,9 +2031,15 @@ export class Parser extends DiagnosticEmitter {
2006
2031
var startPos = tn . tokenPos ;
2007
2032
var statements = new Array < Statement > ( ) ;
2008
2033
while ( ! tn . skip ( Token . CLOSEBRACE ) ) {
2034
+ let state = tn . mark ( ) ;
2009
2035
let statement = this . parseStatement ( tn , topLevel ) ;
2010
- if ( ! statement ) return null ;
2011
- statements . push ( statement ) ;
2036
+ if ( ! statement ) {
2037
+ tn . reset ( state ) ;
2038
+ this . skipStatement ( tn ) ;
2039
+ } else {
2040
+ tn . discard ( state ) ;
2041
+ statements . push ( statement ) ;
2042
+ }
2012
2043
}
2013
2044
var ret = Node . createBlockStatement ( statements , tn . range ( startPos , tn . pos ) ) ;
2014
2045
tn . skip ( Token . SEMICOLON ) ;
@@ -2964,6 +2995,59 @@ export class Parser extends DiagnosticEmitter {
2964
2995
}
2965
2996
return expr ;
2966
2997
}
2998
+
2999
+ /** Skips over a statement on errors in an attempt to reduce unnecessary diagnostic noise. */
3000
+ skipStatement ( tn : Tokenizer ) : void {
3001
+ tn . peek ( true ) ;
3002
+ if ( tn . nextTokenOnNewLine ) tn . next ( ) ; // if reset() to the previous line
3003
+ do {
3004
+ let nextToken = tn . peek ( true ) ;
3005
+ if (
3006
+ nextToken == Token . ENDOFFILE || // next step should handle this
3007
+ nextToken == Token . CLOSEBRACE // current step should handle this
3008
+ ) {
3009
+ break ;
3010
+ }
3011
+ if ( nextToken == Token . SEMICOLON ) { // end of the statement for sure
3012
+ tn . next ( ) ;
3013
+ break ;
3014
+ }
3015
+ if ( tn . nextTokenOnNewLine ) break ; // end of the statement maybe
3016
+ switch ( tn . next ( ) ) {
3017
+ case Token . IDENTIFIER : {
3018
+ tn . readIdentifier ( ) ;
3019
+ break ;
3020
+ }
3021
+ case Token . STRINGLITERAL : {
3022
+ tn . readString ( ) ;
3023
+ break ;
3024
+ }
3025
+ case Token . INTEGERLITERAL : {
3026
+ tn . readInteger ( ) ;
3027
+ break ;
3028
+ }
3029
+ case Token . FLOATLITERAL : {
3030
+ tn . readFloat ( ) ;
3031
+ break ;
3032
+ }
3033
+ }
3034
+ } while ( true ) ;
3035
+ }
3036
+
3037
+ /** Skips over a block on errors in an attempt to reduce unnecessary diagnostic noise. */
3038
+ // skipBlock(tn: Tokenizer): void {
3039
+ // var depth = 0;
3040
+ // var token: Token;
3041
+ // do {
3042
+ // token = tn.next();
3043
+ // if (token == Token.OPENBRACE) {
3044
+ // ++depth;
3045
+ // } else if (token == Token.CLOSEBRACE) {
3046
+ // if (depth) --depth;
3047
+ // if (!depth) break; // done
3048
+ // }
3049
+ // } while (token != Token.ENDOFFILE);
3050
+ // }
2967
3051
}
2968
3052
2969
3053
/** Operator precedence from least to largest. */
0 commit comments