Skip to content

Commit

Permalink
Automated g4 rollback of changelist 208677495.
Browse files Browse the repository at this point in the history
*** Reason for rollback ***

Breaks projects

*** Original change description ***

Ensures for-await-of injects makeasynciterator, async generators inject async_generator_wrapper, and forces traversal in Es6InjectRuntimeLibraries so that Symbol.iterator and Symbol.asyncIterator can always be found if they are present.

Fixes: #3049

***

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=208907739
  • Loading branch information
tjgq authored and lauraharker committed Aug 16, 2018
1 parent 4c7d41a commit 142c8d9
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 126 deletions.
56 changes: 27 additions & 29 deletions src/com/google/javascript/jscomp/Es6InjectRuntimeLibraries.java
Expand Up @@ -39,6 +39,12 @@ public final class Es6InjectRuntimeLibraries extends AbstractPostOrderCallback
private final AbstractCompiler compiler; private final AbstractCompiler compiler;
private final boolean getterSetterSupported; private final boolean getterSetterSupported;


// Since there's currently no Feature for Symbol, run this pass if the code has any ES6 features.
private static final FeatureSet requiredForFeatures = FeatureSet.ES6.without(FeatureSet.ES5);

private static final FeatureSet knownToRequireSymbol =
FeatureSet.BARE_MINIMUM.with(Feature.FOR_OF, Feature.SPREAD_EXPRESSIONS);

public Es6InjectRuntimeLibraries(AbstractCompiler compiler) { public Es6InjectRuntimeLibraries(AbstractCompiler compiler) {
this.compiler = compiler; this.compiler = compiler;
this.getterSetterSupported = this.getterSetterSupported =
Expand All @@ -55,42 +61,36 @@ public void process(Node externs, Node root) {
// We will need these runtime methods when we transpile, but we want the runtime // We will need these runtime methods when we transpile, but we want the runtime
// functions to be have JSType applied to it by the type inferrence. // functions to be have JSType applied to it by the type inferrence.


if (compiler.getOptions().needsTranspilationFrom(FeatureSet.ES6)) { if (used.contains(Feature.FOR_OF)) {
if (used.contains(Feature.FOR_OF)) { Es6ToEs3Util.preloadEs6RuntimeFunction(compiler, "makeIterator");
Es6ToEs3Util.preloadEs6RuntimeFunction(compiler, "makeIterator"); }
}


if (used.contains(Feature.SPREAD_EXPRESSIONS)) { if (used.contains(Feature.SPREAD_EXPRESSIONS)) {
Es6ToEs3Util.preloadEs6RuntimeFunction(compiler, "arrayfromiterable"); Es6ToEs3Util.preloadEs6RuntimeFunction(compiler, "arrayfromiterable");
} }


if (used.contains(Feature.CLASS_EXTENDS)) { if (used.contains(Feature.CLASS_EXTENDS)) {
Es6ToEs3Util.preloadEs6RuntimeFunction(compiler, "inherits"); Es6ToEs3Util.preloadEs6RuntimeFunction(compiler, "inherits");
} }


if (used.contains(Feature.CLASS_GETTER_SETTER)) { if (used.contains(Feature.CLASS_GETTER_SETTER)) {
compiler.ensureLibraryInjected("util/global", /* force= */ false); compiler.ensureLibraryInjected("util/global", /* force= */ false);
} }


if (used.contains(Feature.GENERATORS)) { if (used.contains(Feature.GENERATORS)) {
compiler.ensureLibraryInjected("es6/generator_engine", /* force= */ false); compiler.ensureLibraryInjected("es6/generator_engine", /* force= */ false);
}
} }


if (compiler.getOptions().needsTranspilationFrom(FeatureSet.ES2018)) { if (used.contains(Feature.ASYNC_GENERATORS)) {
if (used.contains(Feature.ASYNC_GENERATORS)) { compiler.ensureLibraryInjected("es6/async_generator_wrapper", /* force= */ false);
compiler.ensureLibraryInjected("es6/async_generator_wrapper", /* force= */ false); }
}


if (used.contains(Feature.FOR_AWAIT_OF)) { if (used.contains(Feature.FOR_AWAIT_OF)) {
compiler.ensureLibraryInjected("es6/util/makeasynciterator", /* force= */ false); compiler.ensureLibraryInjected("es6/util/makeiterator", /* force= */ false);
}
} }


// TODO(johnlenz): remove this. Symbol should be handled like the other polyfills. // TODO(johnlenz): remove this. Symbol should be handled like the other polyfills.
for (Node singleRoot : root.children()) { TranspilationPasses.processTranspile(compiler, root, requiredForFeatures, this);
NodeTraversal.traverse(compiler, singleRoot, this);
}
} }


private static FeatureSet getScriptFeatures(Node script) { private static FeatureSet getScriptFeatures(Node script) {
Expand All @@ -100,9 +100,7 @@ private static FeatureSet getScriptFeatures(Node script) {


@Override @Override
public void hotSwapScript(Node scriptRoot, Node originalRoot) { public void hotSwapScript(Node scriptRoot, Node originalRoot) {
for (Node singleRoot : scriptRoot.children()) { TranspilationPasses.hotSwapTranspile(compiler, scriptRoot, requiredForFeatures, this);
NodeTraversal.traverse(compiler, singleRoot, this);
}
} }


@Override @Override
Expand Down
11 changes: 4 additions & 7 deletions src/com/google/javascript/jscomp/TranspilationPasses.java
Expand Up @@ -121,13 +121,10 @@ static void addPreTypecheckTranspilationPasses(
// TODO(b/73387406): Move each pass above here temporarily, then into // TODO(b/73387406): Move each pass above here temporarily, then into
// addEs6PostCheck Passes once the pass supports propagating type information // addEs6PostCheck Passes once the pass supports propagating type information
} }
} else if (options.needsTranspilationFrom(ES2018)) { } else if (options.needsTranspilationOf(Feature.OBJECT_PATTERN_REST)) {
if (options.needsTranspilationOf(Feature.OBJECT_PATTERN_REST)) { passes.add(es6RenameVariablesInParamLists);
passes.add(es6RenameVariablesInParamLists); passes.add(es6SplitVariableDeclarations);
passes.add(es6SplitVariableDeclarations); passes.add(getEs6RewriteDestructuring(ObjectDestructuringRewriteMode.REWRITE_OBJECT_REST));
passes.add(getEs6RewriteDestructuring(ObjectDestructuringRewriteMode.REWRITE_OBJECT_REST));
}
passes.add(es6InjectRuntimeLibraries);
} }
} }


Expand Down
77 changes: 2 additions & 75 deletions test/com/google/javascript/jscomp/IntegrationTest.java
Expand Up @@ -3454,58 +3454,6 @@ public void testAsyncIterationSuper() {
"}")); "}"));
} }


public void testInitSymbolIteratorInjection() {
CompilerOptions options = createCompilerOptions();
options.setLanguageIn(LanguageMode.ECMASCRIPT_2015);
options.setLanguageOut(LanguageMode.ECMASCRIPT5);
useNoninjectingCompiler = true;
ImmutableList.Builder<SourceFile> externsList = ImmutableList.builder();
externsList.addAll(externs);
externsList.add(SourceFile.fromCode("extraExterns", "var $jscomp = {};"));
externs = externsList.build();
test(
options,
lines(
"var itr = {",
" next: function() { return { value: 1234, done: false }; },",
"};",
"itr[Symbol.iterator] = function() { return itr; }"),
lines(
"var itr = {",
" next: function() { return { value: 1234, done: false }; },",
"};",
// TODO(mattmm): Avoid calls to initSymbol if we can
"$jscomp.initSymbol();",
"$jscomp.initSymbolIterator();",
"itr[Symbol.iterator] = function() { return itr; }"));
}

public void testInitSymbolAsyncIteratorInjection() {
CompilerOptions options = createCompilerOptions();
options.setLanguageIn(LanguageMode.ECMASCRIPT_2018);
options.setLanguageOut(LanguageMode.ECMASCRIPT_2015);
useNoninjectingCompiler = true;
ImmutableList.Builder<SourceFile> externsList = ImmutableList.builder();
externsList.addAll(externs);
externsList.add(SourceFile.fromCode("extraExterns", "var $jscomp = {};"));
externs = externsList.build();
test(
options,
lines(
"const itr = {",
" next() { return { value: 1234, done: false }; },",
" [Symbol.asyncIterator]() { return this; },",
"};"),
lines(
// TODO(mattmm): Avoid calls to initSymbol if we can
"$jscomp.initSymbol();",
"$jscomp.initSymbolAsyncIterator();",
"const itr = {",
" next() { return { value: 1234, done: false }; },",
" [Symbol.asyncIterator]() { return this; },",
"};"));
}

public void testLanguageMode() { public void testLanguageMode() {
CompilerOptions options = createCompilerOptions(); CompilerOptions options = createCompilerOptions();


Expand Down Expand Up @@ -5611,7 +5559,7 @@ public void testDefaultParameterRemoval() {
"let foo=$jscomp$destructuring$var1")); "let foo=$jscomp$destructuring$var1"));
} }


public void testAsyncGenerators() { public void testAsyncIter() {
CompilerOptions options = createCompilerOptions(); CompilerOptions options = createCompilerOptions();
options.setLanguageIn(LanguageMode.ECMASCRIPT_NEXT); options.setLanguageIn(LanguageMode.ECMASCRIPT_NEXT);
useNoninjectingCompiler = true; useNoninjectingCompiler = true;
Expand All @@ -5624,33 +5572,14 @@ public void testAsyncGenerators() {


options.setLanguageOut(LanguageMode.ECMASCRIPT_NEXT); options.setLanguageOut(LanguageMode.ECMASCRIPT_NEXT);
testSame(options, "async function* foo() {}"); testSame(options, "async function* foo() {}");
assertThat(((NoninjectingCompiler) lastCompiler).injected).isEmpty(); testSame(options, "for await (a of b) {}");


options.setLanguageOut(LanguageMode.ECMASCRIPT_2017); options.setLanguageOut(LanguageMode.ECMASCRIPT_2017);
test( test(
options, options,
"async function* foo() {}", "async function* foo() {}",
"function foo() { return new $jscomp.AsyncGeneratorWrapper((function*(){})()); }"); "function foo() { return new $jscomp.AsyncGeneratorWrapper((function*(){})()); }");
assertThat(((NoninjectingCompiler) lastCompiler).injected)
.containsExactly("es6/async_generator_wrapper");
}


public void testForAwaitOf() {
CompilerOptions options = createCompilerOptions();
options.setLanguageIn(LanguageMode.ECMASCRIPT_NEXT);
useNoninjectingCompiler = true;
ImmutableList.Builder<SourceFile> externsList = ImmutableList.builder();
externsList.addAll(externs);
externsList.add(
SourceFile.fromCode(
"extraExterns", "var $jscomp = {}; Symbol.iterator; Symbol.asyncIterator;"));
externs = externsList.build();

options.setLanguageOut(LanguageMode.ECMASCRIPT_NEXT);
testSame(options, "for await (a of b) {}");
assertThat(((NoninjectingCompiler) lastCompiler).injected).isEmpty();

options.setLanguageOut(LanguageMode.ECMASCRIPT_2017);
test( test(
options, options,
lines("async function abc() { for await (a of foo()) { bar(); } }"), lines("async function abc() { for await (a of foo()) { bar(); } }"),
Expand All @@ -5668,8 +5597,6 @@ public void testForAwaitOf() {
" }", " }",
" }", " }",
"}")); "}"));
assertThat(((NoninjectingCompiler) lastCompiler).injected)
.containsExactly("es6/util/makeasynciterator");
} }


public void testDestructuringRest() { public void testDestructuringRest() {
Expand Down
32 changes: 17 additions & 15 deletions test/com/google/javascript/jscomp/TypeCheckTest.java
Expand Up @@ -765,7 +765,7 @@ public void testSymbolComparison8() {
} }


public void testSymbolComparison9() { public void testSymbolComparison9() {
testTypesWithCommonExterns( testTypes(
lines( lines(
"/** @enum {symbol} */ var E = {A:Symbol()};", "/** @enum {symbol} */ var E = {A:Symbol()};",
"/**", "/**",
Expand All @@ -776,7 +776,7 @@ public void testSymbolComparison9() {
} }


public void testSymbolComparison10() { public void testSymbolComparison10() {
testTypesWithCommonExterns( testTypes(
lines( lines(
"/** @enum {symbol} */ var E = {A:Symbol()};", "/** @enum {symbol} */ var E = {A:Symbol()};",
"/**", "/**",
Expand All @@ -787,7 +787,7 @@ public void testSymbolComparison10() {
} }


public void testSymbolComparison11() { public void testSymbolComparison11() {
testTypesWithCommonExterns( testTypes(
lines( lines(
"/** @enum {!Symbol} */ var E = {A:/** @type {!Symbol} */ (Object(Symbol()))};", "/** @enum {!Symbol} */ var E = {A:/** @type {!Symbol} */ (Object(Symbol()))};",
"/**", "/**",
Expand All @@ -798,15 +798,17 @@ public void testSymbolComparison11() {
} }


public void testSymbolComparison12() { public void testSymbolComparison12() {
testTypesWithCommonExterns( testTypes(
lines( lines(
"/** @enum {!Symbol} */ var E = {A:/** @type {!Symbol} */ (Object(Symbol()))};", "/** @enum {!Symbol} */ var E = {A:/** @type {!Symbol} */ (Object(Symbol()))};",
"/**", "/**",
" * @param {symbol} x", " * @param {symbol} x",
" * @param {E} y", " * @param {E} y",
"*/", "*/",
"function f(x, y) { return x === y; }"), "function f(x, y) { return x === y; }"),
"condition always evaluates to false\n" + "left : symbol\n" + "right: E<Symbol>"); "condition always evaluates to false\n"
+ "left : symbol\n"
+ "right: E<Symbol>");
} }


public void testSymbolComparison13() { public void testSymbolComparison13() {
Expand Down Expand Up @@ -19771,9 +19773,8 @@ public void testComparisonTreatingUnknownAsNumber_leftTypeUnknown() {
} }


public void testEnumOfSymbol1() { public void testEnumOfSymbol1() {
testTypesWithCommonExterns( testTypes(
lines( lines("",
"",
"/** @enum {symbol} */", "/** @enum {symbol} */",
"var ES = {A: Symbol('a'), B: Symbol('b')};", "var ES = {A: Symbol('a'), B: Symbol('b')};",
"", "",
Expand All @@ -19784,23 +19785,24 @@ public void testEnumOfSymbol1() {
} }


public void testEnumOfSymbol2() { public void testEnumOfSymbol2() {
testTypesWithCommonExterns( testTypes(
lines( lines("",
"",
"/** @enum {symbol} */", "/** @enum {symbol} */",
"var ES = {A: Symbol('a'), B: Symbol('b')};", "var ES = {A: Symbol('a'), B: Symbol('b')};",
"", "",
"/** @type {!Object<number, number>} */", "/** @type {!Object<number, number>} */",
"var o = {};", "var o = {};",
"", "",
"o[ES.A] = 1;"), "o[ES.A] = 1;"),
lines("restricted index type", "found : ES<symbol>", "required: number")); lines(
"restricted index type",
"found : ES<symbol>",
"required: number"));
} }


public void testEnumOfSymbol4() { public void testEnumOfSymbol4() {
testTypesWithCommonExterns( testTypes(
lines( lines("",
"",
"/** @enum {symbol} */", "/** @enum {symbol} */",
"var ES = {A: Symbol('a'), B: Symbol('b')};", "var ES = {A: Symbol('a'), B: Symbol('b')};",
"", "",
Expand Down

0 comments on commit 142c8d9

Please sign in to comment.