Skip to content

Commit c3c2fd9

Browse files
committed
GROOVY-9510, GROOVY-10192 (pt.4)
1 parent 8346dad commit c3c2fd9

File tree

3 files changed

+44
-6
lines changed

3 files changed

+44
-6
lines changed

base-test/org.eclipse.jdt.groovy.core.tests.builder/src/org/eclipse/jdt/core/groovy/tests/search/ClosureInferencingTests.java

+36
Original file line numberDiff line numberDiff line change
@@ -162,10 +162,46 @@ public void testClosure9() {
162162
" getDelegate()\n" +
163163
" thisObject\n" +
164164
" getThisObject()\n" +
165+
" this\n" + // lastIndexOf
165166
" }\n" +
166167
" }\n" +
167168
"}";
168169
//@formatter:on
170+
assertType(contents, "this", "java.lang.Class<Bar>");
171+
assertType(contents, "owner", "java.lang.Class<Bar>");
172+
assertType(contents, "getOwner()", "java.lang.Class<Bar>");
173+
assertType(contents, "delegate", "java.lang.Class<Bar>");
174+
assertType(contents, "getDelegate()", "java.lang.Class<Bar>");
175+
assertType(contents, "thisObject", "java.lang.Class<Bar>");
176+
assertType(contents, "getThisObject()", "java.lang.Class<Bar>");
177+
}
178+
179+
@Test // closure in static scope wrt owner
180+
public void testClosure9a() {
181+
createUnit("Foo",
182+
"@interface Foo {\n" +
183+
" Class<? extends Closure> value()\n" +
184+
"}\n");
185+
186+
//@formatter:off
187+
String contents =
188+
"@Foo({\n" +
189+
" baz\n" +
190+
" owner\n" +
191+
" getOwner()\n" +
192+
" delegate\n" +
193+
" getDelegate()\n" +
194+
" thisObject\n" +
195+
" getThisObject()\n" +
196+
" this\n" + // lastIndexOf
197+
"})\n" +
198+
"class Bar {\n" +
199+
" int baz\n" +
200+
"}";
201+
//@formatter:on
202+
int offset = contents.indexOf("baz");
203+
assertUnknownConfidence(contents, offset, offset + 3);
204+
assertType(contents, "this", "java.lang.Class<Bar>");
169205
assertType(contents, "owner", "java.lang.Class<Bar>");
170206
assertType(contents, "getOwner()", "java.lang.Class<Bar>");
171207
assertType(contents, "delegate", "java.lang.Class<Bar>");

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

+3-1
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ public void visitJDT(final IType type, final ITypeRequestor requestor) {
282282
return;
283283
}
284284

285-
scopes.add(new VariableScope(scopes.getLast(), node, false));
285+
scopes.add(new VariableScope(scopes.getLast(), node, true));
286286
ASTNode enclosingDeclaration0 = enclosingDeclarationNode;
287287
IJavaElement enclosingElement0 = enclosingElement;
288288
enclosingDeclarationNode = node;
@@ -316,6 +316,8 @@ public void visitJDT(final IType type, final ITypeRequestor requestor) {
316316
visitClassReference(face);
317317
}
318318

319+
scopes.removeLast();
320+
scopes.add(new VariableScope(scopes.getLast(), node, false));
319321
try {
320322
List<IMember> members = membersOf(type, node.isScript());
321323

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

+5-5
Original file line numberDiff line numberDiff line change
@@ -190,22 +190,22 @@ public VariableScope(VariableScope parent, ASTNode enclosingNode, boolean isStat
190190
this.scopeNode = enclosingNode;
191191
this.shared = (parent != null ? parent.shared : new SharedState());
192192
this.enclosingCallStackDepth = this.shared.enclosingCallStack.size();
193-
this.isStaticScope = (isStatic || (!(enclosingNode instanceof ClassNode) && parent != null && parent.isStaticScope)) &&
194-
(getEnclosingClosureScope() == null); // if in a closure, items may be found on delegate or owner
193+
this.isStaticScope = (isStatic || (parent != null && parent.isStaticScope && !(enclosingNode instanceof ClassNode)))
194+
&& (getEnclosingClosureScope() == null); // if in a closure, items may be found on delegate or owner
195195

196196
// determine if scope belongs to script body
197197
if (enclosingNode instanceof ClassNode || enclosingNode instanceof FieldNode) {
198198
this.shared.isRunMethod = false;
199199
} else if (enclosingNode instanceof MethodNode) {
200200
this.shared.isRunMethod = ((MethodNode) enclosingNode).isScriptBody();
201201
}
202-
// TODO: When scope is popped, should the flag be restored to its previous value?
202+
// TODO: Should the flag be restored to its previous value when scope is popped?
203203

204204
// initialize type of "this" (and by extension "super"; see lookupName("super"))
205205
if (enclosingNode instanceof ClassNode) {
206206
ClassNode type = (ClassNode) enclosingNode;
207207
addVariable("this", newClassClassNode(type), type);
208-
} else if (!isStatic && (parent != null && parent.scopeNode instanceof ClassNode)) {
208+
} else if (!isStaticScope && !(enclosingNode instanceof ClosureExpression) && (parent != null && parent.scopeNode instanceof ClassNode)) {
209209
ClassNode type = (ClassNode) parent.scopeNode;
210210
addVariable("this", type, type); // switch from Class<T> to T
211211
}
@@ -412,7 +412,7 @@ public boolean isOwnerStatic() {
412412
break;
413413
}
414414
}
415-
return false;
415+
return CLASS_CLASS_NODE.equals(getOwner());
416416
}
417417

418418
public boolean isFieldAccessDirect() {

0 commit comments

Comments
 (0)