Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into GH-369
Browse files Browse the repository at this point in the history
  • Loading branch information
Quang Tran committed Feb 12, 2018
2 parents b121e53 + f1b1a9a commit 6a95f25
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@ public interface ArrowFunction extends FunctionExpression {
* *
* If {@link #isSingleExprImplicitReturn()} returns <code>true</code>, this method will return the single expression
* that makes up the body of this arrow function, otherwise the behavior is undefined (might throw exception).
* <p>
* In case of broken AST, this method may return <code>null</code> even if {@link #isSingleExprImplicitReturn()}
* returns <code>true</code>.
* <!-- end-model-doc -->
* @model kind="operation" unique="false"
* annotation="http://www.eclipse.org/emf/2002/GenModel body='&lt;%org.eclipse.n4js.n4JS.Statement%&gt; _head = &lt;%org.eclipse.xtext.xbase.lib.IterableExtensions%&gt;.&lt;&lt;%org.eclipse.n4js.n4JS.Statement%&gt;&gt;head(this.getBody().getStatements());\nreturn ((&lt;%org.eclipse.n4js.n4JS.ExpressionStatement%&gt;) _head).getExpression();'"
Expand Down
3 changes: 3 additions & 0 deletions plugins/org.eclipse.n4js.model/model/N4JS.xcore
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,9 @@ class ArrowFunction extends FunctionExpression {
/**
* If {@link #isSingleExprImplicitReturn()} returns <code>true</code>, this method will return the single expression
* that makes up the body of this arrow function, otherwise the behavior is undefined (might throw exception).
* <p>
* In case of broken AST, this method may return <code>null</code> even if {@link #isSingleExprImplicitReturn()}
* returns <code>true</code>.
*/
op Expression getSingleExpression() {
return (body.statements.head as ExpressionStatement).expression;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -270,10 +270,12 @@ package class PolyProcessor_FunctionExpression extends AbstractPolyProcessor {
}
// tweak return type
if (funExpr instanceof ArrowFunction) {
log(0, "===START of special handling of single-expression arrow function");
// NOTE: the next line requires the type of 'funExpr' and types of fpars to be in cache! For example:
// function <T> foo(p: {function(int):T}) {return undefined;}
// foo( (i) => [i] );
tweakReturnTypeOfSingleExpressionArrowFunction(G, cache, funExpr, resultSolved);
log(0, "===END of special handling of single-expression arrow function");
}
}

Expand All @@ -300,18 +302,23 @@ package class PolyProcessor_FunctionExpression extends AbstractPolyProcessor {
if (!arrFun.isSingleExprImplicitReturn) {
return; // not applicable
}
log(0, "===START of special handling of single-expression arrow function");
// Step 1) process arrFun's body, which was postponed earlier according to ASTProcessor#isPostponedNode(EObject)
// Rationale: the body of a single-expression arrow function isn't a true block, so we do not have to
// postpone it AND we need its types in the next step.
val block = arrFun.body;
if (block === null) {
return; // broken AST
}
if(!cache.postponedSubTrees.remove(block)) {
throw new IllegalStateException("body of single-expression arrow function not among postponed subtrees, in resource: " + arrFun.eResource.URI);
}
astProcessor.processSubtree(G, block, cache, 1);
// Step 2) adjust arrFun's return type stored in arrFunTypeRef (if required)
var didTweakReturnType = false;
val expr = arrFun.getSingleExpression();
if (expr === null) {
return; // broken AST
}
val exprTypeRef = cache.getType(expr).value; // must now be in cache, because we just processed arrFun's body
if (TypeUtils.isVoid(exprTypeRef)) {
// the actual type of 'expr' is void
Expand Down Expand Up @@ -344,7 +351,6 @@ package class PolyProcessor_FunctionExpression extends AbstractPolyProcessor {
if(!didTweakReturnType) {
log(1, "tweaking of return type not required");
}
log(0, "===END of special handling of single-expression arrow function");
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3121,4 +3121,15 @@ class GeneratedSmokeTestCases4 {
}
'''.assertNoException
}

/**
* GH-616
*/
@Test
def void test_GH_616() {
// removing the second dot removes the exception
'''
let r = (v) => v..foo();
'''.assertNoException
}
}

0 comments on commit 6a95f25

Please sign in to comment.