aboutsummaryrefslogtreecommitdiff
path: root/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/JavaParserTypeSolver.java
diff options
context:
space:
mode:
Diffstat (limited to 'javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/JavaParserTypeSolver.java')
-rw-r--r--javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/JavaParserTypeSolver.java178
1 files changed, 178 insertions, 0 deletions
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/JavaParserTypeSolver.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/JavaParserTypeSolver.java
new file mode 100644
index 000000000..17e335e09
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/JavaParserTypeSolver.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.github.javaparser.symbolsolver.resolution.typesolvers;
+
+import com.github.javaparser.JavaParser;
+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 java.io.File;
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class JavaParserTypeSolver implements TypeSolver {
+
+ private File srcDir;
+
+ private TypeSolver parent;
+
+ private Cache<String, Optional<CompilationUnit>> parsedFiles = CacheBuilder.newBuilder().softValues().build();
+ private Cache<String, List<CompilationUnit>> parsedDirectories = CacheBuilder.newBuilder().softValues().build();
+ private Cache<String, SymbolReference<ResolvedReferenceTypeDeclaration>> foundTypes = CacheBuilder.newBuilder().softValues().build();
+
+ public JavaParserTypeSolver(File srcDir) {
+ if (!srcDir.exists() || !srcDir.isDirectory()) {
+ throw new IllegalStateException("SrcDir does not exist or is not a directory: " + srcDir.getAbsolutePath());
+ }
+ this.srcDir = srcDir;
+ }
+
+ @Override
+ public String toString() {
+ return "JavaParserTypeSolver{" +
+ "srcDir=" + srcDir +
+ ", parent=" + parent +
+ '}';
+ }
+
+ @Override
+ public TypeSolver getParent() {
+ return parent;
+ }
+
+ @Override
+ public void setParent(TypeSolver parent) {
+ this.parent = parent;
+ }
+
+
+ private Optional<CompilationUnit> parse(File srcFile) {
+ try {
+ return parsedFiles.get(srcFile.getAbsolutePath(), () -> {
+ Optional<CompilationUnit> cu;
+ try {
+ cu = Optional.of(JavaParser.parse(srcFile));
+ } catch (FileNotFoundException e) {
+ cu = Optional.empty();
+ } catch (RuntimeException e) {
+ throw new RuntimeException("Issue while parsing " + srcFile.getAbsolutePath(), e);
+ }
+ return cu;
+ });
+ } catch (ExecutionException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private List<CompilationUnit> parseDirectory(File srcDirectory) {
+ try {
+ return parsedDirectories.get(srcDirectory.getAbsolutePath(), () -> {
+ List<CompilationUnit> units = new ArrayList<>();
+ File[] files = srcDirectory.listFiles();
+ if (files != null) {
+ for (File file : files) {
+ if (file.getName().toLowerCase().endsWith(".java")) {
+ Optional<CompilationUnit> unit = parse(file);
+ if (unit.isPresent()) {
+ units.add(unit.get());
+ }
+ }
+ }
+ }
+ return units;
+ });
+ } catch (ExecutionException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public SymbolReference<ResolvedReferenceTypeDeclaration> tryToSolveType(String name) {
+ // TODO support enums
+ // TODO support interfaces
+ try {
+ return foundTypes.get(name, () -> {
+ SymbolReference<ResolvedReferenceTypeDeclaration> result = tryToSolveTypeUncached(name);
+ if (result.isSolved()) {
+ return SymbolReference.solved(result.getCorrespondingDeclaration());
+ }
+ return result;
+ });
+ } catch (ExecutionException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private SymbolReference<ResolvedReferenceTypeDeclaration> tryToSolveTypeUncached(String name) {
+ String[] nameElements = name.split("\\.");
+
+ for (int i = nameElements.length; i > 0; i--) {
+ String filePath = srcDir.getAbsolutePath();
+ for (int j = 0; j < i; j++) {
+ filePath += "/" + nameElements[j];
+ }
+ filePath += ".java";
+
+ String typeName = "";
+ for (int j = i - 1; j < nameElements.length; j++) {
+ if (j != i - 1) {
+ typeName += ".";
+ }
+ typeName += nameElements[j];
+ }
+
+ File srcFile = new File(filePath);
+ {
+ Optional<CompilationUnit> compilationUnit = parse(srcFile);
+ if (compilationUnit.isPresent()) {
+ Optional<com.github.javaparser.ast.body.TypeDeclaration<?>> astTypeDeclaration = Navigator.findType(compilationUnit.get(), typeName);
+ if (astTypeDeclaration.isPresent()) {
+ return SymbolReference.solved(JavaParserFacade.get(this).getTypeDeclaration(astTypeDeclaration.get()));
+ }
+ }
+ }
+
+ {
+ List<CompilationUnit> compilationUnits = parseDirectory(srcFile.getParentFile());
+ for (CompilationUnit compilationUnit : compilationUnits) {
+ Optional<com.github.javaparser.ast.body.TypeDeclaration<?>> astTypeDeclaration = Navigator.findType(compilationUnit, typeName);
+ if (astTypeDeclaration.isPresent()) {
+ return SymbolReference.solved(JavaParserFacade.get(this).getTypeDeclaration(astTypeDeclaration.get()));
+ }
+ }
+ }
+ }
+
+ return SymbolReference.unsolved(ResolvedReferenceTypeDeclaration.class);
+ }
+
+}