Skip to content

Commit

Permalink
Fix for issue #286: type inferencing of inner class map constructor args
Browse files Browse the repository at this point in the history
  • Loading branch information
eric-milles committed May 7, 2017
1 parent 0426dfb commit 9e7e49c
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1083,14 +1083,14 @@ public void visitConstructorCallExpression(ConstructorCallExpression node) {
boolean shouldContinue = handleSimpleExpression(node);
if (shouldContinue) {
visitClassReference(node.getType());
if (node.getArguments() instanceof TupleExpression
&& ((TupleExpression) node.getArguments()).getExpressions().size() == 1) {
Expression arg = ((TupleExpression) node.getArguments()).getExpressions().get(0);
if (arg instanceof MapExpression) {
// this is a constructor call that is instantiated by a map.
// remember this, so that when visiting the map, we can
// infer field names
enclosingConstructorCall = node;
if (node.getArguments() instanceof TupleExpression) {
TupleExpression tuple = (TupleExpression) node.getArguments();
if (isNotEmpty(tuple.getExpressions())) {
if ((tuple.getExpressions().size() == 1 && tuple.getExpressions().get(0) instanceof MapExpression) ||
tuple.getExpression(tuple.getExpressions().size() - 1) instanceof NamedArgumentListExpression) {
// remember this is a map ctor call, so that field names can be inferred when visiting the map
enclosingConstructorCall = node;
}
}
}
super.visitConstructorCallExpression(node);
Expand Down Expand Up @@ -1671,8 +1671,7 @@ public void visitTupleExpression(TupleExpression node) {
boolean shouldContinue = handleSimpleExpression(node);
if (shouldContinue && isNotEmpty(node.getExpressions())) {
// prevent revisit of statically-compiled chained assignment nodes
if (node instanceof ArgumentListExpression ||
node.getExpression(0) instanceof NamedArgumentListExpression) {
if (node instanceof ArgumentListExpression || node.getExpression(node.getExpressions().size() - 1) instanceof NamedArgumentListExpression) {
super.visitTupleExpression(node);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -742,6 +742,36 @@ final class SemanticHighlightingTests extends GroovyEclipseTestSuite {
new HighlightedTypedPosition(contents.lastIndexOf('X'), 1, CTOR_CALL))
}

@Test
void testInnerClassCtorCalls() {
String contents = '''\
class X {
class Y {
String foo
Integer bar
}
def baz() {
def y = new Y()
def why = new Y(foo: '1', bar: 2) // non-static inner class causes an AST variation
}
}
'''.stripIndent()

assertHighlighting(contents,
new HighlightedTypedPosition(contents.indexOf('foo'), 3, FIELD),
new HighlightedTypedPosition(contents.indexOf('bar'), 3, FIELD),
new HighlightedTypedPosition(contents.indexOf('baz'), 3, METHOD),
new HighlightedTypedPosition(contents.indexOf('y ='), 1, VARIABLE),
new HighlightedTypedPosition(contents.indexOf('Y()'), 1, CTOR_CALL),
new HighlightedTypedPosition(contents.indexOf('why'), 3, VARIABLE),
new HighlightedTypedPosition(contents.lastIndexOf('Y'), 1, CTOR_CALL),
new HighlightedTypedPosition(contents.lastIndexOf('foo'), 3, FIELD),
new HighlightedTypedPosition(contents.lastIndexOf('foo'), 3, MAP_KEY),
new HighlightedTypedPosition(contents.lastIndexOf('bar'), 3, FIELD),
new HighlightedTypedPosition(contents.lastIndexOf('bar'), 3, MAP_KEY),
new HighlightedTypedPosition(contents.lastIndexOf('2'), 1, NUMBER))
}

@Test
void testEnumDefs() {
String contents = '''\
Expand Down

0 comments on commit 9e7e49c

Please sign in to comment.