diff --git a/src/com/google/javascript/jscomp/TypeInference.java b/src/com/google/javascript/jscomp/TypeInference.java index 4be7944a9e9..1b75acb95ff 100644 --- a/src/com/google/javascript/jscomp/TypeInference.java +++ b/src/com/google/javascript/jscomp/TypeInference.java @@ -451,6 +451,11 @@ private FlowScope traverse(Node n, FlowScope scope) { scope = traverseReturn(n, scope); break; + case YIELD: + scope = traverseChildren(n, scope); + n.setJSType(getNativeType(UNKNOWN_TYPE)); + break; + case VAR: case THROW: scope = traverseChildren(n, scope); diff --git a/test/com/google/javascript/jscomp/TypeInferenceTest.java b/test/com/google/javascript/jscomp/TypeInferenceTest.java index 5503dce2e88..b91ae01e3ca 100644 --- a/test/com/google/javascript/jscomp/TypeInferenceTest.java +++ b/test/com/google/javascript/jscomp/TypeInferenceTest.java @@ -16,6 +16,7 @@ package com.google.javascript.jscomp; +import static com.google.javascript.jscomp.CompilerTypeTestCase.lines; import static com.google.javascript.rhino.jstype.JSTypeNative.ALL_TYPE; import static com.google.javascript.rhino.jstype.JSTypeNative.ARRAY_TYPE; import static com.google.javascript.rhino.jstype.JSTypeNative.BOOLEAN_TYPE; @@ -34,7 +35,6 @@ import com.google.common.base.Joiner; import com.google.common.collect.ImmutableList; import com.google.javascript.jscomp.CodingConvention.AssertionFunctionSpec; -import com.google.javascript.jscomp.CompilerOptions.LanguageMode; import com.google.javascript.jscomp.DataFlowAnalysis.BranchedFlowState; import com.google.javascript.jscomp.type.FlowScope; import com.google.javascript.jscomp.type.ReverseAbstractInterpreter; @@ -75,7 +75,6 @@ public void setUp() { compiler = new Compiler(); CompilerOptions options = new CompilerOptions(); options.setClosurePass(true); - options.setLanguageIn(LanguageMode.ECMASCRIPT5); compiler.initOptions(options); registry = compiler.getTypeRegistry(); assumptions = new HashMap<>(); @@ -99,8 +98,15 @@ private void inFunction(String js) { String thisBlock = assumedThisType == null ? "" : "/** @this {" + assumedThisType + "} */"; - Node root = compiler.parseTestCode( - "(" + thisBlock + " function() {" + js + "});"); + parseAndRunTypeInference("(" + thisBlock + " function() {" + js + "});"); + } + + private void inGenerator(String js) { + parseAndRunTypeInference("(function *() {" + js + "});"); + } + + private void parseAndRunTypeInference(String js) { + Node root = compiler.parseTestCode(js); assertEquals("parsing error: " + Joiner.on(", ").join(compiler.getErrors()), 0, compiler.getErrorCount()); @@ -1531,6 +1537,25 @@ public void testNotIsArray() { verify("x", NUMBER_TYPE); } + public void testYield1() { + inGenerator("var x = yield 3;"); + verify("x", registry.getNativeType(UNKNOWN_TYPE)); + } + + public void testYield2() { + // test that type inference happens inside the yield expression + inGenerator( + lines( + "var obj;", + "yield (obj = {a: 3, b: '4'});", + "var a = obj.a;", + "var b = obj.b;" + )); + + verify("a", registry.getNativeType(NUMBER_TYPE)); + verify("b", registry.getNativeType(STRING_TYPE)); + } + private ObjectType getNativeObjectType(JSTypeNative t) { return registry.getNativeObjectType(t); }