diff --git a/src/com/google/javascript/jscomp/parsing/parser/Parser.java b/src/com/google/javascript/jscomp/parsing/parser/Parser.java index bc906c69c3d..4aa2f69a8e2 100644 --- a/src/com/google/javascript/jscomp/parsing/parser/Parser.java +++ b/src/com/google/javascript/jscomp/parsing/parser/Parser.java @@ -206,7 +206,12 @@ public static enum Mode { ES8 } - public final boolean is6Typed; + /** + * Indicates that the parser should look for TypeScript-like data type syntax. + */ + // TODO(bradfordcsmith): Make sure all of the type syntax handling code is avoided when + // this is false. + public final boolean parseTypeSyntax; public final boolean atLeast6; public final boolean atLeast5; public final boolean isStrictMode; @@ -215,7 +220,7 @@ public static enum Mode { public final boolean warnES6NumberLiteral; public Config(Mode mode) { - is6Typed = mode == Mode.ES6_TYPED; + parseTypeSyntax = mode == Mode.ES6_TYPED; atLeast6 = mode == Mode.ES6 || mode == Mode.ES6_STRICT || mode == Mode.ES6_TYPED; atLeast5 = atLeast6 || mode == Mode.ES5 || mode == Mode.ES5_STRICT; @@ -747,7 +752,7 @@ private ParseTree parseClass(boolean isExpression, boolean isAmbient) { } ImmutableList.Builder interfaces = ImmutableList.builder(); - if (peek(TokenType.IMPLEMENTS)) { + if (config.parseTypeSyntax && peek(TokenType.IMPLEMENTS)) { eat(TokenType.IMPLEMENTS); ParseTree type = parseType(); interfaces.add(type); @@ -823,7 +828,7 @@ private ParseTree parseClassMemberDeclaration( nameExpr = null; name = eatIdOrKeywordAsId(); } else { - if (peekIndexSignature()) { + if (config.parseTypeSyntax && peekIndexSignature()) { ParseTree indexSignature = parseIndexSignature(); eatPossibleImplicitSemiColon(); return indexSignature; @@ -1067,7 +1072,7 @@ private boolean peekFunction(int index) { } private boolean peekFunctionTypeExpression() { - if (peek(TokenType.OPEN_PAREN) || peek(TokenType.OPEN_ANGLE)) { + if (config.parseTypeSyntax && peek(TokenType.OPEN_PAREN) || peek(TokenType.OPEN_ANGLE)) { // TODO(blickly): determine if we can parse this without the // overhead of forking the parser. Parser p = createLookaheadParser(); @@ -3666,11 +3671,8 @@ private boolean peekAccessibilityModifier() { } private TokenType maybeParseAccessibilityModifier() { - if (peekAccessibilityModifier()) { + if (config.parseTypeSyntax && peekAccessibilityModifier()) { features = features.require(FeatureSet.TYPESCRIPT); - if (!config.is6Typed) { - reportError("Accessibility modifier is only supported in ES6 typed mode"); - } return nextToken().type; } else { return null; diff --git a/test/com/google/javascript/jscomp/parsing/TypeSyntaxTest.java b/test/com/google/javascript/jscomp/parsing/TypeSyntaxTest.java index 9bcdfeb3eb7..399f857e7b7 100644 --- a/test/com/google/javascript/jscomp/parsing/TypeSyntaxTest.java +++ b/test/com/google/javascript/jscomp/parsing/TypeSyntaxTest.java @@ -401,8 +401,8 @@ public void testFunctionType_missingParens() { } public void testFunctionType_notEs6Typed() { - testNotEs6Typed("var n: (p1:string) => boolean;", "type annotation"); - testNotEs6Typed("var n: (p1?) => boolean;", "type annotation", "optional parameter"); + testNotEs6TypedFullError("var n: (p1:string) => boolean;", "Parse error. ')' expected"); + testNotEs6TypedFullError("var n: (p1?) => boolean;", "Parse error. ')' expected"); } public void testInterface() { @@ -533,7 +533,7 @@ public void testImplements() { parse("class Foo implements Bar, Baz {\n}"); parse("class Foo extends Bar implements Baz {\n}"); - testNotEs6Typed("class Foo implements Bar {\n}", "implements"); + testNotEs6TypedFullError("class Foo implements Bar {\n}", "Parse error. '{' expected"); } public void testTypeAlias() { @@ -615,22 +615,22 @@ public void testAccessibilityModifier() { testNotEs6TypedFullError( "class Foo { private constructor() {} }", - "Parse error. Accessibility modifier is only supported in ES6 typed mode"); + "Parse error. Semi-colon expected"); testNotEs6TypedFullError( "class Foo { protected bar; }", - "Parse error. Accessibility modifier is only supported in ES6 typed mode"); + "Parse error. Semi-colon expected"); testNotEs6TypedFullError( "class Foo { protected bar() {} }", - "Parse error. Accessibility modifier is only supported in ES6 typed mode"); + "Parse error. Semi-colon expected"); testNotEs6TypedFullError( "class Foo { private get() {} }", - "Parse error. Accessibility modifier is only supported in ES6 typed mode"); + "Parse error. Semi-colon expected"); testNotEs6TypedFullError( "class Foo { private set() {} }", - "Parse error. Accessibility modifier is only supported in ES6 typed mode"); + "Parse error. Semi-colon expected"); testNotEs6TypedFullError( "class Foo { private [Symbol.iterator]() {} }", - "Parse error. Accessibility modifier is only supported in ES6 typed mode"); + "Parse error. Semi-colon expected"); } public void testOptionalProperty() { @@ -679,8 +679,7 @@ public void testIndexSignature() { expectErrors("Parse error. Index signature parameter type must be 'string' or 'number'"); parse("interface I {\n [foo: any]: number;\n}"); - testNotEs6Typed("class C {\n [foo: number]: number;\n}", - "index signature", "type annotation", "type annotation"); + testNotEs6TypedFullError("class C {\n [foo: number]: number;\n}", "Parse error. ']' expected"); } public void testCallSignature() {