Removing duplication in the parser.
This commit is contained in:
parent
5f2da4afc8
commit
65b5d47217
|
@ -1736,32 +1736,64 @@ module TypeScript.Parser {
|
|||
return false;
|
||||
}
|
||||
|
||||
function isDefinitelyNotStatement() {
|
||||
var _currentToken = currentToken();
|
||||
var currentTokenKind = _currentToken.kind;
|
||||
|
||||
// 'async' is a modifier, but can start a statement. So we skip further checks if we
|
||||
// see it.
|
||||
if (currentTokenKind !== SyntaxKind.AsyncKeyword) {
|
||||
switch (currentTokenKind) {
|
||||
case SyntaxKind.PublicKeyword:
|
||||
case SyntaxKind.PrivateKeyword:
|
||||
case SyntaxKind.ProtectedKeyword:
|
||||
case SyntaxKind.StaticKeyword:
|
||||
|
||||
//if (isModifierKind(currentTokenKind)) {
|
||||
// ERROR RECOVERY
|
||||
// None of the modifiers are actually keywords. And they might show up in a real
|
||||
// statement (i.e. "public();"). However, if we see 'public <identifier>' then
|
||||
// that can't possibly be a statement (and instead will be a class element),
|
||||
// and we should not parse it out here. Note: if there is a newline between the
|
||||
// elements, then we should not do this. That's because asi might take effect. i.e.:
|
||||
//
|
||||
// public
|
||||
// foo
|
||||
//
|
||||
// Are two legal statements in JS.
|
||||
//
|
||||
// Also: 'async a' can start an statement, so we want to check for that as well.
|
||||
var token1 = peekToken(1);
|
||||
if (!token1.hasLeadingNewLine() && SyntaxFacts.isIdentifierNameOrAnyKeyword(token1)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for common things that might appear where we expect a statement, but which we
|
||||
// do not want to consume. This can happen when the user does not terminate their
|
||||
// existing block properly. We don't want to accidently consume these as expression
|
||||
// below.
|
||||
if (isInterfaceEnumClassModuleImportOrExport(modifierCount(), _currentToken)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function isStatement(modifierCount: number, inErrorRecovery: boolean): boolean {
|
||||
if (SyntaxUtilities.isStatement(currentNode())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (isDefinitelyNotStatement()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var _currentToken = currentToken();
|
||||
var currentTokenKind = _currentToken.kind;
|
||||
|
||||
switch (currentTokenKind) {
|
||||
// ERROR RECOVERY
|
||||
case SyntaxKind.PublicKeyword:
|
||||
case SyntaxKind.PrivateKeyword:
|
||||
case SyntaxKind.ProtectedKeyword:
|
||||
case SyntaxKind.StaticKeyword:
|
||||
// None of the above are actually keywords. And they might show up in a real
|
||||
// statement (i.e. "public();"). However, if we see 'public <identifier>' then
|
||||
// that can't possibly be a statement (and instead will be a class element),
|
||||
// and we should not parse it out here.
|
||||
var token1 = peekToken(1);
|
||||
if (SyntaxFacts.isIdentifierNameOrAnyKeyword(token1)) {
|
||||
// Definitely not a statement.
|
||||
return false;
|
||||
}
|
||||
|
||||
// Handle this below in 'isExpressionStatement()'
|
||||
break;
|
||||
|
||||
// Common cases that we can immediately assume are statements.
|
||||
case SyntaxKind.IfKeyword:
|
||||
case SyntaxKind.OpenBraceToken:
|
||||
|
@ -1779,14 +1811,6 @@ module TypeScript.Parser {
|
|||
return true;
|
||||
}
|
||||
|
||||
// Check for common things that might appear where we expect a statement, but which we
|
||||
// do not want to consume. This can happen when the user does not terminate their
|
||||
// existing block properly. We don't want to accidently consume these as expression
|
||||
// below.
|
||||
if (isInterfaceEnumClassModuleImportOrExport(modifierCount, _currentToken)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// More complicated cases.
|
||||
return isLabeledStatement(_currentToken) ||
|
||||
isVariableStatement(modifierCount) ||
|
||||
|
@ -1812,24 +1836,11 @@ module TypeScript.Parser {
|
|||
}
|
||||
|
||||
function tryParseStatementWorker(_currentToken: ISyntaxToken, currentTokenKind: SyntaxKind, modifierCount: number, inErrorRecovery: boolean): IStatementSyntax {
|
||||
switch (currentTokenKind) {
|
||||
// ERROR RECOVERY
|
||||
case SyntaxKind.PublicKeyword:
|
||||
case SyntaxKind.PrivateKeyword:
|
||||
case SyntaxKind.ProtectedKeyword:
|
||||
case SyntaxKind.StaticKeyword:
|
||||
// None of the above are actually keywords. And they might show up in a real
|
||||
// statement (i.e. "public();"). However, if we see 'public <identifier>' then
|
||||
// that can't possibly be a statement (and instead will be a class element),
|
||||
// and we should not parse it out here.
|
||||
if (SyntaxFacts.isIdentifierNameOrAnyKeyword(peekToken(1))) {
|
||||
// Definitely not a statement.
|
||||
return undefined;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
if (isDefinitelyNotStatement()) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
switch (currentTokenKind) {
|
||||
case SyntaxKind.IfKeyword: return parseIfStatement(_currentToken);
|
||||
case SyntaxKind.OpenBraceToken: return parseStatementBlock();
|
||||
case SyntaxKind.ReturnKeyword: return parseReturnStatement(_currentToken);
|
||||
|
@ -1845,14 +1856,7 @@ module TypeScript.Parser {
|
|||
case SyntaxKind.DebuggerKeyword: return parseDebuggerStatement(_currentToken);
|
||||
}
|
||||
|
||||
// Check for common things that might appear where we expect a statement, but which we
|
||||
// do not want to consume. This can happen when the user does not terminate their
|
||||
// existing block properly. We don't want to accidently consume these as expression
|
||||
// below.
|
||||
if (isInterfaceEnumClassModuleImportOrExport(modifierCount, _currentToken)) {
|
||||
return undefined;
|
||||
}
|
||||
else if (isVariableStatement(modifierCount)) {
|
||||
if (isVariableStatement(modifierCount)) {
|
||||
return parseVariableStatement();
|
||||
}
|
||||
else if (isLabeledStatement(_currentToken)) {
|
||||
|
|
Loading…
Reference in a new issue