Move parser error to grammar check phase.

Conflicts:
	src/services/syntax/SyntaxGenerator.js.map
This commit is contained in:
Cyrus Najmabadi
2014-11-22 12:49:16 -08:00
parent 16d5ae7146
commit 5fcbeb59ae
6 changed files with 32 additions and 17 deletions

View File

@@ -1558,7 +1558,7 @@ var definitions = [
interfaces: ['IStatementSyntax'],
children: [
{ name: 'throwKeyword', isToken: true, excludeFromAST: true },
{ name: 'expression', type: 'IExpressionSyntax' },
{ name: 'expression', type: 'IExpressionSyntax', isOptional: true },
{ name: 'semicolonToken', isToken: true, isOptional: true, excludeFromAST: true }
]
},

File diff suppressed because one or more lines are too long

View File

@@ -2098,33 +2098,33 @@ module TypeScript.Parser {
parseSyntaxList<IStatementSyntax>(ListParsingState.SwitchClause_Statements));
}
function parseThrowStatementExpression(): IExpressionSyntax {
function parseThrowStatement(throwKeyword: ISyntaxToken): ThrowStatementSyntax {
return new ThrowStatementSyntax(parseNodeData,
consumeToken(throwKeyword), tryParseThrowStatementExpression(), eatExplicitOrAutomaticSemicolon(/*allowWithoutNewline:*/ false));
}
function tryParseThrowStatementExpression(): IExpressionSyntax {
// ThrowStatement[Yield] :
// throw [no LineTerminator here]Expression[In, ?Yield];
// Because of automatic semicolon insertion, we need to report error if this
// throw could be terminated with a semicolon. Note: we can't call 'parseExpression'
// directly as that might consume an expression on the following line.
return canEatExplicitOrAutomaticSemicolon(/*allowWithoutNewline:*/ false)
? createMissingToken(SyntaxKind.IdentifierName, undefined)
: allowInAnd(parseExpression);
// We just return 'undefined' in that case. The actual error will be reported in the
// grammar walker.
return canEatExplicitOrAutomaticSemicolon(/*allowWithoutNewline:*/ false) ? undefined : allowInAnd(parseExpression);
}
function parseThrowStatement(throwKeyword: ISyntaxToken): ThrowStatementSyntax {
return new ThrowStatementSyntax(parseNodeData,
consumeToken(throwKeyword), parseThrowStatementExpression(), eatExplicitOrAutomaticSemicolon(/*allowWithoutNewline:*/ false));
function parseReturnStatement(returnKeyword: ISyntaxToken): ReturnStatementSyntax {
return new ReturnStatementSyntax(parseNodeData,
consumeToken(returnKeyword), tryParseReturnStatementExpression(), eatExplicitOrAutomaticSemicolon(/*allowWithoutNewline:*/ false));
}
function tryParseReturnStatementExpression(): IExpressionSyntax {
// ReturnStatement[Yield] :
// return [no LineTerminator here]Expression[In, ?Yield];
return !canEatExplicitOrAutomaticSemicolon(/*allowWithoutNewline:*/ false) ? allowInAnd(parseExpression) : undefined;
}
function parseReturnStatement(returnKeyword: ISyntaxToken): ReturnStatementSyntax {
return new ReturnStatementSyntax(parseNodeData,
consumeToken(returnKeyword), tryParseReturnStatementExpression(), eatExplicitOrAutomaticSemicolon(/*allowWithoutNewline:*/ false));
return canEatExplicitOrAutomaticSemicolon(/*allowWithoutNewline:*/ false) ? undefined : allowInAnd(parseExpression);
}
function isExpressionStatement(currentToken: ISyntaxToken): boolean {

View File

@@ -705,7 +705,7 @@ var definitions:ITypeDefinition[] = [
interfaces: ['IStatementSyntax'],
children: [
<any>{ name: 'throwKeyword', isToken: true, excludeFromAST: true },
<any>{ name: 'expression', type: 'IExpressionSyntax' },
<any>{ name: 'expression', type: 'IExpressionSyntax', isOptional: true },
<any>{ name: 'semicolonToken', isToken: true, isOptional: true, excludeFromAST: true }
]
},

View File

@@ -893,7 +893,7 @@ module TypeScript {
this.expression = expression,
this.semicolonToken = semicolonToken,
throwKeyword.parent = this,
expression.parent = this,
expression && (expression.parent = this),
semicolonToken && (semicolonToken.parent = this);
};
ThrowStatementSyntax.prototype.kind = SyntaxKind.ThrowStatement;

View File

@@ -1264,13 +1264,24 @@ module TypeScript {
}
public visitThrowStatement(node: ThrowStatementSyntax): void {
if (this.checkForStatementInAmbientContxt(node)) {
if (this.checkForStatementInAmbientContxt(node) ||
this.checkForMissingThrowStatementExpression(node)) {
return;
}
super.visitThrowStatement(node);
}
public checkForMissingThrowStatementExpression(node: ThrowStatementSyntax): boolean {
if (node.expression === undefined) {
this.diagnostics.push(new Diagnostic(
this.syntaxTree.fileName(), this.syntaxTree.lineMap(), fullEnd(node.throwKeyword), 0, DiagnosticCode.Expression_expected));
return true;
}
return false;
}
public visitTryStatement(node: TryStatementSyntax): void {
if (this.checkForStatementInAmbientContxt(node)) {
return;