Skip to content

Commit 67588cd

Browse files
committed
GROOVY-9510, GROOVY-10192 (pt.2)
1 parent 306c496 commit 67588cd

File tree

4 files changed

+193
-47
lines changed

4 files changed

+193
-47
lines changed

base/org.eclipse.jdt.groovy.core/src/org/eclipse/jdt/groovy/search/TypeInferencingVisitorWithRequestor.java

+12-2
Original file line numberDiff line numberDiff line change
@@ -661,8 +661,18 @@ private void visitMethodInternal(final MethodNode node) {
661661
ASTNode enclosingDeclaration0 = enclosingDeclarationNode;
662662
enclosingDeclarationNode = node;
663663
try {
664-
visitAnnotations(node); // annotations are in class scope
665-
scopes.add(new VariableScope(scopes.getLast(), node, node.isStatic()));
664+
VariableScope classScope = scopes.getLast();
665+
if (isNotEmpty(node.getAnnotations())) {
666+
// assert(!node.isScriptBody());
667+
classScope.setCurrentNode(node);
668+
try {
669+
visitAnnotations(node); // annotations are in class scope
670+
} finally {
671+
classScope.forgetCurrentNode();
672+
}
673+
}
674+
675+
scopes.add(new VariableScope(classScope, node, node.isStatic()));
666676
try {
667677
visitConstructorOrMethod(node, node instanceof ConstructorNode || node.getName().equals("<clinit>"));
668678
} finally {

base/org.eclipse.jdt.groovy.core/src/org/eclipse/jdt/groovy/search/VariableScope.java

+11-6
Original file line numberDiff line numberDiff line change
@@ -452,13 +452,18 @@ public FieldNode getEnclosingFieldDeclaration() {
452452
}
453453

454454
public MethodNode getEnclosingMethodDeclaration() {
455-
if (scopeNode instanceof MethodNode) {
456-
return (MethodNode) scopeNode;
457-
} else if (parent != null) {
458-
return parent.getEnclosingMethodDeclaration();
459-
} else {
460-
return null;
455+
for (Iterator<ASTNode> it = shared.nodeStack.descendingIterator(); it.hasNext();) {
456+
ASTNode node = it.next();
457+
if (node instanceof MethodNode) {
458+
return (MethodNode) node;
459+
}
461460
}
461+
for (VariableScope scope = this; scope != null; scope = scope.parent) {
462+
if (scope.scopeNode instanceof MethodNode) {
463+
return (MethodNode) scope.scopeNode;
464+
}
465+
}
466+
return null;
462467
}
463468

464469
public ClosureExpression getEnclosingClosure() {

ide-test/org.codehaus.groovy.eclipse.dsl.tests/src/org/codehaus/groovy/eclipse/dsl/tests/DSLContentAssistTests.groovy

+128-10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2009-2021 the original author or authors.
2+
* Copyright 2009-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -1066,6 +1066,24 @@ final class DSLContentAssistTests extends CompletionTestSuite {
10661066
proposalExists(proposals, 'HashMap', 0)
10671067
}
10681068

1069+
@Test
1070+
void testNewifyTransform1a() {
1071+
String contents = '''\
1072+
|class Foo {
1073+
| @Newify bar() {
1074+
| List list = ArrayList.n
1075+
| Map map = HashM
1076+
| }
1077+
|}
1078+
|'''.stripMargin()
1079+
1080+
ICompletionProposal[] proposals = createProposalsAtOffset(contents, getIndexOf(contents, '.n'))
1081+
proposalExists(proposals, 'new', 3) // one for each constructor in ArrayList
1082+
1083+
proposals = createProposalsAtOffset(contents, getIndexOf(contents, 'HashM'))
1084+
proposalExists(proposals, 'HashMap', 0)
1085+
}
1086+
10691087
@Test
10701088
void testNewifyTransform2() {
10711089
String contents = '''\
@@ -1082,6 +1100,24 @@ final class DSLContentAssistTests extends CompletionTestSuite {
10821100
proposalExists(proposals, 'HashMap', 4) // one for each constructor in HashMap
10831101
}
10841102

1103+
@Test
1104+
void testNewifyTransform2a() {
1105+
String contents = '''\
1106+
|class Foo {
1107+
| @Newify(HashMap) bar() {
1108+
| List list = ArrayList.n
1109+
| Map map = HashM
1110+
| }
1111+
|}
1112+
|'''.stripMargin()
1113+
1114+
ICompletionProposal[] proposals = createProposalsAtOffset(contents, getIndexOf(contents, '.n'))
1115+
proposalExists(proposals, 'new', 3) // one for each constructor in ArrayList
1116+
1117+
proposals = createProposalsAtOffset(contents, getLastIndexOf(contents, 'HashM'))
1118+
proposalExists(proposals, 'HashMap', 4) // one for each constructor in HashMap
1119+
}
1120+
10851121
@Test
10861122
void testNewifyTransform3() {
10871123
String contents = '''\
@@ -1099,23 +1135,25 @@ final class DSLContentAssistTests extends CompletionTestSuite {
10991135
}
11001136

11011137
@Test
1102-
void testNewifyTransform4() {
1138+
void testNewifyTransform3a() {
11031139
String contents = '''\
1104-
|@Newify
1105-
|List list = ArrayList.n
1106-
|@Newify(HashMap)
1107-
|Map map = HashM
1140+
|class Foo {
1141+
| @Newify(auto=false, value=HashMap) bar() {
1142+
| List list = ArrayList.n
1143+
| Map map = HashM
1144+
| }
1145+
|}
11081146
|'''.stripMargin()
11091147

11101148
ICompletionProposal[] proposals = createProposalsAtOffset(contents, getIndexOf(contents, '.n'))
1111-
proposalExists(proposals, 'new', 3) // one for each constructor in ArrayList
1149+
proposalExists(proposals, 'new', 0)
11121150

11131151
proposals = createProposalsAtOffset(contents, getLastIndexOf(contents, 'HashM'))
11141152
proposalExists(proposals, 'HashMap', 4) // one for each constructor in HashMap
11151153
}
11161154

11171155
@Test
1118-
void testNewifyTransform5() {
1156+
void testNewifyTransform4() {
11191157
String contents = '''\
11201158
|@Newify(auto=false, pattern=/(Linked)?Hash.*/) class Foo {
11211159
| List list = ArrayList.n
@@ -1131,7 +1169,25 @@ final class DSLContentAssistTests extends CompletionTestSuite {
11311169
}
11321170

11331171
@Test
1134-
void testNewifyTransform5a() {
1172+
void testNewifyTransform4a() {
1173+
String contents = '''\
1174+
|class Foo {
1175+
| @Newify(auto=false, pattern=/(Linked)?Hash.*/) bar() {
1176+
| List list = ArrayList.n
1177+
| Map map = HashM
1178+
| }
1179+
|}
1180+
|'''.stripMargin()
1181+
1182+
ICompletionProposal[] proposals = createProposalsAtOffset(contents, getIndexOf(contents, '.n'))
1183+
proposalExists(proposals, 'new', 0)
1184+
1185+
proposals = createProposalsAtOffset(contents, getLastIndexOf(contents, 'HashM'))
1186+
proposalExists(proposals, 'HashMap', 4) // one for each constructor in HashMap
1187+
}
1188+
1189+
@Test
1190+
void testNewifyTransform5() {
11351191
String contents = '''\
11361192
|@Newify(auto=false, pattern=/(Linked)?Hash.*/) class Foo {
11371193
| Map map = LinkedH
@@ -1143,7 +1199,21 @@ final class DSLContentAssistTests extends CompletionTestSuite {
11431199
}
11441200

11451201
@Test
1146-
void testNewifyTransform5b() {
1202+
void testNewifyTransform5a() {
1203+
String contents = '''\
1204+
|class Foo {
1205+
| @Newify(auto=false, pattern=/(Linked)?Hash.*/) bar() {
1206+
| Map map = LinkedH
1207+
| }
1208+
|}
1209+
|'''.stripMargin()
1210+
1211+
ICompletionProposal[] proposals = createProposalsAtOffset(contents, getIndexOf(contents, 'LinkedH'))
1212+
proposalExists(proposals, 'LinkedHashMap', 5) // one for each constructor in LinkedHashMap
1213+
}
1214+
1215+
@Test
1216+
void testNewifyTransform6() {
11471217
String contents = '''\
11481218
|@Newify(auto=false, pattern=/(Linked)?Hash.*/) class Foo {
11491219
| Map map = LinkedHashMap()
@@ -1154,6 +1224,54 @@ final class DSLContentAssistTests extends CompletionTestSuite {
11541224
proposalExists(proposals, 'LinkedHashMap', 5) // one for each constructor in LinkedHashMap
11551225
}
11561226

1227+
@Test
1228+
void testNewifyTransform6a() {
1229+
String contents = '''\
1230+
|class Foo {
1231+
| @Newify(auto=false, pattern=/(Linked)?Hash.*/) bar() {
1232+
| Map map = LinkedHashMap()
1233+
| }
1234+
|}
1235+
|'''.stripMargin()
1236+
1237+
ICompletionProposal[] proposals = createProposalsAtOffset(contents, getIndexOf(contents, 'LinkedHashMap'))
1238+
proposalExists(proposals, 'LinkedHashMap', 5) // one for each constructor in LinkedHashMap
1239+
}
1240+
1241+
@Test // field/property annotations
1242+
void testNewifyTransform7() {
1243+
String contents = '''\
1244+
|class Foo {
1245+
| @Newify
1246+
| private List list = ArrayList.n
1247+
| @Newify(HashMap)
1248+
| Map map = HashM
1249+
|}
1250+
|'''.stripMargin()
1251+
1252+
ICompletionProposal[] proposals = createProposalsAtOffset(contents, getIndexOf(contents, '.n'))
1253+
proposalExists(proposals, 'new', 3) // one for each constructor in ArrayList
1254+
1255+
proposals = createProposalsAtOffset(contents, getLastIndexOf(contents, 'HashM'))
1256+
proposalExists(proposals, 'HashMap', 4) // one for each constructor in HashMap
1257+
}
1258+
1259+
@Test // local variable annotations
1260+
void testNewifyTransform8() {
1261+
String contents = '''\
1262+
|@Newify
1263+
|List list = ArrayList.n
1264+
|@Newify(HashMap)
1265+
|Map map = HashM
1266+
|'''.stripMargin()
1267+
1268+
ICompletionProposal[] proposals = createProposalsAtOffset(contents, getIndexOf(contents, '.n'))
1269+
proposalExists(proposals, 'new', 3) // one for each constructor in ArrayList
1270+
1271+
proposals = createProposalsAtOffset(contents, getLastIndexOf(contents, 'HashM'))
1272+
proposalExists(proposals, 'HashMap', 4) // one for each constructor in HashMap
1273+
}
1274+
11571275
@Test
11581276
void testSelfTypeTransform1() {
11591277
String contents = '''\

ide-test/org.codehaus.groovy.eclipse.dsl.tests/src/org/codehaus/groovy/eclipse/dsl/tests/PointcutEvaluationTests.groovy

+42-29
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package org.codehaus.groovy.eclipse.dsl.tests
1717

18+
import groovy.test.NotYetImplemented
1819
import groovy.transform.ToString
1920
import groovy.transform.TupleConstructor
2021

@@ -90,21 +91,13 @@ final class PointcutEvaluationTests extends GroovyEclipseTestSuite {
9091
final String bindingToString
9192
}
9293

93-
private void doTestOfLastBindingSet(String cuContents, String pointcutText, BindingResult... results) {
94-
doTestOfLastBindingSet('p', cuContents, pointcutText, results)
95-
}
96-
97-
private void doTestOfLastBindingSet(String pkg, String cuContents, String pointcutText, BindingResult... results) {
94+
private void doTestOfLastBindingSet(String pkg = 'p', String cuContents, String pointcutText, BindingResult... results) {
9895
GroovyCompilationUnit unit = addGroovySource(cuContents, nextUnitName(), pkg)
9996
BindingSet bindings = evaluateForBindings(unit, pointcutText)
10097
assertAllBindings(bindings, results)
10198
}
10299

103-
private void doTestOfLastMatch(String cuContents, String pointcutText, String name) {
104-
doTestOfLastMatch('p', cuContents, pointcutText, name)
105-
}
106-
107-
private void doTestOfLastMatch(String pkg, String cuContents, String pointcutText, String name) {
100+
private void doTestOfLastMatch(String pkg = 'p', String cuContents, String pointcutText, String name) {
108101
GroovyCompilationUnit unit = addGroovySource(cuContents, nextUnitName(), pkg)
109102
Collection<?> match = evaluateForMatch(unit, pointcutText)
110103
assertSingleBinding(match, name)
@@ -398,12 +391,12 @@ final class PointcutEvaluationTests extends GroovyEclipseTestSuite {
398391

399392
@Test
400393
void testPackageFolder1() {
401-
doTestOfLastMatch('p', '2', 'packageFolder("p")', 'p')
394+
doTestOfLastMatch('2', 'packageFolder("p")', 'p')
402395
}
403396

404397
@Test
405398
void testPackageFolder2() {
406-
doTestOfLastMatch('p', '2', 'packageFolder("invalid")', null)
399+
doTestOfLastMatch('2', 'packageFolder("invalid")', null)
407400
}
408401

409402
@Test
@@ -421,37 +414,32 @@ final class PointcutEvaluationTests extends GroovyEclipseTestSuite {
421414

422415
@Test
423416
void testNamedBinding3() {
424-
doTestOfLastBindingSet('2', 'bind( b : nature("org.eclipse.jdt.groovy.core.groovyNature") ) | ' +
425-
'bind( c : fileExtension("groovy") )',
417+
doTestOfLastBindingSet('2', 'bind( b : nature("org.eclipse.jdt.groovy.core.groovyNature") ) | bind( c : fileExtension("groovy") )',
426418
new BindingResult('b', 'org.eclipse.jdt.groovy.core.groovyNature'),
427419
new BindingResult('c', 'src/p/TestUnit_[0-9a-f]{32}.groovy'))
428420
}
429421

430422
@Test
431423
void testNamedBinding4() {
432-
doTestOfLastBindingSet('2', 'bind( b : nature("org.eclipse.jdt.groovy.core.groovyNature") ) & ' +
433-
'bind( c : fileExtension("groovy") )',
424+
doTestOfLastBindingSet('2', 'bind( b : nature("org.eclipse.jdt.groovy.core.groovyNature") ) & bind( c : fileExtension("groovy") )',
434425
new BindingResult('b', 'org.eclipse.jdt.groovy.core.groovyNature'),
435426
new BindingResult('c', 'src/p/TestUnit_[0-9a-f]{32}.groovy'))
436427
}
437428

438429
@Test
439430
void testNamedBinding5() {
440-
doTestOfLastBindingSet('2', 'bind( b : nature("org.eclipse.jdt.groovy.core.groovyNature") ) | ' +
441-
'bind( c : fileExtension("invalid") )',
431+
doTestOfLastBindingSet('2', 'bind( b : nature("org.eclipse.jdt.groovy.core.groovyNature") ) | bind( c : fileExtension("invalid") )',
442432
new BindingResult('b', 'org.eclipse.jdt.groovy.core.groovyNature'))
443433
}
444434

445435
@Test
446436
void testNamedBinding6() {
447-
doTestOfLastBindingSet('2', 'bind( b : nature("invalid") ) & ' +
448-
'bind( c : fileExtension("groovy") )')
437+
doTestOfLastBindingSet('2', 'bind( b : nature("invalid") ) & bind( c : fileExtension("groovy") )')
449438
}
450439

451440
@Test
452-
void testNamedBinding6a() {
453-
doTestOfLastBindingSet('2', 'bind( b : nature("invalid") ) | ' +
454-
'bind( c : fileExtension("groovy") )',
441+
void testNamedBinding7() {
442+
doTestOfLastBindingSet('2', 'bind( b : nature("invalid") ) | bind( c : fileExtension("groovy") )',
455443
new BindingResult('c', 'src/p/TestUnit_[0-9a-f]{32}.groovy'))
456444
}
457445

@@ -463,16 +451,13 @@ final class PointcutEvaluationTests extends GroovyEclipseTestSuite {
463451

464452
@Test
465453
void testTypesNamedBinding2() {
466-
doTestOfLastBindingSet('2', 'bind( b : currentType("java.lang.Integer") ) | ' +
467-
'bind( c : fileExtension("invalid") )',
454+
doTestOfLastBindingSet('2', 'bind( b : currentType("java.lang.Integer") ) | bind( c : fileExtension("invalid") )',
468455
new BindingResult('b', 'java.lang.Integer'))
469456
}
470457

471458
@Test
472459
void testTypesNamedBinding3() {
473-
doTestOfLastBindingSet('2',
474-
'bind( b : currentType("java.lang.Integer") ) | ' +
475-
'bind( c : fileExtension("groovy") )',
460+
doTestOfLastBindingSet('2', 'bind( b : currentType("java.lang.Integer") ) | bind( c : fileExtension("groovy") )',
476461
new BindingResult('b', 'java.lang.Integer'),
477462
new BindingResult('c', 'src/p/TestUnit_[0-9a-f]{32}.groovy'))
478463
}
@@ -653,7 +638,7 @@ final class PointcutEvaluationTests extends GroovyEclipseTestSuite {
653638
}
654639

655640
@Test
656-
void testAnnotatedByBinding7Fail() {
641+
void testAnnotatedByBinding7() {
657642
addGroovySource('@Deprecated\nclass Foo { \n def f }', 'Foo', 'p')
658643
doTestOfLastBindingSet('Foo', 'currentType( fields("g") & bind( b : annotatedBy("java.lang.Deprecated") ) )')
659644
}
@@ -684,6 +669,34 @@ final class PointcutEvaluationTests extends GroovyEclipseTestSuite {
684669
new BindingResult('b', '@java.lang.Deprecated, @java.lang.Deprecated'))
685670
}
686671

672+
@NotYetImplemented @Test
673+
void testEnclosingFieldBinding() {
674+
addGroovySource('@interface Tag {\n Class<? extends Closure> value()\n}', 'Tag', 'p')
675+
676+
doTestOfLastBindingSet('''\
677+
|class C {
678+
| @Tag({ x })
679+
| protected f
680+
|}
681+
|'''.stripMargin(),
682+
'inClosure() & bind(f: enclosingField(annotatedBy("p.Tag")))',
683+
new BindingResult('f', 'p.C.f'))
684+
}
685+
686+
@Test
687+
void testEnclosingMethodBinding() {
688+
addGroovySource('@interface Tag {\n Class<? extends Closure> value()\n}', 'Tag', 'p')
689+
690+
doTestOfLastBindingSet('''\
691+
|class C {
692+
| @Tag({ x })
693+
| void m() {}
694+
|}
695+
|'''.stripMargin(),
696+
'inClosure() & bind(m: enclosingMethod(annotatedBy("p.Tag")))',
697+
new BindingResult('m', 'p.C.m'))
698+
}
699+
687700
@Test
688701
void testNestedCalls1() {
689702
doTestOfLastBindingSet('''\

0 commit comments

Comments
 (0)