Skip to content

Commit

Permalink
Merge pull request #3029 from jlerbsc/master
Browse files Browse the repository at this point in the history
Fix issue #3027 Unable to parse class with generic parameter using JavaParserTypeSolver
  • Loading branch information
jlerbsc committed Jan 8, 2021
2 parents 2a55ce6 + 523ee1c commit 3392953
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,9 @@

package com.github.javaparser.symbolsolver.resolution.typesolvers;

import com.github.javaparser.JavaParser;
import com.github.javaparser.ParserConfiguration;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
import com.github.javaparser.symbolsolver.javaparser.Navigator;
import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import static com.github.javaparser.ParseStart.COMPILATION_UNIT;
import static com.github.javaparser.ParserConfiguration.LanguageLevel.BLEEDING_EDGE;
import static com.github.javaparser.Providers.provider;

import java.io.File;
import java.io.FileNotFoundException;
Expand All @@ -44,9 +37,17 @@
import java.util.Optional;
import java.util.concurrent.ExecutionException;

import static com.github.javaparser.ParseStart.COMPILATION_UNIT;
import static com.github.javaparser.ParserConfiguration.LanguageLevel.BLEEDING_EDGE;
import static com.github.javaparser.Providers.provider;
import com.github.javaparser.JavaParser;
import com.github.javaparser.ParserConfiguration;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
import com.github.javaparser.symbolsolver.javaparser.Navigator;
import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
import com.github.javaparser.symbolsolver.utils.FileUtils;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;

/**
* Defines a directory containing source code that should be used for solving symbols.
Expand Down Expand Up @@ -217,7 +218,7 @@ private SymbolReference<ResolvedReferenceTypeDeclaration> tryToSolveTypeUncached
for (int i = nameElements.length; i > 0; i--) {
StringBuilder filePath = new StringBuilder(srcDir.toAbsolutePath().toString());
for (int j = 0; j < i; j++) {
filePath.append("/")
filePath.append(File.separator)
.append(nameElements[j]);
}
filePath.append(".java");
Expand All @@ -230,26 +231,34 @@ private SymbolReference<ResolvedReferenceTypeDeclaration> tryToSolveTypeUncached
typeName.append(nameElements[j]);
}

String dirToParse = null;
// As an optimization we first try to look in the canonical position where we expect to find the file
Path srcFile = Paths.get(filePath.toString());
{
if (FileUtils.isValidPath(filePath.toString())) {
Path srcFile = Paths.get(filePath.toString());
Optional<CompilationUnit> compilationUnit = parse(srcFile);
if (compilationUnit.isPresent()) {
Optional<com.github.javaparser.ast.body.TypeDeclaration<?>> astTypeDeclaration = Navigator.findType(compilationUnit.get(), typeName.toString());
Optional<com.github.javaparser.ast.body.TypeDeclaration<?>> astTypeDeclaration = Navigator
.findType(compilationUnit.get(), typeName.toString());
if (astTypeDeclaration.isPresent()) {
return SymbolReference.solved(JavaParserFacade.get(this).getTypeDeclaration(astTypeDeclaration.get()));
return SymbolReference
.solved(JavaParserFacade.get(this).getTypeDeclaration(astTypeDeclaration.get()));
}
}
dirToParse = srcFile.getParent().normalize().toString();
} else {
dirToParse = FileUtils.getParentPath(filePath.toString());
}

// If this is not possible we parse all files
// We try just in the same package, for classes defined in a file not named as the class itself
{
List<CompilationUnit> compilationUnits = parseDirectory(srcFile.getParent());
if (FileUtils.isValidPath(dirToParse)) {
List<CompilationUnit> compilationUnits = parseDirectory(Paths.get(dirToParse));
for (CompilationUnit compilationUnit : compilationUnits) {
Optional<com.github.javaparser.ast.body.TypeDeclaration<?>> astTypeDeclaration = Navigator.findType(compilationUnit, typeName.toString());
Optional<com.github.javaparser.ast.body.TypeDeclaration<?>> astTypeDeclaration = Navigator
.findType(compilationUnit, typeName.toString());
if (astTypeDeclaration.isPresent()) {
return SymbolReference.solved(JavaParserFacade.get(this).getTypeDeclaration(astTypeDeclaration.get()));
return SymbolReference
.solved(JavaParserFacade.get(this).getTypeDeclaration(astTypeDeclaration.get()));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.github.javaparser.symbolsolver.utils;

import java.io.File;

import com.github.javaparser.utils.Utils;

public class FileUtils {

/*
* returns true if the filename exists otherwise return false
*/
public static boolean isValidPath(String filename) {
File file = new File(filename);
return file.exists();
}

/*
* returns the parent path from the filename as string
*/
public static String getParentPath(String filename) {
Utils.assertNotNull(filename);
int lastIndex = filename.lastIndexOf(File.separator);
return filename.substring(0, lastIndex);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,26 @@

package com.github.javaparser.symbolsolver.resolution.typesolvers;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.io.File;
import java.io.IOException;
import java.nio.file.Path;

import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;

import com.github.javaparser.ast.Node;
import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
import com.github.javaparser.symbolsolver.AbstractSymbolResolutionTest;
import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration;
import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
import com.github.javaparser.symbolsolver.utils.LeanParserConfiguration;
import com.github.javaparser.utils.CodeGenerationUtils;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;

import java.io.File;
import java.io.IOException;
import java.nio.file.Path;

import static org.junit.jupiter.api.Assertions.*;

class JavaParserTypeSolverTest extends AbstractSymbolResolutionTest {

Expand Down Expand Up @@ -127,5 +131,15 @@ public void givenJavaParserTypeSolver_tryToSolveInterfaceWithGeneric_expectSucce
assertNotNull(x.getCorrespondingDeclaration());
assertTrue(x.getCorrespondingDeclaration().isInterface());
}

@Test
public void givenJavaParserTypeSolver_tryToSolveAnUnexpectedSourceFileName_expectSuccess() {
Path src = adaptPath("src/test/test_sourcecode");
JavaParserTypeSolver typeSolver = new JavaParserTypeSolver(src);

SymbolReference<ResolvedReferenceTypeDeclaration> x = typeSolver.tryToSolveType("A<>");

assertFalse(x.isSolved());
}

}

0 comments on commit 3392953

Please sign in to comment.