diff options
Diffstat (limited to 'javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution')
37 files changed, 5549 insertions, 0 deletions
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/AbstractResolutionTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/AbstractResolutionTest.java new file mode 100644 index 000000000..ded9267d8 --- /dev/null +++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/AbstractResolutionTest.java @@ -0,0 +1,46 @@ +/* + * 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; + +import com.github.javaparser.JavaParser; +import com.github.javaparser.ParseException; +import com.github.javaparser.ast.CompilationUnit; +import com.github.javaparser.symbolsolver.AbstractTest; + +import java.io.InputStream; + +/** + * @author Federico Tomassetti + */ +public abstract class AbstractResolutionTest extends AbstractTest { + + protected CompilationUnit parseSampleWithStandardExtension(String sampleName) { + return parseSample(sampleName, "java"); + } + + protected CompilationUnit parseSample(String sampleName) { + return parseSample(sampleName, "java.txt"); + } + + private CompilationUnit parseSample(String sampleName, String extension) { + InputStream is = this.getClass().getClassLoader().getResourceAsStream(sampleName + "." + extension); + if (is == null) { + throw new RuntimeException("Unable to find sample " + sampleName); + } + return JavaParser.parse(is); + } +} diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/AnalyseJavaParserTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/AnalyseJavaParserTest.java new file mode 100644 index 000000000..7b9f61b29 --- /dev/null +++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/AnalyseJavaParserTest.java @@ -0,0 +1,267 @@ +/* + * 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; + +import com.github.javaparser.ParseException; +import com.github.javaparser.SlowTest; +import com.github.javaparser.symbolsolver.AbstractTest; +import com.github.javaparser.symbolsolver.SourceFileInfoExtractor; +import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade; +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; +import org.junit.experimental.categories.Category; + +import java.io.*; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +@Category(SlowTest.class) +public class AnalyseJavaParserTest extends AbstractTest { + + private static final File src = adaptPath(new File("src/test/test_sourcecode/javaparser_src/proper_source")); + + private SourceFileInfoExtractor getSourceFileInfoExtractor() { + CombinedTypeSolver combinedTypeSolver = new CombinedTypeSolver(); + combinedTypeSolver.add(new ReflectionTypeSolver()); + combinedTypeSolver.add(new JavaParserTypeSolver(src)); + combinedTypeSolver.add(new JavaParserTypeSolver(adaptPath(new File("src/test/test_sourcecode/javaparser_src/generated")))); + SourceFileInfoExtractor sourceFileInfoExtractor = new SourceFileInfoExtractor(); + sourceFileInfoExtractor.setTypeSolver(combinedTypeSolver); + sourceFileInfoExtractor.setPrintFileName(false); + return sourceFileInfoExtractor; + } + + static String readFile(File file) + throws IOException { + byte[] encoded = Files.readAllBytes(Paths.get(file.getAbsolutePath())); + return new String(encoded, StandardCharsets.UTF_8); + } + + private static final boolean DEBUG = true; + + private void parse(String fileName) throws IOException, ParseException { + File sourceFile = new File(src.getAbsolutePath() + "/" + fileName + ".java"); + SourceFileInfoExtractor sourceFileInfoExtractor = getSourceFileInfoExtractor(); + OutputStream outErrStream = new ByteArrayOutputStream(); + PrintStream outErr = new PrintStream(outErrStream); + + sourceFileInfoExtractor.setOut(outErr); + sourceFileInfoExtractor.setErr(outErr); + sourceFileInfoExtractor.solve(sourceFile); + String output = outErrStream.toString(); + + String path = "src/test/resources/javaparser_expected_output/" + fileName.replaceAll("/", "_") + ".txt"; + File dstFile = adaptPath(new File(path)); + + if (DEBUG && (sourceFileInfoExtractor.getKo() != 0 || sourceFileInfoExtractor.getUnsupported() != 0)) { + System.err.println(output); + } + + assertTrue("No failures expected when analyzing " + path, 0 == sourceFileInfoExtractor.getKo()); + assertTrue("No UnsupportedOperationException expected when analyzing " + path, 0 == sourceFileInfoExtractor.getUnsupported()); + + String expected = readFile(dstFile); + + String[] outputLines = output.split("\n"); + String[] expectedLines = expected.split("\n"); + + for (int i = 0; i < Math.min(outputLines.length, expectedLines.length); i++) { + assertEquals("Line " + (i + 1) + " of " + path + " is different from what is expected", expectedLines[i].trim(), outputLines[i].trim()); + } + + assertEquals(expectedLines.length, outputLines.length); + + JavaParserFacade.clearInstances(); + + // If we need to update the file uncomment these lines + //PrintWriter writer = new PrintWriter(dstFile.getAbsoluteFile(), "UTF-8"); + //writer.print(output); + //writer.close(); + } + + @Test + public void parsePositionUtils() throws IOException, ParseException { + parse("com/github/javaparser/PositionUtils"); + } + + @Test + public void parseJavaParser() throws IOException, ParseException { + parse("com/github/javaparser/JavaParser"); + } + + @Test + public void parseStatement() throws IOException, ParseException { + parse("com/github/javaparser/ast/stmt/Statement"); + } + + @Test + public void parseCatchClause() throws IOException, ParseException { + parse("com/github/javaparser/ast/stmt/CatchClause"); + } + + @Test + public void parseStatements() throws IOException, ParseException { + parse("com/github/javaparser/ast/stmt/LabeledStmt"); + parse("com/github/javaparser/ast/stmt/BreakStmt"); + parse("com/github/javaparser/ast/stmt/ReturnStmt"); + parse("com/github/javaparser/ast/stmt/DoStmt"); + parse("com/github/javaparser/ast/stmt/AssertStmt"); + parse("com/github/javaparser/ast/stmt/ContinueStmt"); + parse("com/github/javaparser/ast/stmt/BlockStmt"); + parse("com/github/javaparser/ast/stmt/ExplicitConstructorInvocationStmt"); + parse("com/github/javaparser/ast/stmt/ExpressionStmt"); + parse("com/github/javaparser/ast/stmt/EmptyStmt"); + parse("com/github/javaparser/ast/stmt/SwitchStmt"); + parse("com/github/javaparser/ast/stmt/IfStmt"); + parse("com/github/javaparser/ast/stmt/SwitchEntryStmt"); + parse("com/github/javaparser/ast/stmt/SynchronizedStmt"); + parse("com/github/javaparser/ast/stmt/ForeachStmt"); + parse("com/github/javaparser/ast/stmt/ForStmt"); + parse("com/github/javaparser/ast/stmt/WhileStmt"); + parse("com/github/javaparser/ast/stmt/ThrowStmt"); + parse("com/github/javaparser/ast/stmt/TryStmt"); + parse("com/github/javaparser/ast/stmt/TypeDeclarationStmt"); + } + + @Test + public void parseExpressions() throws IOException, ParseException { + parse("com/github/javaparser/ast/expr/NameExpr"); + parse("com/github/javaparser/ast/expr/FieldAccessExpr"); + parse("com/github/javaparser/ast/expr/CharLiteralExpr"); + parse("com/github/javaparser/ast/expr/IntegerLiteralMinValueExpr"); + parse("com/github/javaparser/ast/expr/IntegerLiteralExpr"); + parse("com/github/javaparser/ast/expr/ArrayCreationExpr"); + parse("com/github/javaparser/ast/expr/VariableDeclarationExpr"); + parse("com/github/javaparser/ast/expr/SuperExpr"); + parse("com/github/javaparser/ast/expr/ArrayInitializerExpr"); + parse("com/github/javaparser/ast/expr/EnclosedExpr"); + parse("com/github/javaparser/ast/expr/Expression"); + parse("com/github/javaparser/ast/expr/SingleMemberAnnotationExpr"); + parse("com/github/javaparser/ast/expr/MethodReferenceExpr"); + parse("com/github/javaparser/ast/expr/ThisExpr"); + parse("com/github/javaparser/ast/expr/LiteralExpr"); + parse("com/github/javaparser/ast/expr/AnnotationExpr"); + parse("com/github/javaparser/ast/expr/InstanceOfExpr"); + parse("com/github/javaparser/ast/expr/LongLiteralExpr"); + parse("com/github/javaparser/ast/expr/StringLiteralExpr"); + parse("com/github/javaparser/ast/expr/NullLiteralExpr"); + parse("com/github/javaparser/ast/expr/ObjectCreationExpr"); + parse("com/github/javaparser/ast/expr/TypeExpr"); + parse("com/github/javaparser/ast/expr/DoubleLiteralExpr"); + parse("com/github/javaparser/ast/expr/LongLiteralMinValueExpr"); + parse("com/github/javaparser/ast/expr/MarkerAnnotationExpr"); + parse("com/github/javaparser/ast/expr/LambdaExpr"); + parse("com/github/javaparser/ast/expr/AssignExpr"); + parse("com/github/javaparser/ast/expr/NormalAnnotationExpr"); + parse("com/github/javaparser/ast/expr/QualifiedNameExpr"); + parse("com/github/javaparser/ast/expr/MemberValuePair"); + parse("com/github/javaparser/ast/expr/ArrayAccessExpr"); + parse("com/github/javaparser/ast/expr/ClassExpr"); + parse("com/github/javaparser/ast/expr/MethodCallExpr"); + parse("com/github/javaparser/ast/expr/ConditionalExpr"); + parse("com/github/javaparser/ast/expr/CastExpr"); + parse("com/github/javaparser/ast/expr/BooleanLiteralExpr"); + parse("com/github/javaparser/ast/expr/BinaryExpr"); + parse("com/github/javaparser/ast/expr/UnaryExpr"); + } + + @Test + public void parseTypes() throws IOException, ParseException { + parse("com/github/javaparser/ast/type/ClassOrInterfaceType"); + parse("com/github/javaparser/ast/type/PrimitiveType"); + parse("com/github/javaparser/ast/type/WildcardType"); + parse("com/github/javaparser/ast/type/UnknownType"); + parse("com/github/javaparser/ast/type/ReferenceType"); + parse("com/github/javaparser/ast/type/VoidType"); + parse("com/github/javaparser/ast/type/Type"); + } + + @Test + public void parseVisitors() throws IOException, ParseException { + parse("com/github/javaparser/ast/visitor/EqualsVisitor"); + parse("com/github/javaparser/ast/visitor/ModifierVisitorAdapter"); + parse("com/github/javaparser/ast/visitor/DumpVisitor"); + parse("com/github/javaparser/ast/visitor/VoidVisitor"); + parse("com/github/javaparser/ast/visitor/GenericVisitor"); + parse("com/github/javaparser/ast/visitor/VoidVisitorAdapter"); + parse("com/github/javaparser/ast/visitor/GenericVisitorAdapter"); + } + + @Test + public void parseCloneVisitor() throws IOException, ParseException { + parse("com/github/javaparser/ast/visitor/CloneVisitor"); + } + + @Test + public void parseSourcesHelper() throws IOException, ParseException { + parse("com/github/javaparser/SourcesHelper"); + } + + @Test + public void parseComments() throws IOException, ParseException { + parse("com/github/javaparser/ast/comments/LineComment"); + parse("com/github/javaparser/ast/comments/Comment"); + parse("com/github/javaparser/ast/comments/CommentsParser"); + parse("com/github/javaparser/ast/comments/JavadocComment"); + parse("com/github/javaparser/ast/comments/BlockComment"); + parse("com/github/javaparser/ast/comments/CommentsCollection"); + } + + @Test + public void parseTheRest() throws IOException, ParseException { + parse("com/github/javaparser/ast/internal/Utils"); + parse("com/github/javaparser/ast/body/AnnotationMemberDeclaration"); + parse("com/github/javaparser/ast/body/EnumDeclaration"); + parse("com/github/javaparser/ast/body/Parameter"); + parse("com/github/javaparser/ast/body/EnumConstantDeclaration"); + parse("com/github/javaparser/ast/body/VariableDeclarator"); + parse("com/github/javaparser/ast/body/TypeDeclaration"); + parse("com/github/javaparser/ast/body/EmptyMemberDeclaration"); + parse("com/github/javaparser/ast/body/ModifierSet"); + parse("com/github/javaparser/ast/body/VariableDeclaratorId"); + parse("com/github/javaparser/ast/body/BaseParameter"); + parse("com/github/javaparser/ast/body/AnnotableNode"); + parse("com/github/javaparser/ast/body/AnnotationDeclaration"); + parse("com/github/javaparser/ast/body/MethodDeclaration"); + parse("com/github/javaparser/ast/body/EmptyTypeDeclaration"); + parse("com/github/javaparser/ast/body/InitializerDeclaration"); + parse("com/github/javaparser/ast/body/BodyDeclaration"); + parse("com/github/javaparser/ast/body/FieldDeclaration"); + parse("com/github/javaparser/ast/body/ConstructorDeclaration"); + parse("com/github/javaparser/ast/body/WithDeclaration"); + parse("com/github/javaparser/ast/body/MultiTypeParameter"); + parse("com/github/javaparser/ast/body/ClassOrInterfaceDeclaration"); + parse("com/github/javaparser/ast/TreeVisitor"); + parse("com/github/javaparser/ast/PackageDeclaration"); + parse("com/github/javaparser/ast/DocumentableNode"); + parse("com/github/javaparser/ast/NamedNode"); + parse("com/github/javaparser/ast/Node"); + parse("com/github/javaparser/ast/AccessSpecifier"); + parse("com/github/javaparser/ast/CompilationUnit"); + parse("com/github/javaparser/ast/TypeParameter"); + parse("com/github/javaparser/ast/ImportDeclaration"); + parse("com/github/javaparser/Position"); + parse("com/github/javaparser/ASTHelper"); + } + +} diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/AnalyseJavaSymbolSolver060Test.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/AnalyseJavaSymbolSolver060Test.java new file mode 100644 index 000000000..1cce12aa8 --- /dev/null +++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/AnalyseJavaSymbolSolver060Test.java @@ -0,0 +1,349 @@ +/* + * 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; + +import com.github.javaparser.ParseException; +import com.github.javaparser.SlowTest; +import com.github.javaparser.symbolsolver.SourceFileInfoExtractor; +import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade; +import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver; +import com.github.javaparser.symbolsolver.resolution.typesolvers.JarTypeSolver; +import com.github.javaparser.symbolsolver.resolution.typesolvers.JavaParserTypeSolver; +import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import java.io.*; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * We analyze JavaParser version 0.6.0. + */ +@Category(SlowTest.class) +public class AnalyseJavaSymbolSolver060Test extends AbstractResolutionTest { + + private static final File root = adaptPath(new File("src/test/resources/javasymbolsolver_0_6_0")); + private static final File src = adaptPath(new File(root + "/src")); + private static final File lib = adaptPath(new File(root + "/lib")); + private static final File expectedOutput = adaptPath(new File(root + "/expected_output")); + + private static SourceFileInfoExtractor getSourceFileInfoExtractor() { + CombinedTypeSolver combinedTypeSolver = new CombinedTypeSolver(); + combinedTypeSolver.add(new ReflectionTypeSolver()); + combinedTypeSolver.add(new JavaParserTypeSolver(new File(src + "/java-symbol-solver-core"))); + combinedTypeSolver.add(new JavaParserTypeSolver(new File(src + "/java-symbol-solver-logic"))); + combinedTypeSolver.add(new JavaParserTypeSolver(new File(src + "/java-symbol-solver-model"))); + try { + combinedTypeSolver.add(new JarTypeSolver(lib + "/guava-21.0.jar")); + combinedTypeSolver.add(new JarTypeSolver(lib + "/javaparser-core-3.3.0.jar")); + combinedTypeSolver.add(new JarTypeSolver(lib + "/javaslang-2.0.3.jar")); + combinedTypeSolver.add(new JarTypeSolver(lib + "/javassist-3.19.0-GA.jar")); + } catch (IOException e) { + Assert.fail("one or more jar dependencies could not be found."); + e.printStackTrace(); + } + SourceFileInfoExtractor sourceFileInfoExtractor = new SourceFileInfoExtractor(); + sourceFileInfoExtractor.setTypeSolver(combinedTypeSolver); + sourceFileInfoExtractor.setPrintFileName(false); + sourceFileInfoExtractor.setVerbose(true); + return sourceFileInfoExtractor; + } + + private static SourceFileInfoExtractor sourceFileInfoExtractor = getSourceFileInfoExtractor(); + + static String readFile(File file) + throws IOException { + byte[] encoded = Files.readAllBytes(Paths.get(file.getAbsolutePath())); + return new String(encoded, StandardCharsets.UTF_8); + } + + private static final boolean DEBUG = true; + + /** + * @param projectName is one of "java-symbol-solver-core", "java-symbol-solver-logic", "java-symbol-solver-model" + * @param fileName describes the file being analyzed + * @throws IOException + * @throws ParseException + */ + private void parse(String projectName, String fileName) throws IOException, ParseException { + File sourceFile = new File(src.getAbsolutePath() + "/" + projectName + "/" + fileName + ".java"); + OutputStream outErrStream = new ByteArrayOutputStream(); + PrintStream outErr = new PrintStream(outErrStream); + + sourceFileInfoExtractor.setOut(outErr); + sourceFileInfoExtractor.setErr(outErr); + sourceFileInfoExtractor.solveMethodCalls(sourceFile); + String output = outErrStream.toString(); + + String path = adaptPath(expectedOutput).getPath() + "/" + projectName + "/" + fileName.replaceAll("/", "_") + ".txt"; + File dstFile = new File(path); + + if (isJava9()) { + String path9 = adaptPath(expectedOutput).getPath() + "/" + projectName + "/" + fileName.replaceAll("/", "_") + "_J9.txt"; + File dstFile9 = new File(path9); + if (dstFile9.exists()) { + path = path9; + dstFile = dstFile9; + } + } + + if (DEBUG && (sourceFileInfoExtractor.getKo() != 0 || sourceFileInfoExtractor.getUnsupported() != 0)) { + System.err.println(output); + } + + assertTrue("No failures expected when analyzing " + path, 0 == sourceFileInfoExtractor.getKo()); + assertTrue("No UnsupportedOperationException expected when analyzing " + path, 0 == sourceFileInfoExtractor.getUnsupported()); + + if (!dstFile.exists()) { + // If we need to update the file uncomment these lines +// PrintWriter writer = new PrintWriter(dstFile.getAbsoluteFile(), "UTF-8"); +// writer.print(output); +// writer.close(); + } + + String expected = readFile(dstFile); + + String[] outputLines = output.split("\n"); + String[] expectedLines = expected.split("\n"); + + for (int i = 0; i < Math.min(outputLines.length, expectedLines.length); i++) { + assertEquals("Line " + (i + 1) + " of " + path + " is different from what is expected", expectedLines[i].trim(), outputLines[i].trim()); + } + + assertEquals(expectedLines.length, outputLines.length); + + JavaParserFacade.clearInstances(); + } + + @Test + public void parseCoreSourceFileInfoExtractor() throws IOException, ParseException { + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/SourceFileInfoExtractor"); + } + + @Test + public void parseCoreCoreResolution() throws IOException, ParseException { + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/core/resolution/Context"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/core/resolution/ContextHelper"); + } + + @Test + public void parseCoreDeclarationsCommon() throws IOException, ParseException { + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/declarations/common/MethodDeclarationCommonLogic"); + } + + @Test + public void parseCoreJavaparserNavigator() throws IOException, ParseException { + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparser/Navigator"); + } + + @Test + public void parseCoreJavaparsermodel() throws IOException, ParseException { + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/DefaultVisitorAdapter"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/JavaParserFacade"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/JavaParserFactory"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/LambdaArgumentTypePlaceholder"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/TypeExtractor"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/UnsolvedSymbolException"); + } + + @Test + public void parseCoreJavaparsermodelContexts() throws IOException, ParseException { + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/contexts/AbstractJavaParserContext"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/contexts/AbstractMethodLikeDeclarationContext"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/contexts/AnonymousClassDeclarationContext"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/contexts/CatchClauseContext"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/contexts/ClassOrInterfaceDeclarationContext"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/contexts/CompilationUnitContext"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/contexts/ConstructorContext"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/contexts/ContextHelper"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/contexts/EnumDeclarationContext"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/contexts/FieldAccessContext"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/contexts/ForechStatementContext"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/contexts/ForStatementContext"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/contexts/JavaParserTypeDeclarationAdapter"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/contexts/LambdaExprContext"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/contexts/MethodCallExprContext"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/contexts/MethodContext"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/contexts/StatementContext"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/contexts/SwitchEntryContext"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/contexts/TryWithResourceContext"); + } + + @Test + public void parseCoreJavaparsermodelDeclarations() throws IOException, ParseException { + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/declarations/DefaultConstructorDeclaration"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/declarations/Helper"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnnotationDeclaration"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnonymousClassDeclaration"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserClassDeclaration"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserConstructorDeclaration"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserEnumConstantDeclaration"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserEnumDeclaration"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserFieldDeclaration"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserInterfaceDeclaration"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserMethodDeclaration"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserParameterDeclaration"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserSymbolDeclaration"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeAdapter"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeParameter"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeVariableDeclaration"); + } + + @Test + public void parseCoreJavaparsermodelDeclarators() throws IOException, ParseException { + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/declarators/AbstractSymbolDeclarator"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/declarators/FieldSymbolDeclarator"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/declarators/NoSymbolDeclarator"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/declarators/ParameterSymbolDeclarator"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/declarators/VariableSymbolDeclarator"); + } + + @Test + public void parseCoreJavassistmodel() throws IOException, ParseException { + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javassistmodel/JavassistClassDeclaration"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javassistmodel/JavassistConstructorDeclaration"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javassistmodel/JavassistEnumDeclaration"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javassistmodel/JavassistFactory"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javassistmodel/JavassistFieldDeclaration"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javassistmodel/JavassistInterfaceDeclaration"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javassistmodel/JavassistMethodDeclaration"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javassistmodel/JavassistParameterDeclaration"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javassistmodel/JavassistTypeDeclarationAdapter"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javassistmodel/JavassistTypeParameter"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javassistmodel/JavassistUtils"); + } + + @Test + public void parseCoreModelTypesystem() throws IOException, ParseException { + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/model/typesystem/LazyType"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/model/typesystem/ReferenceTypeImpl"); + } + + @Test + public void parseCoreReflectionmodel() throws IOException, ParseException { + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/reflectionmodel/MyObjectProvider"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/reflectionmodel/ReflectionClassAdapter"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/reflectionmodel/ReflectionClassDeclaration"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/reflectionmodel/ReflectionConstructorDeclaration"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/reflectionmodel/ReflectionEnumDeclaration"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/reflectionmodel/ReflectionFactory"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/reflectionmodel/ReflectionFieldDeclaration"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/reflectionmodel/ReflectionInterfaceDeclaration"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/reflectionmodel/ReflectionMethodDeclaration"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/reflectionmodel/ReflectionMethodResolutionLogic"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/reflectionmodel/ReflectionParameterDeclaration"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/reflectionmodel/ReflectionTypeParameter"); + } + + @Test + public void parseCoreReflectionmodelComparators() throws IOException, ParseException { + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/reflectionmodel/comparators/ClassComparator"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/reflectionmodel/comparators/MethodComparator"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/reflectionmodel/comparators/ParameterComparator"); + } + + @Test + public void parseCoreResolution() throws IOException, ParseException { + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/resolution/ConstructorResolutionLogic"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/resolution/MethodResolutionLogic"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/resolution/SymbolDeclarator"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/resolution/SymbolSolver"); + } + + @Test + public void parseCoreResolutionTypesolvers() throws IOException, ParseException { + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/resolution/typesolvers/CombinedTypeSolver"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/resolution/typesolvers/JarTypeSolver"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/resolution/typesolvers/JavaParserTypeSolver"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/resolution/typesolvers/MemoryTypeSolver"); + parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/resolution/typesolvers/ReflectionTypeSolver"); + } + + @Test + public void parseLogic() throws IOException, ParseException { + parse("java-symbol-solver-logic", "com/github/javaparser/symbolsolver/logic/AbstractClassDeclaration"); + parse("java-symbol-solver-logic", "com/github/javaparser/symbolsolver/logic/AbstractTypeDeclaration"); + parse("java-symbol-solver-logic", "com/github/javaparser/symbolsolver/logic/ConfilictingGenericTypesException"); + parse("java-symbol-solver-logic", "com/github/javaparser/symbolsolver/logic/FunctionalInterfaceLogic"); + parse("java-symbol-solver-logic", "com/github/javaparser/symbolsolver/logic/InferenceContext"); + parse("java-symbol-solver-logic", "com/github/javaparser/symbolsolver/logic/InferenceVariableType"); + parse("java-symbol-solver-logic", "com/github/javaparser/symbolsolver/logic/ObjectProvider"); + } + + @Test + public void parseModelDeclarations() throws IOException, ParseException { + parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/declarations/AccessLevel"); + parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/declarations/AnnotationDeclaration"); + parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/declarations/ClassDeclaration"); + parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/declarations/ConstructorDeclaration"); + parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/declarations/Declaration"); + parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/declarations/EnumDeclaration"); + parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/declarations/FieldDeclaration"); + parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/declarations/HasAccessLevel"); + parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/declarations/InterfaceDeclaration"); + parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/declarations/MethodAmbiguityException"); + parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/declarations/MethodDeclaration"); + parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/declarations/MethodLikeDeclaration"); + parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/declarations/ParameterDeclaration"); + parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/declarations/ReferenceTypeDeclaration"); + parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/declarations/TypeDeclaration"); + parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/declarations/TypeParameterDeclaration"); + parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/declarations/TypeParametrizable"); + parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/declarations/ValueDeclaration"); + } + + @Test + public void parseModelMethodsMethodUsage() throws IOException, ParseException { + parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/methods/MethodUsage"); + } + + @Test + public void parseModelResolution() throws IOException, ParseException { + parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/resolution/SymbolReference"); + parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/resolution/TypeSolver"); + parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/resolution/UnsolvedSymbolException"); + parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/resolution/Value"); + } + + @Test + public void parseModelTypesystem() throws IOException, ParseException { + parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/typesystem/ArrayType"); + parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/typesystem/LambdaConstraintType"); + parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/typesystem/NullType"); + parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/typesystem/PrimitiveType"); + parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/typesystem/ReferenceType"); + parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/typesystem/Type"); + parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/typesystem/TypeTransformer"); + parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/typesystem/TypeVariable"); + parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/typesystem/VoidType"); + parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/typesystem/Wildcard"); + } + + @Test + public void parseModelTypesystemParametrization() throws IOException, ParseException { + parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/typesystem/parametrization/TypeParametersMap"); + parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/typesystem/parametrization/TypeParameterValueProvider"); + parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/typesystem/parametrization/TypeParametrized"); + } +} diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/AnalyseNewJavaParserHelpersTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/AnalyseNewJavaParserHelpersTest.java new file mode 100644 index 000000000..254609e0c --- /dev/null +++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/AnalyseNewJavaParserHelpersTest.java @@ -0,0 +1,98 @@ +/* + * 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; + +import com.github.javaparser.JavaParser; +import com.github.javaparser.ParseException; +import com.github.javaparser.ast.CompilationUnit; +import com.github.javaparser.ast.expr.NameExpr; +import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration; +import com.github.javaparser.resolution.types.ResolvedType; +import com.github.javaparser.symbolsolver.javaparser.Navigator; +import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade; +import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; +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; + +import java.io.File; +import java.io.IOException; + +import static org.junit.Assert.assertEquals; + +/** + * We analize a more recent version of JavaParser, after the project moved to Java 8. + */ +public class AnalyseNewJavaParserHelpersTest extends AbstractResolutionTest { + + private static final File src = adaptPath(new File("src/test/test_sourcecode/javaparser_new_src/javaparser-core")); + + private static TypeSolver TYPESOLVER = typeSolver(); + + private static TypeSolver typeSolver() { + CombinedTypeSolver combinedTypeSolver = new CombinedTypeSolver(); + combinedTypeSolver.add(new ReflectionTypeSolver()); + combinedTypeSolver.add(new JavaParserTypeSolver(src)); + combinedTypeSolver.add(new JavaParserTypeSolver(adaptPath(new File("src/test/test_sourcecode/javaparser_new_src/javaparser-generated-sources")))); + return combinedTypeSolver; + } + + private CompilationUnit parse(String fileName) throws IOException { + File sourceFile = new File(src.getAbsolutePath() + "/" + fileName + ".java"); + return JavaParser.parse(sourceFile); + } + +// @Test +// public void o1TypeIsCorrect() throws IOException, ParseException { +// CompilationUnit cu = parse("com/github/javaparser/utils/PositionUtils"); +// NameExpr o1 = Navigator.findAllNodesOfGivenClass(cu, NameExpr.class).stream().filter(it -> it.getName()!=null && it.getName().equals("o1")).findFirst().get(); +// System.out.println(JavaParserFacade.get(TYPESOLVER).solve(o1).getCorrespondingDeclaration().getType()); +// } +// +// @Test +// public void o2TypeIsCorrect() throws IOException, ParseException { +// CompilationUnit cu = parse("com/github/javaparser/utils/PositionUtils"); +// NameExpr o2 = Navigator.findAllNodesOfGivenClass(cu, NameExpr.class).stream().filter(it -> it.getName()!=null && it.getName().equals("o2")).findFirst().get(); +// System.out.println(JavaParserFacade.get(TYPESOLVER).solve(o2).getCorrespondingDeclaration().getType()); +// } +// +// // To calculate the type of o1 and o2 I need to first calculate the type of the lambda +// @Test +// public void lambdaTypeIsCorrect() throws IOException, ParseException { +// CompilationUnit cu = parse("com/github/javaparser/utils/PositionUtils"); +// LambdaExpr lambda = Navigator.findAllNodesOfGivenClass(cu, LambdaExpr.class).stream().filter(it -> it.getRange().begin.line == 50).findFirst().get(); +// System.out.println(JavaParserFacade.get(TYPESOLVER).getType(lambda)); +// } + + @Test + public void nodesTypeIsCorrect() throws IOException { + CompilationUnit cu = parse("com/github/javaparser/utils/PositionUtils"); + NameExpr nodes = cu.findAll(NameExpr.class).stream().filter(it -> it.getName() != null && it.getName().getId().equals("nodes")).findFirst().get(); + ResolvedType type = JavaParserFacade.get(TYPESOLVER).solve(nodes).getCorrespondingDeclaration().getType(); + assertEquals("java.util.List<T>", type.describe()); + assertEquals(1, type.asReferenceType().typeParametersValues().size()); + assertEquals(true, type.asReferenceType().typeParametersValues().get(0).isTypeVariable()); + assertEquals("T", type.asReferenceType().typeParametersValues().get(0).asTypeParameter().getName()); + assertEquals("com.github.javaparser.utils.PositionUtils.sortByBeginPosition(java.util.List<T>).T", type.asReferenceType().typeParametersValues().get(0).asTypeParameter().getQualifiedName()); + assertEquals(1, type.asReferenceType().typeParametersValues().get(0).asTypeParameter().getBounds().size()); + ResolvedTypeParameterDeclaration.Bound bound = type.asReferenceType().typeParametersValues().get(0).asTypeParameter().getBounds().get(0); + assertEquals(true, bound.isExtends()); + assertEquals("com.github.javaparser.ast.Node", bound.getType().describe()); + } + +} diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/AnalyseNewJavaParserTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/AnalyseNewJavaParserTest.java new file mode 100644 index 000000000..53c0e040e --- /dev/null +++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/AnalyseNewJavaParserTest.java @@ -0,0 +1,328 @@ +/* + * 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; + +import com.github.javaparser.ParseException; +import com.github.javaparser.SlowTest; +import com.github.javaparser.symbolsolver.SourceFileInfoExtractor; +import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade; +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; +import org.junit.experimental.categories.Category; + +import java.io.*; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * We analyze a more recent version of JavaParser, after the project moved to Java 8. + */ +@Category(SlowTest.class) +public class AnalyseNewJavaParserTest extends AbstractResolutionTest { + + private static final File src = adaptPath(new File("src/test/test_sourcecode/javaparser_new_src/javaparser-core")); + + private static SourceFileInfoExtractor getSourceFileInfoExtractor() { + CombinedTypeSolver combinedTypeSolver = new CombinedTypeSolver(); + combinedTypeSolver.add(new ReflectionTypeSolver()); + combinedTypeSolver.add(new JavaParserTypeSolver(src)); + combinedTypeSolver.add(new JavaParserTypeSolver(adaptPath(new File("src/test/test_sourcecode/javaparser_new_src/javaparser-generated-sources")))); + SourceFileInfoExtractor sourceFileInfoExtractor = new SourceFileInfoExtractor(); + sourceFileInfoExtractor.setTypeSolver(combinedTypeSolver); + sourceFileInfoExtractor.setPrintFileName(false); + sourceFileInfoExtractor.setVerbose(true); + return sourceFileInfoExtractor; + } + + private static SourceFileInfoExtractor sourceFileInfoExtractor = getSourceFileInfoExtractor(); + + static String readFile(File file) + throws IOException { + byte[] encoded = Files.readAllBytes(Paths.get(file.getAbsolutePath())); + return new String(encoded, StandardCharsets.UTF_8); + } + + private static final boolean DEBUG = true; + + private void parse(String fileName) throws IOException, ParseException { + File sourceFile = new File(src.getAbsolutePath() + "/" + fileName + ".java"); + OutputStream outErrStream = new ByteArrayOutputStream(); + PrintStream outErr = new PrintStream(outErrStream); + + sourceFileInfoExtractor.setOut(outErr); + sourceFileInfoExtractor.setErr(outErr); + sourceFileInfoExtractor.solveMethodCalls(sourceFile); + String output = outErrStream.toString(); + + File expectedOutput = new File("src/test/resources/javaparser_methodcalls_expected_output"); + String path = adaptPath(expectedOutput).getPath() + "/" + fileName.replaceAll("/", "_") + ".txt"; + File dstFile = new File(path); + + if (isJava9()) { + String path9 = adaptPath(expectedOutput).getPath() + "/" + fileName.replaceAll("/", "_") + "_J9.txt"; + File dstFile9 = new File(path9); + if (dstFile9.exists()) { + path = path9; + dstFile = dstFile9; + } + } + + if (DEBUG && (sourceFileInfoExtractor.getKo() != 0 || sourceFileInfoExtractor.getUnsupported() != 0)) { + System.err.println(output); + } + + assertTrue("No failures expected when analyzing " + path, 0 == sourceFileInfoExtractor.getKo()); + assertTrue("No UnsupportedOperationException expected when analyzing " + path, 0 == sourceFileInfoExtractor.getUnsupported()); + + if (!dstFile.exists()) { + // If we need to update the file uncomment these lines + PrintWriter writer = new PrintWriter(dstFile.getAbsoluteFile(), "UTF-8"); + writer.print(output); + writer.close(); + } + + String expected = readFile(dstFile); + + String[] outputLines = output.split("\n"); + String[] expectedLines = expected.split("\n"); + + for (int i = 0; i < Math.min(outputLines.length, expectedLines.length); i++) { + assertEquals("Line " + (i + 1) + " of " + path + " is different from what is expected", expectedLines[i].trim(), outputLines[i].trim()); + } + + assertEquals(expectedLines.length, outputLines.length); + + JavaParserFacade.clearInstances(); + } + + @Test + public void parseUtilsUtils() throws IOException, ParseException { + parse("com/github/javaparser/utils/Utils"); + } + + @Test + public void parseCommentsInserter() throws IOException, ParseException { + parse("com/github/javaparser/CommentsInserter"); + } + + @Test + public void parsePositionUtils() throws IOException, ParseException { + parse("com/github/javaparser/utils/PositionUtils"); + } + + @Test + public void parseModifier() throws IOException, ParseException { + parse("com/github/javaparser/ast/Modifier"); + } + + @Test + public void parseNodeWithMembers() throws IOException, ParseException { + parse("com/github/javaparser/ast/nodeTypes/NodeWithMembers"); + } + + @Test + public void parseAstStmts() throws IOException, ParseException { + parse("com/github/javaparser/ast/stmt/AssertStmt"); + parse("com/github/javaparser/ast/stmt/BlockStmt"); + parse("com/github/javaparser/ast/stmt/BreakStmt"); + parse("com/github/javaparser/ast/stmt/CatchClause"); + parse("com/github/javaparser/ast/stmt/ContinueStmt"); + parse("com/github/javaparser/ast/stmt/DoStmt"); + parse("com/github/javaparser/ast/stmt/EmptyStmt"); + parse("com/github/javaparser/ast/stmt/ExplicitConstructorInvocationStmt"); + parse("com/github/javaparser/ast/stmt/ExpressionStmt"); + parse("com/github/javaparser/ast/stmt/ForStmt"); + parse("com/github/javaparser/ast/stmt/ForeachStmt"); + parse("com/github/javaparser/ast/stmt/IfStmt"); + parse("com/github/javaparser/ast/stmt/LabeledStmt"); + parse("com/github/javaparser/ast/stmt/ReturnStmt"); + parse("com/github/javaparser/ast/stmt/Statement"); + parse("com/github/javaparser/ast/stmt/SwitchEntryStmt"); + parse("com/github/javaparser/ast/stmt/SwitchStmt"); + parse("com/github/javaparser/ast/stmt/SynchronizedStmt"); + parse("com/github/javaparser/ast/stmt/ThrowStmt"); + parse("com/github/javaparser/ast/stmt/TryStmt"); + parse("com/github/javaparser/ast/stmt/TypeDeclarationStmt"); + parse("com/github/javaparser/ast/stmt/WhileStmt"); + } + + @Test + public void parseAstExprs() throws IOException, ParseException { + parse("com/github/javaparser/ast/expr/AnnotationExpr"); + parse("com/github/javaparser/ast/expr/ArrayAccessExpr"); + parse("com/github/javaparser/ast/expr/ArrayCreationExpr"); + parse("com/github/javaparser/ast/expr/ArrayInitializerExpr"); + parse("com/github/javaparser/ast/expr/AssignExpr"); + parse("com/github/javaparser/ast/expr/BinaryExpr"); + parse("com/github/javaparser/ast/expr/BooleanLiteralExpr"); + parse("com/github/javaparser/ast/expr/CastExpr"); + parse("com/github/javaparser/ast/expr/CharLiteralExpr"); + parse("com/github/javaparser/ast/expr/ClassExpr"); + parse("com/github/javaparser/ast/expr/ConditionalExpr"); + parse("com/github/javaparser/ast/expr/DoubleLiteralExpr"); + parse("com/github/javaparser/ast/expr/EnclosedExpr"); + parse("com/github/javaparser/ast/expr/Expression"); + parse("com/github/javaparser/ast/expr/FieldAccessExpr"); + parse("com/github/javaparser/ast/expr/InstanceOfExpr"); + parse("com/github/javaparser/ast/expr/IntegerLiteralExpr"); + parse("com/github/javaparser/ast/expr/IntegerLiteralMinValueExpr"); + parse("com/github/javaparser/ast/expr/LambdaExpr"); + parse("com/github/javaparser/ast/expr/LiteralExpr"); + parse("com/github/javaparser/ast/expr/LongLiteralExpr"); + parse("com/github/javaparser/ast/expr/LongLiteralMinValueExpr"); + parse("com/github/javaparser/ast/expr/MarkerAnnotationExpr"); + parse("com/github/javaparser/ast/expr/MemberValuePair"); + parse("com/github/javaparser/ast/expr/MethodCallExpr"); + parse("com/github/javaparser/ast/expr/MethodReferenceExpr"); + parse("com/github/javaparser/ast/expr/NameExpr"); + parse("com/github/javaparser/ast/expr/NormalAnnotationExpr"); + parse("com/github/javaparser/ast/expr/NullLiteralExpr"); + parse("com/github/javaparser/ast/expr/ObjectCreationExpr"); + parse("com/github/javaparser/ast/expr/QualifiedNameExpr"); + parse("com/github/javaparser/ast/expr/SingleMemberAnnotationExpr"); + parse("com/github/javaparser/ast/expr/StringLiteralExpr"); + parse("com/github/javaparser/ast/expr/SuperExpr"); + parse("com/github/javaparser/ast/expr/ThisExpr"); + parse("com/github/javaparser/ast/expr/TypeExpr"); + parse("com/github/javaparser/ast/expr/UnaryExpr"); + } + + @Test + public void parseVariableDeclarationExpr() throws IOException, ParseException { + parse("com/github/javaparser/ast/expr/VariableDeclarationExpr"); + } + + @Test + public void parseAstBody() throws IOException, ParseException { + parse("com/github/javaparser/ast/body/AnnotationDeclaration"); + parse("com/github/javaparser/ast/body/AnnotationMemberDeclaration"); + parse("com/github/javaparser/ast/body/BodyDeclaration"); + parse("com/github/javaparser/ast/body/ClassOrInterfaceDeclaration"); + parse("com/github/javaparser/ast/body/ConstructorDeclaration"); + parse("com/github/javaparser/ast/body/EmptyMemberDeclaration"); + parse("com/github/javaparser/ast/body/EmptyTypeDeclaration"); + parse("com/github/javaparser/ast/body/EnumConstantDeclaration"); + parse("com/github/javaparser/ast/body/EnumDeclaration"); + parse("com/github/javaparser/ast/body/FieldDeclaration"); + parse("com/github/javaparser/ast/body/InitializerDeclaration"); + parse("com/github/javaparser/ast/body/MethodDeclaration"); + parse("com/github/javaparser/ast/body/Parameter"); + parse("com/github/javaparser/ast/body/TypeDeclaration"); + parse("com/github/javaparser/ast/body/VariableDeclarator"); + parse("com/github/javaparser/ast/body/VariableDeclaratorId"); + } + + @Test + public void parseAstComments() throws IOException, ParseException { + parse("com/github/javaparser/ast/comments/BlockComment"); + parse("com/github/javaparser/ast/comments/Comment"); + parse("com/github/javaparser/ast/comments/CommentsCollection"); + parse("com/github/javaparser/ast/comments/JavadocComment"); + parse("com/github/javaparser/ast/comments/LineComment"); + } + + @Test + public void parseAstRest() throws IOException, ParseException { + parse("com/github/javaparser/ast/AccessSpecifier"); + parse("com/github/javaparser/ast/ArrayBracketPair"); + parse("com/github/javaparser/ast/ArrayCreationLevel"); + parse("com/github/javaparser/ast/CompilationUnit"); + parse("com/github/javaparser/ast/Example"); + parse("com/github/javaparser/ast/ImportDeclaration"); + parse("com/github/javaparser/ast/Node"); + parse("com/github/javaparser/ast/PackageDeclaration"); + parse("com/github/javaparser/ast/UserDataKey"); + } + + @Test + public void parseAstNodeTypes() throws IOException, ParseException { + parse("com/github/javaparser/ast/nodeTypes/NodeWithAnnotations"); + parse("com/github/javaparser/ast/nodeTypes/NodeWithBlockStmt"); + parse("com/github/javaparser/ast/nodeTypes/NodeWithBody"); + parse("com/github/javaparser/ast/nodeTypes/NodeWithDeclaration"); + parse("com/github/javaparser/ast/nodeTypes/NodeWithElementType"); + parse("com/github/javaparser/ast/nodeTypes/NodeWithExtends"); + parse("com/github/javaparser/ast/nodeTypes/NodeWithImplements"); + parse("com/github/javaparser/ast/nodeTypes/NodeWithJavaDoc"); + parse("com/github/javaparser/ast/nodeTypes/NodeWithModifiers"); + parse("com/github/javaparser/ast/nodeTypes/NodeWithName"); + parse("com/github/javaparser/ast/nodeTypes/NodeWithParameters"); + parse("com/github/javaparser/ast/nodeTypes/NodeWithStatements"); + parse("com/github/javaparser/ast/nodeTypes/NodeWithThrowable"); + parse("com/github/javaparser/ast/nodeTypes/NodeWithType"); + parse("com/github/javaparser/ast/nodeTypes/NodeWithTypeArguments"); + parse("com/github/javaparser/ast/nodeTypes/NodeWithVariables"); + } + + @Test + public void parseAstTypes() throws IOException, ParseException { + parse("com/github/javaparser/ast/type/ArrayType"); + parse("com/github/javaparser/ast/type/ClassOrInterfaceType"); + parse("com/github/javaparser/ast/type/IntersectionType"); + parse("com/github/javaparser/ast/type/PrimitiveType"); + parse("com/github/javaparser/ast/type/ReferenceType"); + parse("com/github/javaparser/ast/type/Type"); + parse("com/github/javaparser/ast/type/TypeParameter"); + parse("com/github/javaparser/ast/type/UnionType"); + parse("com/github/javaparser/ast/type/UnknownType"); + parse("com/github/javaparser/ast/type/VoidType"); + parse("com/github/javaparser/ast/type/WildcardType"); + } + + @Test + public void parseAstVisitor() throws IOException, ParseException { + parse("com/github/javaparser/ast/visitor/CloneVisitor"); + parse("com/github/javaparser/ast/visitor/EqualsVisitor"); + parse("com/github/javaparser/ast/visitor/GenericVisitor"); + parse("com/github/javaparser/ast/visitor/GenericVisitorAdapter"); + parse("com/github/javaparser/ast/visitor/ModifierVisitorAdapter"); + parse("com/github/javaparser/ast/visitor/TreeVisitor"); + parse("com/github/javaparser/ast/visitor/VoidVisitor"); + parse("com/github/javaparser/ast/visitor/VoidVisitorAdapter"); + } + + @Test + public void parseDumpVisitor() throws IOException, ParseException { + parse("com/github/javaparser/ast/visitor/DumpVisitor"); + } + + @Test + public void parseUtils() throws IOException, ParseException { + parse("com/github/javaparser/utils/ClassUtils"); + parse("com/github/javaparser/utils/Pair"); + } + + @Test + public void parseAllOtherNodes() throws IOException, ParseException { + parse("com/github/javaparser/JavaParser"); + parse("com/github/javaparser/ParseProblemException"); + parse("com/github/javaparser/ParseResult"); + parse("com/github/javaparser/ParseStart"); + parse("com/github/javaparser/ParserConfiguration"); + parse("com/github/javaparser/Position"); + parse("com/github/javaparser/Problem"); + parse("com/github/javaparser/Providers"); + parse("com/github/javaparser/Range"); + } + +} diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/ArrayExprTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/ArrayExprTest.java new file mode 100644 index 000000000..92b973396 --- /dev/null +++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/ArrayExprTest.java @@ -0,0 +1,26 @@ +package com.github.javaparser.symbolsolver.resolution; + +import com.github.javaparser.JavaParser; +import com.github.javaparser.ast.body.FieldDeclaration; +import com.github.javaparser.resolution.types.ResolvedType; +import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade; +import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * See issue #17 + */ +public class ArrayExprTest { + + @Test + public void verifyAnArrayAccessExprTypeIsCalculatedProperly() { + String code = "class A { String[] arrSQL; String toExamine = arrSQL[1]; }"; + FieldDeclaration field = JavaParser.parse(code).getClassByName("A").get().getFieldByName("toExamine").get(); + + ResolvedType type = JavaParserFacade.get(new ReflectionTypeSolver()).getType(field.getVariables().get(0).getInitializer().get()); + assertEquals(true, type.isReferenceType()); + assertEquals("java.lang.String", type.asReferenceType().getQualifiedName()); + } +} diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/ContextTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/ContextTest.java new file mode 100644 index 000000000..45cc56ea6 --- /dev/null +++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/ContextTest.java @@ -0,0 +1,475 @@ +/* + * 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; + +import com.github.javaparser.JavaParser; +import com.github.javaparser.ParseException; +import com.github.javaparser.ast.CompilationUnit; +import com.github.javaparser.ast.body.MethodDeclaration; +import com.github.javaparser.ast.body.Parameter; +import com.github.javaparser.ast.expr.AssignExpr; +import com.github.javaparser.ast.expr.Expression; +import com.github.javaparser.ast.expr.MethodCallExpr; +import com.github.javaparser.ast.expr.NameExpr; +import com.github.javaparser.ast.stmt.ExpressionStmt; +import com.github.javaparser.resolution.MethodUsage; +import com.github.javaparser.resolution.declarations.ResolvedClassDeclaration; +import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration; +import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration; +import com.github.javaparser.resolution.types.ResolvedType; +import com.github.javaparser.symbolsolver.AbstractTest; +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.reflectionmodel.ReflectionClassDeclaration; +import com.github.javaparser.symbolsolver.resolution.typesolvers.*; +import org.junit.Test; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.Collections; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class ContextTest extends AbstractTest { + + private TypeSolver typeSolver = new CombinedTypeSolver(new MemoryTypeSolver(), new ReflectionTypeSolver()); + + private CompilationUnit parseSample(String sampleName) { + InputStream is = ContextTest.class.getClassLoader().getResourceAsStream(sampleName + ".java.txt"); + return JavaParser.parse(is); + } + + @Test + public void resolveDeclaredFieldReference() { + CompilationUnit cu = parseSample("ReferencesToField"); + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration referencesToField = Navigator.demandClass(cu, "ReferencesToField"); + MethodDeclaration method1 = Navigator.demandMethod(referencesToField, "method1"); + ExpressionStmt stmt = (ExpressionStmt) method1.getBody().get().getStatements().get(0); + AssignExpr assignExpr = (AssignExpr) stmt.getExpression(); + + SymbolSolver symbolSolver = new SymbolSolver(typeSolver); + SymbolReference symbolReference = symbolSolver.solveSymbol("i", assignExpr.getTarget()); + + assertEquals(true, symbolReference.isSolved()); + assertEquals("i", symbolReference.getCorrespondingDeclaration().getName()); + assertEquals(true, symbolReference.getCorrespondingDeclaration().isField()); + } + + @Test + public void resolveInheritedFieldReference() { + CompilationUnit cu = parseSample("ReferencesToField"); + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration referencesToField = Navigator.demandClass(cu, "ReferencesToFieldExtendingClass"); + MethodDeclaration method1 = Navigator.demandMethod(referencesToField, "method2"); + ExpressionStmt stmt = (ExpressionStmt) method1.getBody().get().getStatements().get(0); + AssignExpr assignExpr = (AssignExpr) stmt.getExpression(); + + SymbolSolver symbolSolver = new SymbolSolver(typeSolver); + SymbolReference symbolReference = symbolSolver.solveSymbol("i", assignExpr.getTarget()); + + assertEquals(true, symbolReference.isSolved()); + assertEquals("i", symbolReference.getCorrespondingDeclaration().getName()); + assertEquals(true, symbolReference.getCorrespondingDeclaration().isField()); + } + + @Test + public void resolveParameterReference() { + CompilationUnit cu = parseSample("ReferencesToParameter"); + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration referencesToField = Navigator.demandClass(cu, "ReferenceToParameter"); + MethodDeclaration method1 = Navigator.demandMethod(referencesToField, "aMethod"); + NameExpr foo = Navigator.findNameExpression(method1, "foo").get(); + + SymbolSolver symbolSolver = new SymbolSolver(typeSolver); + SymbolReference symbolReference = symbolSolver.solveSymbol("foo", foo); + + assertEquals(true, symbolReference.isSolved()); + assertEquals("foo", symbolReference.getCorrespondingDeclaration().getName()); + assertEquals(true, symbolReference.getCorrespondingDeclaration().isParameter()); + } + + @Test + public void resolveReferenceToImportedType() { + CompilationUnit cu = parseSample("Navigator"); + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration referencesToField = Navigator.demandClass(cu, "Navigator"); + MethodDeclaration method = Navigator.demandMethod(referencesToField, "findType"); + Parameter param = method.getParameters().get(0); + + ResolvedClassDeclaration compilationUnitDecl = mock(ResolvedClassDeclaration.class); + when(compilationUnitDecl.getName()).thenReturn("CompilationUnit"); + when(compilationUnitDecl.getQualifiedName()).thenReturn("com.github.javaparser.ast.CompilationUnit"); + TypeSolver typeSolver = mock(TypeSolver.class); + when(typeSolver.getRoot()).thenReturn(typeSolver); + when(typeSolver.solveType("java.lang.Object")).thenReturn(new ReflectionClassDeclaration(Object.class, typeSolver)); + when(typeSolver.tryToSolveType("com.github.javaparser.ast.CompilationUnit")).thenReturn(SymbolReference.solved(compilationUnitDecl)); + SymbolSolver symbolSolver = new SymbolSolver(typeSolver); + + SymbolReference<? extends ResolvedTypeDeclaration> ref = symbolSolver.solveType("CompilationUnit", param); + + assertEquals(true, ref.isSolved()); + assertEquals("CompilationUnit", ref.getCorrespondingDeclaration().getName()); + assertEquals("com.github.javaparser.ast.CompilationUnit", ref.getCorrespondingDeclaration().getQualifiedName()); + } + + @Test + public void resolveReferenceUsingQualifiedName() { + CompilationUnit cu = parseSample("Navigator2"); + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration referencesToField = Navigator.demandClass(cu, "Navigator"); + MethodDeclaration method = Navigator.demandMethod(referencesToField, "findType"); + Parameter param = method.getParameters().get(0); + + ResolvedClassDeclaration compilationUnitDecl = mock(ResolvedClassDeclaration.class); + when(compilationUnitDecl.getName()).thenReturn("CompilationUnit"); + when(compilationUnitDecl.getQualifiedName()).thenReturn("com.github.javaparser.ast.CompilationUnit"); + TypeSolver typeSolver = mock(TypeSolver.class); + //when(typeSolver.tryToSolveType("java.lang.com.github.javaparser.ast.CompilationUnit")).thenReturn(SymbolReference.unsolved(ClassDeclaration.class)); + when(typeSolver.getRoot()).thenReturn(typeSolver); + when(typeSolver.solveType("java.lang.Object")).thenReturn(new ReflectionClassDeclaration(Object.class, typeSolver)); + when(typeSolver.tryToSolveType("com.github.javaparser.ast.CompilationUnit")).thenReturn(SymbolReference.solved(compilationUnitDecl)); + SymbolSolver symbolSolver = new SymbolSolver(typeSolver); + + SymbolReference<? extends ResolvedTypeDeclaration> ref = symbolSolver.solveType("com.github.javaparser.ast.CompilationUnit", param); + + assertEquals(true, ref.isSolved()); + assertEquals("CompilationUnit", ref.getCorrespondingDeclaration().getName()); + assertEquals("com.github.javaparser.ast.CompilationUnit", ref.getCorrespondingDeclaration().getQualifiedName()); + } + + @Test + public void resolveReferenceToClassesInTheSamePackage() { + CompilationUnit cu = parseSample("Navigator3"); + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration referencesToField = Navigator.demandClass(cu, "Navigator"); + MethodDeclaration method = Navigator.demandMethod(referencesToField, "findType"); + Parameter param = method.getParameters().get(0); + + ResolvedClassDeclaration compilationUnitDecl = mock(ResolvedClassDeclaration.class); + when(compilationUnitDecl.getName()).thenReturn("CompilationUnit"); + when(compilationUnitDecl.getQualifiedName()).thenReturn("my.packagez.CompilationUnit"); + TypeSolver typeSolver = mock(TypeSolver.class); + when(typeSolver.getRoot()).thenReturn(typeSolver); + when(typeSolver.solveType("java.lang.Object")).thenReturn(new ReflectionClassDeclaration(Object.class, typeSolver)); + when(typeSolver.tryToSolveType("my.packagez.CompilationUnit")).thenReturn(SymbolReference.solved(compilationUnitDecl)); + SymbolSolver symbolSolver = new SymbolSolver(typeSolver); + + SymbolReference<? extends ResolvedTypeDeclaration> ref = symbolSolver.solveType("CompilationUnit", param); + + assertEquals(true, ref.isSolved()); + assertEquals("CompilationUnit", ref.getCorrespondingDeclaration().getName()); + assertEquals("my.packagez.CompilationUnit", ref.getCorrespondingDeclaration().getQualifiedName()); + } + + @Test + public void resolveReferenceToClassInJavaLang() { + CompilationUnit cu = parseSample("Navigator"); + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration referencesToField = Navigator.demandClass(cu, "Navigator"); + MethodDeclaration method = Navigator.demandMethod(referencesToField, "findType"); + Parameter param = method.getParameters().get(1); + + ResolvedClassDeclaration stringDecl = mock(ResolvedClassDeclaration.class); + when(stringDecl.getName()).thenReturn("String"); + when(stringDecl.getQualifiedName()).thenReturn("java.lang.String"); + TypeSolver typeSolver = mock(TypeSolver.class); + when(typeSolver.tryToSolveType("me.tomassetti.symbolsolver.javaparser.String")).thenReturn(SymbolReference.unsolved(ResolvedReferenceTypeDeclaration.class)); + when(typeSolver.getRoot()).thenReturn(typeSolver); + when(typeSolver.solveType("java.lang.Object")).thenReturn(new ReflectionClassDeclaration(Object.class, typeSolver)); + when(typeSolver.tryToSolveType("java.lang.String")).thenReturn(SymbolReference.solved(stringDecl)); + SymbolSolver symbolSolver = new SymbolSolver(typeSolver); + + SymbolReference<? extends ResolvedTypeDeclaration> ref = symbolSolver.solveType("String", param); + + assertEquals(true, ref.isSolved()); + assertEquals("String", ref.getCorrespondingDeclaration().getName()); + assertEquals("java.lang.String", ref.getCorrespondingDeclaration().getQualifiedName()); + } + + @Test + public void resolveReferenceToMethod() throws ParseException, IOException { + CompilationUnit cu = parseSample("Navigator"); + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration referencesToField = Navigator.demandClass(cu, "Navigator"); + MethodDeclaration method = Navigator.demandMethod(referencesToField, "findType"); + MethodCallExpr callToGetTypes = Navigator.findMethodCall(method, "getTypes").get(); + + String pathToJar = adaptPath("src/test/resources/javaparser-core-2.1.0.jar"); + TypeSolver typeSolver = new CombinedTypeSolver(new JarTypeSolver(pathToJar), new ReflectionTypeSolver(true)); + SymbolSolver symbolSolver = new SymbolSolver(typeSolver); + + MethodUsage ref = symbolSolver.solveMethod("getTypes", Collections.emptyList(), callToGetTypes); + + assertEquals("getTypes", ref.getName()); + assertEquals("com.github.javaparser.ast.CompilationUnit", ref.declaringType().getQualifiedName()); + + //verify(typeSolver); + } + + @Test + public void resolveCascadeOfReferencesToMethod() throws ParseException, IOException { + CompilationUnit cu = parseSample("Navigator"); + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration referencesToField = Navigator.demandClass(cu, "Navigator"); + MethodDeclaration method = Navigator.demandMethod(referencesToField, "findType"); + MethodCallExpr callToStream = Navigator.findMethodCall(method, "stream").get(); + + String pathToJar = adaptPath("src/test/resources/javaparser-core-2.1.0.jar"); + TypeSolver typeSolver = new CombinedTypeSolver(new JarTypeSolver(pathToJar), new ReflectionTypeSolver(true)); + SymbolSolver symbolSolver = new SymbolSolver(typeSolver); + MethodUsage ref = symbolSolver.solveMethod("stream", Collections.emptyList(), callToStream); + + assertEquals("stream", ref.getName()); + assertEquals("java.util.Collection", ref.declaringType().getQualifiedName()); + } + + @Test + public void resolveReferenceToMethodCalledOnArrayAccess() { + CompilationUnit cu = parseSample("ArrayAccess"); + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "ArrayAccess"); + MethodDeclaration method = Navigator.demandMethod(clazz, "access"); + MethodCallExpr callToTrim = Navigator.findMethodCall(method, "trim").get(); + + File src = adaptPath(new File("src/test/resources")); + TypeSolver typeSolver = new CombinedTypeSolver(new ReflectionTypeSolver(), new JavaParserTypeSolver(src)); + SymbolSolver symbolSolver = new SymbolSolver(typeSolver); + MethodUsage ref = symbolSolver.solveMethod("trim", Collections.emptyList(), callToTrim); + + assertEquals("trim", ref.getName()); + assertEquals("java.lang.String", ref.declaringType().getQualifiedName()); + } + + @Test + public void resolveReferenceToJreType() { + CompilationUnit cu = parseSample("NavigatorSimplified"); + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Navigator"); + MethodDeclaration method = Navigator.demandMethod(clazz, "foo"); + com.github.javaparser.ast.type.Type streamJavaParserType = method.getParameters().get(0).getType(); + + TypeSolver typeSolver = new ReflectionTypeSolver(); + ResolvedType streamType = JavaParserFacade.get(typeSolver).convert(streamJavaParserType, method); + + assertEquals("java.util.stream.Stream<java.lang.String>", streamType.describe()); + } + + @Test + public void resolveReferenceToMethodWithLambda() { + CompilationUnit cu = parseSample("NavigatorSimplified"); + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Navigator"); + MethodDeclaration method = Navigator.demandMethod(clazz, "findType"); + MethodCallExpr methodCallExpr = Navigator.findMethodCall(method, "filter").get(); + + TypeSolver typeSolver = new ReflectionTypeSolver(); + ResolvedType ref = JavaParserFacade.get(typeSolver).getType(methodCallExpr); + + assertEquals("java.util.stream.Stream<java.lang.String>", ref.describe()); + assertEquals(1, ref.asReferenceType().typeParametersValues().size()); + assertEquals("java.lang.String", ref.asReferenceType().typeParametersValues().get(0).describe()); + } + + @Test + public void resolveReferenceToLambdaParamBase() { + CompilationUnit cu = parseSample("NavigatorSimplified"); + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Navigator"); + MethodDeclaration method = Navigator.demandMethod(clazz, "findType"); + NameExpr refToT = Navigator.findNameExpression(method, "t").get(); + + TypeSolver typeSolver = new ReflectionTypeSolver(); + JavaParserFacade javaParserFacade = JavaParserFacade.get(typeSolver); + ResolvedType ref = javaParserFacade.getType(refToT); + + assertEquals("? super java.lang.String", ref.describe()); + } + + @Test + public void resolveReferenceToLambdaParamSimplified() { + CompilationUnit cu = parseSample("NavigatorSimplified"); + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Navigator"); + MethodDeclaration method = Navigator.demandMethod(clazz, "findType"); + MethodCallExpr call = Navigator.findMethodCall(method, "isEmpty").get(); + + TypeSolver typeSolver = new ReflectionTypeSolver(); + SymbolSolver symbolSolver = new SymbolSolver(typeSolver); + MethodUsage ref = symbolSolver.solveMethod("isEmpty", Collections.emptyList(), call); + + assertEquals("isEmpty", ref.getName()); + assertEquals("java.lang.String", ref.declaringType().getQualifiedName()); + } + + @Test + public void resolveGenericReturnTypeOfMethodInJar() throws ParseException, IOException { + CompilationUnit cu = parseSample("Navigator"); + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Navigator"); + MethodDeclaration method = Navigator.demandMethod(clazz, "findType"); + MethodCallExpr call = Navigator.findMethodCall(method, "getTypes").get(); + + String pathToJar = adaptPath("src/test/resources/javaparser-core-2.1.0.jar"); + TypeSolver typeSolver = new CombinedTypeSolver(new ReflectionTypeSolver(), new JarTypeSolver(pathToJar)); + MethodUsage methodUsage = JavaParserFacade.get(typeSolver).solveMethodAsUsage(call); + + assertEquals("getTypes", methodUsage.getName()); + assertEquals("java.util.List<com.github.javaparser.ast.body.TypeDeclaration>", methodUsage.returnType().describe()); + assertEquals(1, methodUsage.returnType().asReferenceType().typeParametersValues().size()); + assertEquals("com.github.javaparser.ast.body.TypeDeclaration", methodUsage.returnType().asReferenceType().typeParametersValues().get(0).describe()); + } + + @Test + public void resolveTypeUsageOfFirstMethodInGenericClass() throws ParseException, IOException { + CompilationUnit cu = parseSample("Navigator"); + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Navigator"); + MethodDeclaration method = Navigator.demandMethod(clazz, "findType"); + MethodCallExpr callToGetTypes = Navigator.findMethodCall(method, "getTypes").get(); + + String pathToJar = adaptPath("src/test/resources/javaparser-core-2.1.0.jar"); + TypeSolver typeSolver = new CombinedTypeSolver(new ReflectionTypeSolver(), new JarTypeSolver(pathToJar)); + MethodUsage filterUsage = JavaParserFacade.get(typeSolver).solveMethodAsUsage(callToGetTypes); + + assertEquals("java.util.List<com.github.javaparser.ast.body.TypeDeclaration>", filterUsage.returnType().describe()); + assertEquals(1, filterUsage.returnType().asReferenceType().typeParametersValues().size()); + assertEquals("com.github.javaparser.ast.body.TypeDeclaration", filterUsage.returnType().asReferenceType().typeParametersValues().get(0).describe()); + } + + @Test + public void resolveTypeUsageOfMethodInGenericClass() throws ParseException, IOException { + CompilationUnit cu = parseSample("Navigator"); + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Navigator"); + MethodDeclaration method = Navigator.demandMethod(clazz, "findType"); + MethodCallExpr callToStream = Navigator.findMethodCall(method, "stream").get(); + + String pathToJar = adaptPath("src/test/resources/javaparser-core-2.1.0.jar"); + TypeSolver typeSolver = new CombinedTypeSolver(new ReflectionTypeSolver(), new JarTypeSolver(pathToJar)); + MethodUsage filterUsage = JavaParserFacade.get(typeSolver).solveMethodAsUsage(callToStream); + + assertEquals("java.util.stream.Stream<com.github.javaparser.ast.body.TypeDeclaration>", filterUsage.returnType().describe()); + } + + @Test + public void resolveTypeUsageOfCascadeMethodInGenericClass() throws ParseException, IOException { + CompilationUnit cu = parseSample("Navigator"); + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Navigator"); + MethodDeclaration method = Navigator.demandMethod(clazz, "findType"); + MethodCallExpr callToFilter = Navigator.findMethodCall(method, "filter").get(); + + String pathToJar = adaptPath("src/test/resources/javaparser-core-2.1.0.jar"); + TypeSolver typeSolver = new CombinedTypeSolver(new ReflectionTypeSolver(), new JarTypeSolver(pathToJar)); + MethodUsage filterUsage = JavaParserFacade.get(typeSolver).solveMethodAsUsage(callToFilter); + + assertEquals("java.util.stream.Stream<com.github.javaparser.ast.body.TypeDeclaration>", filterUsage.returnType().describe()); + } + + @Test + public void resolveLambdaType() throws ParseException, IOException { + CompilationUnit cu = parseSample("Navigator"); + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Navigator"); + MethodDeclaration method = Navigator.demandMethod(clazz, "findType"); + MethodCallExpr callToFilter = Navigator.findMethodCall(method, "filter").get(); + Expression lambdaExpr = callToFilter.getArguments().get(0); + + String pathToJar = adaptPath("src/test/resources/javaparser-core-2.1.0.jar"); + TypeSolver typeSolver = new CombinedTypeSolver(new ReflectionTypeSolver(), new JarTypeSolver(pathToJar)); + ResolvedType typeOfLambdaExpr = JavaParserFacade.get(typeSolver).getType(lambdaExpr); + + assertEquals("java.util.function.Predicate<? super com.github.javaparser.ast.body.TypeDeclaration>", typeOfLambdaExpr.describe()); + } + + @Test + public void resolveReferenceToLambdaParam() throws ParseException, IOException { + CompilationUnit cu = parseSample("Navigator"); + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Navigator"); + MethodDeclaration method = Navigator.demandMethod(clazz, "findType"); + MethodCallExpr callToGetName = Navigator.findMethodCall(method, "getName").get(); + Expression referenceToT = callToGetName.getScope().get(); + + String pathToJar = adaptPath("src/test/resources/javaparser-core-2.1.0.jar"); + TypeSolver typeSolver = new CombinedTypeSolver(new ReflectionTypeSolver(), new JarTypeSolver(pathToJar)); + ResolvedType typeOfT = JavaParserFacade.get(typeSolver).getType(referenceToT); + + assertEquals("? super com.github.javaparser.ast.body.TypeDeclaration", typeOfT.describe()); + } + + @Test + public void resolveReferenceToCallOnLambdaParam() throws ParseException, IOException { + CompilationUnit cu = parseSample("Navigator"); + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Navigator"); + MethodDeclaration method = Navigator.demandMethod(clazz, "findType"); + MethodCallExpr callToGetName = Navigator.findMethodCall(method, "getName").get(); + + String pathToJar = adaptPath("src/test/resources/javaparser-core-2.1.0.jar"); + TypeSolver typeSolver = new CombinedTypeSolver(new ReflectionTypeSolver(), new JarTypeSolver(pathToJar)); + MethodUsage methodUsage = JavaParserFacade.get(typeSolver).solveMethodAsUsage(callToGetName); + + assertEquals("getName", methodUsage.getName()); + assertEquals("com.github.javaparser.ast.body.TypeDeclaration", methodUsage.declaringType().getQualifiedName()); + } + + @Test + public void resolveReferenceToOverloadMethodWithNullParam() { + CompilationUnit cu = parseSample("OverloadedMethods"); + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "OverloadedMethods"); + MethodDeclaration method = Navigator.demandMethod(clazz, "m1"); + MethodCallExpr call = Navigator.findMethodCall(method, "overloaded").get(); + + ReflectionTypeSolver typeSolver = new ReflectionTypeSolver(); + MethodUsage ref = JavaParserFacade.get(typeSolver).solveMethodAsUsage(call); + + assertEquals("overloaded", ref.getName()); + assertEquals(1, ref.getNoParams()); + assertEquals("java.lang.String", ref.getParamTypes().get(0).describe()); + } + + @Test + public void resolveReferenceToOverloadMethodFindStricter() { + CompilationUnit cu = parseSample("OverloadedMethods"); + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "OverloadedMethods"); + MethodDeclaration method = Navigator.demandMethod(clazz, "m2"); + MethodCallExpr call = Navigator.findMethodCall(method, "overloaded").get(); + + ReflectionTypeSolver typeSolver = new ReflectionTypeSolver(); + MethodUsage ref = JavaParserFacade.get(typeSolver).solveMethodAsUsage(call); + + assertEquals("overloaded", ref.getName()); + assertEquals(1, ref.getNoParams()); + assertEquals("java.lang.String", ref.getParamTypes().get(0).describe()); + } + + @Test + public void resolveInheritedMethodFromInterface() { + CompilationUnit cu = parseSample("InterfaceInheritance"); + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Test"); + MethodDeclaration method = Navigator.demandMethod(clazz, "test"); + MethodCallExpr call = Navigator.findMethodCall(method, "foobar").get(); + + File src = adaptPath(new File("src/test/resources")); + TypeSolver typeSolver = new CombinedTypeSolver(new ReflectionTypeSolver(), new JavaParserTypeSolver(src)); + ResolvedType type = JavaParserFacade.get(typeSolver).getType(call); + + assertEquals("double", type.describe()); + } + + @Test + public void resolveReferenceToOverloadMethodFindOnlyCompatible() { + CompilationUnit cu = parseSample("OverloadedMethods"); + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "OverloadedMethods"); + MethodDeclaration method = Navigator.demandMethod(clazz, "m3"); + MethodCallExpr call = Navigator.findMethodCall(method, "overloaded").get(); + + ReflectionTypeSolver typeSolver = new ReflectionTypeSolver(); + MethodUsage ref = JavaParserFacade.get(typeSolver).solveMethodAsUsage(call); + + assertEquals("overloaded", ref.getName()); + assertEquals(1, ref.getNoParams()); + assertEquals("java.lang.Object", ref.getParamTypes().get(0).describe()); + } + +} diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/DefaultPackageTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/DefaultPackageTest.java new file mode 100644 index 000000000..5fcead08f --- /dev/null +++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/DefaultPackageTest.java @@ -0,0 +1,158 @@ +package com.github.javaparser.symbolsolver.resolution; + +import com.github.javaparser.JavaParser; +import com.github.javaparser.ast.AccessSpecifier; +import com.github.javaparser.ast.type.ClassOrInterfaceType; +import com.github.javaparser.resolution.UnsolvedSymbolException; +import com.github.javaparser.resolution.declarations.*; +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.logic.AbstractClassDeclaration; +import com.github.javaparser.symbolsolver.resolution.typesolvers.MemoryTypeSolver; +import org.junit.Test; + +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Optional; +import java.util.Set; + +import static org.junit.Assert.assertEquals; + +/** + * See issue #16 + */ +public class DefaultPackageTest { + + private class MyClassDeclaration extends AbstractClassDeclaration { + + private String qualifiedName; + + private MyClassDeclaration(String qualifiedName) { + this.qualifiedName = qualifiedName; + } + + @Override + public AccessSpecifier accessSpecifier() { + throw new UnsupportedOperationException(); + } + + @Override + public List<ResolvedTypeParameterDeclaration> getTypeParameters() { + return new LinkedList<>(); + } + + @Override + public Set<ResolvedReferenceTypeDeclaration> internalTypes() { + return new HashSet<>(); + } + + @Override + public String getName() { + throw new UnsupportedOperationException(); + } + + @Override + public List<ResolvedReferenceType> getAncestors() { + throw new UnsupportedOperationException(); + } + + @Override + public List<ResolvedFieldDeclaration> getAllFields() { + throw new UnsupportedOperationException(); + } + + @Override + public Set<ResolvedMethodDeclaration> getDeclaredMethods() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isAssignableBy(ResolvedType type) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isAssignableBy(ResolvedReferenceTypeDeclaration other) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean hasDirectlyAnnotation(String qualifiedName) { + throw new UnsupportedOperationException(); + } + + @Override + public ResolvedReferenceType getSuperClass() { + throw new UnsupportedOperationException(); + } + + @Override + public List<ResolvedReferenceType> getInterfaces() { + throw new UnsupportedOperationException(); + } + + @Override + public List<ResolvedConstructorDeclaration> getConstructors() { + throw new UnsupportedOperationException(); + } + + @Override + protected ResolvedReferenceType object() { + throw new UnsupportedOperationException(); + } + + @Override + public String getPackageName() { + throw new UnsupportedOperationException(); + } + + @Override + public String getClassName() { + throw new UnsupportedOperationException(); + } + + @Override + public String getQualifiedName() { + return qualifiedName; + } + + @Override + public Optional<ResolvedReferenceTypeDeclaration> containerType() { + throw new UnsupportedOperationException(); + } + } + + @Test + public void aClassInDefaultPackageCanBeAccessedFromTheDefaultPackage() { + String code = "class A extends B {}"; + MemoryTypeSolver memoryTypeSolver = new MemoryTypeSolver(); + memoryTypeSolver.addDeclaration("B", new MyClassDeclaration("B")); + + ClassOrInterfaceType jpType = JavaParser.parse(code).getClassByName("A").get().getExtendedTypes(0); + ResolvedType resolvedType = JavaParserFacade.get(memoryTypeSolver).convertToUsage(jpType); + assertEquals("B", resolvedType.asReferenceType().getQualifiedName()); + } + + @Test(expected = UnsolvedSymbolException.class) + public void aClassInDefaultPackageCanBeAccessedFromOutsideTheDefaultPackageImportingIt() { + String code = "package myPackage; import B; class A extends B {}"; + MemoryTypeSolver memoryTypeSolver = new MemoryTypeSolver(); + memoryTypeSolver.addDeclaration("B", new MyClassDeclaration("B")); + + ClassOrInterfaceType jpType = JavaParser.parse(code).getClassByName("A").get().getExtendedTypes(0); + ResolvedType resolvedType = JavaParserFacade.get(memoryTypeSolver).convertToUsage(jpType); + assertEquals("B", resolvedType.asReferenceType().getQualifiedName()); + } + + @Test(expected = UnsolvedSymbolException.class) + public void aClassInDefaultPackageCanBeAccessedFromOutsideTheDefaultPackageWithoutImportingIt() { + String code = "package myPackage; class A extends B {}"; + MemoryTypeSolver memoryTypeSolver = new MemoryTypeSolver(); + memoryTypeSolver.addDeclaration("B", new MyClassDeclaration("B")); + + ResolvedType resolvedType = JavaParserFacade.get(memoryTypeSolver).convertToUsage(JavaParser.parse(code).getClassByName("A").get().getExtendedTypes(0)); + assertEquals("B", resolvedType.asReferenceType().getQualifiedName()); + } +} diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/EnumResolutionTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/EnumResolutionTest.java new file mode 100644 index 000000000..edeaf8043 --- /dev/null +++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/EnumResolutionTest.java @@ -0,0 +1,61 @@ +/* + * 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; + +import com.github.javaparser.ParseException; +import com.github.javaparser.ast.CompilationUnit; +import com.github.javaparser.ast.body.MethodDeclaration; +import com.github.javaparser.ast.expr.Expression; +import com.github.javaparser.ast.expr.MethodCallExpr; +import com.github.javaparser.ast.stmt.SwitchStmt; +import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration; +import com.github.javaparser.resolution.types.ResolvedType; +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.resolution.typesolvers.ReflectionTypeSolver; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class EnumResolutionTest extends AbstractResolutionTest { + + @Test + public void switchOnEnum() { + CompilationUnit cu = parseSample("SwitchOnEnum"); + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "SwitchOnEnum"); + MethodDeclaration method = Navigator.demandMethod(clazz, "foo"); + SwitchStmt switchStmt = Navigator.findSwitch(method); + Expression expression = switchStmt.getEntries().get(0).getLabel().get(); + + SymbolReference<? extends ResolvedValueDeclaration> ref = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression); + assertTrue(ref.isSolved()); + assertEquals("SwitchOnEnum.MyEnum", ref.getCorrespondingDeclaration().getType().asReferenceType().getQualifiedName()); + } + + @Test + public void enumAndStaticInitializer() { + CompilationUnit cu = parseSample("EnumAndStaticInitializer"); + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "MyClass"); + MethodCallExpr call = Navigator.findMethodCall(clazz, "put").get(); + + ResolvedType ref = JavaParserFacade.get(new ReflectionTypeSolver()).getType(call); + assertEquals("MyClass.Primitive", ref.describe()); + } + +} diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/FieldsResolutionTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/FieldsResolutionTest.java new file mode 100644 index 000000000..fd95e7314 --- /dev/null +++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/FieldsResolutionTest.java @@ -0,0 +1,107 @@ +/* + * 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; + +import com.github.javaparser.ParseException; +import com.github.javaparser.ast.CompilationUnit; +import com.github.javaparser.ast.body.MethodDeclaration; +import com.github.javaparser.ast.expr.*; +import com.github.javaparser.ast.stmt.ExpressionStmt; +import com.github.javaparser.ast.stmt.ReturnStmt; +import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration; +import com.github.javaparser.resolution.types.ResolvedType; +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.resolution.typesolvers.CombinedTypeSolver; +import com.github.javaparser.symbolsolver.resolution.typesolvers.JavaParserTypeSolver; +import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver; +import org.junit.Test; + +import java.io.File; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class FieldsResolutionTest extends AbstractResolutionTest { + + @Test + public void accessClassFieldThroughThis() { + CompilationUnit cu = parseSample("AccessClassMemberThroughThis"); + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "AccessClassMemberThroughThis"); + MethodDeclaration method = Navigator.demandMethod(clazz, "getLabel2"); + ReturnStmt returnStmt = (ReturnStmt) method.getBody().get().getStatements().get(0); + Expression expression = returnStmt.getExpression().get(); + + ResolvedType ref = JavaParserFacade.get(new ReflectionTypeSolver()).getType(expression); + assertEquals("java.lang.String", ref.describe()); + } + + @Test + public void accessClassFieldThroughThisWithCompetingSymbolInParentContext() { + CompilationUnit cu = parseSample("AccessClassMemberThroughThis"); + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "AccessClassMemberThroughThis"); + MethodDeclaration method = Navigator.demandMethod(clazz, "setLabel"); + ExpressionStmt expressionStmt = (ExpressionStmt) method.getBody().get().getStatements().get(0); + AssignExpr assignExpr = (AssignExpr) expressionStmt.getExpression(); + FieldAccessExpr fieldAccessExpr = (FieldAccessExpr) assignExpr.getTarget(); + + File src = adaptPath(new File("src/test/resources")); + CombinedTypeSolver typeSolver = new CombinedTypeSolver(new JavaParserTypeSolver(src), new ReflectionTypeSolver()); + SymbolSolver symbolSolver = new SymbolSolver(typeSolver); + SymbolReference<? extends ResolvedValueDeclaration> ref = symbolSolver.solveSymbol(fieldAccessExpr.getName().getId(), fieldAccessExpr); + + assertTrue(ref.isSolved()); + assertTrue(ref.getCorrespondingDeclaration().isField()); + } + + @Test + public void accessEnumFieldThroughThis() { + CompilationUnit cu = parseSample("AccessEnumMemberThroughThis"); + com.github.javaparser.ast.body.EnumDeclaration enumDecl = Navigator.demandEnum(cu, "AccessEnumMemberThroughThis"); + MethodDeclaration method = Navigator.demandMethod(enumDecl, "getLabel"); + SimpleName expression = Navigator.findSimpleName(method, "label").get(); + + SymbolReference ref = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression); + assertTrue(ref.isSolved()); + assertEquals("label", ref.getCorrespondingDeclaration().getName()); + } + + @Test + public void accessEnumMethodThroughThis() { + CompilationUnit cu = parseSample("AccessEnumMemberThroughThis"); + com.github.javaparser.ast.body.EnumDeclaration enumDecl = Navigator.demandEnum(cu, "AccessEnumMemberThroughThis"); + MethodDeclaration method = Navigator.demandMethod(enumDecl, "getLabel2"); + ReturnStmt returnStmt = (ReturnStmt) method.getBody().get().getStatements().get(0); + Expression expression = returnStmt.getExpression().get(); + + ResolvedType ref = JavaParserFacade.get(new ReflectionTypeSolver()).getType(expression); + assertEquals("java.lang.String", ref.describe()); + } + + @Test + public void accessFieldThroughSuper() { + CompilationUnit cu = parseSample("AccessThroughSuper"); + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "AccessThroughSuper.SubClass"); + MethodDeclaration method = Navigator.demandMethod(clazz, "fieldTest"); + ReturnStmt returnStmt = (ReturnStmt) method.getBody().get().getStatements().get(0); + Expression expression = returnStmt.getExpression().get(); + + ResolvedType ref = JavaParserFacade.get(new ReflectionTypeSolver()).getType(expression); + assertEquals("java.lang.String", ref.describe()); + } +} diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/GenericsResolutionTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/GenericsResolutionTest.java new file mode 100644 index 000000000..bfc4bfd58 --- /dev/null +++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/GenericsResolutionTest.java @@ -0,0 +1,440 @@ +/* + * 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; + +import com.github.javaparser.ParseException; +import com.github.javaparser.ast.CompilationUnit; +import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; +import com.github.javaparser.ast.body.MethodDeclaration; +import com.github.javaparser.ast.body.VariableDeclarator; +import com.github.javaparser.ast.expr.Expression; +import com.github.javaparser.ast.expr.MethodCallExpr; +import com.github.javaparser.ast.expr.NameExpr; +import com.github.javaparser.ast.expr.ThisExpr; +import com.github.javaparser.ast.stmt.ExpressionStmt; +import com.github.javaparser.ast.stmt.ReturnStmt; +import com.github.javaparser.resolution.MethodUsage; +import com.github.javaparser.resolution.types.ResolvedReferenceType; +import com.github.javaparser.resolution.types.ResolvedType; +import com.github.javaparser.symbolsolver.javaparser.Navigator; +import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade; +import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; +import com.github.javaparser.symbolsolver.model.resolution.Value; +import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver; +import org.junit.Test; + +import java.util.List; +import java.util.Optional; + +import static org.junit.Assert.assertEquals; + +public class GenericsResolutionTest extends AbstractResolutionTest { + + @Test + public void resolveFieldWithGenericTypeToString() { + CompilationUnit cu = parseSample("Generics"); + ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Generics"); + VariableDeclarator fieldS = Navigator.demandField(clazz, "s"); + + SymbolSolver symbolSolver = new SymbolSolver(new ReflectionTypeSolver()); + Optional<Value> symbolReference = symbolSolver.solveSymbolAsValue("s", fieldS); + + assertEquals(true, symbolReference.isPresent()); + assertEquals("s", symbolReference.get().getName()); + + ResolvedType type = symbolReference.get().getType(); + assertEquals(1, type.asReferenceType().typeParametersValues().size()); + assertEquals("java.lang.String", type.asReferenceType().typeParametersValues().get(0).describe()); + } + + @Test + public void resolveFieldWithGenericTypeToDeclaredClass() { + CompilationUnit cu = parseSample("Generics"); + ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Generics"); + VariableDeclarator fieldS = Navigator.demandField(clazz, "g"); + + SymbolSolver symbolSolver = new SymbolSolver(new ReflectionTypeSolver()); + Optional<Value> symbolReference = symbolSolver.solveSymbolAsValue("g", fieldS); + + assertEquals(true, symbolReference.isPresent()); + assertEquals("g", symbolReference.get().getName()); + + ResolvedType type = symbolReference.get().getType(); + assertEquals(1, type.asReferenceType().typeParametersValues().size()); + assertEquals("me.tomassetti.symbolsolver.javaparser.Generics", type.asReferenceType().typeParametersValues().get(0).describe()); + } + + @Test + public void resolveFieldWithGenericTypeToInteger() { + CompilationUnit cu = parseSample("Generics"); + ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Generics"); + VariableDeclarator fieldS = Navigator.demandField(clazz, "i"); + + SymbolSolver symbolSolver = new SymbolSolver(new ReflectionTypeSolver()); + Optional<Value> symbolReference = symbolSolver.solveSymbolAsValue("i", fieldS); + + assertEquals(true, symbolReference.isPresent()); + assertEquals("i", symbolReference.get().getName()); + + ResolvedType type = symbolReference.get().getType(); + assertEquals(1, type.asReferenceType().typeParametersValues().size()); + assertEquals("java.lang.Integer", type.asReferenceType().typeParametersValues().get(0).describe()); + } + + @Test + public void resolveFieldOfVariableType() { + CompilationUnit cu = parseSample("Generics"); + ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "SomeCollection"); + VariableDeclarator field = Navigator.demandField(clazz, "a"); + + SymbolSolver symbolSolver = new SymbolSolver(new ReflectionTypeSolver()); + Optional<Value> symbolReference = symbolSolver.solveSymbolAsValue("a", field); + + assertEquals(true, symbolReference.isPresent()); + assertEquals("a", symbolReference.get().getName()); + + ResolvedType type = symbolReference.get().getType(); + assertEquals(true, type.isTypeVariable()); + assertEquals("A", type.describe()); + } + + @Test + public void resolveFieldOfGenericReferringToVariableType() { + CompilationUnit cu = parseSample("Generics"); + ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "SomeCollection"); + VariableDeclarator field = Navigator.demandField(clazz, "as"); + + SymbolSolver symbolSolver = new SymbolSolver(new ReflectionTypeSolver()); + Optional<Value> symbolReference = symbolSolver.solveSymbolAsValue("as", field); + + assertEquals(true, symbolReference.isPresent()); + assertEquals("as", symbolReference.get().getName()); + + ResolvedType type = symbolReference.get().getType(); + assertEquals(false, type.isTypeVariable()); + assertEquals("java.util.List<A>", type.describe()); + assertEquals(1, type.asReferenceType().typeParametersValues().size()); + ResolvedType typeParam = type.asReferenceType().typeParametersValues().get(0); + assertEquals(true, typeParam.isTypeVariable()); + assertEquals("A", typeParam.describe()); + } + + @Test + public void resolveUsageOfGenericFieldSimpleCase() { + CompilationUnit cu = parseSample("Generics"); + ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "SomeCollection"); + + MethodDeclaration method = Navigator.demandMethod(clazz, "foo1"); + + ExpressionStmt stmt = (ExpressionStmt) method.getBody().get().getStatements().get(0); + Expression expression = stmt.getExpression(); + ResolvedType type = JavaParserFacade.get(new ReflectionTypeSolver()).getType(expression); + + assertEquals(false, type.isTypeVariable()); + assertEquals("java.lang.String", type.describe()); + } + + //PRIMA UN TEST CHE DICA CHE IL TIPO DEL CAMPO AS e' LIST<A> NON LIST<E> + @Test + public void resolveUsageOfGenericFieldIntermediateCase() { + CompilationUnit cu = parseSample("Generics"); + ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "SomeCollection"); + + VariableDeclarator field = Navigator.demandField(clazz, "as"); + + ResolvedType type = JavaParserFacade.get(new ReflectionTypeSolver()).getType(field); + + assertEquals(false, type.isTypeVariable()); + assertEquals("java.util.List<A>", type.describe()); + assertEquals(1, type.asReferenceType().typeParametersValues().size()); + assertEquals(true, type.asReferenceType().typeParametersValues().get(0).isTypeVariable()); + assertEquals("A", type.asReferenceType().typeParametersValues().get(0).describe()); + } + + @Test + public void resolveUsageOfGenericFieldAdvancedCase() { + CompilationUnit cu = parseSample("Generics"); + ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "SomeCollection"); + + MethodDeclaration method = Navigator.demandMethod(clazz, "foo2"); + + ExpressionStmt stmt = (ExpressionStmt) method.getBody().get().getStatements().get(0); + Expression expression = stmt.getExpression(); + ResolvedType type = JavaParserFacade.get(new ReflectionTypeSolver()).getType(expression); + + assertEquals(false, type.isTypeVariable()); + assertEquals("java.util.List<java.lang.String>", type.describe()); + assertEquals(1, type.asReferenceType().typeParametersValues().size()); + assertEquals(false, type.asReferenceType().typeParametersValues().get(0).isTypeVariable()); + assertEquals("java.lang.String", type.asReferenceType().typeParametersValues().get(0).describe()); + } + + @Test + public void resolveUsageOfMethodOfGenericClass() { + CompilationUnit cu = parseSample("Generics"); + ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "GenericMethodCalls.Derived"); + MethodDeclaration method = Navigator.demandMethod(clazz, "caller"); + MethodCallExpr expression = Navigator.findMethodCall(method, "callee").get(); + + MethodUsage methodUsage = JavaParserFacade.get(new ReflectionTypeSolver()).solveMethodAsUsage(expression); + + assertEquals("callee", methodUsage.getName()); + } + + @Test + public void resolveElementOfList() { + CompilationUnit cu = parseSample("ElementOfList"); + ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "ElementOfList"); + MethodDeclaration method = Navigator.demandMethod(clazz, "foo"); + VariableDeclarator variableDeclarator = Navigator.demandVariableDeclaration(method, "a").get(); + Expression expression = variableDeclarator.getInitializer().get(); + + ResolvedType type = JavaParserFacade.get(new ReflectionTypeSolver()).getType(expression); + + assertEquals(false, type.isTypeVariable()); + assertEquals("Comment", type.describe()); + } + + @Test + public void resolveElementOfListAdvancedExample() { + CompilationUnit cu = parseSample("ElementOfList"); + ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "ElementOfList"); + MethodDeclaration method = Navigator.demandMethod(clazz, "annotations"); + VariableDeclarator variableDeclarator = Navigator.demandVariableDeclaration(method, "a").get(); + Expression expression = variableDeclarator.getInitializer().get(); + + ResolvedType type = JavaParserFacade.get(new ReflectionTypeSolver()).getType(expression); + + assertEquals(false, type.isTypeVariable()); + assertEquals("AnnotationExpr", type.describe()); + } + + @Test + public void genericsInheritance() { + CompilationUnit cu = parseSample("MethodTypeParams"); + ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "VoidVisitorAdapter"); + MethodDeclaration method = Navigator.demandMethod(clazz, "visit"); + MethodCallExpr call = Navigator.findMethodCall(method, "accept").get(); + Expression thisRef = call.getArguments().get(0); + + TypeSolver typeSolver = new ReflectionTypeSolver(); + JavaParserFacade javaParserFacade = JavaParserFacade.get(typeSolver); + + ResolvedType voidVisitorAdapterOfA = javaParserFacade.getType(thisRef); + List<ResolvedReferenceType> allAncestors = voidVisitorAdapterOfA.asReferenceType().getAllAncestors(); + assertEquals(2, allAncestors.size()); + } + + @Test + public void methodTypeParams() { + CompilationUnit cu = parseSample("MethodTypeParams"); + ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "VoidVisitorAdapter"); + MethodDeclaration method = Navigator.demandMethod(clazz, "visit"); + MethodCallExpr call = Navigator.findMethodCall(method, "accept").get(); + + ResolvedType type = JavaParserFacade.get(new ReflectionTypeSolver()).getType(call); + + assertEquals(false, type.isTypeVariable()); + assertEquals("void", type.describe()); + } + + @Test + public void classCastScope() { + CompilationUnit cu = parseSample("ClassCast"); + ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "ClassCast"); + MethodDeclaration method = Navigator.demandMethod(clazz, "getNodesByType"); + MethodCallExpr call = Navigator.findMethodCall(method, "cast").get(); + + TypeSolver typeSolver = new ReflectionTypeSolver(); + Expression scope = call.getScope().get(); + ResolvedType type = JavaParserFacade.get(typeSolver).getType(scope); + + //System.out.println(typeUsage); + + assertEquals(false, type.isTypeVariable()); + assertEquals("java.lang.Class<N>", type.describe()); + } + + @Test + public void classCast() { + CompilationUnit cu = parseSample("ClassCast"); + ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "ClassCast"); + MethodDeclaration method = Navigator.demandMethod(clazz, "getNodesByType"); + ReturnStmt returnStmt = Navigator.findReturnStmt(method); + + ResolvedType type = JavaParserFacade.get(new ReflectionTypeSolver()).getType(returnStmt.getExpression().get()); + + assertEquals(true, type.isTypeVariable()); + assertEquals("N", type.describe()); + } + + @Test + public void typeParamOnReturnTypeStep1() { + CompilationUnit cu = parseSample("TypeParamOnReturnType"); + ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "TypeParamOnReturnType"); + MethodDeclaration method = Navigator.demandMethod(clazz, "nodeEquals"); + ThisExpr thisExpr = Navigator.findNodeOfGivenClass(method, ThisExpr.class); + + ResolvedType type = JavaParserFacade.get(new ReflectionTypeSolver()).getType(thisExpr); + + assertEquals(false, type.isTypeVariable()); + assertEquals("TypeParamOnReturnType", type.describe()); + } + + @Test + public void typeParamOnReturnTypeStep2() { + CompilationUnit cu = parseSample("TypeParamOnReturnType"); + ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "TypeParamOnReturnType"); + MethodDeclaration method = Navigator.demandMethod(clazz, "nodeEquals"); + NameExpr n1 = Navigator.findNameExpression(method, "n1").get(); + + ResolvedType type = JavaParserFacade.get(new ReflectionTypeSolver()).getType(n1); + + assertEquals(true, type.isTypeVariable()); + assertEquals("T", type.describe()); + } + + @Test + public void typeParamOnReturnTypeStep3() { + CompilationUnit cu = parseSample("TypeParamOnReturnType"); + ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "TypeParamOnReturnType"); + MethodDeclaration method = Navigator.demandMethod(clazz, "nodeEquals"); + MethodCallExpr call = Navigator.findMethodCall(method, "accept").get(); + + JavaParserFacade javaParserFacade = JavaParserFacade.get(new ReflectionTypeSolver()); + ResolvedType type = javaParserFacade.getType(call); + + assertEquals(false, type.isTypeVariable()); + assertEquals("java.lang.Boolean", type.describe()); + } + + @Test + public void typeParamOnReturnType() { + CompilationUnit cu = parseSample("TypeParamOnReturnType"); + ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "TypeParamOnReturnType"); + MethodDeclaration method = Navigator.demandMethod(clazz, "nodeEquals"); + ReturnStmt returnStmt = Navigator.findReturnStmt(method); + + ResolvedType type = JavaParserFacade.get(new ReflectionTypeSolver()).getType(returnStmt.getExpression().get()); + + assertEquals(false, type.isTypeVariable()); + assertEquals("boolean", type.describe()); + } + + /*@Test + public void genericCollectionWithWildcardsAndExtensionsPrep() { + CompilationUnit cu = parseSample("GenericCollectionWithExtension"); + ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Foo"); + MethodDeclaration method = Navigator.demandMethod(clazz, "bar"); + ReturnStmt returnStmt = Navigator.findReturnStmt(method); + + TypeSolver typeSolver = new JreTypeSolver(); + MethodCallExpr call = (MethodCallExpr) returnStmt.getExpr(); + JavaParserFacade javaParserFacade = JavaParserFacade.get(typeSolver); + + List<TypeUsage> params = new ArrayList<>(); + if (call.getArgs() != null) { + for (Expression param : call.getArgs()) { + params.add(javaParserFacade.getType(param, false)); + } + } + Context context = JavaParserFactory.getContext(call, typeSolver); + + ReferenceTypeUsage typeOfScope = javaParserFacade.getType(call.getScope()).asReferenceType(); + me.tomassetti.symbolsolver.model.declarations.TypeDeclaration typeDeclaration = typeOfScope.getTypeDeclaration(); + List<TypeUsage> typeParametersValues = typeOfScope.typeParametersValues(); + + List<MethodUsage> methods = new ArrayList<>(); + for (Method m : List.class.getMethods()) { + if (m.getName().equals("addAll") && !m.isBridge() && !m.isSynthetic()) { + me.tomassetti.symbolsolver.model.declarations.MethodDeclaration methodDeclaration = new ReflectionMethodDeclaration(m, typeSolver); + if (methods.size() == 0) { + // ok, e' il primo + ReferenceTypeUsage paramType = methodDeclaration.getParam(0).getType(typeSolver).asReferenceType(); + assertTrue(paramType.asReferenceType().typeParametersValues().get(0).isWildcard()); + } + MethodUsage mu = new MethodUsage(methodDeclaration, typeSolver); + int i = 0; + for (TypeParameter tp : typeDeclaration.getTypeParameters()) { + mu = mu.replaceTypeParameter(tp.getName(), typeParametersValues.get(i)); + i++; + } + methods.add(mu); + } + + } + + assertTrue(MethodResolutionLogic.isApplicable(methods.get(0), "addAll", params, typeSolver)); + //Optional<MethodUsage> methodUsage = MethodResolutionLogic.findMostApplicableUsage(methods, "addAll", params, typeSolver); + + //Optional<MethodUsage> methodUsage = typeDeclaration.solveMethodAsUsage("addAll", params, typeSolver, context, typeParametersValues); + + //Optional<MethodUsage> methodUsage = context.solveMethodAsUsage("addAll", params, typeSolver); + + //assertTrue(methodUsage.isPresent()); + + }*/ + + @Test + public void genericCollectionWithWildcardsAndExtensions() { + CompilationUnit cu = parseSample("GenericCollectionWithExtension"); + ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Foo"); + MethodDeclaration method = Navigator.demandMethod(clazz, "bar"); + ReturnStmt returnStmt = Navigator.findReturnStmt(method); + + TypeSolver typeSolver = new ReflectionTypeSolver(); + Expression returnStmtExpr = returnStmt.getExpression().get(); + JavaParserFacade javaParserFacade = JavaParserFacade.get(typeSolver); + + ResolvedType type = javaParserFacade.getType(returnStmtExpr); + + assertEquals(false, type.isTypeVariable()); + assertEquals("boolean", type.describe()); + } + + @Test + public void methodWithGenericParameterTypes() { + CompilationUnit cu = parseSample("GenericCollectionWithExtension"); + ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Foo"); + MethodDeclaration method = Navigator.demandMethod(clazz, "bar"); + MethodCallExpr methodCall = Navigator.findMethodCall(method, "foo").get(); + + TypeSolver typeSolver = new ReflectionTypeSolver(); + JavaParserFacade javaParserFacade = JavaParserFacade.get(typeSolver); + + MethodUsage methodUsage = javaParserFacade.solveMethodAsUsage(methodCall); + + assertEquals("foo", methodUsage.getName()); + } + + @Test + public void genericCollectionWithWildcards() { + CompilationUnit cu = parseSample("GenericCollection"); + ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Foo"); + MethodDeclaration method = Navigator.demandMethod(clazz, "bar"); + ReturnStmt returnStmt = Navigator.findReturnStmt(method); + + TypeSolver typeSolver = new ReflectionTypeSolver(); + Expression returnStmtExpr = returnStmt.getExpression().get(); + JavaParserFacade javaParserFacade = JavaParserFacade.get(typeSolver); + + ResolvedType type = javaParserFacade.getType(returnStmtExpr); + + assertEquals(false, type.isTypeVariable()); + assertEquals("boolean", type.describe()); + } +} diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/JavaParserFacadeResolutionTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/JavaParserFacadeResolutionTest.java new file mode 100644 index 000000000..37fec2647 --- /dev/null +++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/JavaParserFacadeResolutionTest.java @@ -0,0 +1,163 @@ +/* + * 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; + +import com.github.javaparser.*; +import com.github.javaparser.ast.CompilationUnit; +import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; +import com.github.javaparser.ast.body.FieldDeclaration; +import com.github.javaparser.ast.expr.Expression; +import com.github.javaparser.ast.expr.MethodCallExpr; +import com.github.javaparser.ast.expr.NameExpr; +import com.github.javaparser.ast.stmt.CatchClause; +import com.github.javaparser.ast.stmt.TryStmt; +import com.github.javaparser.ast.type.Type; +import com.github.javaparser.resolution.MethodUsage; +import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration; +import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration; +import com.github.javaparser.resolution.types.ResolvedReferenceType; +import com.github.javaparser.resolution.types.ResolvedType; +import com.github.javaparser.resolution.types.ResolvedUnionType; +import com.github.javaparser.symbolsolver.JavaSymbolSolver; +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.resolution.typesolvers.ReflectionTypeSolver; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + + +public class JavaParserFacadeResolutionTest extends AbstractResolutionTest { + + @Test + public void typeDeclarationSuperClassImplicitlyIncludeObject() { + CompilationUnit cu = parseSample("Generics"); + ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Generics"); + ResolvedTypeDeclaration typeDeclaration = JavaParserFacade.get(new ReflectionTypeSolver()).getTypeDeclaration(clazz); + ResolvedReferenceType superclass = typeDeclaration.asClass().getSuperClass(); + assertEquals(Object.class.getCanonicalName(), superclass.getQualifiedName()); + } + + // See issue 42 + @Test + public void solvingReferenceToUnsupportedOperationException() { + String code = "public class Bla {\n" + + " public void main()\n" + + " {\n" + + " try\n" + + " {\n" + + " int i = 0;\n" + + " }\n" + + " catch (UnsupportedOperationException e)\n" + + " {\n" + + " String s;\n" + + " e.getMessage();\n" + + " }\n" + + " }\n" + + "}"; + MethodCallExpr methodCallExpr = Navigator.findNodeOfGivenClass(JavaParser.parse(code), MethodCallExpr.class); + MethodUsage methodUsage = JavaParserFacade.get(new ReflectionTypeSolver()).solveMethodAsUsage(methodCallExpr); + assertEquals("java.lang.Throwable.getMessage()", methodUsage.getQualifiedSignature()); + } + + // See issue 46 + @Test + public void solvingReferenceToCatchClauseParam() { + String code = "public class Bla {\n" + + " public void main()\n" + + " {\n" + + " try\n" + + " {\n" + + " int i = 0;\n" + + " }\n" + + " catch (UnsupportedOperationException e)\n" + + " {\n" + + " String s;\n" + + " e.getMessage();\n" + + " }\n" + + " }\n" + + "}"; + MethodCallExpr methodCallExpr = Navigator.findNodeOfGivenClass(JavaParser.parse(code), MethodCallExpr.class); + NameExpr nameE = (NameExpr)methodCallExpr.getScope().get(); + SymbolReference<? extends ResolvedValueDeclaration> symbolReference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(nameE); + assertEquals(true, symbolReference.isSolved()); + assertEquals(true, symbolReference.getCorrespondingDeclaration().isParameter()); + assertEquals("e", symbolReference.getCorrespondingDeclaration().asParameter().getName()); + assertEquals("java.lang.UnsupportedOperationException", symbolReference.getCorrespondingDeclaration().asParameter().getType().asReferenceType().getQualifiedName()); + } + + // See issue 47 + @Test + public void solvingReferenceToAnAncestorInternalClass() { + String code = "public class Foo {\n" + + " public class Base {\n" + + " public class X {\n" + + " }\n" + + " }\n" + + "\n" + + " public class Derived extends Base {\n" + + " public X x = null;\n" + + " }\n" + + "}"; + FieldDeclaration fieldDeclaration = Navigator.findNodeOfGivenClass(JavaParser.parse(code), FieldDeclaration.class); + Type jpType = fieldDeclaration.getCommonType(); + ResolvedType jssType = JavaParserFacade.get(new ReflectionTypeSolver()).convertToUsage(jpType); + assertEquals("Foo.Base.X", jssType.asReferenceType().getQualifiedName()); + } + + // See issue 119 + @Test + public void solveTryWithResourceVariable() { + String code = "import java.util.Scanner; class A { void foo() { try (Scanner sc = new Scanner(System.in)) {\n" + + " sc.nextLine();\n" + + "} } }"; + CompilationUnit cu = JavaParser.parse(code); + MethodCallExpr methodCallExpr = Navigator.findMethodCall(cu, "nextLine").get(); + Expression scope = methodCallExpr.getScope().get(); + ResolvedType type = JavaParserFacade.get(new ReflectionTypeSolver()).getType(scope); + assertEquals(true, type.isReferenceType()); + assertEquals("java.util.Scanner", type.asReferenceType().getQualifiedName()); + } + + private CompilationUnit parseWithTypeSolver(String code) { + TypeSolver typeSolver = new ReflectionTypeSolver(); + ParserConfiguration parserConfiguration = new ParserConfiguration(); + parserConfiguration.setSymbolResolver(new JavaSymbolSolver(typeSolver)); + JavaParser javaParser = new JavaParser(parserConfiguration); + return javaParser.parse(ParseStart.COMPILATION_UNIT, new StringProvider(code)).getResult().get(); + } + + @Test + public void solveMultiCatchType() { + String code = "class A {\n" + + " public void foo() {\n" + + " try {\n" + + " \n" + + " } catch (IllegalStateException | IllegalArgumentException e) {\n" + + " \n" + + " }\n" + + " }\n" + + " }"; + CompilationUnit cu = parseWithTypeSolver(code); + CatchClause catchClause = Navigator.findNodeOfGivenClass(cu, CatchClause.class); + Type jpType = catchClause.getParameter().getType(); + ResolvedType jssType = jpType.resolve(); + assertEquals(true, jssType instanceof ResolvedUnionType); + } +} diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/LambdaResolutionTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/LambdaResolutionTest.java new file mode 100644 index 000000000..3620c5230 --- /dev/null +++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/LambdaResolutionTest.java @@ -0,0 +1,177 @@ +/* + * 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; + +import com.github.javaparser.ParseException; +import com.github.javaparser.ast.CompilationUnit; +import com.github.javaparser.ast.body.MethodDeclaration; +import com.github.javaparser.ast.expr.Expression; +import com.github.javaparser.ast.expr.LambdaExpr; +import com.github.javaparser.ast.expr.MethodCallExpr; +import com.github.javaparser.ast.stmt.ReturnStmt; +import com.github.javaparser.resolution.types.ResolvedType; +import com.github.javaparser.symbolsolver.javaparser.Navigator; +import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade; +import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class LambdaResolutionTest extends AbstractResolutionTest { + + @Test + public void lambdaMapParameter() { + CompilationUnit cu = parseSample("Lambda"); + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Agenda"); + MethodDeclaration method = Navigator.demandMethod(clazz, "lambdaMap"); + ReturnStmt returnStmt = Navigator.findReturnStmt(method); + MethodCallExpr methodCallExpr = (MethodCallExpr) returnStmt.getExpression().get(); + Expression expression = methodCallExpr.getArguments().get(0); + + JavaParserFacade javaParserFacade = JavaParserFacade.get(new ReflectionTypeSolver()); + ResolvedType type = javaParserFacade.getType(expression); + assertEquals("java.util.function.Function<? super java.lang.String, ? extends java.lang.String>", type.describe()); + } + + @Test + public void personsStream() { + CompilationUnit cu = parseSample("Lambda"); + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Agenda"); + MethodDeclaration method = Navigator.demandMethod(clazz, "lambdaMap"); + ReturnStmt returnStmt = Navigator.findReturnStmt(method); + Expression expression = returnStmt.getExpression().get(); + expression = Navigator.findMethodCall(expression, "stream").get(); + + JavaParserFacade javaParserFacade = JavaParserFacade.get(new ReflectionTypeSolver()); + ResolvedType type = javaParserFacade.getType(expression); + assertEquals("java.util.stream.Stream<java.lang.String>", type.describe()); + } + + @Test + public void lambdaMap() { + CompilationUnit cu = parseSample("Lambda"); + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Agenda"); + MethodDeclaration m1 = Navigator.demandMethod(clazz, "lambdaMap"); + MethodDeclaration m2 = Navigator.demandMethod(clazz, "lambdaMap2"); + ReturnStmt returnStmt1 = Navigator.findReturnStmt(m1); + ReturnStmt returnStmt2 = Navigator.findReturnStmt(m2); + Expression e1 = returnStmt1.getExpression().get(); + Expression e2 = returnStmt2.getExpression().get(); + + JavaParserFacade javaParserFacade = JavaParserFacade.get(new ReflectionTypeSolver()); + ResolvedType type1 = javaParserFacade.getType(e1); + ResolvedType type2 = javaParserFacade.getType(e2); + assertEquals("java.util.stream.Stream<java.lang.String>", type1.describe()); + assertEquals("java.util.stream.Stream<java.util.stream.IntStream>", type2.describe()); + } + + @Test + public void lambdaReduce() { + CompilationUnit cu = parseSample("Lambda"); + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Agenda"); + MethodDeclaration method = Navigator.demandMethod(clazz, "reduce"); + ReturnStmt returnStmt = Navigator.findReturnStmt(method); + Expression expr = returnStmt.getExpression().get(); + + JavaParserFacade javaParserFacade = JavaParserFacade.get(new ReflectionTypeSolver()); + ResolvedType type1 = javaParserFacade.getType(expr); + assertEquals("java.util.Optional<java.lang.Integer>", type1.describe()); + } + + @Test + public void lambdaBifunc() { + CompilationUnit cu = parseSample("Lambda"); + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Agenda"); + MethodDeclaration method = Navigator.demandMethod(clazz, "bifunc"); + ReturnStmt returnStmt = Navigator.findReturnStmt(method); + Expression expr = returnStmt.getExpression().get(); + + JavaParserFacade javaParserFacade = JavaParserFacade.get(new ReflectionTypeSolver()); + ResolvedType type1 = javaParserFacade.getType(expr); + assertEquals("double", type1.describe()); + } + + @Test + public void lambdaCollectParam() { + CompilationUnit cu = parseSample("LambdaCollect"); + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Agenda"); + MethodDeclaration method = Navigator.demandMethod(clazz, "lambdaMap"); + ReturnStmt returnStmt = Navigator.findReturnStmt(method); + MethodCallExpr methodCallExpr = (MethodCallExpr) returnStmt.getExpression().get(); + // Collectors.toList() + Expression expression = methodCallExpr.getArguments().get(0); + + JavaParserFacade javaParserFacade = JavaParserFacade.get(new ReflectionTypeSolver()); + ResolvedType type = javaParserFacade.getType(expression); + assertEquals("java.util.stream.Collector<T, ? extends java.lang.Object, java.util.List<T>>", type.describe()); + } + + @Test + public void lambdaCollect() { + CompilationUnit cu = parseSample("LambdaCollect"); + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Agenda"); + MethodDeclaration method = Navigator.demandMethod(clazz, "lambdaMap"); + ReturnStmt returnStmt = Navigator.findReturnStmt(method); + Expression expression = returnStmt.getExpression().get(); + + JavaParserFacade javaParserFacade = JavaParserFacade.get(new ReflectionTypeSolver()); + ResolvedType type = javaParserFacade.getType(expression); + assertEquals("java.util.List<java.lang.String>", type.describe()); + } + + @Test + public void lambdaBlockExplicitReturn() { + CompilationUnit cu = parseSample("LambdaMulti"); + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Agenda"); + MethodDeclaration method = Navigator.demandMethod(clazz, "lambdaSingleReturn"); + ReturnStmt returnStmt = Navigator.findReturnStmt(method); + Expression expression = returnStmt.getExpression().get(); + + JavaParserFacade javaParserFacade = JavaParserFacade.get(new ReflectionTypeSolver()); + ResolvedType type = javaParserFacade.getType(expression); + assertEquals("java.lang.String", type.describe()); + } + + @Test + public void lambdaBlockMultiLineReturn() { + CompilationUnit cu = parseSample("LambdaMulti"); + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Agenda"); + MethodDeclaration method = Navigator.demandMethod(clazz, "multiLineReturn"); + ReturnStmt returnStmt = Navigator.findReturnStmt(method); + Expression expression = returnStmt.getExpression().get(); + + JavaParserFacade javaParserFacade = JavaParserFacade.get(new ReflectionTypeSolver()); + ResolvedType type = javaParserFacade.getType(expression); + assertEquals("java.lang.String", type.describe()); + } + + @Test + public void typeOfVoidLambda() { + CompilationUnit cu = parseSample("LambdaVoid"); + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Agenda"); + MethodDeclaration method = Navigator.demandMethod(clazz, "lambdaEmpty"); + ReturnStmt returnStmt = Navigator.findReturnStmt(method); + Expression expression = returnStmt.getExpression().get(); + LambdaExpr lambdaExpr = Navigator.findNodeOfGivenClass(expression, LambdaExpr.class); + + JavaParserFacade javaParserFacade = JavaParserFacade.get(new ReflectionTypeSolver()); + ResolvedType type = javaParserFacade.getType(lambdaExpr); + assertEquals("void", type.describe()); + } + + +} diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/MethodsResolutionLogicTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/MethodsResolutionLogicTest.java new file mode 100644 index 000000000..b53607dbd --- /dev/null +++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/MethodsResolutionLogicTest.java @@ -0,0 +1,83 @@ +/* + * 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; + +import com.github.javaparser.resolution.MethodUsage; +import com.github.javaparser.resolution.types.ResolvedReferenceType; +import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration; +import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; +import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionFactory; +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 com.google.common.collect.ImmutableList; +import org.junit.Before; +import org.junit.Test; + +import java.io.File; + +import static org.junit.Assert.assertEquals; + +public class MethodsResolutionLogicTest extends AbstractResolutionTest { + + private TypeSolver typeSolver; + + @Before + public void setup() { + File srcNewCode = adaptPath(new File("src/test/test_sourcecode/javaparser_new_src/javaparser-core")); + CombinedTypeSolver combinedTypeSolverNewCode = new CombinedTypeSolver(); + combinedTypeSolverNewCode.add(new ReflectionTypeSolver()); + combinedTypeSolverNewCode.add(new JavaParserTypeSolver(srcNewCode)); + combinedTypeSolverNewCode.add(new JavaParserTypeSolver(adaptPath(new File("src/test/test_sourcecode/javaparser_new_src/javaparser-generated-sources")))); + typeSolver = combinedTypeSolverNewCode; + } + + @Test + public void compatibilityShouldConsiderAlsoTypeVariablesNegative() { + JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolver.solveType("com.github.javaparser.ast.body.ConstructorDeclaration"); + + ResolvedReferenceType stringType = (ResolvedReferenceType) ReflectionFactory.typeUsageFor(String.class, typeSolver); + ResolvedReferenceType rawClassType = (ResolvedReferenceType) ReflectionFactory.typeUsageFor(Class.class, typeSolver); + assertEquals(true, rawClassType.isRawType()); + ResolvedReferenceType classOfStringType = (ResolvedReferenceType) rawClassType.replaceTypeVariables(rawClassType.getTypeDeclaration().getTypeParameters().get(0), stringType); + MethodUsage mu = constructorDeclaration.getAllMethods().stream().filter(m -> m.getDeclaration().getSignature().equals("isThrows(java.lang.Class<? extends java.lang.Throwable>)")).findFirst().get(); + + assertEquals(false, MethodResolutionLogic.isApplicable(mu, "isThrows", ImmutableList.of(classOfStringType), typeSolver)); + } + + @Test + public void compatibilityShouldConsiderAlsoTypeVariablesRaw() { + JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolver.solveType("com.github.javaparser.ast.body.ConstructorDeclaration"); + + ResolvedReferenceType rawClassType = (ResolvedReferenceType) ReflectionFactory.typeUsageFor(Class.class, typeSolver); + MethodUsage mu = constructorDeclaration.getAllMethods().stream().filter(m -> m.getDeclaration().getSignature().equals("isThrows(java.lang.Class<? extends java.lang.Throwable>)")).findFirst().get(); + + assertEquals(true, MethodResolutionLogic.isApplicable(mu, "isThrows", ImmutableList.of(rawClassType), typeSolver)); + } + + @Test + public void compatibilityShouldConsiderAlsoTypeVariablesPositive() { + JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolver.solveType("com.github.javaparser.ast.body.ConstructorDeclaration"); + + ResolvedReferenceType runtimeException = (ResolvedReferenceType) ReflectionFactory.typeUsageFor(RuntimeException.class, typeSolver); + ResolvedReferenceType rawClassType = (ResolvedReferenceType) ReflectionFactory.typeUsageFor(Class.class, typeSolver); + ResolvedReferenceType classOfRuntimeType = (ResolvedReferenceType) rawClassType.replaceTypeVariables(rawClassType.getTypeDeclaration().getTypeParameters().get(0), runtimeException); + MethodUsage mu = constructorDeclaration.getAllMethods().stream().filter(m -> m.getDeclaration().getSignature().equals("isThrows(java.lang.Class<? extends java.lang.Throwable>)")).findFirst().get(); + + assertEquals(true, MethodResolutionLogic.isApplicable(mu, "isThrows", ImmutableList.of(classOfRuntimeType), typeSolver)); + } +} diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/MethodsResolutionTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/MethodsResolutionTest.java new file mode 100644 index 000000000..2e6dc946d --- /dev/null +++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/MethodsResolutionTest.java @@ -0,0 +1,361 @@ +/* + * 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; + +import com.github.javaparser.ast.CompilationUnit; +import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; +import com.github.javaparser.ast.body.MethodDeclaration; +import com.github.javaparser.ast.expr.Expression; +import com.github.javaparser.ast.expr.MethodCallExpr; +import com.github.javaparser.ast.expr.ThisExpr; +import com.github.javaparser.ast.stmt.ReturnStmt; +import com.github.javaparser.resolution.MethodUsage; +import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration; +import com.github.javaparser.resolution.types.ResolvedType; +import com.github.javaparser.symbolsolver.javaparser.Navigator; +import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade; +import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserAnonymousClassDeclaration; +import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; +import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; +import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class MethodsResolutionTest extends AbstractResolutionTest { + + @Test + public void solveMethodAccessThroughSuper() { + CompilationUnit cu = parseSample("AccessThroughSuper"); + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "AccessThroughSuper.SubClass"); + MethodDeclaration method = Navigator.demandMethod(clazz, "methodTest"); + ReturnStmt returnStmt = (ReturnStmt) method.getBody().get().getStatements().get(0); + Expression expression = returnStmt.getExpression().get(); + + ResolvedType ref = JavaParserFacade.get(new ReflectionTypeSolver()).getType(expression); + assertEquals("java.lang.String", ref.describe()); + } + + @Test + public void solveMethodWithClassExpressionAsParameter() { + CompilationUnit cu = parseSample("ClassExpression"); + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "ClassExpression"); + MethodDeclaration method = Navigator.demandMethod(clazz, "foo"); + MethodCallExpr expression = Navigator.findMethodCall(method, "noneOf").get(); + + MethodUsage methodUsage = JavaParserFacade.get(new ReflectionTypeSolver()).solveMethodAsUsage(expression); + assertEquals("noneOf", methodUsage.getName()); + } + + @Test + public void solveMethodInInterfaceParent() { + CompilationUnit cu = parseSample("MethodCalls"); + ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "MethodCalls"); + + MethodDeclaration method = Navigator.demandMethod(clazz, "inheritedInterfaceMethod"); + MethodCallExpr expression = Navigator.findMethodCall(method, "toString").get(); + + TypeSolver typeSolver = new ReflectionTypeSolver(); + + JavaParserFacade javaParserFacade = JavaParserFacade.get(typeSolver); + MethodUsage call1 = javaParserFacade.solveMethodAsUsage(expression); + assertEquals("java.lang.Object.toString()", call1.getQualifiedSignature()); + } + + @Test + public void solveMethodWithTypePromotionsToLong() { + CompilationUnit cu = parseSample("Issue338"); + ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "TypePromotions"); + + MethodDeclaration method = Navigator.demandMethod(clazz, "callingLong"); + + { + MethodCallExpr expression = method.getBody().get().getStatements().get(0).asExpressionStmt().getExpression().asMethodCallExpr(); + SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression); + assertEquals(true, reference.isSolved()); + assertEquals("longParam", reference.getCorrespondingDeclaration().getName()); + } + { + MethodCallExpr expression = method.getBody().get().getStatements().get(1).asExpressionStmt().getExpression().asMethodCallExpr(); + SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression); + assertEquals(true, reference.isSolved()); + assertEquals("longParam", reference.getCorrespondingDeclaration().getName()); + } + { + MethodCallExpr expression = method.getBody().get().getStatements().get(2).asExpressionStmt().getExpression().asMethodCallExpr(); + SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression); + assertEquals(true, reference.isSolved()); + assertEquals("longParam", reference.getCorrespondingDeclaration().getName()); + } + { + MethodCallExpr expression = method.getBody().get().getStatements().get(3).asExpressionStmt().getExpression().asMethodCallExpr(); + SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression); + assertEquals(true, reference.isSolved()); + assertEquals("longParam", reference.getCorrespondingDeclaration().getName()); + } + + } + + @Test + public void solveMethodWithTypePromotionsToInt() { + CompilationUnit cu = parseSample("Issue338"); + ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "TypePromotions"); + + MethodDeclaration method = Navigator.demandMethod(clazz, "callingInt"); + + { + MethodCallExpr expression = method.getBody().get().getStatements().get(0).asExpressionStmt().getExpression().asMethodCallExpr(); + SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression); + assertEquals(true, reference.isSolved()); + assertEquals("intParam", reference.getCorrespondingDeclaration().getName()); + } + { + MethodCallExpr expression = method.getBody().get().getStatements().get(1).asExpressionStmt().getExpression().asMethodCallExpr(); + SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression); + assertEquals(true, reference.isSolved()); + assertEquals("intParam", reference.getCorrespondingDeclaration().getName()); + } + { + MethodCallExpr expression = method.getBody().get().getStatements().get(2).asExpressionStmt().getExpression().asMethodCallExpr(); + SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression); + assertEquals(true, reference.isSolved()); + assertEquals("intParam", reference.getCorrespondingDeclaration().getName()); + } + { + MethodCallExpr expression = method.getBody().get().getStatements().get(3).asExpressionStmt().getExpression().asMethodCallExpr(); + SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression); + assertEquals(false, reference.isSolved()); + } + + } + + @Test + public void solveMethodWithTypePromotionsToShort() { + CompilationUnit cu = parseSample("Issue338"); + ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "TypePromotions"); + + MethodDeclaration method = Navigator.demandMethod(clazz, "callingShort"); + + { + MethodCallExpr expression = method.getBody().get().getStatements().get(0).asExpressionStmt().getExpression().asMethodCallExpr(); + SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression); + assertEquals(true, reference.isSolved()); + assertEquals("shortParam", reference.getCorrespondingDeclaration().getName()); + } + { + MethodCallExpr expression = method.getBody().get().getStatements().get(1).asExpressionStmt().getExpression().asMethodCallExpr(); + SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression); + assertEquals(true, reference.isSolved()); + assertEquals("shortParam", reference.getCorrespondingDeclaration().getName()); + } + { + MethodCallExpr expression = method.getBody().get().getStatements().get(2).asExpressionStmt().getExpression().asMethodCallExpr(); + SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression); + assertEquals(false, reference.isSolved()); + } + { + MethodCallExpr expression = method.getBody().get().getStatements().get(3).asExpressionStmt().getExpression().asMethodCallExpr(); + SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression); + assertEquals(false, reference.isSolved()); + } + + } + + @Test + public void solveMethodWithTypePromotionsToByte() { + CompilationUnit cu = parseSample("Issue338"); + ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "TypePromotions"); + + MethodDeclaration method = Navigator.demandMethod(clazz, "callingByte"); + + { + MethodCallExpr expression = method.getBody().get().getStatements().get(0).asExpressionStmt().getExpression().asMethodCallExpr(); + SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression); + assertEquals(true, reference.isSolved()); + assertEquals("byteParam", reference.getCorrespondingDeclaration().getName()); + } + { + MethodCallExpr expression = method.getBody().get().getStatements().get(1).asExpressionStmt().getExpression().asMethodCallExpr(); + SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression); + assertEquals(false, reference.isSolved()); + } + { + MethodCallExpr expression = method.getBody().get().getStatements().get(2).asExpressionStmt().getExpression().asMethodCallExpr(); + SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression); + assertEquals(false, reference.isSolved()); + } + { + MethodCallExpr expression = method.getBody().get().getStatements().get(3).asExpressionStmt().getExpression().asMethodCallExpr(); + SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression); + assertEquals(false, reference.isSolved()); + } + + } + + @Test + public void solveMethodWithTypePromotionsToLongWithExtraParam() { + CompilationUnit cu = parseSample("Issue338"); + ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "TypePromotionsWithExtraParam"); + + MethodDeclaration method = Navigator.demandMethod(clazz, "callingLong"); + + { + MethodCallExpr expression = method.getBody().get().getStatements().get(0).asExpressionStmt().getExpression().asMethodCallExpr(); + SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression); + assertEquals(true, reference.isSolved()); + assertEquals("longParam", reference.getCorrespondingDeclaration().getName()); + } + { + MethodCallExpr expression = method.getBody().get().getStatements().get(1).asExpressionStmt().getExpression().asMethodCallExpr(); + SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression); + assertEquals(true, reference.isSolved()); + assertEquals("longParam", reference.getCorrespondingDeclaration().getName()); + } + { + MethodCallExpr expression = method.getBody().get().getStatements().get(2).asExpressionStmt().getExpression().asMethodCallExpr(); + SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression); + assertEquals(true, reference.isSolved()); + assertEquals("longParam", reference.getCorrespondingDeclaration().getName()); + } + { + MethodCallExpr expression = method.getBody().get().getStatements().get(3).asExpressionStmt().getExpression().asMethodCallExpr(); + SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression); + assertEquals(true, reference.isSolved()); + assertEquals("longParam", reference.getCorrespondingDeclaration().getName()); + } + + } + + @Test + public void solveMethodWithTypePromotionsToIntWithExtraParam() { + CompilationUnit cu = parseSample("Issue338"); + ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "TypePromotionsWithExtraParam"); + + MethodDeclaration method = Navigator.demandMethod(clazz, "callingInt"); + + { + MethodCallExpr expression = method.getBody().get().getStatements().get(0).asExpressionStmt().getExpression().asMethodCallExpr(); + SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression); + assertEquals(true, reference.isSolved()); + assertEquals("intParam", reference.getCorrespondingDeclaration().getName()); + } + { + MethodCallExpr expression = method.getBody().get().getStatements().get(1).asExpressionStmt().getExpression().asMethodCallExpr(); + SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression); + assertEquals(true, reference.isSolved()); + assertEquals("intParam", reference.getCorrespondingDeclaration().getName()); + } + { + MethodCallExpr expression = method.getBody().get().getStatements().get(2).asExpressionStmt().getExpression().asMethodCallExpr(); + SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression); + assertEquals(true, reference.isSolved()); + assertEquals("intParam", reference.getCorrespondingDeclaration().getName()); + } + { + MethodCallExpr expression = method.getBody().get().getStatements().get(3).asExpressionStmt().getExpression().asMethodCallExpr(); + SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression); + assertEquals(false, reference.isSolved()); + } + + } + + @Test + public void solveMethodWithTypePromotionsToShortWithExtraParam() { + CompilationUnit cu = parseSample("Issue338"); + ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "TypePromotionsWithExtraParam"); + + MethodDeclaration method = Navigator.demandMethod(clazz, "callingShort"); + + { + MethodCallExpr expression = method.getBody().get().getStatements().get(0).asExpressionStmt().getExpression().asMethodCallExpr(); + SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression); + assertEquals(true, reference.isSolved()); + assertEquals("shortParam", reference.getCorrespondingDeclaration().getName()); + } + { + MethodCallExpr expression = method.getBody().get().getStatements().get(1).asExpressionStmt().getExpression().asMethodCallExpr(); + SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression); + assertEquals(true, reference.isSolved()); + assertEquals("shortParam", reference.getCorrespondingDeclaration().getName()); + } + { + MethodCallExpr expression = method.getBody().get().getStatements().get(2).asExpressionStmt().getExpression().asMethodCallExpr(); + SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression); + assertEquals(false, reference.isSolved()); + } + { + MethodCallExpr expression = method.getBody().get().getStatements().get(3).asExpressionStmt().getExpression().asMethodCallExpr(); + SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression); + assertEquals(false, reference.isSolved()); + } + + } + + @Test + public void solveMethodWithTypePromotionsToByteWithExtraParam() { + CompilationUnit cu = parseSample("Issue338"); + ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "TypePromotionsWithExtraParam"); + + MethodDeclaration method = Navigator.demandMethod(clazz, "callingByte"); + + { + MethodCallExpr expression = method.getBody().get().getStatements().get(0).asExpressionStmt().getExpression().asMethodCallExpr(); + SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression); + assertEquals(true, reference.isSolved()); + assertEquals("byteParam", reference.getCorrespondingDeclaration().getName()); + } + { + MethodCallExpr expression = method.getBody().get().getStatements().get(1).asExpressionStmt().getExpression().asMethodCallExpr(); + SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression); + assertEquals(false, reference.isSolved()); + } + { + MethodCallExpr expression = method.getBody().get().getStatements().get(2).asExpressionStmt().getExpression().asMethodCallExpr(); + SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression); + assertEquals(false, reference.isSolved()); + } + { + MethodCallExpr expression = method.getBody().get().getStatements().get(3).asExpressionStmt().getExpression().asMethodCallExpr(); + SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression); + assertEquals(false, reference.isSolved()); + } + + } + + @Test + public void callOnThisInAnonymousClass() { + CompilationUnit cu = parseSample("ThisInAnonymousClass"); + ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Bar"); + + MethodCallExpr fooCall = Navigator.findMethodCall(clazz, "foo").get(); + + SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(fooCall); + assertEquals(true, reference.isSolved()); + } + + @Test + public void thisInAnonymousClass() { + CompilationUnit cu = parseSample("ThisInAnonymousClass"); + ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Bar"); + + ThisExpr thisExpression = Navigator.findNodeOfGivenClass(clazz, ThisExpr.class); + + ResolvedType type = JavaParserFacade.get(new ReflectionTypeSolver()).getType(thisExpression); + assertEquals(true, type.isReferenceType()); + assertEquals(true, type.asReferenceType().getTypeDeclaration() instanceof JavaParserAnonymousClassDeclaration); + } +} diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/QualifiedNameResolutionTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/QualifiedNameResolutionTest.java new file mode 100644 index 000000000..906ac68e6 --- /dev/null +++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/QualifiedNameResolutionTest.java @@ -0,0 +1,47 @@ +/* + * 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; + +import com.github.javaparser.ParseException; +import com.github.javaparser.ast.CompilationUnit; +import com.github.javaparser.ast.body.MethodDeclaration; +import com.github.javaparser.ast.expr.NameExpr; +import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration; +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.resolution.typesolvers.ReflectionTypeSolver; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class QualifiedNameResolutionTest extends AbstractResolutionTest { + + @Test + public void resolveLocalVariableInParentOfParent() { + CompilationUnit cu = parseSample("QualifiedNameTest"); + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration referencesToField = Navigator.demandClass(cu, "QualifiedNameTest"); + MethodDeclaration method = Navigator.demandMethod(referencesToField, "foo1"); + NameExpr nameExpr = Navigator.findNameExpression(method, "s").get(); + + SymbolReference<? extends ResolvedValueDeclaration> ref = JavaParserFacade.get(new ReflectionTypeSolver()).solve(nameExpr); + assertTrue(ref.isSolved()); + assertEquals("java.util.Scanner", ref.getCorrespondingDeclaration().getType().asReferenceType().getQualifiedName()); + } + +} diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/StatementContextResolutionTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/StatementContextResolutionTest.java new file mode 100644 index 000000000..b96abf721 --- /dev/null +++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/StatementContextResolutionTest.java @@ -0,0 +1,108 @@ +/* + * 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; + +import com.github.javaparser.ParseException; +import com.github.javaparser.ast.CompilationUnit; +import com.github.javaparser.ast.body.MethodDeclaration; +import com.github.javaparser.ast.expr.MethodCallExpr; +import com.github.javaparser.ast.expr.NameExpr; +import com.github.javaparser.resolution.MethodUsage; +import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration; +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.resolution.typesolvers.ReflectionTypeSolver; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class StatementContextResolutionTest extends AbstractResolutionTest { + + @Test + public void resolveLocalVariableInParentOfParent() { + CompilationUnit cu = parseSample("LocalVariableInParent"); + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration referencesToField = Navigator.demandClass(cu, "LocalVariableInParent"); + MethodDeclaration method = Navigator.demandMethod(referencesToField, "foo1"); + NameExpr nameExpr = Navigator.findNameExpression(method, "s").get(); + + SymbolReference<? extends ResolvedValueDeclaration> ref = JavaParserFacade.get(new ReflectionTypeSolver()).solve(nameExpr); + assertTrue(ref.isSolved()); + assertEquals("java.lang.String", ref.getCorrespondingDeclaration().getType().asReferenceType().getQualifiedName()); + } + + @Test + public void resolveLocalVariableInParent() { + CompilationUnit cu = parseSample("LocalVariableInParent"); + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration referencesToField = Navigator.demandClass(cu, "LocalVariableInParent"); + MethodDeclaration method = Navigator.demandMethod(referencesToField, "foo3"); + NameExpr nameExpr = Navigator.findNameExpression(method, "s").get(); + + SymbolReference<? extends ResolvedValueDeclaration> ref = JavaParserFacade.get(new ReflectionTypeSolver()).solve(nameExpr); + assertTrue(ref.isSolved()); + assertEquals("java.lang.String", ref.getCorrespondingDeclaration().getType().asReferenceType().getQualifiedName()); + } + + @Test + public void resolveLocalVariableInSameParent() { + CompilationUnit cu = parseSample("LocalVariableInParent"); + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration referencesToField = Navigator.demandClass(cu, "LocalVariableInParent"); + MethodDeclaration method = Navigator.demandMethod(referencesToField, "foo2"); + NameExpr nameExpr = Navigator.findNameExpression(method, "s").get(); + + SymbolReference<? extends ResolvedValueDeclaration> ref = JavaParserFacade.get(new ReflectionTypeSolver()).solve(nameExpr); + assertTrue(ref.isSolved()); + assertEquals("java.lang.String", ref.getCorrespondingDeclaration().getType().asReferenceType().getQualifiedName()); + } + + @Test + public void resolveLocalAndSeveralAnnidatedLevels() { + CompilationUnit cu = parseSample("LocalVariableInParent"); + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration referencesToField = Navigator.demandClass(cu, "LocalVariableInParent"); + MethodDeclaration method = Navigator.demandMethod(referencesToField, "foo4"); + MethodCallExpr call = Navigator.findMethodCall(method, "add").get(); + + TypeSolver typeSolver = new ReflectionTypeSolver(); + + SymbolReference<? extends ResolvedValueDeclaration> ref = JavaParserFacade.get(typeSolver).solve(call.getScope().get()); + assertTrue(ref.isSolved()); + assertEquals("java.util.List<Comment>", ref.getCorrespondingDeclaration().getType().describe()); + + MethodUsage methodUsage = JavaParserFacade.get(typeSolver).solveMethodAsUsage(call); + assertEquals("add", methodUsage.getName()); + } + + @Test + public void resolveMethodOnGenericClass() { + CompilationUnit cu = parseSample("LocalVariableInParent"); + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration referencesToField = Navigator.demandClass(cu, "LocalVariableInParent"); + MethodDeclaration method = Navigator.demandMethod(referencesToField, "foo5"); + MethodCallExpr call = Navigator.findMethodCall(method, "add").get(); + + TypeSolver typeSolver = new ReflectionTypeSolver(); + + SymbolReference<? extends ResolvedValueDeclaration> ref = JavaParserFacade.get(typeSolver).solve(call.getScope().get()); + assertTrue(ref.isSolved()); + assertEquals("java.util.List<Comment>", ref.getCorrespondingDeclaration().getType().describe()); + + MethodUsage methodUsage = JavaParserFacade.get(typeSolver).solveMethodAsUsage(call); + assertEquals("add", methodUsage.getName()); + } + +} diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/SymbolSolverTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/SymbolSolverTest.java new file mode 100644 index 000000000..eafe60122 --- /dev/null +++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/SymbolSolverTest.java @@ -0,0 +1,100 @@ +/* + * 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; + +import com.github.javaparser.JavaParser; +import com.github.javaparser.ast.expr.MethodCallExpr; +import com.github.javaparser.ast.visitor.VoidVisitor; +import com.github.javaparser.ast.visitor.VoidVisitorAdapter; +import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration; +import com.github.javaparser.symbolsolver.AbstractTest; +import com.github.javaparser.symbolsolver.javaparser.Navigator; +import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade; +import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration; +import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; +import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; +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.Before; +import org.junit.Test; + +import java.io.File; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * @author Federico Tomassetti + */ +public class SymbolSolverTest extends AbstractTest { + + private TypeSolver typeSolverNewCode; + private SymbolSolver symbolSolver; + + @Before + public void setup() { + + File srcNewCode = adaptPath(new File("src/test/test_sourcecode/javaparser_new_src/javaparser-core")); + CombinedTypeSolver combinedTypeSolverNewCode = new CombinedTypeSolver(); + combinedTypeSolverNewCode.add(new ReflectionTypeSolver()); + combinedTypeSolverNewCode.add(new JavaParserTypeSolver(srcNewCode)); + combinedTypeSolverNewCode.add(new JavaParserTypeSolver(adaptPath(new File("src/test/test_sourcecode/javaparser_new_src/javaparser-generated-sources")))); + typeSolverNewCode = combinedTypeSolverNewCode; + + symbolSolver = new SymbolSolver(typeSolverNewCode); + } + + @Test + public void testSolveSymbolUnexisting() { + JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration"); + + SymbolReference<? extends ResolvedValueDeclaration> res = symbolSolver.solveSymbolInType(constructorDeclaration, "unexisting"); + assertEquals(false, res.isSolved()); + } + + @Test + public void testSolveSymbolToDeclaredField() { + JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration"); + + SymbolReference<? extends ResolvedValueDeclaration> res = symbolSolver.solveSymbolInType(constructorDeclaration, "name"); + assertEquals(true, res.isSolved()); + assertEquals(true, res.getCorrespondingDeclaration().isField()); + } + + @Test + public void testSolveSymbolToInheritedPublicField() { + JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration"); + + SymbolReference<? extends ResolvedValueDeclaration> res = symbolSolver.solveSymbolInType(constructorDeclaration, "NODE_BY_BEGIN_POSITION"); + assertEquals(true, res.isSolved()); + assertEquals(true, res.getCorrespondingDeclaration().isField()); + } + + @Test + public void testSolveSymbolToInheritedPrivateField() { + JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration"); + + SymbolReference<? extends ResolvedValueDeclaration> res = symbolSolver.solveSymbolInType(constructorDeclaration, "parentNode"); + assertEquals(false, res.isSolved()); + } + + @Test + public void testSolvePackageLocalClass() { + assertTrue(typeSolverNewCode.solveType("com.github.javaparser.FooClass").isClass()); + } +} diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/SymbolSolverWithJavassistClassTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/SymbolSolverWithJavassistClassTest.java new file mode 100644 index 000000000..cf103f156 --- /dev/null +++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/SymbolSolverWithJavassistClassTest.java @@ -0,0 +1,139 @@ +/* + * 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; + +import com.github.javaparser.resolution.UnsolvedSymbolException; +import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration; +import com.github.javaparser.symbolsolver.AbstractTest; +import com.github.javaparser.symbolsolver.javassistmodel.JavassistClassDeclaration; +import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; +import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; +import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver; +import com.github.javaparser.symbolsolver.resolution.typesolvers.JarTypeSolver; +import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver; +import org.junit.Before; +import org.junit.Test; + +import java.io.IOException; + +import static org.junit.Assert.*; + +public class SymbolSolverWithJavassistClassTest extends AbstractTest { + private TypeSolver typeSolver; + private SymbolSolver symbolSolver; + private JavassistClassDeclaration classDeclarationConcreteClass; + private JavassistClassDeclaration classDeclarationSubClassOwnJar; + private JavassistClassDeclaration classDeclarationInterfaceUserOwnJar; + private JavassistClassDeclaration classDeclarationSubClassIncludedJar; + private JavassistClassDeclaration classDeclarationInterfaceUserIncludedJar; + private JavassistClassDeclaration classDeclarationSubClassExcludedJar; + private JavassistClassDeclaration classDeclarationInterfaceUserExcludedJar; + + @Before + public void setup() throws IOException { + final String pathToMainJar = adaptPath("src/test/resources/javassist_symbols/main_jar/main_jar.jar"); + final String pathToIncludedJar = adaptPath("src/test/resources/javassist_symbols/included_jar/included_jar.jar"); + typeSolver = new CombinedTypeSolver(new JarTypeSolver(pathToIncludedJar), new JarTypeSolver(pathToMainJar), new ReflectionTypeSolver()); + + symbolSolver = new SymbolSolver(typeSolver); + + classDeclarationConcreteClass = (JavassistClassDeclaration) typeSolver.solveType("com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar.ConcreteClass"); + classDeclarationSubClassOwnJar = (JavassistClassDeclaration) typeSolver.solveType("com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar.SubClassOwnJar"); + classDeclarationSubClassIncludedJar = (JavassistClassDeclaration) typeSolver.solveType("com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar.SubClassIncludedJar"); + classDeclarationSubClassExcludedJar = (JavassistClassDeclaration) typeSolver.solveType("com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar.SubClassExcludedJar"); + classDeclarationInterfaceUserOwnJar = (JavassistClassDeclaration) typeSolver.solveType("com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar.InterfaceUserOwnJar"); + classDeclarationInterfaceUserIncludedJar = (JavassistClassDeclaration) typeSolver.solveType("com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar.InterfaceUserIncludedJar"); + classDeclarationInterfaceUserExcludedJar = (JavassistClassDeclaration) typeSolver.solveType("com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar.InterfaceUserExcludedJar"); + } + + @Test + public void testSolveSymbolInTypeCanSolveFirstOwnField() { + assertCanSolveSymbol("STATIC_STRING", classDeclarationConcreteClass); + } + + @Test + public void testSolveSymbolInTypeCanSolveSecondOwnField() { + assertCanSolveSymbol("SECOND_STRING", classDeclarationConcreteClass); + } + + @Test + public void testSolveSymbolInTypeCantResolveNonExistentField() { + SymbolReference<? extends ResolvedValueDeclaration> solvedSymbol = symbolSolver.solveSymbolInType(classDeclarationConcreteClass, "FIELD_THAT_DOES_NOT_EXIST"); + + assertFalse(solvedSymbol.isSolved()); + + try { + solvedSymbol.getCorrespondingDeclaration(); + } catch (Exception e) { + assertTrue(e instanceof UnsupportedOperationException); + assertEquals("CorrespondingDeclaration not available for unsolved symbol.", e.getMessage()); + return; + } + fail("Expected UnsupportedOperationException when requesting CorrespondingDeclaration on unsolved SymbolRefernce"); + } + + @Test + public void testSolveSymbolInTypeCanResolveFieldInSuper() { + assertCanSolveSymbol("SUPER_FIELD", classDeclarationSubClassOwnJar); + } + + @Test + public void testSolveSymbolInTypeCanResolveFieldInSuperIncludedJar() { + assertCanSolveSymbol("SUPER_FIELD", classDeclarationSubClassIncludedJar); + } + + @Test + public void testSolveSymbolInTypeThrowsExceptionOnResolveFieldInSuperExcludedJar() { + try { + symbolSolver.solveSymbolInType(classDeclarationSubClassExcludedJar, "SUPER_FIELD"); + } catch (Exception e) { + assertTrue(e instanceof UnsolvedSymbolException); + assertEquals("Unsolved symbol : com.github.javaparser.javasymbolsolver.javassist_symbols.excluded_jar.SuperClassExcludedJar", e.getMessage()); + return; + } + fail("Excepted NotFoundException wrapped in a RuntimeException, but got no exception."); + } + + @Test + public void testSolveSymbolInTypeCanResolveFieldInInterface() { + assertCanSolveSymbol("INTERFACE_FIELD", classDeclarationInterfaceUserOwnJar); + } + + @Test + public void testSolveSymbolInTypeCanResolveFieldInInterfaceIncludedJar() { + assertCanSolveSymbol("INTERFACE_FIELD", classDeclarationInterfaceUserIncludedJar); + } + + @Test + public void testSolveSymbolInTypeThrowsExceptionOnResolveFieldInInterfaceExcludedJar() { + try { + symbolSolver.solveSymbolInType(classDeclarationInterfaceUserExcludedJar, "INTERFACE_FIELD"); + } catch (Exception e) { + assertTrue(e instanceof UnsolvedSymbolException); + assertEquals("Unsolved symbol : com.github.javaparser.javasymbolsolver.javassist_symbols.excluded_jar.InterfaceExcludedJar", e.getMessage()); + return; + } + fail("Excepted NotFoundException wrapped in a RuntimeException, but got no exception."); + } + + private void assertCanSolveSymbol(String symbolName, JavassistClassDeclaration classDeclaration) { + SymbolReference<? extends ResolvedValueDeclaration> solvedSymbol = symbolSolver.solveSymbolInType(classDeclaration, symbolName); + + assertTrue(solvedSymbol.isSolved()); + assertEquals(symbolName, solvedSymbol.getCorrespondingDeclaration().asField().getName()); + } +} diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/SymbolSolverWithJavassistEnumTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/SymbolSolverWithJavassistEnumTest.java new file mode 100644 index 000000000..120d2f14d --- /dev/null +++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/SymbolSolverWithJavassistEnumTest.java @@ -0,0 +1,106 @@ +package com.github.javaparser.symbolsolver.resolution; + +import com.github.javaparser.resolution.UnsolvedSymbolException; +import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration; +import com.github.javaparser.symbolsolver.AbstractTest; +import com.github.javaparser.symbolsolver.javassistmodel.JavassistEnumDeclaration; +import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; +import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; +import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver; +import com.github.javaparser.symbolsolver.resolution.typesolvers.JarTypeSolver; +import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver; +import org.junit.Before; +import org.junit.Test; + +import java.io.IOException; + +import static org.junit.Assert.*; +import static org.junit.Assert.fail; + +public class SymbolSolverWithJavassistEnumTest extends AbstractTest { + private TypeSolver typeSolver; + private SymbolSolver symbolSolver; + private JavassistEnumDeclaration enumDeclarationConcrete; + private JavassistEnumDeclaration enumDeclarationInterfaceUserOwnJar; + private JavassistEnumDeclaration enumDeclarationInterfaceUserIncludedJar; + private JavassistEnumDeclaration enumDeclarationInterfaceUserExcludedJar; + + @Before + public void setup() throws IOException { + final String pathToMainJar = adaptPath("src/test/resources/javassist_symbols/main_jar/main_jar.jar"); + final String pathToIncludedJar = adaptPath("src/test/resources/javassist_symbols/included_jar/included_jar.jar"); + typeSolver = new CombinedTypeSolver(new JarTypeSolver(pathToIncludedJar), new JarTypeSolver(pathToMainJar), new ReflectionTypeSolver()); + + symbolSolver = new SymbolSolver(typeSolver); + + enumDeclarationConcrete = (JavassistEnumDeclaration) typeSolver.solveType("com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar.ConcreteEnum"); + enumDeclarationInterfaceUserOwnJar = (JavassistEnumDeclaration) typeSolver.solveType("com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar.EnumInterfaceUserOwnJar"); + enumDeclarationInterfaceUserIncludedJar = (JavassistEnumDeclaration) typeSolver.solveType("com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar.EnumInterfaceUserIncludedJar"); + enumDeclarationInterfaceUserExcludedJar = (JavassistEnumDeclaration) typeSolver.solveType("com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar.EnumInterfaceUserExcludedJar"); + } + + @Test + public void testSolveSymbolInTypeCanResolveFirstEnumValue() { + assertCanSolveSymbol("ENUM_VAL_ONE", enumDeclarationConcrete); + } + + @Test + public void testSolveSymbolInTypeCanResolveSecondEnumValue() { + assertCanSolveSymbol("ENUM_VAL_TWO", enumDeclarationConcrete); + } + + @Test + public void testSolveSymbolInTypeCanResolveFirstNormalField() { + assertCanSolveSymbol("STATIC_STRING", enumDeclarationConcrete); + } + + @Test + public void testSolveSymbolInTypeCanResolveSecondNormalField() { + assertCanSolveSymbol("SECOND_STRING", enumDeclarationConcrete); + } + + @Test + public void testSolveSymbolInTypeCantResolveNonExistentField() { + SymbolReference<? extends ResolvedValueDeclaration> solvedSymbol = symbolSolver.solveSymbolInType(enumDeclarationConcrete, "FIELD_THAT_DOES_NOT_EXIST"); + + assertFalse(solvedSymbol.isSolved()); + + try { + solvedSymbol.getCorrespondingDeclaration(); + } catch (Exception e) { + assertTrue(e instanceof UnsupportedOperationException); + assertEquals("CorrespondingDeclaration not available for unsolved symbol.", e.getMessage()); + return; + } + fail("Expected UnsupportedOperationException when requesting CorrespondingDeclaration on unsolved SymbolRefernce"); + } + + @Test + public void testSolveSymbolInTypeCanResolveFieldInInterface() { + assertCanSolveSymbol("INTERFACE_FIELD", enumDeclarationInterfaceUserOwnJar); + } + + @Test + public void testSolveSymbolInTypeCanResolveFieldInInterfaceIncludedJar() { + assertCanSolveSymbol("INTERFACE_FIELD", enumDeclarationInterfaceUserIncludedJar); + } + + @Test + public void testSolveSymbolInTypeThrowsExceptionOnResolveFieldInInterfaceExcludedJar() { + try { + symbolSolver.solveSymbolInType(enumDeclarationInterfaceUserExcludedJar, "INTERFACE_FIELD"); + } catch (Exception e) { + assertTrue(e instanceof UnsolvedSymbolException); + assertEquals("Unsolved symbol : com.github.javaparser.javasymbolsolver.javassist_symbols.excluded_jar.InterfaceExcludedJar", e.getMessage()); + return; + } + fail("Excepted NotFoundException wrapped in a RuntimeException, but got no exception."); + } + + private void assertCanSolveSymbol(String symbolName, JavassistEnumDeclaration enumDeclaration) { + SymbolReference<? extends ResolvedValueDeclaration> solvedSymbol = symbolSolver.solveSymbolInType(enumDeclaration, symbolName); + + assertTrue(solvedSymbol.isSolved()); + assertEquals(symbolName, solvedSymbol.getCorrespondingDeclaration().asField().getName()); + } +} diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/SymbolSolverWithJavassistInterfaceTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/SymbolSolverWithJavassistInterfaceTest.java new file mode 100644 index 000000000..7745e813f --- /dev/null +++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/SymbolSolverWithJavassistInterfaceTest.java @@ -0,0 +1,96 @@ +package com.github.javaparser.symbolsolver.resolution; + +import com.github.javaparser.resolution.UnsolvedSymbolException; +import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration; +import com.github.javaparser.symbolsolver.AbstractTest; +import com.github.javaparser.symbolsolver.javassistmodel.JavassistInterfaceDeclaration; +import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; +import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; +import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver; +import com.github.javaparser.symbolsolver.resolution.typesolvers.JarTypeSolver; +import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver; +import org.junit.Before; +import org.junit.Test; + +import java.io.IOException; + +import static org.junit.Assert.*; + +public class SymbolSolverWithJavassistInterfaceTest extends AbstractTest { + private TypeSolver typeSolver; + private SymbolSolver symbolSolver; + private JavassistInterfaceDeclaration interfaceDeclarationStandalone; + private JavassistInterfaceDeclaration interfaceDeclarationSubInterfaceOwnJar; + private JavassistInterfaceDeclaration interfaceDeclarationSubInterfaceIncludedJar; + private JavassistInterfaceDeclaration interfaceDeclarationSubInterfaceExcludedJar; + + @Before + public void setup() throws IOException { + final String pathToMainJar = adaptPath("src/test/resources/javassist_symbols/main_jar/main_jar.jar"); + final String pathToIncludedJar = adaptPath("src/test/resources/javassist_symbols/included_jar/included_jar.jar"); + typeSolver = new CombinedTypeSolver(new JarTypeSolver(pathToIncludedJar), new JarTypeSolver(pathToMainJar), new ReflectionTypeSolver()); + + symbolSolver = new SymbolSolver(typeSolver); + + interfaceDeclarationStandalone = (JavassistInterfaceDeclaration) typeSolver.solveType("com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar.StandaloneInterface"); + interfaceDeclarationSubInterfaceOwnJar = (JavassistInterfaceDeclaration) typeSolver.solveType("com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar.SubInterfaceOwnJar"); + interfaceDeclarationSubInterfaceIncludedJar = (JavassistInterfaceDeclaration) typeSolver.solveType("com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar.SubInterfaceIncludedJar"); + interfaceDeclarationSubInterfaceExcludedJar = (JavassistInterfaceDeclaration) typeSolver.solveType("com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar.SubInterfaceExcludedJar"); + } + + @Test + public void testSolveSymbolInTypeCanResolveFirstNormalField() { + assertCanSolveSymbol("STATIC_STRING", interfaceDeclarationStandalone); + } + + @Test + public void testSolveSymbolInTypeCanResolveSecondNormalField() { + assertCanSolveSymbol("SECOND_STRING", interfaceDeclarationStandalone); + } + + @Test + public void testSolveSymbolInTypeCantResolveNonExistentField() { + SymbolReference<? extends ResolvedValueDeclaration> solvedSymbol = symbolSolver.solveSymbolInType(interfaceDeclarationStandalone, "FIELD_THAT_DOES_NOT_EXIST"); + + assertFalse(solvedSymbol.isSolved()); + + try { + solvedSymbol.getCorrespondingDeclaration(); + } catch (Exception e) { + assertTrue(e instanceof UnsupportedOperationException); + assertEquals("CorrespondingDeclaration not available for unsolved symbol.", e.getMessage()); + return; + } + fail("Expected UnsupportedOperationException when requesting CorrespondingDeclaration on unsolved SymbolRefernce"); + } + + @Test + public void testSolveSymbolInTypeCanResolveFieldInExtendedInterfaceOwnJar() { + assertCanSolveSymbol("INTERFACE_FIELD", interfaceDeclarationSubInterfaceOwnJar); + } + + @Test + public void testSolveSymbolInTypeCanResolveFieldInExtendedInterfaceIncludedJar() { + assertCanSolveSymbol("INTERFACE_FIELD", interfaceDeclarationSubInterfaceIncludedJar); + } + + @Test + public void testSolveSymbolInTypeThrowsExceptionOnResolveFieldInExtendedInterfaceExcludedJar() { + try { + symbolSolver.solveSymbolInType(interfaceDeclarationSubInterfaceExcludedJar, "INTERFACE_FIELD"); + } catch (Exception e) { + assertTrue(e instanceof UnsolvedSymbolException); + assertEquals("Unsolved symbol : com.github.javaparser.javasymbolsolver.javassist_symbols.excluded_jar.InterfaceExcludedJar", e.getMessage()); + return; + } + fail("Excepted NotFoundException wrapped in a RuntimeException, but got no exception."); + } + + private void assertCanSolveSymbol(String symbolName, JavassistInterfaceDeclaration interfaceDeclaration) { + SymbolReference<? extends ResolvedValueDeclaration> solvedSymbol = symbolSolver.solveSymbolInType(interfaceDeclaration, symbolName); + + assertTrue(solvedSymbol.isSolved()); + assertEquals(symbolName, solvedSymbol.getCorrespondingDeclaration().asField().getName()); + } + +} diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/VariadicResolutionTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/VariadicResolutionTest.java new file mode 100644 index 000000000..48c0ca708 --- /dev/null +++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/VariadicResolutionTest.java @@ -0,0 +1,104 @@ +/* + * 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; + +import com.github.javaparser.ast.CompilationUnit; +import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; +import com.github.javaparser.ast.body.MethodDeclaration; +import com.github.javaparser.ast.expr.Expression; +import com.github.javaparser.ast.expr.MethodCallExpr; +import com.github.javaparser.ast.stmt.ReturnStmt; +import com.github.javaparser.resolution.MethodUsage; +import com.github.javaparser.resolution.types.ResolvedType; +import com.github.javaparser.symbolsolver.javaparser.Navigator; +import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade; +import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; +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; + +import java.io.File; +import java.util.List; + +import static org.junit.Assert.assertEquals; + +public class VariadicResolutionTest extends AbstractResolutionTest { + + @Test + public void issue7() { + CompilationUnit cu = parseSample("Generics_issue7"); + ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "SomeCollection"); + + MethodDeclaration method = Navigator.demandMethod(clazz, "foo3"); + + ReturnStmt stmt = (ReturnStmt) method.getBody().get().getStatements().get(0); + Expression expression = stmt.getExpression().get(); + JavaParserFacade javaParserFacade = JavaParserFacade.get(new ReflectionTypeSolver()); + ResolvedType type = javaParserFacade.getType(expression); + assertEquals(true, type.isReferenceType()); + assertEquals(List.class.getCanonicalName(), type.asReferenceType().getQualifiedName()); + assertEquals("java.util.List<java.lang.Long>", type.describe()); + } + + @Test + public void methodCallWithReferenceTypeAsVaridicArgumentIsSolved() { + CompilationUnit cu = parseSample("MethodCalls"); + ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "MethodCalls"); + + MethodDeclaration method = Navigator.demandMethod(clazz, "variadicMethod"); + MethodCallExpr callExpr = Navigator.findMethodCall(method, "variadicMethod").get(); + + TypeSolver typeSolver = new ReflectionTypeSolver(); + JavaParserFacade javaParserFacade = JavaParserFacade.get(typeSolver); + MethodUsage callee = javaParserFacade.solveMethodAsUsage(callExpr); + assertEquals("variadicMethod", callee.getName()); + } + + @Test + public void resolveVariadicMethodWithGenericArgument() { + CompilationUnit cu = parseSample("MethodCalls"); + ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "MethodCalls"); + + MethodDeclaration method = Navigator.demandMethod(clazz, "genericMethodTest"); + MethodCallExpr callExpr = Navigator.findMethodCall(method, "variadicWithGenericArg").get(); + + TypeSolver typeSolver = new ReflectionTypeSolver(); + JavaParserFacade javaParserFacade = JavaParserFacade.get(typeSolver); + MethodUsage callee = javaParserFacade.solveMethodAsUsage(callExpr); + assertEquals("variadicWithGenericArg", callee.getName()); + } + + @Test + public void selectMostSpecificVariadic() { + CompilationUnit cu = parseSample("MethodCalls"); + ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "MethodCalls"); + + MethodDeclaration method = Navigator.demandMethod(clazz, "variadicTest"); + List<MethodCallExpr> calls = method.findAll(MethodCallExpr.class); + + File src = adaptPath(new File("src/test/resources")); + TypeSolver typeSolver = new CombinedTypeSolver(new ReflectionTypeSolver(), new JavaParserTypeSolver(src)); + + JavaParserFacade javaParserFacade = JavaParserFacade.get(typeSolver); + MethodUsage call1 = javaParserFacade.solveMethodAsUsage(calls.get(0)); + MethodUsage call2 = javaParserFacade.solveMethodAsUsage(calls.get(1)); + assertEquals("int", call1.returnType().describe()); + assertEquals("void", call2.returnType().describe()); + } + +} diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/VarTypeTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/VarTypeTest.java new file mode 100644 index 000000000..d8d0eafe0 --- /dev/null +++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/VarTypeTest.java @@ -0,0 +1,62 @@ +package com.github.javaparser.symbolsolver.resolution.javaparser; + +import com.github.javaparser.JavaParser; +import com.github.javaparser.ParseStart; +import com.github.javaparser.ParserConfiguration; +import com.github.javaparser.ast.CompilationUnit; +import com.github.javaparser.ast.type.VarType; +import com.github.javaparser.resolution.types.ResolvedPrimitiveType; +import com.github.javaparser.resolution.types.ResolvedType; +import com.github.javaparser.symbolsolver.JavaSymbolSolver; +import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; +import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl; +import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassDeclaration; +import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver; +import org.junit.Test; + +import static com.github.javaparser.ParserConfiguration.LanguageLevel.JAVA_10; +import static com.github.javaparser.Providers.provider; +import static org.junit.Assert.assertEquals; + +public class VarTypeTest { + private final TypeSolver typeSolver = new ReflectionTypeSolver(); + private final JavaParser javaParser = new JavaParser(new ParserConfiguration() + .setLanguageLevel(JAVA_10) + .setSymbolResolver(new JavaSymbolSolver(typeSolver))); + + @Test + public void resolveAPrimitive() { + CompilationUnit ast = javaParser.parse(ParseStart.COMPILATION_UNIT, provider("class X{void x(){var abc = 1;}}")).getResult().get(); + VarType varType = ast.findFirst(VarType.class).get(); + + ResolvedType resolvedType = varType.resolve(); + + assertEquals(ResolvedPrimitiveType.INT, resolvedType); + } + + @Test + public void resolveAReferenceType() { + CompilationUnit ast = javaParser.parse(ParseStart.COMPILATION_UNIT, provider("class X{void x(){var abc = \"\";}}")).getResult().get(); + VarType varType = ast.findFirst(VarType.class).get(); + + ResolvedType resolvedType = varType.resolve(); + + assertEquals(new ReferenceTypeImpl(new ReflectionClassDeclaration(String.class, typeSolver), typeSolver), resolvedType); + } + + @Test(expected = IllegalStateException.class) + public void failResolveNoInitializer() { + CompilationUnit ast = javaParser.parse(ParseStart.COMPILATION_UNIT, provider("class X{void x(){var abc;}}")).getResult().get(); + VarType varType = ast.findFirst(VarType.class).get(); + + varType.resolve(); + } + + @Test(expected = IllegalStateException.class) + public void failResolveWrongLocation() { + CompilationUnit ast = javaParser.parse(ParseStart.COMPILATION_UNIT, provider("class X{void x(var x){};}")).getResult().get(); + VarType varType = ast.findFirst(VarType.class).get(); + + varType.resolve(); + } +} diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/contexts/ClassOrInterfaceDeclarationContextResolutionTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/contexts/ClassOrInterfaceDeclarationContextResolutionTest.java new file mode 100644 index 000000000..a55941808 --- /dev/null +++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/contexts/ClassOrInterfaceDeclarationContextResolutionTest.java @@ -0,0 +1,490 @@ +/* + * 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.javaparser.contexts; + +import com.github.javaparser.ParseException; +import com.github.javaparser.ast.CompilationUnit; +import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; +import com.github.javaparser.resolution.MethodAmbiguityException; +import com.github.javaparser.resolution.MethodUsage; +import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration; +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.ResolvedType; +import com.github.javaparser.symbolsolver.core.resolution.Context; +import com.github.javaparser.symbolsolver.javaparser.Navigator; +import com.github.javaparser.symbolsolver.javaparsermodel.contexts.ClassOrInterfaceDeclarationContext; +import com.github.javaparser.symbolsolver.javaparsermodel.contexts.CompilationUnitContext; +import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; +import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; +import com.github.javaparser.symbolsolver.model.resolution.Value; +import com.github.javaparser.symbolsolver.model.typesystem.NullType; +import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl; +import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassDeclaration; +import com.github.javaparser.symbolsolver.resolution.AbstractResolutionTest; +import com.github.javaparser.symbolsolver.resolution.typesolvers.MemoryTypeSolver; +import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver; +import com.google.common.collect.ImmutableList; +import org.junit.Before; +import org.junit.Test; + +import java.util.Optional; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + +/** + * @author Federico Tomassetti + */ +public class ClassOrInterfaceDeclarationContextResolutionTest extends AbstractResolutionTest { + + private TypeSolver typeSolver; + + @Before + public void setup() { + typeSolver = new ReflectionTypeSolver(); + } + + @Test + public void getParentForTopClass() { + CompilationUnit cu = parseSample("ClassWithTypeVariables"); + ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A"); + Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver); + + assertFalse(null == context.getParent()); + assertEquals(new CompilationUnitContext(cu, typeSolver), context.getParent()); + } + + @Test + public void solveExistingGenericType() { + CompilationUnit cu = parseSample("ClassWithTypeVariables"); + ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A"); + Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver); + + Optional<ResolvedType> a = context.solveGenericType("A", new MemoryTypeSolver()); + Optional<ResolvedType> b = context.solveGenericType("B", new MemoryTypeSolver()); + Optional<ResolvedType> c = context.solveGenericType("C", new MemoryTypeSolver()); + + assertEquals(true, a.isPresent()); + assertEquals("A", a.get().describe()); + assertEquals(true, a.get().isTypeVariable()); + assertEquals(true, b.isPresent()); + assertEquals("B", b.get().describe()); + assertEquals(true, b.get().isTypeVariable()); + assertEquals(true, c.isPresent()); + assertEquals("C", c.get().describe()); + assertEquals(true, c.get().isTypeVariable()); + } + + @Test + public void solveUnexistingGenericType() { + CompilationUnit cu = parseSample("ClassWithTypeVariables"); + ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A"); + Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver); + + Optional<ResolvedType> d = context.solveGenericType("D", new MemoryTypeSolver()); + + assertEquals(false, d.isPresent()); + } + + @Test + public void solveSymbolReferringToDeclaredInstanceField() { + CompilationUnit cu = parseSample("ClassWithSymbols"); + ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A"); + Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver); + + SymbolReference<? extends ResolvedValueDeclaration> ref = context.solveSymbol("i", new MemoryTypeSolver()); + assertEquals(true, ref.isSolved()); + assertEquals("int", ref.getCorrespondingDeclaration().getType().describe()); + } + + @Test + public void solveSymbolReferringToDeclaredStaticField() { + CompilationUnit cu = parseSample("ClassWithSymbols"); + ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A"); + Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver); + + SymbolReference<? extends ResolvedValueDeclaration> ref = context.solveSymbol("j", new MemoryTypeSolver()); + assertEquals(true, ref.isSolved()); + assertEquals("long", ref.getCorrespondingDeclaration().getType().describe()); + } + + @Test + public void solveSymbolReferringToInheritedInstanceField() { + CompilationUnit cu = parseSample("ClassWithSymbols"); + ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A"); + Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver); + + SymbolReference<? extends ResolvedValueDeclaration> ref = context.solveSymbol("k", new MemoryTypeSolver()); + assertEquals(true, ref.isSolved()); + assertEquals("boolean", ref.getCorrespondingDeclaration().getType().describe()); + } + + @Test + public void solveSymbolReferringToInterfaceInheritedInstanceField() { + CompilationUnit cu = parseSample("ClassWithSymbols"); + ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A"); + Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver); + + SymbolReference<? extends ResolvedValueDeclaration> ref = context.solveSymbol("o", new MemoryTypeSolver()); + assertEquals(true, ref.isSolved()); + assertEquals("int", ref.getCorrespondingDeclaration().getType().describe()); + } + + @Test + public void solveSymbolReferringToInheritedStaticField() { + CompilationUnit cu = parseSample("ClassWithSymbols"); + ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A"); + Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver); + + SymbolReference<? extends ResolvedValueDeclaration> ref = context.solveSymbol("m", new MemoryTypeSolver()); + assertEquals(true, ref.isSolved()); + assertEquals("char", ref.getCorrespondingDeclaration().getType().describe()); + } + + @Test + public void solveSymbolReferringToUnknownElement() { + CompilationUnit cu = parseSample("ClassWithSymbols"); + ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A"); + Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver); + + SymbolReference<? extends ResolvedValueDeclaration> ref = context.solveSymbol("zzz", new MemoryTypeSolver()); + assertEquals(false, ref.isSolved()); + } + + @Test + public void solveSymbolAsValueReferringToDeclaredInstanceField() { + CompilationUnit cu = parseSample("ClassWithSymbols"); + ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A"); + Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver); + + Optional<Value> ref = context.solveSymbolAsValue("i", new MemoryTypeSolver()); + assertEquals(true, ref.isPresent()); + assertEquals("int", ref.get().getType().describe()); + } + + @Test + public void solveSymbolAsValueReferringToDeclaredStaticField() { + CompilationUnit cu = parseSample("ClassWithSymbols"); + ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A"); + Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver); + + Optional<Value> ref = context.solveSymbolAsValue("j", new MemoryTypeSolver()); + assertEquals(true, ref.isPresent()); + assertEquals("long", ref.get().getType().describe()); + } + + @Test + public void solveSymbolAsValueReferringToInheritedInstanceField() { + CompilationUnit cu = parseSample("ClassWithSymbols"); + ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A"); + Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver); + + Optional<Value> ref = context.solveSymbolAsValue("k", new MemoryTypeSolver()); + assertEquals(true, ref.isPresent()); + assertEquals("boolean", ref.get().getType().describe()); + } + + @Test + public void solveSymbolAsValueReferringToInterfaceInheritedInstanceField() { + CompilationUnit cu = parseSample("ClassWithSymbols"); + ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A"); + ClassOrInterfaceDeclarationContext context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver); + + Optional<Value> ref = context.solveSymbolAsValue("o", new MemoryTypeSolver()); + assertEquals(true, ref.isPresent()); + assertEquals("int", ref.get().getType().describe()); + } + + @Test + public void solveSymbolAsValueReferringToInheritedStaticField() { + CompilationUnit cu = parseSample("ClassWithSymbols"); + ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A"); + Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver); + + Optional<Value> ref = context.solveSymbolAsValue("m", new MemoryTypeSolver()); + assertEquals(true, ref.isPresent()); + assertEquals("char", ref.get().getType().describe()); + } + + @Test + public void solveSymbolAsValueReferringToUnknownElement() { + CompilationUnit cu = parseSample("ClassWithSymbols"); + ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A"); + Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver); + + Optional<Value> ref = context.solveSymbolAsValue("zzz", new MemoryTypeSolver()); + assertEquals(false, ref.isPresent()); + } + + @Test + public void solveTypeRefToItself() { + CompilationUnit cu = parseSample("ClassWithTypes"); + ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A"); + Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver); + + SymbolReference<ResolvedTypeDeclaration> ref = context.solveType("A", new MemoryTypeSolver()); + assertEquals(true, ref.isSolved()); + } + + @Test + public void solveTypeRefToUnexisting() { + CompilationUnit cu = parseSample("ClassWithTypes"); + ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A"); + Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver); + + SymbolReference<ResolvedTypeDeclaration> ref = context.solveType("Foo", new MemoryTypeSolver()); + assertEquals(false, ref.isSolved()); + } + + @Test + public void solveTypeRefToObject() { + CompilationUnit cu = parseSample("ClassWithTypes"); + ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A"); + Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver); + + SymbolReference<ResolvedTypeDeclaration> ref = context.solveType("Object", new ReflectionTypeSolver()); + assertEquals(true, ref.isSolved()); + } + + @Test + public void solveTypeRefToJavaLangObject() { + CompilationUnit cu = parseSample("ClassWithTypes"); + ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A"); + Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver); + + SymbolReference<ResolvedTypeDeclaration> ref = context.solveType("java.lang.Object", new ReflectionTypeSolver()); + assertEquals(true, ref.isSolved()); + } + + @Test + public void solveTypeRefToInternalClass() { + CompilationUnit cu = parseSample("ClassWithTypes"); + ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A"); + Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver); + + SymbolReference<ResolvedTypeDeclaration> ref = context.solveType("B", new MemoryTypeSolver()); + assertEquals(true, ref.isSolved()); + } + + @Test + public void solveTypeRefToInternalEnum() { + CompilationUnit cu = parseSample("ClassWithTypes"); + ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A"); + Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver); + + SymbolReference<ResolvedTypeDeclaration> ref = context.solveType("E", new MemoryTypeSolver()); + assertEquals(true, ref.isSolved()); + } + + @Test + public void solveTypeRefToInternalOfInternalClass() { + CompilationUnit cu = parseSample("ClassWithTypes"); + ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A"); + Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver); + + SymbolReference<ResolvedTypeDeclaration> ref = context.solveType("C", new MemoryTypeSolver()); + assertEquals(false, ref.isSolved()); + } + + @Test + public void solveTypeRefToAnotherClassInFile() { + CompilationUnit cu = parseSample("ClassWithTypes"); + ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A"); + Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver); + + SymbolReference<ResolvedTypeDeclaration> ref = context.solveType("Super", new MemoryTypeSolver()); + assertEquals(true, ref.isSolved()); + } + + @Test + public void solveTypeRefToQualifiedInternalClass() { + CompilationUnit cu = parseSample("ClassWithTypes"); + ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A"); + Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver); + + SymbolReference<ResolvedTypeDeclaration> ref = context.solveType("A.B", new MemoryTypeSolver()); + assertEquals(true, ref.isSolved()); + } + + @Test + public void solveTypeRefToQualifiedInternalOfInternalClass() { + CompilationUnit cu = parseSample("ClassWithTypes"); + ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A"); + Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver); + + SymbolReference<ResolvedTypeDeclaration> ref = context.solveType("B.C", new MemoryTypeSolver()); + assertEquals(true, ref.isSolved()); + } + + @Test + public void solveTypeRefToMoreQualifiedInternalOfInternalClass() { + CompilationUnit cu = parseSample("ClassWithTypes"); + ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A"); + Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver); + + SymbolReference<ResolvedTypeDeclaration> ref = context.solveType("A.B.C", new MemoryTypeSolver()); + assertEquals(true, ref.isSolved()); + } + + @Test + public void solveMethodSimpleCase() { + CompilationUnit cu = parseSample("ClassWithMethods"); + ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A"); + Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver); + + SymbolReference<ResolvedMethodDeclaration> ref = context.solveMethod("foo0", ImmutableList.of(), false, new ReflectionTypeSolver()); + assertEquals(true, ref.isSolved()); + assertEquals("A", ref.getCorrespondingDeclaration().declaringType().getName()); + assertEquals(0, ref.getCorrespondingDeclaration().getNumberOfParams()); + } + + @Test + public void solveMethodOverrideCase() { + CompilationUnit cu = parseSample("ClassWithMethods"); + ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A"); + Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver); + + SymbolReference<ResolvedMethodDeclaration> ref = context.solveMethod("foo1", ImmutableList.of(), false, new ReflectionTypeSolver()); + assertEquals(true, ref.isSolved()); + assertEquals("A", ref.getCorrespondingDeclaration().declaringType().getName()); + assertEquals(0, ref.getCorrespondingDeclaration().getNumberOfParams()); + } + + @Test + public void solveMethodInheritedCase() { + CompilationUnit cu = parseSample("ClassWithMethods"); + ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A"); + Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver); + + SymbolReference<ResolvedMethodDeclaration> ref = context.solveMethod("foo2", ImmutableList.of(), false, new ReflectionTypeSolver()); + assertEquals(true, ref.isSolved()); + assertEquals("Super", ref.getCorrespondingDeclaration().declaringType().getName()); + assertEquals(0, ref.getCorrespondingDeclaration().getNumberOfParams()); + } + + @Test + public void solveMethodWithPrimitiveParameters() { + CompilationUnit cu = parseSample("ClassWithMethods"); + ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A"); + Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver); + + ResolvedType intType = ResolvedPrimitiveType.INT; + + SymbolReference<ResolvedMethodDeclaration> ref = context.solveMethod("foo3", ImmutableList.of(intType), false, new ReflectionTypeSolver()); + assertEquals(true, ref.isSolved()); + assertEquals("A", ref.getCorrespondingDeclaration().declaringType().getName()); + assertEquals(1, ref.getCorrespondingDeclaration().getNumberOfParams()); + } + + @Test + public void solveMethodWithMoreSpecializedParameter() { + CompilationUnit cu = parseSample("ClassWithMethods"); + ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A"); + Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver); + + ResolvedType stringType = new ReferenceTypeImpl(new ReflectionClassDeclaration(String.class, typeSolver), typeSolver); + + SymbolReference<ResolvedMethodDeclaration> ref = context.solveMethod("foo4", ImmutableList.of(stringType), false, new ReflectionTypeSolver()); + assertEquals(true, ref.isSolved()); + assertEquals("A", ref.getCorrespondingDeclaration().declaringType().getName()); + assertEquals(1, ref.getCorrespondingDeclaration().getNumberOfParams()); + } + + @Test(expected = MethodAmbiguityException.class) + public void solveMethodWithAmbiguosCall() { + CompilationUnit cu = parseSample("ClassWithMethods"); + ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A"); + Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver); + + SymbolReference<ResolvedMethodDeclaration> ref = context.solveMethod("foo5", ImmutableList.of(NullType.INSTANCE), false, new ReflectionTypeSolver()); + } + + @Test + public void solveMethodAsUsageSimpleCase() { + CompilationUnit cu = parseSample("ClassWithMethods"); + ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A"); + Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver); + + Optional<MethodUsage> ref = context.solveMethodAsUsage("foo0", ImmutableList.of(), new ReflectionTypeSolver()); + assertEquals(true, ref.isPresent()); + assertEquals("A", ref.get().declaringType().getName()); + assertEquals(0, ref.get().getNoParams()); + } + + @Test + public void solveMethodAsUsageOverrideCase() { + CompilationUnit cu = parseSample("ClassWithMethods"); + ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A"); + Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver); + + Optional<MethodUsage> ref = context.solveMethodAsUsage("foo1", ImmutableList.of(), new ReflectionTypeSolver()); + assertEquals(true, ref.isPresent()); + assertEquals("A", ref.get().declaringType().getName()); + assertEquals(0, ref.get().getNoParams()); + } + + @Test + public void solveMethodAsUsageInheritedCase() { + CompilationUnit cu = parseSample("ClassWithMethods"); + ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A"); + Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver); + + Optional<MethodUsage> ref = context.solveMethodAsUsage("foo2", ImmutableList.of(), new ReflectionTypeSolver()); + assertEquals(true, ref.isPresent()); + assertEquals("Super", ref.get().declaringType().getName()); + assertEquals(0, ref.get().getNoParams()); + } + + @Test + public void solveMethodAsUsageWithPrimitiveParameters() { + CompilationUnit cu = parseSample("ClassWithMethods"); + ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A"); + Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver); + + ResolvedType intType = ResolvedPrimitiveType.INT; + + Optional<MethodUsage> ref = context.solveMethodAsUsage("foo3", ImmutableList.of(intType), new ReflectionTypeSolver()); + assertEquals(true, ref.isPresent()); + assertEquals("A", ref.get().declaringType().getName()); + assertEquals(1, ref.get().getNoParams()); + } + + @Test + public void solveMethodAsUsageWithMoreSpecializedParameter() { + CompilationUnit cu = parseSample("ClassWithMethods"); + ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A"); + Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver); + + ResolvedType stringType = new ReferenceTypeImpl(new ReflectionClassDeclaration(String.class, typeSolver), typeSolver); + + Optional<MethodUsage> ref = context.solveMethodAsUsage("foo4", ImmutableList.of(stringType), new ReflectionTypeSolver()); + assertEquals(true, ref.isPresent()); + assertEquals("A", ref.get().declaringType().getName()); + assertEquals(1, ref.get().getNoParams()); + } + + @Test(expected = MethodAmbiguityException.class) + public void solveMethodAsUsageWithAmbiguosCall() { + CompilationUnit cu = parseSample("ClassWithMethods"); + ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A"); + Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver); + + Optional<MethodUsage> ref = context.solveMethodAsUsage("foo5", ImmutableList.of(NullType.INSTANCE), new ReflectionTypeSolver()); + } +} diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/contexts/CompilationUnitContextResolutionTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/contexts/CompilationUnitContextResolutionTest.java new file mode 100644 index 000000000..c079e5982 --- /dev/null +++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/contexts/CompilationUnitContextResolutionTest.java @@ -0,0 +1,236 @@ +/* + * 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.javaparser.contexts; + +import com.github.javaparser.ParseException; +import com.github.javaparser.ast.CompilationUnit; +import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration; +import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration; +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.ResolvedType; +import com.github.javaparser.symbolsolver.core.resolution.Context; +import com.github.javaparser.symbolsolver.javaparsermodel.contexts.CompilationUnitContext; +import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; +import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; +import com.github.javaparser.symbolsolver.model.resolution.Value; +import com.github.javaparser.symbolsolver.model.typesystem.NullType; +import com.github.javaparser.symbolsolver.resolution.AbstractResolutionTest; +import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver; +import com.github.javaparser.symbolsolver.resolution.typesolvers.JarTypeSolver; +import com.github.javaparser.symbolsolver.resolution.typesolvers.MemoryTypeSolver; +import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver; +import com.google.common.collect.ImmutableList; +import org.junit.Before; +import org.junit.Test; + +import java.io.IOException; +import java.util.Optional; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +/** + * @author Federico Tomassetti + */ +public class CompilationUnitContextResolutionTest extends AbstractResolutionTest { + + private TypeSolver typeSolver; + + @Before + public void setup() { + typeSolver = new ReflectionTypeSolver(); + } + + @Test + public void getParent() { + CompilationUnit cu = parseSample("ClassWithTypeVariables"); + Context context = new CompilationUnitContext(cu, typeSolver); + + assertTrue(null == context.getParent()); + } + + @Test + public void solveExistingGenericType() { + CompilationUnit cu = parseSample("ClassWithTypeVariables"); + Context context = new CompilationUnitContext(cu, typeSolver); + + Optional<ResolvedType> a = context.solveGenericType("A", new MemoryTypeSolver()); + Optional<ResolvedType> b = context.solveGenericType("B", new MemoryTypeSolver()); + Optional<ResolvedType> c = context.solveGenericType("C", new MemoryTypeSolver()); + + assertEquals(false, a.isPresent()); + assertEquals(false, b.isPresent()); + assertEquals(false, c.isPresent()); + } + + @Test + public void solveUnexistingGenericType() { + CompilationUnit cu = parseSample("ClassWithTypeVariables"); + Context context = new CompilationUnitContext(cu, typeSolver); + + Optional<ResolvedType> d = context.solveGenericType("D", new MemoryTypeSolver()); + + assertEquals(false, d.isPresent()); + } + + @Test + public void solveSymbolReferringToStaticallyImportedValue() throws ParseException, IOException { + CompilationUnit cu = parseSample("CompilationUnitSymbols"); + Context context = new CompilationUnitContext(cu, typeSolver); + + CombinedTypeSolver typeSolver = new CombinedTypeSolver(); + typeSolver.add(new ReflectionTypeSolver()); + typeSolver.add(new JarTypeSolver(adaptPath("src/test/resources/junit-4.8.1.jar"))); + SymbolReference<? extends ResolvedValueDeclaration> ref = context.solveSymbol("out", typeSolver); + assertEquals(true, ref.isSolved()); + assertEquals("java.io.PrintStream", ref.getCorrespondingDeclaration().getType().asReferenceType().getQualifiedName()); + } + + @Test + public void solveSymbolReferringToStaticallyImportedUsingAsteriskValue() throws ParseException, IOException { + CompilationUnit cu = parseSample("CompilationUnitSymbols"); + Context context = new CompilationUnitContext(cu, typeSolver); + + CombinedTypeSolver typeSolver = new CombinedTypeSolver(); + typeSolver.add(new ReflectionTypeSolver()); + typeSolver.add(new JarTypeSolver(adaptPath("src/test/resources/junit-4.8.1.jar"))); + SymbolReference<? extends ResolvedValueDeclaration> ref = context.solveSymbol("err", typeSolver); + assertEquals(true, ref.isSolved()); + assertEquals("java.io.PrintStream", ref.getCorrespondingDeclaration().getType().asReferenceType().getQualifiedName()); + } + + @Test + public void solveSymbolReferringToStaticField() throws ParseException, IOException { + CompilationUnit cu = parseSample("CompilationUnitSymbols"); + Context context = new CompilationUnitContext(cu, typeSolver); + + SymbolReference<? extends ResolvedValueDeclaration> ref = context.solveSymbol("java.lang.System.out", new ReflectionTypeSolver()); + assertEquals(true, ref.isSolved()); + assertEquals("java.io.PrintStream", ref.getCorrespondingDeclaration().getType().asReferenceType().getQualifiedName()); + } + + @Test + public void solveSymbolAsValueReferringToStaticallyImportedValue() throws ParseException, IOException { + CompilationUnit cu = parseSample("CompilationUnitSymbols"); + Context context = new CompilationUnitContext(cu, typeSolver); + + CombinedTypeSolver typeSolver = new CombinedTypeSolver(); + typeSolver.add(new ReflectionTypeSolver()); + typeSolver.add(new JarTypeSolver(adaptPath("src/test/resources/junit-4.8.1.jar"))); + Optional<Value> ref = context.solveSymbolAsValue("out", typeSolver); + assertEquals(true, ref.isPresent()); + assertEquals("java.io.PrintStream", ref.get().getType().describe()); + } + + @Test + public void solveSymbolAsValueReferringToStaticallyImportedUsingAsteriskValue() throws ParseException, IOException { + CompilationUnit cu = parseSample("CompilationUnitSymbols"); + Context context = new CompilationUnitContext(cu, typeSolver); + + CombinedTypeSolver typeSolver = new CombinedTypeSolver(); + typeSolver.add(new ReflectionTypeSolver()); + typeSolver.add(new JarTypeSolver(adaptPath("src/test/resources/junit-4.8.1.jar"))); + Optional<Value> ref = context.solveSymbolAsValue("err", typeSolver); + assertEquals(true, ref.isPresent()); + assertEquals("java.io.PrintStream", ref.get().getType().describe()); + } + + @Test + public void solveSymbolAsValueReferringToStaticField() throws ParseException, IOException { + CompilationUnit cu = parseSample("CompilationUnitSymbols"); + Context context = new CompilationUnitContext(cu, typeSolver); + + Optional<Value> ref = context.solveSymbolAsValue("java.lang.System.out", new ReflectionTypeSolver()); + assertEquals(true, ref.isPresent()); + assertEquals("java.io.PrintStream", ref.get().getType().describe()); + } + + @Test + public void solveTypeInSamePackage() { + CompilationUnit cu = parseSample("CompilationUnitWithImports"); + Context context = new CompilationUnitContext(cu, typeSolver); + + ResolvedReferenceTypeDeclaration otherClass = mock(ResolvedReferenceTypeDeclaration.class); + when(otherClass.getQualifiedName()).thenReturn("com.foo.OtherClassInSamePackage"); + MemoryTypeSolver memoryTypeSolver = new MemoryTypeSolver(); + memoryTypeSolver.addDeclaration("com.foo.OtherClassInSamePackage", otherClass); + + SymbolReference<ResolvedTypeDeclaration> ref = context.solveType("OtherClassInSamePackage", memoryTypeSolver); + assertEquals(true, ref.isSolved()); + assertEquals("com.foo.OtherClassInSamePackage", ref.getCorrespondingDeclaration().getQualifiedName()); + } + + @Test + public void solveTypeImported() throws ParseException, IOException { + CompilationUnit cu = parseSample("CompilationUnitWithImports"); + Context context = new CompilationUnitContext(cu, typeSolver); + + SymbolReference<ResolvedTypeDeclaration> ref = context.solveType("Assert", new JarTypeSolver(adaptPath("src/test/resources/junit-4.8.1.jar"))); + assertEquals(true, ref.isSolved()); + assertEquals("org.junit.Assert", ref.getCorrespondingDeclaration().getQualifiedName()); + } + + @Test + public void solveTypeNotImported() throws ParseException, IOException { + CompilationUnit cu = parseSample("CompilationUnitWithImports"); + Context context = new CompilationUnitContext(cu, typeSolver); + + SymbolReference<ResolvedTypeDeclaration> ref = context.solveType("org.junit.Assume", new JarTypeSolver(adaptPath("src/test/resources/junit-4.8.1.jar"))); + assertEquals(true, ref.isSolved()); + assertEquals("org.junit.Assume", ref.getCorrespondingDeclaration().getQualifiedName()); + } + + @Test + public void solveMethodStaticallyImportedWithAsterisk() throws ParseException, IOException { + CompilationUnit cu = parseSample("CompilationUnitWithImports"); + Context context = new CompilationUnitContext(cu, typeSolver); + + CombinedTypeSolver typeSolver = new CombinedTypeSolver(); + typeSolver.add(new JarTypeSolver(adaptPath("src/test/resources/junit-4.8.1.jar"))); + typeSolver.add(new ReflectionTypeSolver()); + + SymbolReference<ResolvedMethodDeclaration> ref = context.solveMethod("assertFalse", ImmutableList.of(ResolvedPrimitiveType.BOOLEAN), false, typeSolver); + assertEquals(true, ref.isSolved()); + assertEquals("assertFalse", ref.getCorrespondingDeclaration().getName()); + assertEquals(1, ref.getCorrespondingDeclaration().getNumberOfParams()); + assertEquals("boolean", ref.getCorrespondingDeclaration().getParam(0).getType().describe()); + assertEquals(true, ref.getCorrespondingDeclaration().getParam(0).getType().isPrimitive()); + } + + @Test + public void solveMethodStaticallyImportedWithoutAsterisk() throws ParseException, IOException { + CompilationUnit cu = parseSample("CompilationUnitSymbols"); + Context context = new CompilationUnitContext(cu, typeSolver); + + CombinedTypeSolver typeSolver = new CombinedTypeSolver(); + typeSolver.add(new JarTypeSolver(adaptPath("src/test/resources/junit-4.8.1.jar"))); + typeSolver.add(new ReflectionTypeSolver()); + + SymbolReference<ResolvedMethodDeclaration> ref = context.solveMethod("assertEquals", ImmutableList.of(NullType.INSTANCE, NullType.INSTANCE), false, typeSolver); + assertEquals(true, ref.isSolved()); + assertEquals("assertEquals", ref.getCorrespondingDeclaration().getName()); + assertEquals(2, ref.getCorrespondingDeclaration().getNumberOfParams()); + assertEquals("java.lang.Object", ref.getCorrespondingDeclaration().getParam(0).getType().asReferenceType().getQualifiedName()); + assertEquals("java.lang.Object", ref.getCorrespondingDeclaration().getParam(1).getType().asReferenceType().getQualifiedName()); + + } + +} diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/contexts/EnumDeclarationContextResolutionTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/contexts/EnumDeclarationContextResolutionTest.java new file mode 100644 index 000000000..93af30e48 --- /dev/null +++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/contexts/EnumDeclarationContextResolutionTest.java @@ -0,0 +1,116 @@ +/* + * 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.javaparser.contexts; + +import com.github.javaparser.ParseException; +import com.github.javaparser.ast.CompilationUnit; +import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration; +import com.github.javaparser.symbolsolver.core.resolution.Context; +import com.github.javaparser.symbolsolver.javaparser.Navigator; +import com.github.javaparser.symbolsolver.javaparsermodel.contexts.EnumDeclarationContext; +import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; +import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; +import com.github.javaparser.symbolsolver.model.resolution.Value; +import com.github.javaparser.symbolsolver.resolution.AbstractResolutionTest; +import com.github.javaparser.symbolsolver.resolution.typesolvers.MemoryTypeSolver; +import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver; +import org.junit.Before; +import org.junit.Test; + +import java.util.Optional; + +import static org.junit.Assert.assertEquals; + +/** + * @author Federico Tomassetti + */ +public class EnumDeclarationContextResolutionTest extends AbstractResolutionTest { + + private TypeSolver typeSolver; + + @Before + public void setup() { + typeSolver = new ReflectionTypeSolver(); + } + + @Test + public void solveSymbolReferringToDeclaredInstanceField() { + CompilationUnit cu = parseSample("AnEnum"); + com.github.javaparser.ast.body.EnumDeclaration enumDeclaration = Navigator.demandEnum(cu, "MyEnum"); + Context context = new EnumDeclarationContext(enumDeclaration, typeSolver); + + SymbolReference<? extends ResolvedValueDeclaration> ref = context.solveSymbol("i", new MemoryTypeSolver()); + assertEquals(true, ref.isSolved()); + assertEquals("int", ref.getCorrespondingDeclaration().getType().describe()); + } + + @Test + public void solveSymbolReferringToDeclaredStaticField() { + CompilationUnit cu = parseSample("AnEnum"); + com.github.javaparser.ast.body.EnumDeclaration enumDeclaration = Navigator.demandEnum(cu, "MyEnum"); + Context context = new EnumDeclarationContext(enumDeclaration, typeSolver); + + SymbolReference<? extends ResolvedValueDeclaration> ref = context.solveSymbol("j", new MemoryTypeSolver()); + assertEquals(true, ref.isSolved()); + assertEquals("long", ref.getCorrespondingDeclaration().getType().describe()); + } + + @Test + public void solveSymbolReferringToValue() { + CompilationUnit cu = parseSample("AnEnum"); + com.github.javaparser.ast.body.EnumDeclaration enumDeclaration = Navigator.demandEnum(cu, "MyEnum"); + Context context = new EnumDeclarationContext(enumDeclaration, typeSolver); + + SymbolReference<? extends ResolvedValueDeclaration> ref = context.solveSymbol("E1", new MemoryTypeSolver()); + assertEquals(true, ref.isSolved()); + assertEquals("MyEnum", ref.getCorrespondingDeclaration().getType().describe()); + } + + @Test + public void solveSymbolAsValueReferringToDeclaredInstanceField() { + CompilationUnit cu = parseSample("AnEnum"); + com.github.javaparser.ast.body.EnumDeclaration enumDeclaration = Navigator.demandEnum(cu, "MyEnum"); + Context context = new EnumDeclarationContext(enumDeclaration, typeSolver); + + Optional<Value> ref = context.solveSymbolAsValue("i", new MemoryTypeSolver()); + assertEquals(true, ref.isPresent()); + assertEquals("int", ref.get().getType().describe()); + } + + @Test + public void solveSymbolAsValueReferringToDeclaredStaticField() { + CompilationUnit cu = parseSample("AnEnum"); + com.github.javaparser.ast.body.EnumDeclaration enumDeclaration = Navigator.demandEnum(cu, "MyEnum"); + Context context = new EnumDeclarationContext(enumDeclaration, typeSolver); + + Optional<Value> ref = context.solveSymbolAsValue("j", new MemoryTypeSolver()); + assertEquals(true, ref.isPresent()); + assertEquals("long", ref.get().getType().describe()); + } + + @Test + public void solveSymbolAsValueReferringToValue() { + CompilationUnit cu = parseSample("AnEnum"); + com.github.javaparser.ast.body.EnumDeclaration enumDeclaration = Navigator.demandEnum(cu, "MyEnum"); + Context context = new EnumDeclarationContext(enumDeclaration, typeSolver); + + Optional<Value> ref = context.solveSymbolAsValue("E1", new MemoryTypeSolver()); + assertEquals(true, ref.isPresent()); + assertEquals("MyEnum", ref.get().getType().describe()); + } + +} diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/contexts/FieldAccessContextResolutionTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/contexts/FieldAccessContextResolutionTest.java new file mode 100644 index 000000000..b13737e51 --- /dev/null +++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/contexts/FieldAccessContextResolutionTest.java @@ -0,0 +1,51 @@ +/* + * 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.javaparser.contexts; + +import com.github.javaparser.ParseException; +import com.github.javaparser.ast.CompilationUnit; +import com.github.javaparser.ast.body.MethodDeclaration; +import com.github.javaparser.ast.expr.MethodCallExpr; +import com.github.javaparser.resolution.MethodUsage; +import com.github.javaparser.symbolsolver.javaparser.Navigator; +import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade; +import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; +import com.github.javaparser.symbolsolver.resolution.AbstractResolutionTest; +import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * @author Malte Langkabel + */ +public class FieldAccessContextResolutionTest extends AbstractResolutionTest { + + @Test + public void solveMethodCallInFieldAccessContext() { + CompilationUnit cu = parseSample("MethodCalls"); + + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "MethodCalls"); + MethodDeclaration method = Navigator.demandMethod(clazz, "bar2"); + MethodCallExpr methodCallExpr = Navigator.findMethodCall(method, "getSelf").get(); + + TypeSolver typeSolver = new ReflectionTypeSolver(); + MethodUsage methodUsage = JavaParserFacade.get(typeSolver).solveMethodAsUsage(methodCallExpr); + + assertEquals(methodUsage.getName(), "getSelf"); + } +} diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/contexts/LambdaExprContextResolutionTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/contexts/LambdaExprContextResolutionTest.java new file mode 100644 index 000000000..63e513c7a --- /dev/null +++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/contexts/LambdaExprContextResolutionTest.java @@ -0,0 +1,112 @@ +/* + * 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.javaparser.contexts; + +import com.github.javaparser.ast.CompilationUnit; +import com.github.javaparser.ast.body.MethodDeclaration; +import com.github.javaparser.ast.body.VariableDeclarator; +import com.github.javaparser.ast.expr.LambdaExpr; +import com.github.javaparser.ast.expr.MethodCallExpr; +import com.github.javaparser.ast.stmt.ReturnStmt; +import com.github.javaparser.symbolsolver.core.resolution.Context; +import com.github.javaparser.symbolsolver.javaparser.Navigator; +import com.github.javaparser.symbolsolver.javaparsermodel.contexts.LambdaExprContext; +import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; +import com.github.javaparser.symbolsolver.model.resolution.Value; +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.Before; +import org.junit.Test; + +import java.io.File; +import java.util.Optional; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * @author Malte Langkabel + */ +public class LambdaExprContextResolutionTest extends AbstractResolutionTest { + + private TypeSolver typeSolver; + + @Before + public void setup() { + typeSolver = new ReflectionTypeSolver(); + } + + @Test + public void solveParameterOfLambdaInMethodCallExpr() { + CompilationUnit cu = parseSample("Lambda"); + + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Agenda"); + MethodDeclaration method = Navigator.demandMethod(clazz, "lambdaMap"); + ReturnStmt returnStmt = Navigator.findReturnStmt(method); + MethodCallExpr methodCallExpr = (MethodCallExpr) returnStmt.getExpression().get(); + LambdaExpr lambdaExpr = (LambdaExpr) methodCallExpr.getArguments().get(0); + + Context context = new LambdaExprContext(lambdaExpr, typeSolver); + + Optional<Value> ref = context.solveSymbolAsValue("p", typeSolver); + assertTrue(ref.isPresent()); + assertEquals("? super java.lang.String", ref.get().getType().describe()); + } + + @Test + public void solveParameterOfLambdaInFieldDecl() { + CompilationUnit cu = parseSample("Lambda"); + + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Agenda"); + VariableDeclarator field = Navigator.demandField(clazz, "functional"); + LambdaExpr lambdaExpr = (LambdaExpr) field.getInitializer().get(); + + File src = new File("src/test/resources"); + CombinedTypeSolver combinedTypeSolver = new CombinedTypeSolver(); + combinedTypeSolver.add(new ReflectionTypeSolver()); + combinedTypeSolver.add(new JavaParserTypeSolver(adaptPath(src))); + + Context context = new LambdaExprContext(lambdaExpr, combinedTypeSolver); + + Optional<Value> ref = context.solveSymbolAsValue("p", typeSolver); + assertTrue(ref.isPresent()); + assertEquals("java.lang.String", ref.get().getType().describe()); + } + + @Test + public void solveParameterOfLambdaInVarDecl() { + CompilationUnit cu = parseSample("Lambda"); + + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Agenda"); + MethodDeclaration method = Navigator.demandMethod(clazz, "testFunctionalVar"); + VariableDeclarator varDecl = Navigator.demandVariableDeclaration(method, "a").get(); + LambdaExpr lambdaExpr = (LambdaExpr) varDecl.getInitializer().get(); + + File src = adaptPath(new File("src/test/resources")); + CombinedTypeSolver combinedTypeSolver = new CombinedTypeSolver(); + combinedTypeSolver.add(new ReflectionTypeSolver()); + combinedTypeSolver.add(new JavaParserTypeSolver(src)); + + Context context = new LambdaExprContext(lambdaExpr, combinedTypeSolver); + + Optional<Value> ref = context.solveSymbolAsValue("p", typeSolver); + assertTrue(ref.isPresent()); + assertEquals("java.lang.String", ref.get().getType().describe()); + } +} diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/contexts/MethodCallExprContextResolutionTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/contexts/MethodCallExprContextResolutionTest.java new file mode 100644 index 000000000..7fdaf73fd --- /dev/null +++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/contexts/MethodCallExprContextResolutionTest.java @@ -0,0 +1,126 @@ +/* + * 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.javaparser.contexts; + +import com.github.javaparser.ParseException; +import com.github.javaparser.ast.CompilationUnit; +import com.github.javaparser.ast.body.MethodDeclaration; +import com.github.javaparser.ast.expr.MethodCallExpr; +import com.github.javaparser.resolution.MethodUsage; +import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration; +import com.github.javaparser.resolution.types.ResolvedType; +import com.github.javaparser.symbolsolver.core.resolution.Context; +import com.github.javaparser.symbolsolver.javaparser.Navigator; +import com.github.javaparser.symbolsolver.javaparsermodel.contexts.MethodCallExprContext; +import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl; +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; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * @author Malte Langkabel + */ +public class MethodCallExprContextResolutionTest extends AbstractResolutionTest { + private MethodCallExpr getMethodCallExpr(String methodName, String callingMethodName) { + CompilationUnit cu = parseSample("MethodCalls"); + + com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "MethodCalls"); + MethodDeclaration method = Navigator.demandMethod(clazz, methodName); + return Navigator.findMethodCall(method, callingMethodName).get(); + } + + private CombinedTypeSolver createTypeSolver() { + File src = adaptPath(new File("src/test/resources")); + CombinedTypeSolver combinedTypeSolver = new CombinedTypeSolver(); + combinedTypeSolver.add(new ReflectionTypeSolver()); + combinedTypeSolver.add(new JavaParserTypeSolver(src)); + return combinedTypeSolver; + } + + @Test + public void solveNestedMethodCallExprContextWithoutScope() { + MethodCallExpr methodCallExpr = getMethodCallExpr("bar1", "foo"); + CombinedTypeSolver typeSolver = createTypeSolver(); + + Context context = new MethodCallExprContext(methodCallExpr, typeSolver); + + Optional<MethodUsage> ref = context.solveMethodAsUsage("foo", Collections.emptyList(), typeSolver); + assertTrue(ref.isPresent()); + assertEquals("MethodCalls", ref.get().declaringType().getQualifiedName()); + } + + @Test + public void solveGenericMethodCallMustUseProvidedTypeArgs() { + assertCanSolveGenericMethodCallMustUseProvidedTypeArgs("genericMethod0"); + } + + @Test + public void solveStaticGenericMethodCallMustUseProvidedTypeArgs() { + assertCanSolveGenericMethodCallMustUseProvidedTypeArgs("staticGenericMethod0"); + } + + private void assertCanSolveGenericMethodCallMustUseProvidedTypeArgs(String callMethodName) { + MethodCallExpr methodCallExpr = getMethodCallExpr("genericMethodTest", callMethodName); + CombinedTypeSolver typeSolver = createTypeSolver(); + + MethodCallExprContext context = new MethodCallExprContext(methodCallExpr, typeSolver); + + Optional<MethodUsage> ref = context.solveMethodAsUsage(callMethodName, Collections.emptyList(), typeSolver); + assertTrue(ref.isPresent()); + assertEquals("MethodCalls", ref.get().declaringType().getQualifiedName()); + assertEquals(Collections.singletonList("java.lang.Integer"), ref.get().typeParametersMap().getTypes().stream().map(ty -> ty.asReferenceType().describe()).collect(Collectors.toList())); + } + + @Test + public void solveGenericMethodCallCanInferFromArguments() { + assertCanSolveGenericMethodCallCanInferFromArguments("genericMethod1"); + } + + @Test + public void solveStaticGenericMethodCallCanInferFromArguments() { + assertCanSolveGenericMethodCallCanInferFromArguments("staticGenericMethod1"); + } + + private void assertCanSolveGenericMethodCallCanInferFromArguments(String callMethodName) { + MethodCallExpr methodCallExpr = getMethodCallExpr("genericMethodTest", callMethodName); + CombinedTypeSolver typeSolver = createTypeSolver(); + + MethodCallExprContext context = new MethodCallExprContext(methodCallExpr, typeSolver); + + ResolvedReferenceTypeDeclaration stringType = typeSolver.solveType("java.lang.String"); + + List<ResolvedType> argumentsTypes = new ArrayList<>(); + argumentsTypes.add(new ReferenceTypeImpl(stringType, typeSolver)); + + Optional<MethodUsage> ref = context.solveMethodAsUsage(callMethodName, argumentsTypes, typeSolver); + assertTrue(ref.isPresent()); + assertEquals("MethodCalls", ref.get().declaringType().getQualifiedName()); + assertEquals(Collections.singletonList("java.lang.String"), ref.get().typeParametersMap().getTypes().stream().map(ty -> ty.asReferenceType().describe()).collect(Collectors.toList())); + } +} diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/contexts/MethodContextResolutionTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/contexts/MethodContextResolutionTest.java new file mode 100644 index 000000000..17d978079 --- /dev/null +++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/contexts/MethodContextResolutionTest.java @@ -0,0 +1,59 @@ +/* + * 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.javaparser.contexts; + +import com.github.javaparser.ParseException; +import com.github.javaparser.ast.CompilationUnit; +import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; +import com.github.javaparser.ast.body.MethodDeclaration; +import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration; +import com.github.javaparser.symbolsolver.core.resolution.Context; +import com.github.javaparser.symbolsolver.javaparser.Navigator; +import com.github.javaparser.symbolsolver.javaparsermodel.contexts.MethodContext; +import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; +import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; +import com.github.javaparser.symbolsolver.resolution.AbstractResolutionTest; +import com.github.javaparser.symbolsolver.resolution.typesolvers.MemoryTypeSolver; +import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * @author Malte Langkabel + */ +public class MethodContextResolutionTest extends AbstractResolutionTest { + + private TypeSolver typeSolver; + + @Before + public void setup() { + typeSolver = new ReflectionTypeSolver(); + } + + @Test + public void solveTypeRefToLocalClass() { + CompilationUnit cu = parseSample("MethodWithTypes"); + ClassOrInterfaceDeclaration cd = Navigator.demandClass(cu, "Main"); + MethodDeclaration md = Navigator.demandMethod(cd, "methodWithLocalTypes"); + Context context = new MethodContext(md, typeSolver); + + SymbolReference<ResolvedTypeDeclaration> ref = context.solveType("LocalClass", new MemoryTypeSolver()); + assertEquals(true, ref.isSolved()); + } +} diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/declarations/JavaParserTypeParameterResolutionTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/declarations/JavaParserTypeParameterResolutionTest.java new file mode 100644 index 000000000..c72e7727f --- /dev/null +++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/declarations/JavaParserTypeParameterResolutionTest.java @@ -0,0 +1,100 @@ +/* + * 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.javaparser.declarations; + +import com.github.javaparser.ParseException; +import com.github.javaparser.ast.CompilationUnit; +import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; +import com.github.javaparser.ast.body.MethodDeclaration; +import com.github.javaparser.ast.expr.MethodCallExpr; +import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration; +import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration; +import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration; +import com.github.javaparser.symbolsolver.javaparser.Navigator; +import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade; +import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeParameter; +import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; +import com.github.javaparser.symbolsolver.resolution.AbstractResolutionTest; +import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class JavaParserTypeParameterResolutionTest extends AbstractResolutionTest { + + private void testGenericArguments(String containingMethodName) { + CompilationUnit cu = parseSample("GenericMethodArguments"); + TypeSolver typeSolver = new ReflectionTypeSolver(); + JavaParserFacade javaParserFacade = JavaParserFacade.get(typeSolver); + ClassOrInterfaceDeclaration classDecl = Navigator.demandClass(cu, "GenericMethodArguments"); + MethodDeclaration containingMethod = Navigator.demandMethod(classDecl, containingMethodName); + MethodCallExpr bar = Navigator.findMethodCall(containingMethod, "apply").get(); + + assertTrue(javaParserFacade.solve(bar).isSolved()); + } + + @Test + public void genericMethodWithGenericClassBasedArgument() { + testGenericArguments("useCase1"); + } + + @Test + public void genericMethodWithGenericClassArgument() { + testGenericArguments("useCase2"); + } + + @Test + public void declaredOnMethodPositiveCase() { + CompilationUnit cu = parseSample("MethodTypeParameter"); + TypeSolver typeSolver = new ReflectionTypeSolver(); + JavaParserFacade javaParserFacade = JavaParserFacade.get(typeSolver); + ClassOrInterfaceDeclaration classDecl = Navigator.demandClass(cu, "Foo"); + MethodDeclaration methodDecl = Navigator.demandMethod(classDecl, "usage"); + MethodCallExpr callToFoo = (MethodCallExpr) Navigator.findReturnStmt(methodDecl).getExpression().get(); + ResolvedMethodDeclaration methodDeclaration = javaParserFacade.solve(callToFoo).getCorrespondingDeclaration(); + for (ResolvedTypeParameterDeclaration tp : methodDeclaration.getTypeParameters()) { + assertTrue(tp instanceof JavaParserTypeParameter); + assertEquals("C", tp.getName()); + assertEquals(true, tp.declaredOnMethod()); + assertEquals(false, tp.declaredOnType()); + } + } + + @Test + public void declaredOnMethodNegativeCase() { + CompilationUnit cu = parseSample("ClassTypeParameter"); + TypeSolver typeSolver = new ReflectionTypeSolver(); + JavaParserFacade javaParserFacade = JavaParserFacade.get(typeSolver); + ClassOrInterfaceDeclaration classDecl = Navigator.demandClass(cu, "Foo"); + MethodDeclaration methodDecl = Navigator.demandMethod(classDecl, "usage"); + MethodCallExpr callToFoo = (MethodCallExpr) Navigator.findReturnStmt(methodDecl).getExpression().get(); + ResolvedMethodDeclaration methodDeclaration = javaParserFacade.solve(callToFoo).getCorrespondingDeclaration(); + ResolvedReferenceTypeDeclaration typeDeclaration = methodDeclaration.declaringType(); + assertEquals(2, typeDeclaration.getTypeParameters().size()); + assertTrue(typeDeclaration.getTypeParameters().get(0) instanceof JavaParserTypeParameter); + assertEquals("A", typeDeclaration.getTypeParameters().get(0).getName()); + assertEquals(false, typeDeclaration.getTypeParameters().get(0).declaredOnMethod()); + assertEquals(true, typeDeclaration.getTypeParameters().get(0).declaredOnType()); + assertTrue(typeDeclaration.getTypeParameters().get(1) instanceof JavaParserTypeParameter); + assertEquals("B", typeDeclaration.getTypeParameters().get(1).getName()); + assertEquals(false, typeDeclaration.getTypeParameters().get(1).declaredOnMethod()); + assertEquals(true, typeDeclaration.getTypeParameters().get(1).declaredOnType()); + + } + +} diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/reflectionmodel/SymbolResolutionResolutionTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/reflectionmodel/SymbolResolutionResolutionTest.java new file mode 100644 index 000000000..8e0989f24 --- /dev/null +++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/reflectionmodel/SymbolResolutionResolutionTest.java @@ -0,0 +1,86 @@ +/* + * 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.reflectionmodel; + +import com.github.javaparser.ParseException; +import com.github.javaparser.ast.CompilationUnit; +import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; +import com.github.javaparser.ast.body.MethodDeclaration; +import com.github.javaparser.ast.body.VariableDeclarator; +import com.github.javaparser.ast.expr.Expression; +import com.github.javaparser.ast.expr.MethodCallExpr; +import com.github.javaparser.ast.stmt.ReturnStmt; +import com.github.javaparser.resolution.types.ResolvedType; +import com.github.javaparser.symbolsolver.javaparser.Navigator; +import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade; +import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; +import com.github.javaparser.symbolsolver.resolution.AbstractResolutionTest; +import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class SymbolResolutionResolutionTest extends AbstractResolutionTest { + + @Test + public void getTypeOfField() { + CompilationUnit cu = parseSample("ReflectionFieldOfItself"); + ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "MyClass"); + VariableDeclarator field = Navigator.demandField(clazz, "PUBLIC"); + + TypeSolver typeSolver = new ReflectionTypeSolver(); + ResolvedType ref = JavaParserFacade.get(typeSolver).getType(field); + assertEquals("int", ref.describe()); + } + + @Test + public void getTypeOfFieldAccess() { + CompilationUnit cu = parseSample("ReflectionFieldOfItself"); + ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "MyClass"); + VariableDeclarator field = Navigator.demandField(clazz, "PUBLIC"); + + TypeSolver typeSolver = new ReflectionTypeSolver(); + ResolvedType ref = JavaParserFacade.get(typeSolver).getType(field.getInitializer().get()); + assertEquals("int", ref.describe()); + } + + @Test + public void conditionalExpressionExample() { + CompilationUnit cu = parseSample("JreConditionalExpression"); + ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "MyClass"); + MethodDeclaration method = Navigator.demandMethod(clazz, "foo1"); + ReturnStmt returnStmt = Navigator.findReturnStmt(method); + Expression expression = returnStmt.getExpression().get(); + + TypeSolver typeSolver = new ReflectionTypeSolver(); + ResolvedType ref = JavaParserFacade.get(typeSolver).getType(expression); + assertEquals("java.lang.String", ref.describe()); + } + + @Test + public void conditionalExpressionExampleFollowUp1() { + CompilationUnit cu = parseSample("JreConditionalExpression"); + ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "MyClass"); + MethodDeclaration method = Navigator.demandMethod(clazz, "foo1"); + MethodCallExpr expression = Navigator.findMethodCall(method, "next").get(); + + TypeSolver typeSolver = new ReflectionTypeSolver(); + ResolvedType ref = JavaParserFacade.get(typeSolver).getType(expression); + assertEquals("java.lang.String", ref.describe()); + } + +} diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/typeinference/bounds/SameAsBoundTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/typeinference/bounds/SameAsBoundTest.java new file mode 100644 index 000000000..ba58dc797 --- /dev/null +++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/typeinference/bounds/SameAsBoundTest.java @@ -0,0 +1,32 @@ +package com.github.javaparser.symbolsolver.resolution.typeinference.bounds; + +import com.github.javaparser.resolution.types.ResolvedType; +import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; +import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl; +import com.github.javaparser.symbolsolver.resolution.typeinference.Bound; +import com.github.javaparser.symbolsolver.resolution.typeinference.InferenceVariable; +import com.github.javaparser.symbolsolver.resolution.typeinference.Instantiation; +import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver; +import org.junit.Test; + +import java.util.Optional; + +import static org.junit.Assert.assertEquals; + +public class SameAsBoundTest { + + private TypeSolver typeSolver = new ReflectionTypeSolver(); + private ResolvedType stringType = new ReferenceTypeImpl(new ReflectionTypeSolver().solveType(String.class.getCanonicalName()), typeSolver); + + @Test + public void recognizeInstantiation() { + // { α = String } contains a single bound, instantiating α as String. + InferenceVariable inferenceVariable = new InferenceVariable("α", null); + Bound bound1 = new SameAsBound(inferenceVariable, stringType); + Bound bound2 = new SameAsBound(stringType, inferenceVariable); + + assertEquals(Optional.of(new Instantiation(inferenceVariable, stringType)), bound1.isAnInstantiation()); + assertEquals(Optional.of(new Instantiation(inferenceVariable, stringType)), bound2.isAnInstantiation()); + } + +} diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/typeinference/bounds/SubtypeOfBoundTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/typeinference/bounds/SubtypeOfBoundTest.java new file mode 100644 index 000000000..ecda07701 --- /dev/null +++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/typeinference/bounds/SubtypeOfBoundTest.java @@ -0,0 +1,86 @@ +package com.github.javaparser.symbolsolver.resolution.typeinference.bounds; + +import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration; +import com.github.javaparser.resolution.types.ResolvedReferenceType; +import com.github.javaparser.resolution.types.ResolvedType; +import com.github.javaparser.resolution.types.ResolvedWildcard; +import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; +import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl; +import com.github.javaparser.symbolsolver.resolution.typeinference.*; +import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver; +import org.junit.Test; + +import java.util.Arrays; +import java.util.List; +import java.util.Optional; + +import static com.github.javaparser.symbolsolver.resolution.typeinference.TypeHelper.isProperType; +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; + +public class SubtypeOfBoundTest { + + private TypeSolver typeSolver = new ReflectionTypeSolver(); + private ResolvedReferenceType iterableType = new ReferenceTypeImpl(new ReflectionTypeSolver().solveType(Iterable.class.getCanonicalName()), typeSolver); + private ResolvedReferenceType listType = new ReferenceTypeImpl(new ReflectionTypeSolver().solveType(List.class.getCanonicalName()), typeSolver); + private ResolvedType integerType = new ReferenceTypeImpl(new ReflectionTypeSolver().solveType(Integer.class.getCanonicalName()), typeSolver); + private ResolvedType doubleType = new ReferenceTypeImpl(new ReflectionTypeSolver().solveType(Double.class.getCanonicalName()), typeSolver); + private ResolvedType objectType = new ReferenceTypeImpl(new ReflectionTypeSolver().solveType(Object.class.getCanonicalName()), typeSolver); + + @Test + public void recognizeProperLowerBound1() { + ResolvedTypeParameterDeclaration typeParameterDeclaration = mock(ResolvedTypeParameterDeclaration.class); + + // { Integer <: α, Double <: α, α <: Object } describes two proper lower bounds and one proper upper bound for α. + + InferenceVariable inferenceVariable = new InferenceVariable("α", typeParameterDeclaration); + Bound bound = new SubtypeOfBound(integerType, inferenceVariable); + + assertEquals(Optional.of(new ProperLowerBound(inferenceVariable, integerType)), bound.isProperLowerBound()); + } + + @Test + public void recognizeProperLowerBound2() { + ResolvedTypeParameterDeclaration typeParameterDeclaration = mock(ResolvedTypeParameterDeclaration.class); + + // { Integer <: α, Double <: α, α <: Object } describes two proper lower bounds and one proper upper bound for α. + + InferenceVariable inferenceVariable = new InferenceVariable("α", typeParameterDeclaration); + Bound bound = new SubtypeOfBound(doubleType, inferenceVariable); + + assertEquals(Optional.of(new ProperLowerBound(inferenceVariable, doubleType)), bound.isProperLowerBound()); + } + + @Test + public void recognizeProperUpperBound1() { + ResolvedTypeParameterDeclaration typeParameterDeclaration = mock(ResolvedTypeParameterDeclaration.class); + + // { Integer <: α, Double <: α, α <: Object } describes two proper lower bounds and one proper upper bound for α. + + InferenceVariable inferenceVariable = new InferenceVariable("α", typeParameterDeclaration); + Bound bound = new SubtypeOfBound(inferenceVariable, objectType); + + assertEquals(Optional.of(new ProperUpperBound(inferenceVariable, objectType)), bound.isProperUpperBound()); + } + + @Test + public void recognizeProperUpperBound2() { + ResolvedTypeParameterDeclaration typeParameterDeclaration1 = mock(ResolvedTypeParameterDeclaration.class); + ResolvedTypeParameterDeclaration typeParameterDeclaration2 = mock(ResolvedTypeParameterDeclaration.class); + // { α <: Iterable<?>, β <: Object, α <: List<β> } describes a proper upper bound for each of α and β, along with a dependency between them. + + InferenceVariable alpha = new InferenceVariable("α", typeParameterDeclaration1); + InferenceVariable beta = new InferenceVariable("β", typeParameterDeclaration2); + ResolvedType iterableOfWildcard = new ReferenceTypeImpl(iterableType.getTypeDeclaration(), Arrays.asList(ResolvedWildcard.UNBOUNDED), typeSolver); + ResolvedType listOfBeta = new ReferenceTypeImpl(listType.getTypeDeclaration(), Arrays.asList(beta), typeSolver); + + Bound bound1 = new SubtypeOfBound(alpha, iterableOfWildcard); + Bound bound2 = new SubtypeOfBound(beta, objectType); + Bound bound3 = new SubtypeOfBound(alpha, listOfBeta); + + assertEquals(false, isProperType(listOfBeta)); + assertEquals(Optional.of(new ProperUpperBound(alpha, iterableOfWildcard)), bound1.isProperUpperBound()); + assertEquals(Optional.of(new ProperUpperBound(beta, objectType)), bound2.isProperUpperBound()); + assertEquals(true, bound3.isADependency()); + } +} diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/typeinference/constraintformulas/ConstraintFormulaTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/typeinference/constraintformulas/ConstraintFormulaTest.java new file mode 100644 index 000000000..0563ca5b3 --- /dev/null +++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/typeinference/constraintformulas/ConstraintFormulaTest.java @@ -0,0 +1,70 @@ +package com.github.javaparser.symbolsolver.resolution.typeinference.constraintformulas; + +import com.github.javaparser.ast.expr.Expression; +import com.github.javaparser.ast.expr.StringLiteralExpr; +import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration; +import com.github.javaparser.resolution.types.ResolvedType; +import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; +import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl; +import com.github.javaparser.symbolsolver.resolution.typeinference.BoundSet; +import com.github.javaparser.symbolsolver.resolution.typeinference.ConstraintFormula; +import com.github.javaparser.symbolsolver.resolution.typeinference.InferenceVariable; +import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; + +public class ConstraintFormulaTest { + + private TypeSolver typeSolver = new ReflectionTypeSolver(); + private ResolvedType stringType = new ReferenceTypeImpl(new ReflectionTypeSolver().solveType(String.class.getCanonicalName()), typeSolver); + + /** + * From JLS 18.1.2 + * + * From Collections.singleton("hi"), we have the constraint formula ‹"hi" → α›. + * Through reduction, this will become the constraint formula: ‹String <: α›. + */ + @Test + public void testExpressionCompatibleWithTypeReduce1() { + ResolvedTypeParameterDeclaration tp = mock(ResolvedTypeParameterDeclaration.class); + + Expression e = new StringLiteralExpr("hi"); + InferenceVariable inferenceVariable = new InferenceVariable("α", tp); + + ExpressionCompatibleWithType formula = new ExpressionCompatibleWithType(typeSolver, e, inferenceVariable); + + ConstraintFormula.ReductionResult res1 = formula.reduce(BoundSet.empty()); + assertEquals( + ConstraintFormula.ReductionResult.empty().withConstraint(new TypeCompatibleWithType(typeSolver, stringType, inferenceVariable)), + res1); + + assertEquals( + ConstraintFormula.ReductionResult.empty().withConstraint(new TypeSubtypeOfType(typeSolver, stringType, inferenceVariable)), + res1.getConstraint(0).reduce(BoundSet.empty())); + } + +// /** +// * From JLS 18.1.2 +// * +// * From Arrays.asList(1, 2.0), we have the constraint formulas ‹1 → α› and ‹2.0 → α›. Through reduction, +// * these will become the constraint formulas ‹int → α› and ‹double → α›, and then ‹Integer <: α› and ‹Double <: α›. +// */ +// @Test +// public void testExpressionCompatibleWithTypeReduce2() { +// throw new UnsupportedOperationException(); +// } +// +// /** +// * From JLS 18.1.2 +// * +// * From the target type of the constructor invocation List<Thread> lt = new ArrayList<>(), we have the constraint +// * formula ‹ArrayList<α> → List<Thread>›. Through reduction, this will become the constraint formula ‹α <= Thread›, +// * and then ‹α = Thread›. +// */ +// @Test +// public void testExpressionCompatibleWithTypeReduce3() { +// throw new UnsupportedOperationException(); +// } +} diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/typesolvers/AarTypeSolverTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/typesolvers/AarTypeSolverTest.java new file mode 100644 index 000000000..b9be96899 --- /dev/null +++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/typesolvers/AarTypeSolverTest.java @@ -0,0 +1,43 @@ +/* + * 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.symbolsolver.AbstractTest; +import org.junit.Test; + +import java.io.File; +import java.io.IOException; + +import static org.junit.Assert.assertEquals; + +public class AarTypeSolverTest extends AbstractTest { + + @Test + public void initial() throws IOException { + String pathToJar = adaptPath("src/test/resources/aars/support-compat-24.2.0.aar"); + AarTypeSolver aarTypeSolver = new AarTypeSolver(new File(pathToJar)); + assertEquals(true, aarTypeSolver.tryToSolveType("android.support.v4.app.ActivityCompat").isSolved()); + assertEquals(true, aarTypeSolver.tryToSolveType("android.support.v4.app.ActivityManagerCompat").isSolved()); + assertEquals(true, aarTypeSolver.tryToSolveType("android.support.v4.app.NotificationCompat").isSolved()); + assertEquals(true, aarTypeSolver.tryToSolveType("android.support.v4.app.NotificationCompat.Action").isSolved()); + assertEquals(true, aarTypeSolver.tryToSolveType("android.support.v4.app.NotificationCompat.Action.Builder").isSolved()); + assertEquals(false, aarTypeSolver.tryToSolveType("com.github.javaparser.ASTParser.Foo").isSolved()); + assertEquals(false, aarTypeSolver.tryToSolveType("com.github.javaparser.Foo").isSolved()); + assertEquals(false, aarTypeSolver.tryToSolveType("Foo").isSolved()); + } + +} diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/typesolvers/JarTypeSolverTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/typesolvers/JarTypeSolverTest.java new file mode 100644 index 000000000..346fcfd60 --- /dev/null +++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/typesolvers/JarTypeSolverTest.java @@ -0,0 +1,41 @@ +/* + * 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.symbolsolver.AbstractTest; +import org.junit.Test; + +import java.io.IOException; + +import static org.junit.Assert.assertEquals; + + +public class JarTypeSolverTest extends AbstractTest { + + @Test + public void initial() throws IOException { + String pathToJar = adaptPath("src/test/resources/javaparser-core-2.1.0.jar"); + JarTypeSolver jarTypeSolver = new JarTypeSolver(pathToJar); + assertEquals(true, jarTypeSolver.tryToSolveType("com.github.javaparser.SourcesHelper").isSolved()); + assertEquals(true, jarTypeSolver.tryToSolveType("com.github.javaparser.Token").isSolved()); + assertEquals(true, jarTypeSolver.tryToSolveType("com.github.javaparser.ASTParser.JJCalls").isSolved()); + assertEquals(false, jarTypeSolver.tryToSolveType("com.github.javaparser.ASTParser.Foo").isSolved()); + assertEquals(false, jarTypeSolver.tryToSolveType("com.github.javaparser.Foo").isSolved()); + assertEquals(false, jarTypeSolver.tryToSolveType("Foo").isSolved()); + } + +} |