Skip to content

Commit

Permalink
Fix for #837: check super(s) for import static fields and methods
Browse files Browse the repository at this point in the history
  • Loading branch information
eric-milles committed Mar 17, 2019
1 parent 1e1af09 commit 31d3ff0
Show file tree
Hide file tree
Showing 4 changed files with 186 additions and 68 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -878,7 +878,7 @@ final class FieldCompletionTests extends CompletionTestSuite {
}

@Test
void testStaticFields() {
void testStaticFields1() {
String contents = '''\
import java.util.regex.Pattern
Pattern.
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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 = '''\
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ final class MethodCompletionTests extends CompletionTestSuite {
}

@Test
void testStaticMethods() {
void testStaticMethods1() {
String contents = '''\
import java.util.regex.Pattern
Pattern.
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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.*')
Expand Down Expand Up @@ -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 = '''\
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,37 +104,26 @@ public List<IGroovyProposal> findAllProposals(ClassNode type, Set<ClassNode> 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<IGroovyProposal> proposals, String prefix, ModuleNode module) {
for (Map.Entry<String, ImportNode> 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<String, ImportNode> 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<String, ImportNode> 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<String, ImportNode> 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);
Expand All @@ -159,18 +148,18 @@ private void findStaticFavoriteProposals(List<IGroovyProposal> 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());
proposal.setRelevanceMultiplier(0.95f);
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);
Expand All @@ -180,4 +169,20 @@ private void findStaticFavoriteProposals(List<IGroovyProposal> 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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -108,26 +108,25 @@ public List<IGroovyProposal> findAllProposals(ClassNode type, Set<ClassNode> cat
}

private void findStaticImportProposals(List<IGroovyProposal> proposals, String prefix, ModuleNode module) {
for (Map.Entry<String, ImportNode> entry : module.getStaticImports().entrySet()) {
String fieldName = entry.getValue().getFieldName();
if (matcher.test(prefix, fieldName)) {
List<MethodNode> 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<String, ImportNode> 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<String, ImportNode> 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<String, ImportNode> 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);
Expand All @@ -152,31 +151,31 @@ private void findStaticFavoriteProposals(List<IGroovyProposal> 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());
proposal.setRelevanceMultiplier(0.95f);
proposals.add(proposal);
}
}
} else {
if (matcher.test(prefix, fieldName)) {
List<MethodNode> 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;
Expand Down

0 comments on commit 31d3ff0

Please sign in to comment.