Skip to content

Commit

Permalink
Merge pull request #2883 from jlerbsc/master
Browse files Browse the repository at this point in the history
Fix issue 2823 solving symbol as value in the case where the scope is a constraint
  • Loading branch information
jlerbsc committed Nov 7, 2020
2 parents a4a0bea + 5000030 commit dd9e324
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@

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

import static com.github.javaparser.symbolsolver.javaparser.Navigator.demandParentNode;

import java.util.Collection;
import java.util.List;
import java.util.Optional;

import com.github.javaparser.ast.expr.Expression;
import com.github.javaparser.ast.expr.FieldAccessExpr;
import com.github.javaparser.ast.expr.ThisExpr;
Expand All @@ -32,6 +38,7 @@
import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration;
import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
import com.github.javaparser.resolution.types.ResolvedPrimitiveType;
import com.github.javaparser.resolution.types.ResolvedReferenceType;
import com.github.javaparser.resolution.types.ResolvedType;
import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory;
Expand All @@ -40,12 +47,6 @@
import com.github.javaparser.symbolsolver.model.resolution.Value;
import com.github.javaparser.symbolsolver.resolution.SymbolSolver;

import java.util.Collection;
import java.util.List;
import java.util.Optional;

import static com.github.javaparser.symbolsolver.javaparser.Navigator.demandParentNode;

/**
* @author Federico Tomassetti
*/
Expand Down Expand Up @@ -92,18 +93,9 @@ public Optional<Value> solveSymbolAsValue(String name) {
return Optional.of(new Value(ResolvedPrimitiveType.INT, ARRAY_LENGTH_FIELD_NAME));
}
if (typeOfScope.isReferenceType()) {
Optional<ResolvedReferenceTypeDeclaration> optionalTypeDeclaration = typeOfScope.asReferenceType().getTypeDeclaration();
if(optionalTypeDeclaration.isPresent()) {
ResolvedReferenceTypeDeclaration typeDeclaration = optionalTypeDeclaration.get();
if (typeDeclaration.isEnum()) {
ResolvedEnumDeclaration enumDeclaration = (ResolvedEnumDeclaration) typeDeclaration;
if (enumDeclaration.hasEnumConstant(name)) {
return Optional.of(new Value(enumDeclaration.getEnumConstant(name).getType(), name));
}
}
}
Optional<ResolvedType> typeUsage = typeOfScope.asReferenceType().getFieldType(name);
return typeUsage.map(resolvedType -> new Value(resolvedType, name));
return solveSymbolAsValue(name, typeOfScope.asReferenceType());
} else if (typeOfScope.isConstraint()) {
return solveSymbolAsValue(name, typeOfScope.asConstraintType().getBound().asReferenceType());
} else {
return Optional.empty();
}
Expand All @@ -113,6 +105,24 @@ public Optional<Value> solveSymbolAsValue(String name) {
.solveSymbolAsValue(name);
}
}

/*
* Try to resolve the name parameter as a field of the reference type
*/
private Optional<Value> solveSymbolAsValue(String name, ResolvedReferenceType type) {
Optional<ResolvedReferenceTypeDeclaration> optionalTypeDeclaration = type.getTypeDeclaration();
if (optionalTypeDeclaration.isPresent()) {
ResolvedReferenceTypeDeclaration typeDeclaration = optionalTypeDeclaration.get();
if (typeDeclaration.isEnum()) {
ResolvedEnumDeclaration enumDeclaration = (ResolvedEnumDeclaration) typeDeclaration;
if (enumDeclaration.hasEnumConstant(name)) {
return Optional.of(new Value(enumDeclaration.getEnumConstant(name).getType(), name));
}
}
}
Optional<ResolvedType> typeUsage = type.getFieldType(name);
return typeUsage.map(resolvedType -> new Value(resolvedType, name));
}

public SymbolReference<ResolvedValueDeclaration> solveField(String name) {
Collection<ResolvedReferenceTypeDeclaration> rrtds = findTypeDeclarations(Optional.of(wrappedNode.getScope()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import com.github.javaparser.StaticJavaParser;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.expr.FieldAccessExpr;
import com.github.javaparser.resolution.UnsolvedSymbolException;
import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
import com.github.javaparser.symbolsolver.resolution.typesolvers.JavaParserTypeSolver;
Expand All @@ -17,7 +16,7 @@
public class Issue2823Test extends AbstractSymbolResolutionTest {

@Test
public void testOK() {
public void test() {
final Path testRoot = adaptPath("src/test/resources/issue2823");
TypeSolver reflectionTypeSolver = new ReflectionTypeSolver();
JavaParserTypeSolver javaParserTypeSolver = new JavaParserTypeSolver(testRoot);
Expand All @@ -26,53 +25,20 @@ public void testOK() {
.setSymbolResolver(new JavaSymbolSolver(combinedTypeSolver));
StaticJavaParser.setConfiguration(configuration);

String src =
"import java.util.Optional;\n"
+ "public class TestClass {\n"
String src = "import java.util.Optional;\n"
+ "public class TestClass {\n"
+ " public Long getValue() {\n"
+ " Optional<ClassA> classA = Optional.of(new ClassA());\n"
+ " return classA.map(a -> a.obj)\n"
+ " return classA.map(a -> a.obj)\n"
+ " .map(b -> b.value)\n"
+ " .orElse(null);\n"
+ " }\n"
+ " .orElse(null);\n"
+ " }\n"
+ "}";

CompilationUnit cu = StaticJavaParser.parse(src);

try {
cu.findAll(FieldAccessExpr.class).forEach(FieldAccessExpr::resolve);
} catch (UnsolvedSymbolException e) {
// Bug to be solved
}

}

@Test
public void testKO() {
final Path testRoot = adaptPath("src/test/resources/issue2823");
TypeSolver reflectionTypeSolver = new ReflectionTypeSolver();
JavaParserTypeSolver javaParserTypeSolver = new JavaParserTypeSolver(testRoot);
CombinedTypeSolver combinedTypeSolver = new CombinedTypeSolver(reflectionTypeSolver, javaParserTypeSolver);
ParserConfiguration configuration = new ParserConfiguration()
.setSymbolResolver(new JavaSymbolSolver(combinedTypeSolver));
StaticJavaParser.setConfiguration(configuration);

String src =
"import java.util.Optional;\n"
+ "import ClassA;\n" + "import ClassB;\n"
+ "public class TestClass {\n"
+ " public Long getValue() {\n"
+ " Optional<ClassA> classA = Optional.of(new ClassA());\n"
+ " Optional<ClassB> classB = classA.map(a -> a.obj);\n"
+ " return classB\n"
+ " .map(b -> b.value)\n"
+ " .orElse(null);"
+ " }\n"
+ "}";

CompilationUnit cu = StaticJavaParser.parse(src);

cu.findAll(FieldAccessExpr.class).forEach(FieldAccessExpr::resolve);
// verify there is no exception thrown when we try to resolve all field access expressions
cu.findAll(FieldAccessExpr.class).forEach(fd -> fd.resolve());

}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
public class ClassA {
public ClassB obj;
}
}

0 comments on commit dd9e324

Please sign in to comment.