diff --git a/src/com/google/javascript/jscomp/AbstractPeepholeOptimization.java b/src/com/google/javascript/jscomp/AbstractPeepholeOptimization.java index 366cbae33a0..26492f9731c 100644 --- a/src/com/google/javascript/jscomp/AbstractPeepholeOptimization.java +++ b/src/com/google/javascript/jscomp/AbstractPeepholeOptimization.java @@ -17,6 +17,7 @@ package com.google.javascript.jscomp; import com.google.common.base.Preconditions; +import com.google.javascript.jscomp.parsing.parser.FeatureSet; import com.google.javascript.rhino.Node; /** @@ -134,7 +135,8 @@ boolean nodeTypeMayHaveSideEffects(Node n) { * ignored when this is true. */ boolean isEcmaScript5OrGreater() { - return compiler != null && compiler.getOptions().getLanguageOut().isEs5OrHigher(); + return compiler != null + && compiler.getOptions().getLanguageOut().toFeatureSet().contains(FeatureSet.ES5); } /** diff --git a/src/com/google/javascript/jscomp/CommandLineRunner.java b/src/com/google/javascript/jscomp/CommandLineRunner.java index dd9b1a9b674..64cfcb22975 100644 --- a/src/com/google/javascript/jscomp/CommandLineRunner.java +++ b/src/com/google/javascript/jscomp/CommandLineRunner.java @@ -31,6 +31,7 @@ import com.google.javascript.jscomp.CompilerOptions.IsolationMode; import com.google.javascript.jscomp.SourceMap.LocationMapping; import com.google.javascript.jscomp.deps.ModuleLoader; +import com.google.javascript.jscomp.parsing.parser.FeatureSet; import com.google.javascript.rhino.TokenStream; import com.google.protobuf.TextFormat; import java.io.BufferedReader; @@ -1688,7 +1689,8 @@ protected CompilerOptions createOptions() { options.setForceLibraryInjection(flags.forceInjectLibraries); } - options.rewritePolyfills = flags.rewritePolyfills && options.getLanguageIn().isEs6OrHigher(); + options.rewritePolyfills = + flags.rewritePolyfills && options.getLanguageIn().toFeatureSet().contains(FeatureSet.ES6); if (!flags.translationsFile.isEmpty()) { try { diff --git a/src/com/google/javascript/jscomp/CompilerOptions.java b/src/com/google/javascript/jscomp/CompilerOptions.java index bb82158194a..3f2f1acd46e 100644 --- a/src/com/google/javascript/jscomp/CompilerOptions.java +++ b/src/com/google/javascript/jscomp/CompilerOptions.java @@ -3015,25 +3015,10 @@ boolean isDefaultStrict() { } } - /** Whether this is ECMAScript 5 or higher. */ - @Deprecated - public boolean isEs5OrHigher() { - Preconditions.checkState(this != NO_TRANSPILE); - return this != LanguageMode.ECMASCRIPT3; - } - /** Whether this is ECMAScript 6 or higher. */ @Deprecated public boolean isEs6OrHigher() { - Preconditions.checkState(this != NO_TRANSPILE); - switch (this) { - case ECMASCRIPT3: - case ECMASCRIPT5: - case ECMASCRIPT5_STRICT: - return false; - default: - return true; - } + return this.toFeatureSet().contains(FeatureSet.ES6); } public static LanguageMode fromString(String value) { diff --git a/src/com/google/javascript/jscomp/CompilerOptionsPreprocessor.java b/src/com/google/javascript/jscomp/CompilerOptionsPreprocessor.java index 0a07760c5ae..eea2f1fdfe3 100644 --- a/src/com/google/javascript/jscomp/CompilerOptionsPreprocessor.java +++ b/src/com/google/javascript/jscomp/CompilerOptionsPreprocessor.java @@ -17,6 +17,7 @@ import static com.google.common.base.Strings.isNullOrEmpty; +import com.google.javascript.jscomp.parsing.parser.FeatureSet; import com.google.javascript.jscomp.parsing.parser.util.format.SimpleFormat; /** @@ -47,8 +48,9 @@ static void preprocess(CompilerOptions options) { + "remove_unused_prototype_props to be turned on."); } - if (options.getLanguageOut().isEs6OrHigher() - && !options.skipNonTranspilationPasses && !options.skipTranspilationAndCrash) { + if (options.getLanguageOut().toFeatureSet().contains(FeatureSet.ES6) + && !options.skipNonTranspilationPasses + && !options.skipTranspilationAndCrash) { throw new InvalidOptionsException( "ES6 is only supported for transpilation to a lower ECMAScript" + " version. Set --language_out to ES3, ES5, or ES5_STRICT."); @@ -71,7 +73,7 @@ static void preprocess(CompilerOptions options) { } if (options.dartPass) { - if (!options.getLanguageOut().isEs5OrHigher()) { + if (!options.getLanguageOut().toFeatureSet().contains(FeatureSet.ES5)) { throw new InvalidOptionsException("Dart requires --language_out=ES5 or higher."); } // --dart_pass does not support type-aware property renaming yet. diff --git a/src/com/google/javascript/jscomp/ConvertToDottedProperties.java b/src/com/google/javascript/jscomp/ConvertToDottedProperties.java index be6d6f73a92..f32838a362c 100644 --- a/src/com/google/javascript/jscomp/ConvertToDottedProperties.java +++ b/src/com/google/javascript/jscomp/ConvertToDottedProperties.java @@ -16,9 +16,8 @@ package com.google.javascript.jscomp; - -import com.google.javascript.jscomp.CompilerOptions.LanguageMode; import com.google.javascript.jscomp.NodeTraversal.AbstractPostOrderCallback; +import com.google.javascript.jscomp.parsing.parser.FeatureSet; import com.google.javascript.rhino.IR; import com.google.javascript.rhino.Node; @@ -48,7 +47,7 @@ public void visit(NodeTraversal t, Node n, Node parent) { case GETTER_DEF: case SETTER_DEF: case STRING_KEY: - if (NodeUtil.isValidPropertyName(LanguageMode.ECMASCRIPT3, n.getString())) { + if (NodeUtil.isValidPropertyName(FeatureSet.ES3, n.getString())) { if (n.getBooleanProp(Node.QUOTED_PROP)) { n.putBooleanProp(Node.QUOTED_PROP, false); compiler.reportChangeToEnclosingScope(n); @@ -59,8 +58,7 @@ public void visit(NodeTraversal t, Node n, Node parent) { case GETELEM: Node left = n.getFirstChild(); Node right = left.getNext(); - if (right.isString() - && NodeUtil.isValidPropertyName(LanguageMode.ECMASCRIPT3, right.getString())) { + if (right.isString() && NodeUtil.isValidPropertyName(FeatureSet.ES3, right.getString())) { n.removeChild(left); n.removeChild(right); Node newGetProp = IR.getprop(left, right); diff --git a/src/com/google/javascript/jscomp/DartSuperAccessorsPass.java b/src/com/google/javascript/jscomp/DartSuperAccessorsPass.java index fdf32e1c1ef..47d9649c3e6 100644 --- a/src/com/google/javascript/jscomp/DartSuperAccessorsPass.java +++ b/src/com/google/javascript/jscomp/DartSuperAccessorsPass.java @@ -16,6 +16,7 @@ package com.google.javascript.jscomp; import com.google.common.base.Preconditions; +import com.google.javascript.jscomp.parsing.parser.FeatureSet; import com.google.javascript.rhino.IR; import com.google.javascript.rhino.Node; @@ -50,7 +51,8 @@ public DartSuperAccessorsPass(AbstractCompiler compiler) { this.renameProperties = options.propertyRenaming == PropertyRenamingPolicy.ALL_UNQUOTED; - Preconditions.checkState(options.getLanguageOut().isEs5OrHigher(), + Preconditions.checkState( + options.getLanguageOut().toFeatureSet().contains(FeatureSet.ES5), "Dart super accessors pass requires ES5+ output"); // We currently rely on JSCompiler_renameProperty, which is not type-aware. diff --git a/src/com/google/javascript/jscomp/DefaultPassConfig.java b/src/com/google/javascript/jscomp/DefaultPassConfig.java index 4ef45399ded..42b195712bb 100644 --- a/src/com/google/javascript/jscomp/DefaultPassConfig.java +++ b/src/com/google/javascript/jscomp/DefaultPassConfig.java @@ -368,7 +368,7 @@ protected List getChecks() { // It's important that the Dart super accessors pass run *before* es6ConvertSuper, // which is a "late" ES6 pass. This is enforced in the assertValidOrder method. - if (options.dartPass && !options.getLanguageOut().isEs6OrHigher()) { + if (options.dartPass && !options.getLanguageOut().toFeatureSet().contains(FeatureSet.ES6)) { checks.add(dartSuperAccessorsPass); } @@ -911,7 +911,7 @@ protected List getOptimizations() { passes.add(sanityCheckVars); // Raise to ES6, if allowed - if (options.getLanguageOut().isEs6OrHigher()) { + if (options.getLanguageOut().toFeatureSet().contains(FeatureSet.ES6)) { passes.add(optimizeToEs6); } diff --git a/src/com/google/javascript/jscomp/NodeUtil.java b/src/com/google/javascript/jscomp/NodeUtil.java index d2e0d323f3c..26fb89f64dc 100644 --- a/src/com/google/javascript/jscomp/NodeUtil.java +++ b/src/com/google/javascript/jscomp/NodeUtil.java @@ -22,6 +22,8 @@ import com.google.common.base.Splitter; import com.google.common.collect.ImmutableSet; import com.google.javascript.jscomp.CompilerOptions.LanguageMode; +import com.google.javascript.jscomp.parsing.parser.FeatureSet; +import com.google.javascript.jscomp.parsing.parser.FeatureSet.Feature; import com.google.javascript.rhino.IR; import com.google.javascript.rhino.InputId; import com.google.javascript.rhino.JSDocInfo; @@ -3507,10 +3509,13 @@ static boolean isValidSimpleName(String name) { && isLatin(name); } - /** - * Determines whether the given name is a valid qualified name. - */ + @Deprecated public static boolean isValidQualifiedName(LanguageMode mode, String name) { + return isValidQualifiedName(mode.toFeatureSet(), name); + } + + /** Determines whether the given name is a valid qualified name. */ + public static boolean isValidQualifiedName(FeatureSet mode, String name) { if (name.endsWith(".") || name.startsWith(".")) { return false; } @@ -3525,14 +3530,14 @@ public static boolean isValidQualifiedName(LanguageMode mode, String name) { } /** - * Determines whether the given name can appear on the right side of - * the dot operator. Many properties (like reserved words) cannot, in ES3. + * Determines whether the given name can appear on the right side of the dot operator. Many + * properties (like reserved words) cannot, in ES3. */ - static boolean isValidPropertyName(LanguageMode mode, String name) { + static boolean isValidPropertyName(FeatureSet mode, String name) { if (isValidSimpleName(name)) { return true; } else { - return mode.isEs5OrHigher() && TokenStream.isKeyword(name); + return mode.contains(Feature.KEYWORDS_AS_PROPERTIES) && TokenStream.isKeyword(name); } } diff --git a/src/com/google/javascript/jscomp/ProcessClosurePrimitives.java b/src/com/google/javascript/jscomp/ProcessClosurePrimitives.java index 8105ed052d9..cdb3d250c03 100644 --- a/src/com/google/javascript/jscomp/ProcessClosurePrimitives.java +++ b/src/com/google/javascript/jscomp/ProcessClosurePrimitives.java @@ -1043,7 +1043,8 @@ private boolean verifyProvide(NodeTraversal t, Node methodName, Node arg) { return false; } - if (!NodeUtil.isValidQualifiedName(compiler.getOptions().getLanguageIn(), arg.getString())) { + if (!NodeUtil.isValidQualifiedName( + compiler.getOptions().getLanguageIn().toFeatureSet(), arg.getString())) { compiler.report(t.makeError(arg, INVALID_PROVIDE_ERROR, arg.getString(), compiler.getOptions().getLanguageIn().toString())); return false; @@ -1077,7 +1078,8 @@ private boolean verifyDefine(NodeTraversal t, } String name = args.getString(); - if (!NodeUtil.isValidQualifiedName(compiler.getOptions().getLanguageIn(), name)) { + if (!NodeUtil.isValidQualifiedName( + compiler.getOptions().getLanguageIn().toFeatureSet(), name)) { compiler.report(t.makeError(args, INVALID_DEFINE_NAME_ERROR, name)); return false; } diff --git a/src/com/google/javascript/jscomp/ProcessCommonJSModules.java b/src/com/google/javascript/jscomp/ProcessCommonJSModules.java index 4c989bab121..7b7169cbd9e 100644 --- a/src/com/google/javascript/jscomp/ProcessCommonJSModules.java +++ b/src/com/google/javascript/jscomp/ProcessCommonJSModules.java @@ -1150,7 +1150,7 @@ private String getExportedName(NodeTraversal t, Node n, Var var) { if (key.isStringKey() && !key.isQuotedString() && NodeUtil.isValidPropertyName( - compiler.getOptions().getLanguageIn(), key.getString())) { + compiler.getOptions().getLanguageIn().toFeatureSet(), key.getString())) { if (key.hasChildren()) { if (key.getFirstChild().isQualifiedName()) { if (key.getFirstChild() == n) { diff --git a/src/com/google/javascript/jscomp/TranspilationPasses.java b/src/com/google/javascript/jscomp/TranspilationPasses.java index 0170ac17bfe..6c8c85c926a 100644 --- a/src/com/google/javascript/jscomp/TranspilationPasses.java +++ b/src/com/google/javascript/jscomp/TranspilationPasses.java @@ -205,7 +205,7 @@ static boolean isScriptEs6ImplOrHigher(Node script) { * @param callbacks The callbacks that should be invoked if a file has ES6 features. */ static void processCheck(AbstractCompiler compiler, Node combinedRoot, Callback... callbacks) { - if (compiler.getOptions().getLanguageIn().isEs6OrHigher()) { + if (compiler.getOptions().getLanguageIn().toFeatureSet().contains(FeatureSet.ES6)) { for (Node singleRoot : combinedRoot.children()) { if (isScriptEs6ImplOrHigher(singleRoot)) { for (Callback callback : callbacks) { @@ -225,7 +225,7 @@ static void processCheck(AbstractCompiler compiler, Node combinedRoot, Callback. * @param callbacks The callbacks that should be invoked if the file has ES6 features. */ static void hotSwapCheck(AbstractCompiler compiler, Node scriptRoot, Callback... callbacks) { - if (compiler.getOptions().getLanguageIn().isEs6OrHigher()) { + if (compiler.getOptions().getLanguageIn().toFeatureSet().contains(FeatureSet.ES6)) { if (isScriptEs6ImplOrHigher(scriptRoot)) { for (Callback callback : callbacks) { NodeTraversal.traverseEs6(compiler, scriptRoot, callback); diff --git a/src/com/google/javascript/jscomp/VariableReferenceCheck.java b/src/com/google/javascript/jscomp/VariableReferenceCheck.java index 3902e7aa965..c8b246f8df8 100644 --- a/src/com/google/javascript/jscomp/VariableReferenceCheck.java +++ b/src/com/google/javascript/jscomp/VariableReferenceCheck.java @@ -20,6 +20,7 @@ import com.google.common.collect.Sets; import com.google.javascript.jscomp.NodeTraversal.AbstractShallowCallback; import com.google.javascript.jscomp.ReferenceCollectingCallback.Behavior; +import com.google.javascript.jscomp.parsing.parser.FeatureSet; import com.google.javascript.rhino.JSDocInfo; import com.google.javascript.rhino.Node; import com.google.javascript.rhino.Token; @@ -95,7 +96,7 @@ private boolean shouldProcess(Node root) { if (!forTranspileOnly) { return true; } - if (compiler.getOptions().getLanguageIn().isEs6OrHigher()) { + if (compiler.getOptions().getLanguageIn().toFeatureSet().contains(FeatureSet.ES6)) { for (Node singleRoot : root.children()) { if (TranspilationPasses.isScriptEs6ImplOrHigher(singleRoot)) { return true; @@ -117,7 +118,7 @@ compiler, new ReferenceCheckingBehavior(), new Es6SyntacticScopeCreator(compiler @Override public void hotSwapScript(Node scriptRoot, Node originalRoot) { if (!forTranspileOnly - || (compiler.getOptions().getLanguageIn().isEs6OrHigher() + || (compiler.getOptions().getLanguageIn().toFeatureSet().contains(FeatureSet.ES6) && TranspilationPasses.isScriptEs6ImplOrHigher(scriptRoot))) { new ReferenceCollectingCallback( compiler, new ReferenceCheckingBehavior(), new Es6SyntacticScopeCreator(compiler)) diff --git a/test/com/google/javascript/jscomp/NewTypeInferenceTestBase.java b/test/com/google/javascript/jscomp/NewTypeInferenceTestBase.java index e86f2e410ab..14f62f97f0e 100644 --- a/test/com/google/javascript/jscomp/NewTypeInferenceTestBase.java +++ b/test/com/google/javascript/jscomp/NewTypeInferenceTestBase.java @@ -22,6 +22,7 @@ import com.google.common.collect.ImmutableList; import com.google.javascript.jscomp.CompilerOptions.LanguageMode; +import com.google.javascript.jscomp.parsing.parser.FeatureSet; import com.google.javascript.rhino.IR; import com.google.javascript.rhino.InputId; import com.google.javascript.rhino.Node; @@ -222,8 +223,7 @@ private final void parseAndTypeCheck(String externs, String js) { passes.add(makePassFactory("convertEs6TypedToEs6", new Es6TypedToEs6Converter(compiler))); } - if (compilerOptions.getLanguageIn().isEs6OrHigher() - && !compilerOptions.getLanguageOut().isEs6OrHigher()) { + if (compilerOptions.needsTranspilationFrom(FeatureSet.ES6)) { TranspilationPasses.addEs2017Passes(passes); TranspilationPasses.addEs6EarlyPasses(passes); TranspilationPasses.addEs6LatePasses(passes); diff --git a/test/com/google/javascript/jscomp/NodeUtilTest.java b/test/com/google/javascript/jscomp/NodeUtilTest.java index c8ac4f84cd9..9fa14e2ed48 100644 --- a/test/com/google/javascript/jscomp/NodeUtilTest.java +++ b/test/com/google/javascript/jscomp/NodeUtilTest.java @@ -25,6 +25,7 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.javascript.jscomp.CompilerOptions.LanguageMode; +import com.google.javascript.jscomp.parsing.parser.FeatureSet; import com.google.javascript.rhino.IR; import com.google.javascript.rhino.JSTypeExpression; import com.google.javascript.rhino.Node; @@ -2587,10 +2588,10 @@ private static Node getNameNode(Node n, String name) { } private static boolean isValidPropertyName(String s) { - return NodeUtil.isValidPropertyName(LanguageMode.ECMASCRIPT3, s); + return NodeUtil.isValidPropertyName(FeatureSet.ES3, s); } private static boolean isValidQualifiedName(String s) { - return NodeUtil.isValidQualifiedName(LanguageMode.ECMASCRIPT3, s); + return NodeUtil.isValidQualifiedName(FeatureSet.ES3, s); } } diff --git a/test/com/google/javascript/jscomp/TypeCheckTest.java b/test/com/google/javascript/jscomp/TypeCheckTest.java index 3bdf6433344..c6f317a2dc8 100644 --- a/test/com/google/javascript/jscomp/TypeCheckTest.java +++ b/test/com/google/javascript/jscomp/TypeCheckTest.java @@ -24,6 +24,7 @@ import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.javascript.jscomp.CompilerOptions.LanguageMode; +import com.google.javascript.jscomp.parsing.parser.FeatureSet; import com.google.javascript.jscomp.type.ClosureReverseAbstractInterpreter; import com.google.javascript.jscomp.type.SemanticReverseAbstractInterpreter; import com.google.javascript.rhino.IR; @@ -17849,7 +17850,7 @@ private TypeCheckResult parseAndTypeCheckWithScope( Joiner.on(", ").join(compiler.getErrors()), 0, compiler.getErrorCount()); - if (compiler.getOptions().getLanguageIn().isEs6OrHigher()) { + if (compiler.getOptions().getLanguageIn().toFeatureSet().contains(FeatureSet.ES6)) { List passes = new ArrayList<>(); TranspilationPasses.addEs2017Passes(passes); TranspilationPasses.addEs6EarlyPasses(passes);