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 dbed0b2ac4..edca532838 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 @@ -878,7 +878,7 @@ final class FieldCompletionTests extends CompletionTestSuite { } @Test - void testStaticFields() { + void testStaticFields1() { String contents = '''\ import java.util.regex.Pattern Pattern. @@ -889,7 +889,26 @@ final class FieldCompletionTests extends CompletionTestSuite { } @Test - void testImportStaticField() { + void testStaticFields2() { + addGroovySource '''\ + abstract class A { + public static final Number SOME_THING = 42 + } + class C extends A { + public static final Number SOME_THANG = -1 + } + '''.stripIndent(), 'C', 'p' + String contents = '''\ + import p.C + C.SOME + '''.stripIndent() + ICompletionProposal[] proposals = createProposalsAtOffset(contents, getLastIndexOf(contents, 'SOME')) + proposalExists(proposals, 'SOME_THANG', 1) + proposalExists(proposals, 'SOME_THING', 1) + } + + @Test + void testImportStaticField1() { String contents = '''\ import static java.util.regex.Pattern.DOTALL DOT @@ -898,7 +917,26 @@ final class FieldCompletionTests extends CompletionTestSuite { } @Test - void testImportStaticStarField() { + void testImportStaticField2() { + addGroovySource '''\ + abstract class A { + public static final Number SOME_THING = 42 + } + class C extends A { + public static final Number SOME_THANG = -1 + } + '''.stripIndent(), 'C', 'p' + String contents = '''\ + import static p.C.SOME_THANG + import static p.C.SOME_THING + SOME + '''.stripIndent() + checkUniqueProposal(contents, 'SOME', 'SOME_THANG') + checkUniqueProposal(contents, 'SOME', 'SOME_THING') + } + + @Test + void testImportStaticStarField1() { String contents = '''\ import static java.util.regex.Pattern.* DOT @@ -907,7 +945,25 @@ final class FieldCompletionTests extends CompletionTestSuite { } @Test - void testFavoriteStaticStarField() { + void testImportStaticStarField2() { + addGroovySource '''\ + abstract class A { + public static final Number SOME_THING = 42 + } + class C extends A { + public static final Number SOME_THANG = -1 + } + '''.stripIndent(), 'C', 'p' + String contents = '''\ + import static p.C.* + SOME + '''.stripIndent() + checkUniqueProposal(contents, 'SOME', 'SOME_THANG') + checkUniqueProposal(contents, 'SOME', 'SOME_THING') + } + + @Test + void testFavoriteStaticStarField1() { setJavaPreference(PreferenceConstants.CODEASSIST_FAVORITE_STATIC_MEMBERS, 'java.util.regex.Pattern.*') String contents = '''\ diff --git a/ide-test/org.codehaus.groovy.eclipse.codeassist.completion.test/src/org/codehaus/groovy/eclipse/codeassist/tests/MethodCompletionTests.groovy b/ide-test/org.codehaus.groovy.eclipse.codeassist.completion.test/src/org/codehaus/groovy/eclipse/codeassist/tests/MethodCompletionTests.groovy index 503b0258f6..f54c568d64 100644 --- a/ide-test/org.codehaus.groovy.eclipse.codeassist.completion.test/src/org/codehaus/groovy/eclipse/codeassist/tests/MethodCompletionTests.groovy +++ b/ide-test/org.codehaus.groovy.eclipse.codeassist.completion.test/src/org/codehaus/groovy/eclipse/codeassist/tests/MethodCompletionTests.groovy @@ -446,7 +446,7 @@ final class MethodCompletionTests extends CompletionTestSuite { } @Test - void testStaticMethods() { + void testStaticMethods1() { String contents = '''\ import java.util.regex.Pattern Pattern. @@ -457,7 +457,26 @@ final class MethodCompletionTests extends CompletionTestSuite { } @Test - void testImportStaticMethod() { + void testStaticMethods2() { + addGroovySource '''\ + abstract class A { + static void someThing() {} + } + class C extends A { + static void someThang() {} + } + '''.stripIndent(), 'C', 'p' + String contents = '''\ + import p.C + C.some + '''.stripIndent() + ICompletionProposal[] proposals = createProposalsAtOffset(contents, getLastIndexOf(contents, 'some')) + proposalExists(proposals, 'someThang', 1) + proposalExists(proposals, 'someThing', 1) + } + + @Test + void testImportStaticMethod1() { String contents = '''\ import static java.util.regex.Pattern.compile comp @@ -467,7 +486,27 @@ final class MethodCompletionTests extends CompletionTestSuite { } @Test - void testImportStaticStarMethod() { + void testImportStaticMethod2() { + addGroovySource '''\ + abstract class A { + static void someThing() {} + } + class C extends A { + static void someThang() {} + } + '''.stripIndent(), 'C', 'p' + String contents = '''\ + import static p.C.someThang + import static p.C.someThing + some + '''.stripIndent() + ICompletionProposal[] proposals = createProposalsAtOffset(contents, getLastIndexOf(contents, 'some')) + proposalExists(proposals, 'someThang', 1) + proposalExists(proposals, 'someThing', 1) + } + + @Test + void testImportStaticStarMethod1() { String contents = '''\ import static java.util.regex.Pattern.* comp @@ -476,6 +515,25 @@ final class MethodCompletionTests extends CompletionTestSuite { proposalExists(proposals, 'compile', 2) } + @Test + void testImportStaticStarMethod2() { + addGroovySource '''\ + abstract class A { + static void someThing() {} + } + class C extends A { + static void someThang() {} + } + '''.stripIndent(), 'C', 'p' + String contents = '''\ + import static p.C.* + some + '''.stripIndent() + ICompletionProposal[] proposals = createProposalsAtOffset(contents, getLastIndexOf(contents, 'some')) + proposalExists(proposals, 'someThang', 1) + proposalExists(proposals, 'someThing', 1) + } + @Test void testFavoriteStaticStarMethod() { setJavaPreference(PreferenceConstants.CODEASSIST_FAVORITE_STATIC_MEMBERS, 'java.util.regex.Pattern.*') @@ -506,7 +564,7 @@ final class MethodCompletionTests extends CompletionTestSuite { } @Test - void testFavoriteStaticMethod() { + void testFavoriteStaticMethod1() { setJavaPreference(PreferenceConstants.CODEASSIST_FAVORITE_STATIC_MEMBERS, 'java.util.regex.Pattern.compile') String contents = '''\ diff --git a/ide/org.codehaus.groovy.eclipse.codeassist.completion/src/org/codehaus/groovy/eclipse/codeassist/creators/FieldProposalCreator.java b/ide/org.codehaus.groovy.eclipse.codeassist.completion/src/org/codehaus/groovy/eclipse/codeassist/creators/FieldProposalCreator.java index 274b8d4909..caa927eb5f 100644 --- a/ide/org.codehaus.groovy.eclipse.codeassist.completion/src/org/codehaus/groovy/eclipse/codeassist/creators/FieldProposalCreator.java +++ b/ide/org.codehaus.groovy.eclipse.codeassist.completion/src/org/codehaus/groovy/eclipse/codeassist/creators/FieldProposalCreator.java @@ -104,37 +104,26 @@ public List findAllProposals(ClassNode type, Set cat return proposals; } - private MethodNode convertToMethodProposal(FieldNode field) { - MethodNode method = new MethodNode(field.getName(), field.getModifiers(), field.getType(), - extractParameters(field.getInitialExpression()), ClassNode.EMPTY_ARRAY, new BlockStatement()); - method.setDeclaringClass(field.getDeclaringClass()); - return method; - } - - private Parameter[] extractParameters(Expression expr) { - if (expr instanceof ClosureExpression) { - return ((ClosureExpression) expr).getParameters(); - } - return Parameter.EMPTY_ARRAY; - } - private void findStaticImportProposals(List proposals, String prefix, ModuleNode module) { - for (Map.Entry entry : module.getStaticImports().entrySet()) { - String fieldName = entry.getValue().getFieldName(); - if (fieldName != null && matcher.test(prefix, fieldName)) { - FieldNode field = entry.getValue().getType().getField(fieldName); - if (field != null && field.isStatic()) { - GroovyFieldProposal proposal = new GroovyFieldProposal(field); - proposal.setRelevanceMultiplier(0.95f); - proposals.add(proposal); + for (Map.Entry entry : module.getStaticStarImports().entrySet()) { + ClassNode typeNode = entry.getValue().getType(); + if (typeNode != null) { + for (FieldNode field : getAllFields(typeNode, alreadySeen)) { + if (field.isStatic() && matcher.test(prefix, field.getName())) { + GroovyFieldProposal proposal = new GroovyFieldProposal(field); + proposal.setRelevanceMultiplier(0.95f); + proposals.add(proposal); + } } } } - for (Map.Entry entry : module.getStaticStarImports().entrySet()) { - ClassNode type = entry.getValue().getType(); - if (type != null) { - for (FieldNode field : type.getFields()) { - if (field.isStatic() && matcher.test(prefix, field.getName())) { + for (Map.Entry entry : module.getStaticImports().entrySet()) { + String fieldName = entry.getValue().getFieldName(); + if (fieldName != null && matcher.test(prefix, fieldName)) { + ClassNode typeNode = entry.getValue().getType(); + // do not add to 'alreadySeen' since this loop is limited to 'fieldName' + for (FieldNode field : getAllFields(typeNode, new HashSet<>(alreadySeen))) { + if (field.isStatic() && field.getName().equals(fieldName)) { GroovyFieldProposal proposal = new GroovyFieldProposal(field); proposal.setRelevanceMultiplier(0.95f); proposals.add(proposal); @@ -159,7 +148,7 @@ private void findStaticFavoriteProposals(List proposals, String } if ("*".equals(fieldName)) { - for (FieldNode field : typeNode.getFields()) { + for (FieldNode field : getAllFields(typeNode, alreadySeen)) { if (field.isStatic() && matcher.test(prefix, field.getName())) { GroovyFieldProposal proposal = new GroovyFieldProposal(field); proposal.setRequiredStaticImport(typeName + '.' + field.getName()); @@ -167,10 +156,10 @@ private void findStaticFavoriteProposals(List proposals, String proposals.add(proposal); } } - } else { - if (matcher.test(prefix, fieldName)) { - FieldNode field = typeNode.getField(fieldName); - if (field != null && field.isStatic()) { + } else if (matcher.test(prefix, fieldName)) { + // do not add to 'alreadySeen' since this loop is limited to 'fieldName' + for (FieldNode field : getAllFields(typeNode, new HashSet<>(alreadySeen))) { + if (field.isStatic() && field.getName().equals(fieldName)) { GroovyFieldProposal proposal = new GroovyFieldProposal(field); proposal.setRequiredStaticImport(favoriteStaticMember); proposal.setRelevanceMultiplier(0.95f); @@ -180,4 +169,20 @@ private void findStaticFavoriteProposals(List proposals, String } } } + + //-------------------------------------------------------------------------- + + private static MethodNode convertToMethodProposal(FieldNode field) { + MethodNode method = new MethodNode(field.getName(), field.getModifiers(), field.getType(), + extractParameters(field.getInitialExpression()), ClassNode.EMPTY_ARRAY, new BlockStatement()); + method.setDeclaringClass(field.getDeclaringClass()); + return method; + } + + private static Parameter[] extractParameters(Expression expr) { + if (expr instanceof ClosureExpression) { + return ((ClosureExpression) expr).getParameters(); + } + return Parameter.EMPTY_ARRAY; + } } diff --git a/ide/org.codehaus.groovy.eclipse.codeassist.completion/src/org/codehaus/groovy/eclipse/codeassist/creators/MethodProposalCreator.java b/ide/org.codehaus.groovy.eclipse.codeassist.completion/src/org/codehaus/groovy/eclipse/codeassist/creators/MethodProposalCreator.java index d72041cf63..42d681d87b 100644 --- a/ide/org.codehaus.groovy.eclipse.codeassist.completion/src/org/codehaus/groovy/eclipse/codeassist/creators/MethodProposalCreator.java +++ b/ide/org.codehaus.groovy.eclipse.codeassist.completion/src/org/codehaus/groovy/eclipse/codeassist/creators/MethodProposalCreator.java @@ -108,26 +108,25 @@ public List findAllProposals(ClassNode type, Set cat } private void findStaticImportProposals(List proposals, String prefix, ModuleNode module) { - for (Map.Entry entry : module.getStaticImports().entrySet()) { - String fieldName = entry.getValue().getFieldName(); - if (matcher.test(prefix, fieldName)) { - List methods = entry.getValue().getType().getDeclaredMethods(fieldName); - if (methods != null) { - for (MethodNode method : methods) { - if (method.isStatic()) { - GroovyMethodProposal proposal = new GroovyMethodProposal(method); - proposal.setRelevanceMultiplier(0.95f); - proposals.add(proposal); - } + for (Map.Entry entry : module.getStaticStarImports().entrySet()) { + ClassNode typeNode = entry.getValue().getType(); + if (typeNode != null) { + for (MethodNode method : getAllMethods(typeNode, alreadySeen)) { + if (method.isStatic() && matcher.test(prefix, method.getName())) { + GroovyMethodProposal proposal = new GroovyMethodProposal(method); + proposal.setRelevanceMultiplier(0.95f); + proposals.add(proposal); } } } } - for (Map.Entry entry : module.getStaticStarImports().entrySet()) { - ClassNode type = entry.getValue().getType(); - if (type != null) { - for (MethodNode method : type.getMethods()) { - if (method.isStatic() && matcher.test(prefix, method.getName())) { + for (Map.Entry entry : module.getStaticImports().entrySet()) { + String fieldName = entry.getValue().getFieldName(); + if (matcher.test(prefix, fieldName)) { + ClassNode typeNode = entry.getValue().getType(); + // do not add to 'alreadySeen' since this loop is limited to 'fieldName' + for (MethodNode method : getAllMethods(typeNode, new HashSet<>(alreadySeen))) { + if (method.isStatic() && method.getName().equals(fieldName)) { GroovyMethodProposal proposal = new GroovyMethodProposal(method); proposal.setRelevanceMultiplier(0.95f); proposals.add(proposal); @@ -152,7 +151,7 @@ private void findStaticFavoriteProposals(List proposals, String } if ("*".equals(fieldName)) { - for (MethodNode method : typeNode.getMethods()) { + for (MethodNode method : getAllMethods(typeNode, alreadySeen)) { if (method.isStatic() && matcher.test(prefix, method.getName())) { GroovyMethodProposal proposal = new GroovyMethodProposal(method); proposal.setRequiredStaticImport(typeName + '.' + method.getName()); @@ -160,23 +159,23 @@ private void findStaticFavoriteProposals(List proposals, String proposals.add(proposal); } } - } else { - if (matcher.test(prefix, fieldName)) { - List methods = typeNode.getDeclaredMethods(fieldName); - for (MethodNode method : methods) { - if (method.isStatic()) { - GroovyMethodProposal proposal = new GroovyMethodProposal(method); - proposal.setRequiredStaticImport(favoriteStaticMember); - proposal.setRelevanceMultiplier(0.95f); - proposals.add(proposal); - } + } else if (matcher.test(prefix, fieldName)) { + // do not add to 'alreadySeen' since this loop is limited to 'fieldName' + for (MethodNode method : getAllMethods(typeNode, new HashSet<>(alreadySeen))) { + if (method.isStatic() && method.getName().equals(fieldName)) { + GroovyMethodProposal proposal = new GroovyMethodProposal(method); + proposal.setRequiredStaticImport(favoriteStaticMember); + proposal.setRelevanceMultiplier(0.95f); + proposals.add(proposal); } } } } } - private void setRelevanceMultiplier(GroovyMethodProposal proposal, boolean isStatic) { + //-------------------------------------------------------------------------- + + private static void setRelevanceMultiplier(GroovyMethodProposal proposal, boolean isStatic) { MethodNode method = proposal.getMethod(); float relevanceMultiplier;