diff --git a/ide-test/org.codehaus.groovy.eclipse.codeassist.completion.test/src/org/codehaus/groovy/eclipse/codeassist/tests/FieldCompletionTests.groovy b/ide-test/org.codehaus.groovy.eclipse.codeassist.completion.test/src/org/codehaus/groovy/eclipse/codeassist/tests/FieldCompletionTests.groovy index 376056c4d5..dbed0b2ac4 100644 --- a/ide-test/org.codehaus.groovy.eclipse.codeassist.completion.test/src/org/codehaus/groovy/eclipse/codeassist/tests/FieldCompletionTests.groovy +++ b/ide-test/org.codehaus.groovy.eclipse.codeassist.completion.test/src/org/codehaus/groovy/eclipse/codeassist/tests/FieldCompletionTests.groovy @@ -719,6 +719,38 @@ final class FieldCompletionTests extends CompletionTestSuite { } } + @Test // https://github.com/groovy/groovy-eclipse/issues/803 + void testClosure14() { + String contents = '''\ + import groovy.transform.stc.* + class A { + String zzz + static class B { + String zzz + } + static class C { + String zzz + } + def foo(@ClosureParams(value=SimpleType, options='A.B') Closure block) {} + def bar(@ClosureParams(value=SimpleType, options='A.C') Closure block) {} + void test() { + foo { b -> + bar { c -> + zz // delegate is Closure, owner is Closure, owner.delegate is Closure, owner.owner is A + } + } + } + } + '''.stripIndent() + ICompletionProposal[] proposals = createProposalsAtOffset(contents, getLastIndexOf(contents, 'zz')) + + proposalExists(proposals, 'zzz', 1) + findFirstProposal(proposals, 'zzz').with { + assert displayString == 'zzz : String - A' // not B or C + applyProposalAndCheck(it, contents.replace('zz //', 'zzz //')) + } + } + @Test void testArrayLength1() { String contents = 'int[] arr; arr.len' diff --git a/ide/org.codehaus.groovy.eclipse.codeassist.completion/src/org/codehaus/groovy/eclipse/codeassist/processors/StatementAndExpressionCompletionProcessor.java b/ide/org.codehaus.groovy.eclipse.codeassist.completion/src/org/codehaus/groovy/eclipse/codeassist/processors/StatementAndExpressionCompletionProcessor.java index 9056db3e97..109821bc75 100644 --- a/ide/org.codehaus.groovy.eclipse.codeassist.completion/src/org/codehaus/groovy/eclipse/codeassist/processors/StatementAndExpressionCompletionProcessor.java +++ b/ide/org.codehaus.groovy.eclipse.codeassist.completion/src/org/codehaus/groovy/eclipse/codeassist/processors/StatementAndExpressionCompletionProcessor.java @@ -282,12 +282,13 @@ private void proposalCreatorOuterLoop(Collection groovyProposal // within a closure, include content assist for the enclosing type (aka "owner") if (closureStrategy >= Closure.OWNER_FIRST) { ClassNode enclosingType = requestor.currentScope.getOwner(); - if (enclosingType != null && !enclosingType.equals(completionType)) { - Collection ownerProposals = new ArrayList<>(); // keep proposals separate - proposalCreatorInnerLoop(ownerProposals, creators, requestor, context, options, enclosingType, isStatic, isPrimary); + if (enclosingType != null) { + Collection ownerProposals = new ArrayList<>(); - requestor.currentScope = enclosingType.getNodeMetaData("outer.scope"); - if (requestor.currentScope != null) { // TODO: add another "owner." qualifier + if (!enclosingType.equals(completionType)) { + proposalCreatorInnerLoop(ownerProposals, creators, requestor, context, options, enclosingType, isStatic, isPrimary); + } + if ((requestor.currentScope = enclosingType.getNodeMetaData("outer.scope")) != null) { proposalCreatorOuterLoop(ownerProposals, creators, requestor, context, options, requestor.currentScope.getDelegate(), isStatic, isPrimary); }