Skip to content

Commit

Permalink
disambiguation based on fields
Browse files Browse the repository at this point in the history
  • Loading branch information
ftomassetti committed Jul 30, 2018
1 parent 2f89028 commit 53cc9f9
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 15 deletions.
Expand Up @@ -21,7 +21,9 @@

package com.github.javaparser.resolution.types;

import com.github.javaparser.ast.body.VariableDeclarator;
import com.github.javaparser.resolution.MethodUsage;
import com.github.javaparser.resolution.declarations.ResolvedFieldDeclaration;
import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
Expand Down Expand Up @@ -331,6 +333,8 @@ public String getId() {
*/
public abstract Set<MethodUsage> getDeclaredMethods();

public abstract Set<ResolvedFieldDeclaration> getDeclaredFields();

public boolean isRawType() {
if (!typeDeclaration.getTypeParameters().isEmpty()) {
if (typeParametersMap().isEmpty()) {
Expand Down Expand Up @@ -376,13 +380,22 @@ public List<ResolvedMethodDeclaration> getAllMethods() {
List<ResolvedMethodDeclaration> allMethods = new LinkedList<>();
allMethods.addAll(this.getDeclaredMethods().stream().map(m -> m.getDeclaration()).collect(Collectors.toList()));

System.out.println("Ancestors of " + this + ": " + getDirectAncestors());

getDirectAncestors().forEach(a ->
allMethods.addAll(a.getAllMethods()));
return allMethods;
}

public List<ResolvedFieldDeclaration> getAllFieldsVisibleToInheritors() {
List<ResolvedFieldDeclaration> res = new LinkedList<>();

res.addAll(this.getDeclaredFields());

getDirectAncestors().forEach(a ->
res.addAll(a.getAllFieldsVisibleToInheritors()));

return res;
}

//
// Protected methods
//
Expand Down
Expand Up @@ -108,17 +108,16 @@ default Optional<MethodUsage> solveMethodAsUsage(String name, List<ResolvedType>
* @return
*/
default List<VariableDeclarator> localVariablesExposedToChild(Node child) {
//throw new UnsupportedOperationException(this.getClass().getCanonicalName());
// TODO fixme
return Collections.emptyList();
}

default List<Parameter> parametersExposedToChild(Node child) {
//throw new UnsupportedOperationException(this.getClass().getCanonicalName());
// TODO fixme
return Collections.emptyList();
}

default List<ResolvedFieldDeclaration> fieldsExposedToChild(Node child) {
return Collections.emptyList();
}

/**
* The local variables that are visible in a certain scope are defined in JLS 6.3. Scope of a Declaration.
Expand Down Expand Up @@ -177,9 +176,16 @@ default Optional<Parameter> parameterDeclarationInScope(String name) {
return getParent().parameterDeclarationInScope(name);
}

default Optional<VariableDeclarator> fieldDeclarationInScope(String name) {
//throw new UnsupportedOperationException();
// TODO Fixme
return Optional.empty();
default Optional<ResolvedFieldDeclaration> fieldDeclarationInScope(String name) {
if (getParent() == null) {
return Optional.empty();
}
Optional<ResolvedFieldDeclaration> localRes = getParent().fieldsExposedToChild(((AbstractJavaParserContext)this)
.getWrappedNode()).stream().filter(vd -> vd.getName().equals(name)).findFirst();
if (localRes.isPresent()) {
return localRes;
}

return getParent().fieldDeclarationInScope(name);
}
}
Expand Up @@ -16,7 +16,9 @@

package com.github.javaparser.symbolsolver.javaparsermodel.contexts;

import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.ast.body.VariableDeclarator;
import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
import com.github.javaparser.resolution.declarations.*;
import com.github.javaparser.resolution.types.ResolvedType;
Expand All @@ -27,6 +29,7 @@
import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
import com.github.javaparser.symbolsolver.model.resolution.Value;

import java.util.LinkedList;
import java.util.List;
import java.util.Optional;

Expand Down Expand Up @@ -99,6 +102,15 @@ public SymbolReference<ResolvedConstructorDeclaration> solveConstructor(List<Res
return javaParserTypeDeclarationAdapter.solveConstructor(argumentsTypes, typeSolver);
}

@Override
public List<ResolvedFieldDeclaration> fieldsExposedToChild(Node child) {
List<ResolvedFieldDeclaration> fields = new LinkedList<>();
fields.addAll(this.wrappedNode.resolve().getDeclaredFields());
this.wrappedNode.getExtendedTypes().forEach(i -> fields.addAll(i.resolve().getAllFieldsVisibleToInheritors()));
this.wrappedNode.getImplementedTypes().forEach(i -> fields.addAll(i.resolve().getAllFieldsVisibleToInheritors()));
return fields;
}

///
/// Private methods
///
Expand Down
Expand Up @@ -17,6 +17,7 @@
package com.github.javaparser.symbolsolver.model.typesystem;

import com.github.javaparser.resolution.MethodUsage;
import com.github.javaparser.resolution.declarations.ResolvedFieldDeclaration;
import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
Expand Down Expand Up @@ -229,4 +230,10 @@ public ResolvedReferenceType deriveTypeParameters(ResolvedTypeParametersMap type
return create(typeDeclaration, typeParametersMap);
}

@Override
public Set<ResolvedFieldDeclaration> getDeclaredFields() {
Set<ResolvedFieldDeclaration> res = new HashSet<>();
res.addAll(getTypeDeclaration().getDeclaredFields());
return res;
}
}
Expand Up @@ -631,7 +631,7 @@ public static SymbolReference<ResolvedMethodDeclaration> solveMethodInType(Resol
if (typeDeclaration instanceof JavassistClassDeclaration) {
return ((JavassistClassDeclaration) typeDeclaration).solveMethod(name, argumentsTypes, staticOnly);
}
if (typeDeclaration instanceof JavassistEnumDeclaration) {
if (typeDeclaration instanceof JavassistEnumDeclaration) {
return ((JavassistEnumDeclaration) typeDeclaration).solveMethod(name, argumentsTypes, staticOnly);
}
throw new UnsupportedOperationException(typeDeclaration.getClass().getCanonicalName());
Expand Down
Expand Up @@ -2,26 +2,37 @@

import com.github.javaparser.*;
import com.github.javaparser.ast.Node;
import com.github.javaparser.symbolsolver.JavaSymbolSolver;
import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
import com.github.javaparser.symbolsolver.resolution.AbstractResolutionTest;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import static org.junit.Assert.assertTrue;

public abstract class AbstractNameLogicTest extends AbstractResolutionTest {

protected Node getNameInCodeTollerant(String code, String name, ParseStart parseStart) {
return getNameInCode(code, name, parseStart, true);
return getNameInCode(code, name, parseStart, true, Optional.empty());
}

protected Node getNameInCodeTollerant(String code, String name, ParseStart parseStart, TypeSolver typeSolver) {
return getNameInCode(code, name, parseStart, true, Optional.of(typeSolver));
}

protected Node getNameInCode(String code, String name, ParseStart parseStart) {
return getNameInCode(code, name, parseStart, false);
return getNameInCode(code, name, parseStart, false, Optional.empty());
}

private Node getNameInCode(String code, String name, ParseStart parseStart, boolean tollerant) {
private Node getNameInCode(String code, String name, ParseStart parseStart, boolean tollerant,
Optional<TypeSolver> typeSolver) {
ParserConfiguration parserConfiguration = new ParserConfiguration();
parserConfiguration.setLanguageLevel(ParserConfiguration.LanguageLevel.JAVA_10);
if (typeSolver.isPresent()) {
parserConfiguration.setSymbolResolver(new JavaSymbolSolver(typeSolver.get()));
}
ParseResult<? extends Node> parseResult = new JavaParser(parserConfiguration).parse(parseStart, new StringProvider(code));
if (!parseResult.isSuccessful()) {
parseResult.getProblems().forEach(p -> System.out.println("ERR: " + p));
Expand Down
Expand Up @@ -4,6 +4,8 @@
import com.github.javaparser.ast.Node;
import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
import com.github.javaparser.symbolsolver.resolution.AbstractResolutionTest;
import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
import com.github.javaparser.symbolsolver.resolution.typesolvers.JavaParserTypeSolver;
import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
import org.junit.Test;

Expand All @@ -19,7 +21,7 @@ private void assertNameInCodeIsDisambiguited(String code, String name,
NameCategory syntacticClassification,
NameCategory nameCategory,
ParseStart parseStart, TypeSolver typeSolver) {
Node nameNode = getNameInCodeTollerant(code, name, parseStart);
Node nameNode = getNameInCodeTollerant(code, name, parseStart, typeSolver);
assertEquals(syntacticClassification, NameLogic.syntacticClassificationAccordingToContext(nameNode));
assertEquals(nameCategory, NameLogic.classifyReference(nameNode, typeSolver));
}
Expand Down Expand Up @@ -80,4 +82,36 @@ public void ambiguousNameToCatchParameter() {
new ReflectionTypeSolver());
}

@Test
public void ambiguousNameToInstanceFieldDeclared() {
assertNameInCodeIsDisambiguited("class A { SomeClass a; void foo() {\n" +
"a.aField;" + "\n" +
"} }", "a", NameCategory.AMBIGUOUS_NAME, NameCategory.EXPRESSION_NAME, ParseStart.COMPILATION_UNIT,
new CombinedTypeSolver(new ReflectionTypeSolver()));
}

@Test
public void ambiguousNameToStaticFieldDeclared() {
assertNameInCodeIsDisambiguited("class A { static SomeClass a; void foo() {\n" +
"a.aField;" + "\n" +
"} }", "a", NameCategory.AMBIGUOUS_NAME, NameCategory.EXPRESSION_NAME, ParseStart.COMPILATION_UNIT,
new CombinedTypeSolver(new ReflectionTypeSolver()));
}

@Test
public void ambiguousNameToInstanceFieldInherited() {
assertNameInCodeIsDisambiguited("class A { SomeClass a; } class B extends A { void foo() {\n" +
"a.aField;" + "\n" +
"} }", "a", NameCategory.AMBIGUOUS_NAME, NameCategory.EXPRESSION_NAME, ParseStart.COMPILATION_UNIT,
new CombinedTypeSolver(new ReflectionTypeSolver()));
}

@Test
public void ambiguousNameToStaticFieldInherited() {
assertNameInCodeIsDisambiguited("class A { static SomeClass a; } class B extends A { void foo() {\n" +
"a.aField;" + "\n" +
"} }", "a", NameCategory.AMBIGUOUS_NAME, NameCategory.EXPRESSION_NAME, ParseStart.COMPILATION_UNIT,
new CombinedTypeSolver(new ReflectionTypeSolver()));
}

}

0 comments on commit 53cc9f9

Please sign in to comment.