Reduce unnecessary diagnostic noise

This commit is contained in:
dcodeIO 2018-03-14 15:31:50 +01:00
parent 507482adb2
commit 8e7bad7459
6 changed files with 105 additions and 36 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1927,37 +1927,47 @@ export class Parser extends DiagnosticEmitter {
var state = tn.mark();
var token = tn.next();
var statement: Statement | null = null;
switch (token) {
case Token.BREAK: {
return this.parseBreak(tn);
statement = this.parseBreak(tn);
break;
}
case Token.CONST: {
return this.parseVariable(tn, [
statement = this.parseVariable(tn, [
Node.createModifier(ModifierKind.CONST, tn.range())
], null);
break;
}
case Token.CONTINUE: {
return this.parseContinue(tn);
statement = this.parseContinue(tn);
break;
}
case Token.DO: {
return this.parseDoStatement(tn);
statement = this.parseDoStatement(tn);
break;
}
case Token.FOR: {
return this.parseForStatement(tn);
statement = this.parseForStatement(tn);
break;
}
case Token.IF: {
return this.parseIfStatement(tn);
statement = this.parseIfStatement(tn);
break;
}
case Token.LET: {
return this.parseVariable(tn, [
statement = this.parseVariable(tn, [
Node.createModifier(ModifierKind.LET, tn.range())
], null);
break;
}
case Token.VAR: {
return this.parseVariable(tn, null, null);
statement = this.parseVariable(tn, null, null);
break;
}
case Token.OPENBRACE: {
return this.parseBlockStatement(tn, topLevel);
statement = this.parseBlockStatement(tn, topLevel);
break;
}
case Token.RETURN: {
if (topLevel) {
@ -1966,34 +1976,49 @@ export class Parser extends DiagnosticEmitter {
tn.range()
); // recoverable
}
return this.parseReturn(tn);
statement = this.parseReturn(tn);
break;
}
case Token.SEMICOLON: {
return Node.createEmptyStatement(tn.range(tn.tokenPos));
}
case Token.SWITCH: {
return this.parseSwitchStatement(tn);
statement = this.parseSwitchStatement(tn);
break;
}
case Token.THROW: {
return this.parseThrowStatement(tn);
statement = this.parseThrowStatement(tn);
break;
}
case Token.TRY: {
return this.parseTryStatement(tn);
statement = this.parseTryStatement(tn);
break;
}
case Token.TYPE: {
return this.parseTypeDeclaration(tn);
statement = this.parseTypeDeclaration(tn);
break;
}
case Token.VOID: {
return this.parseVoidStatement(tn);
statement = this.parseVoidStatement(tn);
break;
}
case Token.WHILE: {
return this.parseWhileStatement(tn);
statement = this.parseWhileStatement(tn);
break;
}
default: {
tn.reset(state);
return this.parseExpressionStatement(tn);
statement = this.parseExpressionStatement(tn);
break;
}
}
if (!statement) { // has been reported
tn.reset(state);
this.skipStatement(tn);
} else {
tn.discard(state);
}
return statement;
}
parseBlockStatement(
@ -2006,9 +2031,15 @@ export class Parser extends DiagnosticEmitter {
var startPos = tn.tokenPos;
var statements = new Array<Statement>();
while (!tn.skip(Token.CLOSEBRACE)) {
let state = tn.mark();
let statement = this.parseStatement(tn, topLevel);
if (!statement) return null;
statements.push(statement);
if (!statement) {
tn.reset(state);
this.skipStatement(tn);
} else {
tn.discard(state);
statements.push(statement);
}
}
var ret = Node.createBlockStatement(statements, tn.range(startPos, tn.pos));
tn.skip(Token.SEMICOLON);
@ -2964,6 +2995,59 @@ export class Parser extends DiagnosticEmitter {
}
return expr;
}
/** Skips over a statement on errors in an attempt to reduce unnecessary diagnostic noise. */
skipStatement(tn: Tokenizer): void {
tn.peek(true);
if (tn.nextTokenOnNewLine) tn.next(); // if reset() to the previous line
do {
let nextToken = tn.peek(true);
if (
nextToken == Token.ENDOFFILE || // next step should handle this
nextToken == Token.CLOSEBRACE // current step should handle this
) {
break;
}
if (nextToken == Token.SEMICOLON) { // end of the statement for sure
tn.next();
break;
}
if (tn.nextTokenOnNewLine) break; // end of the statement maybe
switch (tn.next()) {
case Token.IDENTIFIER: {
tn.readIdentifier();
break;
}
case Token.STRINGLITERAL: {
tn.readString();
break;
}
case Token.INTEGERLITERAL: {
tn.readInteger();
break;
}
case Token.FLOATLITERAL: {
tn.readFloat();
break;
}
}
} while (true);
}
/** Skips over a block on errors in an attempt to reduce unnecessary diagnostic noise. */
// skipBlock(tn: Tokenizer): void {
// var depth = 0;
// var token: Token;
// do {
// token = tn.next();
// if (token == Token.OPENBRACE) {
// ++depth;
// } else if (token == Token.CLOSEBRACE) {
// if (depth) --depth;
// if (!depth) break; // done
// }
// } while (token != Token.ENDOFFILE);
// }
}
/** Operator precedence from least to largest. */

View File

@ -871,17 +871,6 @@ export class Tokenizer extends DiagnosticEmitter {
}
}
// skipUntil(token1: Token, token2: Token = -1): bool {
// var next: Token;
// do {
// if ((next = this.peek()) == Token.ENDOFFILE)
// return false;
// if (next == token1 || next == token2)
// return true;
// this.next();
// } while (true);
// }
mark(): State {
var state: State;
if (reusableState) {

View File

@ -1,5 +1,4 @@
;
;
a;
from;
"./other";
@ -8,5 +7,3 @@ do {
} while (false);
// ERROR 1003: "Identifier expected." in continue-on-error.ts @ 0,3
// ERROR 1005: "'(' expected." in continue-on-error.ts @ 5,10
// ERROR 1005: "'(' expected." in continue-on-error.ts @ 11,14
// ERROR 1003: "Identifier expected." in continue-on-error.ts @ 15,18

View File

@ -2,7 +2,6 @@
/(abc)\//;
var re = /(abc)\//ig;
var noRe = !/(abc)\//i;
b / ig;
/(abc)\//iig;
/(abc)\//iX;
false && /abc/gX.test(someString) || true;