diff --git a/javaparser-symbol-solver-core/pom.xml b/javaparser-symbol-solver-core/pom.xml deleted file mode 100644 index c07194d..0000000 --- a/javaparser-symbol-solver-core/pom.xml +++ /dev/null @@ -1,69 +0,0 @@ - - - - sdg - es.upv.mist.slicing - 1.3.0 - - 4.0.0 - - javaparser-symbol-solver-core - com.github.javaparser - 3.23.2 - jar - A Symbol Solver for Java, built on top of JavaParser (core) - - - - GNU Lesser General Public License - http://www.gnu.org/licenses/lgpl-3.0.html - repo - - - Apache License, Version 2.0 - http://www.apache.org/licenses/LICENSE-2.0.txt - repo - A business-friendly OSS license - - - - - 1.8 - ${maven.build.timestamp} - - - - - com.github.javaparser - javaparser-core - 3.23.1 - - - org.javassist - javassist - 3.28.0-GA - - - com.google.guava - guava - 31.0.1-jre - - - - - - - - org.apache.maven.plugins - maven-jar-plugin - - - - com.github.javaparser.symbolsolver.core - - - - - - - diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/core/package-info.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/core/package-info.java deleted file mode 100644 index 2755f8f..0000000 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/core/package-info.java +++ /dev/null @@ -1 +0,0 @@ -package com.github.javaparser.symbolsolver.core; \ No newline at end of file diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/core/resolution/Context.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/core/resolution/Context.java deleted file mode 100644 index 821ec7d..0000000 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/core/resolution/Context.java +++ /dev/null @@ -1,381 +0,0 @@ -/* - * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. - * - * This file is part of JavaParser. - * - * JavaParser can be used either under the terms of - * a) the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * b) the terms of the Apache License - * - * You should have received a copy of both licenses in LICENCE.LGPL and - * LICENCE.APACHE. Please refer to those files for details. - * - * JavaParser is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - */ - -package com.github.javaparser.symbolsolver.core.resolution; - -import com.github.javaparser.ast.Node; -import com.github.javaparser.ast.body.Parameter; -import com.github.javaparser.ast.body.VariableDeclarator; -import com.github.javaparser.ast.expr.PatternExpr; -import com.github.javaparser.resolution.MethodUsage; -import com.github.javaparser.resolution.declarations.*; -import com.github.javaparser.resolution.types.ResolvedType; -import com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext; -import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; -import com.github.javaparser.symbolsolver.model.resolution.Value; - -import java.util.Collections; -import java.util.List; -import java.util.Optional; - -/** - * Context is very similar to scope. - * In the context we look for solving symbols. - * - * @author Federico Tomassetti - */ -public interface Context { - - /** - * @return The parent context, if there is one. For example, a method exists within a compilation unit. - */ - Optional getParent(); - - - /* Type resolution */ - - /** - * Default to no generics available in this context, delegating solving to the parent context. - * Contexts which have generics available to it will override this method. - * For example class and method declarations, and method calls. - * - * @param name For example, solving {@code T} within {@code class Foo {}} or - * @return The resolved generic type, if found. - */ - default Optional solveGenericType(String name) { - // Default to solving within the parent context. - return solveGenericTypeInParentContext(name); - } - - default Optional solveGenericTypeInParentContext(String name) { - Optional optionalParentContext = getParent(); - if (!optionalParentContext.isPresent()) { - return Optional.empty(); - } - - // Delegate solving to the parent context. - return optionalParentContext.get().solveGenericType(name); - } - - /** - * Default to being unable to solve any reference in this context, delegating solving to the parent context. - * Contexts which exist as the "parent" of a resolvable type will override this method. - * For example, a compilation unit can contain classes. A class declaration can also contain types (e.g. a subclass). - * - * @param name For example, solving {@code List} or {@code java.util.List}. - * @return The declaration associated with the given type name. - */ - default SymbolReference solveType(String name) { - // Default to solving within the parent context. - return solveTypeInParentContext(name); - } - - default SymbolReference solveTypeInParentContext(String name) { - Optional optionalParentContext = getParent(); - if (!optionalParentContext.isPresent()) { - return SymbolReference.unsolved(ResolvedReferenceTypeDeclaration.class); - } - - // Delegate solving to the parent context. - return optionalParentContext.get().solveType(name); - } - - /* Symbol resolution */ - - /** - * Used where a symbol is being used (e.g. solving {@code x} when used as an argument {@code doubleThis(x)}, or calculation {@code return x * 2;}). - * @param name the variable / reference / identifier used. - * @return // FIXME: Better documentation on how this is different to solveSymbolAsValue() - */ - default SymbolReference solveSymbol(String name) { - // Default to solving within the parent context. - return solveSymbolInParentContext(name); - } - - default SymbolReference solveSymbolInParentContext(String name) { - Optional optionalParentContext = getParent(); - if (!optionalParentContext.isPresent()) { - return SymbolReference.unsolved(ResolvedValueDeclaration.class); - } - - // Delegate solving to the parent context. - return optionalParentContext.get().solveSymbol(name); - } - - /** - * Used where a symbol is being used (e.g. solving {@code x} when used as an argument {@code doubleThis(x)}, or calculation {@code return x * 2;}). - * @param name the variable / reference / identifier used. - * @return // FIXME: Better documentation on how this is different to solveSymbol() - */ - default Optional solveSymbolAsValue(String name) { - SymbolReference ref = solveSymbol(name); - if (!ref.isSolved()) { - return Optional.empty(); - } - - return Optional.of(Value.from(ref.getCorrespondingDeclaration())); - } - - default Optional solveSymbolAsValueInParentContext(String name) { - SymbolReference ref = solveSymbolInParentContext(name); - if (!ref.isSolved()) { - return Optional.empty(); - } - - return Optional.of(Value.from(ref.getCorrespondingDeclaration())); - } - - - /** - * The fields that are declared and in this immediate context made visible to a given child. - * This list could include values which are shadowed. - */ - default List fieldsExposedToChild(Node child) { - return Collections.emptyList(); - } - - /** - * The local variables that are declared in this immediate context and made visible to a given child. - * This list could include values which are shadowed. - */ - default List localVariablesExposedToChild(Node child) { - return Collections.emptyList(); - } - - /** - * The parameters that are declared in this immediate context and made visible to a given child. - * This list could include values which are shadowed. - */ - default List parametersExposedToChild(Node child) { - return Collections.emptyList(); - } - - /** - * The pattern expressions that are declared in this immediate context and made visible to a given child. - * This list could include values which are shadowed. - */ - default List patternExprsExposedToChild(Node child) { - return Collections.emptyList(); - } - - /** - */ - default List patternExprsExposedFromChildren() { - return Collections.emptyList(); - } - - /** - */ - default List negatedPatternExprsExposedFromChildren() { - return Collections.emptyList(); - } - - /** - * Aim to resolve the given name by looking for a variable matching it. - *

- * To do it consider local variables that are visible in a certain scope as defined in JLS 6.3. Scope of a - * Declaration. - *

- * 1. The scope of a local variable declaration in a block (§14.4) is the rest of the block in which the - * declaration - * appears, starting with its own initializer and including any further declarators to the right in the local - * variable declaration statement. - *

- * 2. The scope of a local variable declared in the ForInit part of a basic for statement (§14.14.1) includes all - * of the following: - * 2.1 Its own initializer - * 2.2 Any further declarators to the right in the ForInit part of the for statement - * 2.3 The Expression and ForUpdate parts of the for statement - * 2.4 The contained Statement - *

- * 3. The scope of a local variable declared in the FormalParameter part of an enhanced for statement (§14.14.2) is - * the contained Statement. - * 4. The scope of a parameter of an exception handler that is declared in a catch clause of a try statement - * (§14.20) is the entire block associated with the catch. - *

- * 5. The scope of a variable declared in the ResourceSpecification of a try-with-resources statement (§14.20.3) is - * from the declaration rightward over the remainder of the ResourceSpecification and the entire try block - * associated with the try-with-resources statement. - */ - default Optional localVariableDeclarationInScope(String name) { - if (!getParent().isPresent()) { - return Optional.empty(); - } - - // First check if the variable is directly declared within this context. - Node wrappedNode = ((AbstractJavaParserContext) this).getWrappedNode(); - Context parentContext = getParent().get(); - Optional localResolutionResults = parentContext - .localVariablesExposedToChild(wrappedNode) - .stream() - .filter(vd -> vd.getNameAsString().equals(name)) - .findFirst(); - - if (localResolutionResults.isPresent()) { - return localResolutionResults; - } - - - // If we don't find the variable locally, escalate up the scope hierarchy to see if it is declared there. - return parentContext.localVariableDeclarationInScope(name); - } - - default Optional parameterDeclarationInScope(String name) { - if (!getParent().isPresent()) { - return Optional.empty(); - } - - // First check if the parameter is directly declared within this context. - Node wrappedNode = ((AbstractJavaParserContext) this).getWrappedNode(); - Context parentContext = getParent().get(); - Optional localResolutionResults = parentContext - .parametersExposedToChild(wrappedNode) - .stream() - .filter(vd -> vd.getNameAsString().equals(name)) - .findFirst(); - - if (localResolutionResults.isPresent()) { - return localResolutionResults; - } - - // If we don't find the parameter locally, escalate up the scope hierarchy to see if it is declared there. - return parentContext.parameterDeclarationInScope(name); - } - - - /** - * With respect to solving, the AST "parent" of a block statement is not necessarily the same as the scope parent. - *
Example: - *
- *

{@code
-     *  public String x() {
-     *      if(x) {
-     *          // Parent node: the block attached to the method declaration
-     *          // Scope-parent: the block attached to the method declaration
-     *      } else if {
-     *          // Parent node: the if
-     *          // Scope-parent: the block attached to the method declaration
-     *      } else {
-     *          // Parent node: the elseif
-     *          // Scope-parent: the block attached to the method declaration
-     *      }
-     *  }
-     * }
- */ - default Optional patternExprInScope(String name) { - if (!getParent().isPresent()) { - return Optional.empty(); - } - Context parentContext = getParent().get(); - - // FIXME: "scroll backwards" from the wrapped node - // FIXME: If there are multiple patterns, throw an error? - - // First check if the pattern is directly declared within this context. - Node wrappedNode = ((AbstractJavaParserContext) this).getWrappedNode(); - Optional localResolutionResults = parentContext - .patternExprsExposedToChild(wrappedNode) - .stream() - .filter(vd -> vd.getNameAsString().equals(name)) - .findFirst(); - - if (localResolutionResults.isPresent()) { - return localResolutionResults; - } - - // If we don't find the parameter locally, escalate up the scope hierarchy to see if it is declared there. - return parentContext.patternExprInScope(name); - } - - default Optional fieldDeclarationInScope(String name) { - if (!getParent().isPresent()) { - return Optional.empty(); - } - Context parentContext = getParent().get(); - // First check if the parameter is directly declared within this context. - Node wrappedNode = ((AbstractJavaParserContext) this).getWrappedNode(); - Optional localResolutionResults = parentContext - .fieldsExposedToChild(wrappedNode) - .stream() - .filter(vd -> vd.getName().equals(name)) - .findFirst(); - - if (localResolutionResults.isPresent()) { - return localResolutionResults; - } - - // If we don't find the field locally, escalate up the scope hierarchy to see if it is declared there. - return parentContext.fieldDeclarationInScope(name); - } - - - /* Constructor resolution */ - - /** - * We find the method declaration which is the best match for the given name and list of typeParametersValues. - */ - default SymbolReference solveConstructor(List argumentsTypes) { - throw new IllegalArgumentException("Constructor resolution is available only on Class Context"); - } - - /* Methods resolution */ - - /** - * We find the method declaration which is the best match for the given name and list of typeParametersValues. - */ - default SymbolReference solveMethod(String name, List argumentsTypes, boolean staticOnly) { - // Default to solving within the parent context. - return solveMethodInParentContext(name, argumentsTypes, staticOnly); - } - - default SymbolReference solveMethodInParentContext(String name, List argumentsTypes, boolean staticOnly) { - Optional optionalParentContext = getParent(); - if (!optionalParentContext.isPresent()) { - return SymbolReference.unsolved(ResolvedMethodDeclaration.class); - } - - // Delegate solving to the parent context. - return optionalParentContext.get().solveMethod(name, argumentsTypes, staticOnly); - } - - /** - * Similar to solveMethod but we return a MethodUsage. - * A MethodUsage corresponds to a MethodDeclaration plus the resolved type variables. - */ - default Optional solveMethodAsUsage(String name, List argumentsTypes) { - SymbolReference methodSolved = solveMethod(name, argumentsTypes, false); - if (methodSolved.isSolved()) { - ResolvedMethodDeclaration methodDeclaration = methodSolved.getCorrespondingDeclaration(); - if (!(methodDeclaration instanceof TypeVariableResolutionCapability)) { - throw new UnsupportedOperationException(String.format( - "Resolved method declarations must implement %s.", - TypeVariableResolutionCapability.class.getName() - )); - } - - MethodUsage methodUsage = ((TypeVariableResolutionCapability) methodDeclaration).resolveTypeVariables(this, argumentsTypes); - return Optional.of(methodUsage); - } else { - return Optional.empty(); - } - } - -} diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparser/Navigator.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparser/Navigator.java deleted file mode 100644 index b0a46db..0000000 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparser/Navigator.java +++ /dev/null @@ -1,269 +0,0 @@ -/* - * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. - * - * This file is part of JavaParser. - * - * JavaParser can be used either under the terms of - * a) the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * b) the terms of the Apache License - * - * You should have received a copy of both licenses in LICENCE.LGPL and - * LICENCE.APACHE. Please refer to those files for details. - * - * JavaParser is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - */ - -package com.github.javaparser.symbolsolver.javaparser; - -import com.github.javaparser.ast.CompilationUnit; -import com.github.javaparser.ast.Node; -import com.github.javaparser.ast.body.*; -import com.github.javaparser.ast.expr.MethodCallExpr; -import com.github.javaparser.ast.expr.NameExpr; -import com.github.javaparser.ast.expr.SimpleName; -import com.github.javaparser.ast.stmt.ReturnStmt; -import com.github.javaparser.ast.stmt.SwitchStmt; - -import java.util.Optional; - -/** - * This class can be used to easily retrieve nodes from a JavaParser AST. - * - * Note that methods with the prefix `demand` indicate that if the search value is not found, an exception will be thrown. - * - * @author Federico Tomassetti - */ -public final class Navigator { - - private Navigator() { - // prevent instantiation - } - - public static ClassOrInterfaceDeclaration demandClass(CompilationUnit cu, String qualifiedName) { - ClassOrInterfaceDeclaration cd = demandClassOrInterface(cu, qualifiedName); - if (cd.isInterface()) { - throw new IllegalStateException("Type is not a class"); - } - return cd; - } - - public static ClassOrInterfaceDeclaration demandClassOrInterface(CompilationUnit compilationUnit, String qualifiedName) { - return findType(compilationUnit, qualifiedName) - .map(res -> res.toClassOrInterfaceDeclaration().orElseThrow(() -> new IllegalStateException("Type is not a class or an interface, it is " + res.getClass().getCanonicalName()))) - .orElseThrow(() -> new IllegalStateException("No type named '" + qualifiedName + "'found")); - } - - /** - * Returns the {@code (i+1)}'th constructor of the given type declaration, in textual order. The constructor that - * appears first has the index 0, the second one the index 1, and so on. - * - * @param td The type declaration to search in. Note that only classes and enums have constructors. - * @param index The index of the desired constructor. - * @return The desired ConstructorDeclaration if it was found, else an exception is thrown. - */ - public static ConstructorDeclaration demandConstructor(TypeDeclaration td, int index) { - // TODO: Refactor to use `td.findAll(ConstructorDeclaration.class);` - potential difference re: searching only immediate children? - ConstructorDeclaration found = null; - int i = 0; - for (BodyDeclaration bd : td.getMembers()) { - if (bd instanceof ConstructorDeclaration) { - ConstructorDeclaration cd = (ConstructorDeclaration) bd; - if (i == index) { - found = cd; - break; - } - i++; - } - } - if (found == null) { - throw new IllegalStateException("No constructor with index " + index); - } - return found; - } - - public static EnumDeclaration demandEnum(CompilationUnit cu, String qualifiedName) { - Optional> res = findType(cu, qualifiedName); - if (!res.isPresent()) { - throw new IllegalStateException("No type found"); - } - if (!(res.get() instanceof EnumDeclaration)) { - throw new IllegalStateException("Type is not an enum"); - } - return (EnumDeclaration) res.get(); - } - - public static VariableDeclarator demandField(ClassOrInterfaceDeclaration cd, String name) { - for (BodyDeclaration bd : cd.getMembers()) { - if (bd instanceof FieldDeclaration) { - FieldDeclaration fd = (FieldDeclaration) bd; - for (VariableDeclarator vd : fd.getVariables()) { - if (vd.getName().getId().equals(name)) { - return vd; - } - } - } - } - throw new IllegalStateException("No field with given name"); - } - - public static ClassOrInterfaceDeclaration demandInterface(CompilationUnit cu, String qualifiedName) { - ClassOrInterfaceDeclaration cd = demandClassOrInterface(cu, qualifiedName); - if (!cd.isInterface()) { - throw new IllegalStateException("Type is not an interface"); - } - return cd; - } - - public static MethodDeclaration demandMethod(TypeDeclaration cd, String name) { - MethodDeclaration found = null; - for (BodyDeclaration bd : cd.getMembers()) { - if (bd instanceof MethodDeclaration) { - MethodDeclaration md = (MethodDeclaration) bd; - if (md.getNameAsString().equals(name)) { - if (found != null) { - throw new IllegalStateException("Ambiguous getName"); - } - found = md; - } - } - } - if (found == null) { - throw new IllegalStateException("No method called " + name); - } - return found; - } - - public static N demandNodeOfGivenClass(Node node, Class clazz) { - return node.findFirst(clazz).orElseThrow(IllegalArgumentException::new); - } - - public static Node demandParentNode(Node node) { - return node.getParentNode().orElseThrow(() -> new IllegalStateException("Parent not found, the node does not appear to be inserted in a correct AST")); - } - - public static ReturnStmt demandReturnStmt(MethodDeclaration method) { - return demandNodeOfGivenClass(method, ReturnStmt.class); - } - - public static SwitchStmt demandSwitch(Node node) { - return findSwitchHelper(node).orElseThrow(IllegalArgumentException::new); - } - - public static Optional demandVariableDeclaration(Node node, String name) { - return node.findFirst(VariableDeclarator.class, n -> n.getNameAsString().equals(name)); - } - - public static Optional findMethodCall(Node node, String methodName) { - return node.findFirst(MethodCallExpr.class, n -> n.getNameAsString().equals(methodName)); - } - - public static Optional findNameExpression(Node node, String name) { - return node.findFirst(NameExpr.class, n -> n.getNameAsString().equals(name)); - } - - /** - * @deprecated Use {@link #demandNodeOfGivenClass(Node, Class)} - */ - @Deprecated - public static N findNodeOfGivenClass(Node node, Class clazz) { - return demandNodeOfGivenClass(node, clazz); - } - - /** - * @deprecated Use {@link #demandReturnStmt(MethodDeclaration)} - */ - @Deprecated - public static ReturnStmt findReturnStmt(MethodDeclaration method) { - return demandReturnStmt(method); - } - - public static Optional findSimpleName(Node node, String name) { - return node.findFirst(SimpleName.class, n -> n.asString().equals(name)); - } - - /** - * @deprecated Use {@link #demandSwitch(Node)} - */ - @Deprecated - public static SwitchStmt findSwitch(Node node) { - return demandSwitch(node); - } - - private static Optional findSwitchHelper(Node node) { - if (node instanceof SwitchStmt) { - return Optional.of((SwitchStmt) node); - } - - return node.findFirst(SwitchStmt.class); - } - - /** - * Looks among the type declared in the Compilation Unit for one having the specified name. - * The name can be qualified with respect to the compilation unit. For example, if the compilation - * unit is in package a.b; and it contains two top level classes named C and D, with class E being defined inside D - * then the qualifiedName that can be resolved are "C", "D", and "D.E". - */ - public static Optional> findType(CompilationUnit cu, String qualifiedName) { - if (cu.getTypes().isEmpty()) { - return Optional.empty(); - } - - final String typeName = getOuterTypeName(qualifiedName); - Optional> type = cu.getTypes().stream().filter((t) -> t.getName().getId().equals(typeName)).findFirst(); - - final String innerTypeName = getInnerTypeName(qualifiedName); - if (type.isPresent() && !innerTypeName.isEmpty()) { - return findType(type.get(), innerTypeName); - } - return type; - } - - /** - * Looks among the type declared in the TypeDeclaration for one having the specified name. - * The name can be qualified with respect to the TypeDeclaration. For example, if the class declaration defines - * class D and class D contains an internal class named E then the qualifiedName that can be resolved are "D", and - * "D.E". - */ - public static Optional> findType(TypeDeclaration td, String qualifiedName) { - final String typeName = getOuterTypeName(qualifiedName); - - Optional> type = Optional.empty(); - for (Node n : td.getMembers()) { - if (n instanceof TypeDeclaration && ((TypeDeclaration) n).getName().getId().equals(typeName)) { - type = Optional.of((TypeDeclaration) n); - break; - } - } - final String innerTypeName = getInnerTypeName(qualifiedName); - if (type.isPresent() && !innerTypeName.isEmpty()) { - return findType(type.get(), innerTypeName); - } - return type; - } - - private static String getInnerTypeName(String qualifiedName) { - if (qualifiedName.contains(".")) { - return qualifiedName.split("\\.", 2)[1]; - } - return ""; - } - - private static String getOuterTypeName(String qualifiedName) { - return qualifiedName.split("\\.", 2)[0]; - } - - /** - * @deprecated Use {@link #demandParentNode(Node)} - */ - @Deprecated - public static Node requireParentNode(Node node) { - return demandParentNode(node); - } - -} diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/LambdaArgumentTypePlaceholder.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/LambdaArgumentTypePlaceholder.java deleted file mode 100644 index ed8eebe..0000000 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/LambdaArgumentTypePlaceholder.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. - * - * This file is part of JavaParser. - * - * JavaParser can be used either under the terms of - * a) the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * b) the terms of the Apache License - * - * You should have received a copy of both licenses in LICENCE.LGPL and - * LICENCE.APACHE. Please refer to those files for details. - * - * JavaParser is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - */ - -package com.github.javaparser.symbolsolver.javaparsermodel; - -import com.github.javaparser.resolution.declarations.ResolvedMethodLikeDeclaration; -import com.github.javaparser.resolution.types.ResolvedType; -import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; - -/** - * Placeholder used to represent a lambda argument type while it is being - * calculated. - * - * @author Federico Tomassetti - */ -public class LambdaArgumentTypePlaceholder implements ResolvedType { - - private int pos; - private SymbolReference method; - - public LambdaArgumentTypePlaceholder(int pos) { - this.pos = pos; - } - - @Override - public boolean isArray() { - return false; - } - - @Override - public boolean isPrimitive() { - return false; - } - - @Override - public boolean isReferenceType() { - return false; - } - - @Override - public String describe() { - throw new UnsupportedOperationException(); - } - - @Override - public boolean isTypeVariable() { - return false; - } - - public void setMethod(SymbolReference method) { - this.method = method; - } - - @Override - public boolean isAssignableBy(ResolvedType other) { - throw new UnsupportedOperationException(); - } - -} diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/logic/FunctionalInterfaceLogic.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/logic/FunctionalInterfaceLogic.java deleted file mode 100644 index 2431a3d..0000000 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/logic/FunctionalInterfaceLogic.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. - * - * This file is part of JavaParser. - * - * JavaParser can be used either under the terms of - * a) the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * b) the terms of the Apache License - * - * You should have received a copy of both licenses in LICENCE.LGPL and - * LICENCE.APACHE. Please refer to those files for details. - * - * JavaParser is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - */ - -package com.github.javaparser.symbolsolver.logic; - -import com.github.javaparser.resolution.MethodUsage; -import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration; -import com.github.javaparser.resolution.types.ResolvedType; - -import java.lang.reflect.Method; -import java.lang.reflect.Parameter; -import java.util.Arrays; -import java.util.List; -import java.util.Optional; -import java.util.Set; -import java.util.stream.Collectors; - -/** - * @author Federico Tomassetti - */ -public final class FunctionalInterfaceLogic { - - private static String JAVA_LANG_FUNCTIONAL_INTERFACE = FunctionalInterface.class.getCanonicalName(); - - private FunctionalInterfaceLogic() { - // prevent instantiation - } - - /** - * Get the functional method defined by the type, if any. - */ - public static Optional getFunctionalMethod(ResolvedType type) { - Optional optionalTypeDeclaration = type.asReferenceType().getTypeDeclaration(); - if(!optionalTypeDeclaration.isPresent()) { - return Optional.empty(); - } - - ResolvedReferenceTypeDeclaration typeDeclaration = optionalTypeDeclaration.get(); - if (type.isReferenceType() && typeDeclaration.isInterface()) { - return getFunctionalMethod(typeDeclaration); - } else { - return Optional.empty(); - } - } - - /** - * Get the functional method defined by the type, if any. - */ - public static Optional getFunctionalMethod(ResolvedReferenceTypeDeclaration typeDeclaration) { - //We need to find all abstract methods - Set methods = typeDeclaration.getAllMethods().stream() - .filter(m -> m.getDeclaration().isAbstract()) - // Remove methods inherited by Object: - // Consider the case of Comparator which define equals. It would be considered a functional method. - .filter(m -> !declaredOnObject(m)) - .collect(Collectors.toSet()); - - if (methods.size() == 1) { - return Optional.of(methods.iterator().next()); - } else { - return Optional.empty(); - } - } - - public static boolean isFunctionalInterfaceType(ResolvedType type) { - if (type.isReferenceType()) { - Optional optionalTypeDeclaration = type.asReferenceType().getTypeDeclaration(); - if (optionalTypeDeclaration.isPresent() && optionalTypeDeclaration.get().hasAnnotation(JAVA_LANG_FUNCTIONAL_INTERFACE)) { - return true; - } - } - return getFunctionalMethod(type).isPresent(); - } - - private static String getSignature(Method m) { - return String.format("%s(%s)", m.getName(), String.join(", ", Arrays.stream(m.getParameters()).map(p -> toSignature(p)).collect(Collectors.toList()))); - } - - private static String toSignature(Parameter p) { - return p.getType().getCanonicalName(); - } - - private static List OBJECT_METHODS_SIGNATURES = Arrays.stream(Object.class.getDeclaredMethods()) - .map(method -> getSignature(method)) - .collect(Collectors.toList()); - - private static boolean declaredOnObject(MethodUsage m) { - return OBJECT_METHODS_SIGNATURES.contains(m.getDeclaration().getSignature()); - } -} diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/logic/InferenceContext.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/logic/InferenceContext.java deleted file mode 100644 index 931730a..0000000 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/logic/InferenceContext.java +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. - * - * This file is part of JavaParser. - * - * JavaParser can be used either under the terms of - * a) the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * b) the terms of the Apache License - * - * You should have received a copy of both licenses in LICENCE.LGPL and - * LICENCE.APACHE. Please refer to those files for details. - * - * JavaParser is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - */ - -package com.github.javaparser.symbolsolver.logic; - -import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration; -import com.github.javaparser.resolution.types.*; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -/** - * @author Federico Tomassetti - */ -public class InferenceContext { - - private int nextInferenceVariableId = 0; - private ObjectProvider objectProvider; - private List inferenceVariableTypes = new ArrayList<>(); - private Map inferenceVariableTypeMap = new HashMap<>(); - - public InferenceContext(ObjectProvider objectProvider) { - this.objectProvider = objectProvider; - } - - private InferenceVariableType inferenceVariableTypeForTp(ResolvedTypeParameterDeclaration tp) { - if (!inferenceVariableTypeMap.containsKey(tp.getName())) { - InferenceVariableType inferenceVariableType = new InferenceVariableType(nextInferenceVariableId++, objectProvider); - inferenceVariableTypes.add(inferenceVariableType); - inferenceVariableType.setCorrespondingTp(tp); - inferenceVariableTypeMap.put(tp.getName(), inferenceVariableType); - } - return inferenceVariableTypeMap.get(tp.getName()); - } - - /** - * @return the actual with the inference variable inserted - */ - public ResolvedType addPair(ResolvedType target, ResolvedType actual) { - target = placeInferenceVariables(target); - actual = placeInferenceVariables(actual); - registerCorrespondance(target, actual); - return target; - } - - public ResolvedType addSingle(ResolvedType actual) { - return placeInferenceVariables(actual); - } - - private void registerCorrespondance(ResolvedType formalType, ResolvedType actualType) { - if (formalType.isReferenceType() && actualType.isReferenceType()) { - ResolvedReferenceType formalTypeAsReference = formalType.asReferenceType(); - ResolvedReferenceType actualTypeAsReference = actualType.asReferenceType(); - - if (!formalTypeAsReference.getQualifiedName().equals(actualTypeAsReference.getQualifiedName())) { - List ancestors = actualTypeAsReference.getAllAncestors(); - final String formalParamTypeQName = formalTypeAsReference.getQualifiedName(); - List correspondingFormalType = ancestors.stream().filter((a) -> a.getQualifiedName().equals(formalParamTypeQName)).collect(Collectors.toList()); - if (correspondingFormalType.isEmpty()) { - ancestors = formalTypeAsReference.getAllAncestors(); - final String actualParamTypeQname = actualTypeAsReference.getQualifiedName(); - List correspondingActualType = ancestors.stream().filter(a -> a.getQualifiedName().equals(actualParamTypeQname)).collect(Collectors.toList()); - if (correspondingActualType.isEmpty()) { - throw new ConfilictingGenericTypesException(formalType, actualType); - } - correspondingFormalType = correspondingActualType; - - } - actualTypeAsReference = correspondingFormalType.get(0).asReferenceType(); - } - - if (formalTypeAsReference.getQualifiedName().equals(actualTypeAsReference.getQualifiedName())) { - if (!formalTypeAsReference.typeParametersValues().isEmpty()) { - if (actualTypeAsReference.isRawType()) { - // nothing to do - } else { - int i = 0; - for (ResolvedType formalTypeParameter : formalTypeAsReference.typeParametersValues()) { - registerCorrespondance(formalTypeParameter, actualTypeAsReference.typeParametersValues().get(i)); - i++; - } - } - } - } - } else if (formalType instanceof InferenceVariableType && !actualType.isPrimitive()) { - ((InferenceVariableType) formalType).registerEquivalentType(actualType); - if (actualType instanceof InferenceVariableType) { - ((InferenceVariableType) actualType).registerEquivalentType(formalType); - } - } else if (actualType.isNull()) { - // nothing to do - } else if (actualType.equals(formalType)) { - // nothing to do - } else if (actualType.isArray() && formalType.isArray()) { - registerCorrespondance(formalType.asArrayType().getComponentType(), actualType.asArrayType().getComponentType()); - } else if (formalType.isWildcard()) { - // nothing to do - if ((actualType instanceof InferenceVariableType) && formalType.asWildcard().isBounded()) { - ((InferenceVariableType) actualType).registerEquivalentType(formalType.asWildcard().getBoundedType()); - if (formalType.asWildcard().getBoundedType() instanceof InferenceVariableType) { - ((InferenceVariableType) formalType.asWildcard().getBoundedType()).registerEquivalentType(actualType); - } - } - if (actualType.isWildcard()) { - ResolvedWildcard formalWildcard = formalType.asWildcard(); - ResolvedWildcard actualWildcard = actualType.asWildcard(); - if (formalWildcard.isBounded() && formalWildcard.getBoundedType() instanceof InferenceVariableType) { - if (formalWildcard.isSuper() && actualWildcard.isSuper()) { - ((InferenceVariableType) formalType.asWildcard().getBoundedType()).registerEquivalentType(actualWildcard.getBoundedType()); - } else if (formalWildcard.isExtends() && actualWildcard.isExtends()) { - ((InferenceVariableType) formalType.asWildcard().getBoundedType()).registerEquivalentType(actualWildcard.getBoundedType()); - } - } - } - - if (actualType.isReferenceType()) { - if (formalType.asWildcard().isBounded()) { - registerCorrespondance(formalType.asWildcard().getBoundedType(), actualType); - } - } - } else if (actualType instanceof InferenceVariableType) { - if (formalType instanceof ResolvedReferenceType) { - ((InferenceVariableType) actualType).registerEquivalentType(formalType); - } else if (formalType instanceof InferenceVariableType) { - ((InferenceVariableType) actualType).registerEquivalentType(formalType); - } - } else if (actualType.isConstraint()) { - ResolvedLambdaConstraintType constraintType = actualType.asConstraintType(); - if (constraintType.getBound() instanceof InferenceVariableType) { - ((InferenceVariableType) constraintType.getBound()).registerEquivalentType(formalType); - } - } else if (actualType.isPrimitive()) { - if (formalType.isPrimitive()) { - // nothing to do - } else { - registerCorrespondance(formalType, objectProvider.byName(actualType.asPrimitive().getBoxTypeQName())); - } - } else if (actualType.isReferenceType()) { - if (formalType.isPrimitive()) { - if (formalType.asPrimitive().getBoxTypeQName().equals(actualType.describe())) { - registerCorrespondance(objectProvider.byName(formalType.asPrimitive().getBoxTypeQName()), actualType); - } else { - // nothing to do - } - } else { - // nothing to do - } - } else { - throw new UnsupportedOperationException(formalType.describe() + " " + actualType.describe()); - } - } - - private ResolvedType placeInferenceVariables(ResolvedType type) { - if (type.isWildcard()) { - if (type.asWildcard().isExtends()) { - return ResolvedWildcard.extendsBound(placeInferenceVariables(type.asWildcard().getBoundedType())); - } else if (type.asWildcard().isSuper()) { - return ResolvedWildcard.superBound(placeInferenceVariables(type.asWildcard().getBoundedType())); - } else { - return type; - } - } else if (type.isTypeVariable()) { - return inferenceVariableTypeForTp(type.asTypeParameter()); - } else if (type.isReferenceType()) { - return type.asReferenceType().transformTypeParameters(tp -> placeInferenceVariables(tp)); - } else if (type.isArray()) { - return new ResolvedArrayType(placeInferenceVariables(type.asArrayType().getComponentType())); - } else if (type.isNull() || type.isPrimitive() || type.isVoid()) { - return type; - } else if (type.isConstraint()) { - return ResolvedLambdaConstraintType.bound(placeInferenceVariables(type.asConstraintType().getBound())); - } else if (type instanceof InferenceVariableType) { - return type; - } else { - throw new UnsupportedOperationException(type.describe()); - } - } - - public ResolvedType resolve(ResolvedType type) { - if (type instanceof InferenceVariableType) { - InferenceVariableType inferenceVariableType = (InferenceVariableType) type; - return inferenceVariableType.equivalentType(); - } else if (type.isReferenceType()) { - return type.asReferenceType().transformTypeParameters(tp -> resolve(tp)); - } else if (type.isNull() || type.isPrimitive() || type.isVoid()) { - return type; - } else if (type.isArray()) { - return new ResolvedArrayType(resolve(type.asArrayType().getComponentType())); - } else if (type.isWildcard()) { - if (type.asWildcard().isExtends()) { - return ResolvedWildcard.extendsBound(resolve(type.asWildcard().getBoundedType())); - } else if (type.asWildcard().isSuper()) { - return ResolvedWildcard.superBound(resolve(type.asWildcard().getBoundedType())); - } else { - return type; - } - } else { - throw new UnsupportedOperationException(type.describe()); - } - } -} diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/logic/InferenceVariableType.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/logic/InferenceVariableType.java deleted file mode 100644 index e85fa22..0000000 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/logic/InferenceVariableType.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. - * - * This file is part of JavaParser. - * - * JavaParser can be used either under the terms of - * a) the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * b) the terms of the Apache License - * - * You should have received a copy of both licenses in LICENCE.LGPL and - * LICENCE.APACHE. Please refer to those files for details. - * - * JavaParser is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - */ - -package com.github.javaparser.symbolsolver.logic; - -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.ResolvedTypeVariable; -import com.github.javaparser.resolution.types.ResolvedWildcard; - -import java.util.HashSet; -import java.util.Set; -import java.util.stream.Collectors; - -/** - * An element using during type inference. - * - * @author Federico Tomassetti - */ -public class InferenceVariableType implements ResolvedType { - @Override - public String toString() { - return "InferenceVariableType{" + - "id=" + id + - '}'; - } - - private int id; - private ResolvedTypeParameterDeclaration correspondingTp; - - public void setCorrespondingTp(ResolvedTypeParameterDeclaration correspondingTp) { - this.correspondingTp = correspondingTp; - } - - private Set equivalentTypes = new HashSet<>(); - private ObjectProvider objectProvider; - - public void registerEquivalentType(ResolvedType type) { - this.equivalentTypes.add(type); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof InferenceVariableType)) return false; - - InferenceVariableType that = (InferenceVariableType) o; - - return id == that.id; - - } - - @Override - public int hashCode() { - return id; - } - - private Set superTypes = new HashSet<>(); - - public InferenceVariableType(int id, ObjectProvider objectProvider) { - this.id = id; - this.objectProvider = objectProvider; - } - - public static InferenceVariableType fromWildcard(ResolvedWildcard wildcard, int id, ObjectProvider objectProvider) { - InferenceVariableType inferenceVariableType = new InferenceVariableType(id, objectProvider); - if (wildcard.isExtends()) { - inferenceVariableType.superTypes.add(wildcard.getBoundedType()); - } - if (wildcard.isSuper()) { - // I am not sure about this one... - inferenceVariableType.superTypes.add(wildcard.getBoundedType()); - } - return inferenceVariableType; - } - - @Override - public String describe() { - return "InferenceVariable_" + id; - } - - @Override - public boolean isAssignableBy(ResolvedType other) { - throw new UnsupportedOperationException(); - } - - private Set concreteEquivalentTypesAlsoIndirectly(Set considered, InferenceVariableType inferenceVariableType) { - considered.add(inferenceVariableType); - Set result = new HashSet<>(); - result.addAll(inferenceVariableType.equivalentTypes.stream().filter(t -> !t.isTypeVariable() && !(t instanceof InferenceVariableType)).collect(Collectors.toSet())); - inferenceVariableType.equivalentTypes.stream().filter(t -> t instanceof InferenceVariableType).forEach(t -> { - InferenceVariableType ivt = (InferenceVariableType)t; - if (!considered.contains(ivt)) { - result.addAll(concreteEquivalentTypesAlsoIndirectly(considered, ivt)); - } - }); - return result; - } - - public ResolvedType equivalentType() { - Set concreteEquivalent = concreteEquivalentTypesAlsoIndirectly(new HashSet<>(), this); - if (concreteEquivalent.isEmpty()) { - if (correspondingTp == null) { - return objectProvider.object(); - } else { - return new ResolvedTypeVariable(correspondingTp); - } - } - if (concreteEquivalent.size() == 1) { - return concreteEquivalent.iterator().next(); - } - Set notTypeVariables = equivalentTypes.stream() - .filter(t -> !t.isTypeVariable() && !hasInferenceVariables(t)) - .collect(Collectors.toSet()); - if (notTypeVariables.size() == 1) { - return notTypeVariables.iterator().next(); - } else if (notTypeVariables.size() == 0 && !superTypes.isEmpty()) { - if (superTypes.size() == 1) { - return superTypes.iterator().next(); - } else { - throw new IllegalStateException("Super types are: " + superTypes); - } - } else { - throw new IllegalStateException("Equivalent types are: " + equivalentTypes); - } - } - - private boolean hasInferenceVariables(ResolvedType type){ - if (type instanceof InferenceVariableType){ - return true; - } - - if (type.isReferenceType()){ - ResolvedReferenceType refType = type.asReferenceType(); - for (ResolvedType t : refType.typeParametersValues()){ - if (hasInferenceVariables(t)){ - return true; - } - } - return false; - } - - if (type.isWildcard()){ - ResolvedWildcard wildcardType = type.asWildcard(); - return hasInferenceVariables(wildcardType.getBoundedType()); - } - - return false; - } -} diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/logic/MethodResolutionCapability.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/logic/MethodResolutionCapability.java deleted file mode 100644 index 20783e1..0000000 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/logic/MethodResolutionCapability.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. - * - * This file is part of JavaParser. - * - * JavaParser can be used either under the terms of - * a) the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * b) the terms of the Apache License - * - * You should have received a copy of both licenses in LICENCE.LGPL and - * LICENCE.APACHE. Please refer to those files for details. - * - * JavaParser is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - */ - -package com.github.javaparser.symbolsolver.logic; - -import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration; -import com.github.javaparser.resolution.types.ResolvedType; -import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; - -import java.util.List; - -public interface MethodResolutionCapability { - SymbolReference solveMethod(String name, List argumentsTypes, - boolean staticOnly); -} diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/model/resolution/SymbolReference.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/model/resolution/SymbolReference.java deleted file mode 100644 index c5f70ff..0000000 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/model/resolution/SymbolReference.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. - * - * This file is part of JavaParser. - * - * JavaParser can be used either under the terms of - * a) the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * b) the terms of the Apache License - * - * You should have received a copy of both licenses in LICENCE.LGPL and - * LICENCE.APACHE. Please refer to those files for details. - * - * JavaParser is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - */ - -package com.github.javaparser.symbolsolver.model.resolution; - -import com.github.javaparser.resolution.declarations.ResolvedDeclaration; - -import java.util.Optional; - -/** - * A reference to a symbol. It can solved or not solved. If solved the corresponding - * declaration will be provided. - * - * @author Federico Tomassetti - */ -public class SymbolReference { - - private Optional correspondingDeclaration; - - private SymbolReference(Optional correspondingDeclaration) { - this.correspondingDeclaration = correspondingDeclaration; - } - - /** - * Create a solve reference to the given symbol. - */ - public static SymbolReference solved(S2 symbolDeclaration) { - return new SymbolReference(Optional.of(symbolDeclaration)); - } - - /** - * Create an unsolved reference specifying the type of the value expected. - */ - public static SymbolReference unsolved(Class clazz) { - return new SymbolReference<>(Optional.empty()); - } - - @Override - public String toString() { - return "SymbolReference{" + correspondingDeclaration + "}"; - } - - /** - * The corresponding declaration. If not solve this throws UnsupportedOperationException. - * // TODO: Convert this to returning Optional. - */ - public S getCorrespondingDeclaration() { - if (!isSolved()) { - throw new UnsupportedOperationException("CorrespondingDeclaration not available for unsolved symbol."); - } - return correspondingDeclaration.get(); - } - - /** - * Is the reference solved? - */ - public boolean isSolved() { - return correspondingDeclaration.isPresent(); - } - - public static SymbolReference adapt(SymbolReference ref, Class clazz) { - if (ref.isSolved()) { - return SymbolReference.solved(ref.getCorrespondingDeclaration()); - } else { - return SymbolReference.unsolved(clazz); - } - } -} diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/model/resolution/TypeSolver.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/model/resolution/TypeSolver.java deleted file mode 100644 index 1fc4242..0000000 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/model/resolution/TypeSolver.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. - * - * This file is part of JavaParser. - * - * JavaParser can be used either under the terms of - * a) the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * b) the terms of the Apache License - * - * You should have received a copy of both licenses in LICENCE.LGPL and - * LICENCE.APACHE. Please refer to those files for details. - * - * JavaParser is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - */ - -package com.github.javaparser.symbolsolver.model.resolution; - -import com.github.javaparser.resolution.UnsolvedSymbolException; -import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration; - -/** - * An element able to find TypeDeclaration from their name. - * TypeSolvers are organized in hierarchies. - * - * @author Federico Tomassetti - */ -public interface TypeSolver { - - String JAVA_LANG_OBJECT = Object.class.getCanonicalName(); - - /** - * Get the root of the hierarchy of type solver. - */ - default TypeSolver getRoot() { - if (getParent() == null) { - return this; - } else { - return getParent().getRoot(); - } - } - - /** - * Parent of the this TypeSolver. This can return null. - */ - TypeSolver getParent(); - - /** - * Set the parent of this TypeSolver. - */ - void setParent(TypeSolver parent); - - /** - * Try to solve the type with the given name. It always return a SymbolReference which can be solved - * or unsolved. - */ - SymbolReference tryToSolveType(String name); - - /** - * Solve the given type. Either the type is found and returned or an UnsolvedSymbolException is thrown. - */ - default ResolvedReferenceTypeDeclaration solveType(String name) throws UnsolvedSymbolException { - SymbolReference ref = tryToSolveType(name); - if (ref.isSolved()) { - return ref.getCorrespondingDeclaration(); - } else { - throw new UnsolvedSymbolException(name, this.toString()); - } - } - - /** - * @return A resolved reference to {@code java.lang.Object} - */ - default ResolvedReferenceTypeDeclaration getSolvedJavaLangObject() throws UnsolvedSymbolException { - return solveType(JAVA_LANG_OBJECT); - } - - default boolean hasType(String name) { - return tryToSolveType(name).isSolved(); - } -} diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/model/resolution/Value.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/model/resolution/Value.java deleted file mode 100644 index be1ab2d..0000000 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/model/resolution/Value.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. - * - * This file is part of JavaParser. - * - * JavaParser can be used either under the terms of - * a) the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * b) the terms of the Apache License - * - * You should have received a copy of both licenses in LICENCE.LGPL and - * LICENCE.APACHE. Please refer to those files for details. - * - * JavaParser is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - */ - -package com.github.javaparser.symbolsolver.model.resolution; - -import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration; -import com.github.javaparser.resolution.types.ResolvedType; - -/** - * Any type of value. - * - * @author Federico Tomassetti - */ -public class Value { - private ResolvedType type; - private String name; - - public Value(ResolvedType type, String name) { - this.type = type; - this.name = name; - } - - /** - * Create a Value from a ValueDeclaration. - */ - public static Value from(ResolvedValueDeclaration decl) { - ResolvedType type = decl.getType(); - return new Value(type, decl.getName()); - } - - @Override - public String toString() { - return "Value{" + - "type=" + type + - ", name='" + name + '\'' + - '}'; - } - - public String getName() { - return name; - } - - public ResolvedType getType() { - return type; - } - -} diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/model/typesystem/LazyType.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/model/typesystem/LazyType.java deleted file mode 100644 index d32182e..0000000 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/model/typesystem/LazyType.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. - * - * This file is part of JavaParser. - * - * JavaParser can be used either under the terms of - * a) the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * b) the terms of the Apache License - * - * You should have received a copy of both licenses in LICENCE.LGPL and - * LICENCE.APACHE. Please refer to those files for details. - * - * JavaParser is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - */ - -package com.github.javaparser.symbolsolver.model.typesystem; - -import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration; -import com.github.javaparser.resolution.types.*; - -import java.util.Map; -import java.util.function.Function; - -public class LazyType implements ResolvedType { - private ResolvedType concrete; - private Function provider; - - public LazyType(Function provider) { - this.provider = provider; - } - - private ResolvedType getType() { - if (concrete == null) { - concrete = provider.apply(null); - } - return concrete; - } - - @Override - public boolean isArray() { - return getType().isArray(); - } - - @Override - public int arrayLevel() { - return getType().arrayLevel(); - } - - @Override - public boolean isPrimitive() { - return getType().isPrimitive(); - } - - @Override - public boolean isNull() { - return getType().isNull(); - } - - @Override - public boolean isReference() { - return getType().isReference(); - } - - @Override - public boolean isReferenceType() { - return getType().isReferenceType(); - } - - @Override - public boolean isVoid() { - return getType().isVoid(); - } - - @Override - public boolean isTypeVariable() { - return getType().isTypeVariable(); - } - - @Override - public boolean isWildcard() { - return getType().isWildcard(); - } - - @Override - public ResolvedArrayType asArrayType() { - return getType().asArrayType(); - } - - @Override - public ResolvedReferenceType asReferenceType() { - return getType().asReferenceType(); - } - - @Override - public ResolvedTypeParameterDeclaration asTypeParameter() { - return getType().asTypeParameter(); - } - - @Override - public ResolvedTypeVariable asTypeVariable() { - return getType().asTypeVariable(); - } - - @Override - public ResolvedPrimitiveType asPrimitive() { - return getType().asPrimitive(); - } - - @Override - public ResolvedWildcard asWildcard() { - return getType().asWildcard(); - } - - @Override - public String describe() { - return getType().describe(); - } - - @Override - public ResolvedType replaceTypeVariables(ResolvedTypeParameterDeclaration tp, ResolvedType replaced, - Map inferredTypes) { - return getType().replaceTypeVariables(tp, replaced, inferredTypes); - } - - @Override - public ResolvedType replaceTypeVariables(ResolvedTypeParameterDeclaration tp, ResolvedType replaced) { - return getType().replaceTypeVariables(tp, replaced); - } - - @Override - public boolean isAssignableBy(ResolvedType other) { - return getType().isAssignableBy(other); - } -} diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/model/typesystem/NullType.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/model/typesystem/NullType.java deleted file mode 100644 index dac282e..0000000 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/model/typesystem/NullType.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. - * - * This file is part of JavaParser. - * - * JavaParser can be used either under the terms of - * a) the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * b) the terms of the Apache License - * - * You should have received a copy of both licenses in LICENCE.LGPL and - * LICENCE.APACHE. Please refer to those files for details. - * - * JavaParser is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - */ - -package com.github.javaparser.symbolsolver.model.typesystem; - -import com.github.javaparser.resolution.types.ResolvedType; - -/** - * This is a virtual type used to represent null values. - * - * @author Federico Tomassetti - */ -public class NullType implements ResolvedType { - - public static final NullType INSTANCE = new NullType(); - - private NullType() { - // prevent instantiation - } - - @Override - public boolean isArray() { - return false; - } - - @Override - public boolean isPrimitive() { - return false; - } - - public boolean isNull() { - return true; - } - - @Override - public boolean isReferenceType() { - return false; - } - - @Override - public String describe() { - return "null"; - } - - @Override - public boolean isTypeVariable() { - return false; - } - - @Override - public boolean isAssignableBy(ResolvedType other) { - throw new UnsupportedOperationException("It does not make sense to assign a value to null, it can only be assigned"); - } - -} diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/model/typesystem/ReferenceTypeImpl.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/model/typesystem/ReferenceTypeImpl.java deleted file mode 100644 index bbb6bc5..0000000 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/model/typesystem/ReferenceTypeImpl.java +++ /dev/null @@ -1,266 +0,0 @@ -/* - * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. - * - * This file is part of JavaParser. - * - * JavaParser can be used either under the terms of - * a) the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * b) the terms of the Apache License - * - * You should have received a copy of both licenses in LICENCE.LGPL and - * LICENCE.APACHE. Please refer to those files for details. - * - * JavaParser is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - */ - -package com.github.javaparser.symbolsolver.model.typesystem; - -import com.github.javaparser.resolution.MethodUsage; -import com.github.javaparser.resolution.declarations.ResolvedFieldDeclaration; -import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration; -import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration; -import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration; -import com.github.javaparser.resolution.types.ResolvedReferenceType; -import com.github.javaparser.resolution.types.ResolvedType; -import com.github.javaparser.resolution.types.ResolvedTypeTransformer; -import com.github.javaparser.resolution.types.ResolvedTypeVariable; -import com.github.javaparser.resolution.types.parametrization.ResolvedTypeParametersMap; -import com.github.javaparser.symbolsolver.javaparsermodel.LambdaArgumentTypePlaceholder; -import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeVariableDeclaration; -import com.github.javaparser.symbolsolver.logic.FunctionalInterfaceLogic; -import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; - -import java.util.*; -import java.util.stream.Collectors; - -/** - * @author Federico Tomassetti - */ -// TODO Remove references to typeSolver: it is needed to instantiate other instances of ReferenceTypeUsage -// and to get the Object type declaration -public class ReferenceTypeImpl extends ResolvedReferenceType { - - private TypeSolver typeSolver; - - public static ResolvedReferenceType undeterminedParameters(ResolvedReferenceTypeDeclaration typeDeclaration, TypeSolver typeSolver) { - return new ReferenceTypeImpl(typeDeclaration, typeDeclaration.getTypeParameters().stream().map( - ResolvedTypeVariable::new - ).collect(Collectors.toList()), typeSolver); - } - - @Override - protected ResolvedReferenceType create(ResolvedReferenceTypeDeclaration typeDeclaration, List typeParametersCorrected) { - return new ReferenceTypeImpl(typeDeclaration, typeParametersCorrected, typeSolver); - } - - @Override - protected ResolvedReferenceType create(ResolvedReferenceTypeDeclaration typeDeclaration) { - return new ReferenceTypeImpl(typeDeclaration, typeSolver); - } - - public ReferenceTypeImpl(ResolvedReferenceTypeDeclaration typeDeclaration, TypeSolver typeSolver) { - super(typeDeclaration); - this.typeSolver = typeSolver; - } - - public ReferenceTypeImpl(ResolvedReferenceTypeDeclaration typeDeclaration, List typeArguments, TypeSolver typeSolver) { - super(typeDeclaration, typeArguments); - this.typeSolver = typeSolver; - } - - @Override - public ResolvedTypeParameterDeclaration asTypeParameter() { - if (this.typeDeclaration instanceof JavaParserTypeVariableDeclaration) { - JavaParserTypeVariableDeclaration javaParserTypeVariableDeclaration = (JavaParserTypeVariableDeclaration) this.typeDeclaration; - return javaParserTypeVariableDeclaration.asTypeParameter(); - } - throw new UnsupportedOperationException(this.typeDeclaration.getClass().getCanonicalName()); - } - - /** - * This method checks if ThisType t = new OtherType() would compile. - */ - @Override - public boolean isAssignableBy(ResolvedType other) { - if (other instanceof NullType) { - return !this.isPrimitive(); - } - // everything is assignable to Object except void - if (!other.isVoid() && this.isJavaLangObject()) { - return true; - } - // consider boxing - if (other.isPrimitive()) { - if (this.isJavaLangObject()) { - return true; - } else { - // Check if 'other' can be boxed to match this type - if (isCorrespondingBoxingType(other.describe())) return true; - - // Resolve the boxed type and check if it can be assigned via widening reference conversion - SymbolReference type = typeSolver.tryToSolveType(other.asPrimitive().getBoxTypeQName()); - return type.getCorrespondingDeclaration().canBeAssignedTo(super.typeDeclaration); - } - } - if (other instanceof LambdaArgumentTypePlaceholder) { - return FunctionalInterfaceLogic.isFunctionalInterfaceType(this); - } else if (other instanceof ReferenceTypeImpl) { - ReferenceTypeImpl otherRef = (ReferenceTypeImpl) other; - if (compareConsideringTypeParameters(otherRef)) { - return true; - } - for (ResolvedReferenceType otherAncestor : otherRef.getAllAncestors()) { - if (compareConsideringTypeParameters(otherAncestor)) { - return true; - } - } - return false; - } else if (other.isTypeVariable()) { - for (ResolvedTypeParameterDeclaration.Bound bound : other.asTypeVariable().asTypeParameter().getBounds()) { - if (bound.isExtends()) { - if (this.isAssignableBy(bound.getType())) { - return true; - } - } - } - return false; - } else if (other.isConstraint()){ - return isAssignableBy(other.asConstraintType().getBound()); - } else if (other.isWildcard()) { - if (this.isJavaLangObject()) { - return true; - } else if (other.asWildcard().isExtends()) { - return isAssignableBy(other.asWildcard().getBoundedType()); - } else { - return false; - } - } else if (other.isUnionType()) { - return other.asUnionType().getCommonAncestor() - .map(ancestor -> isAssignableBy(ancestor)).orElse(false); - } else { - return false; - } - } - - @Override - public Set getDeclaredMethods() { - // TODO replace variables - Set methods = new HashSet<>(); - - getTypeDeclaration().ifPresent(referenceTypeDeclaration -> { - for (ResolvedMethodDeclaration methodDeclaration : referenceTypeDeclaration.getDeclaredMethods()) { - MethodUsage methodUsage = new MethodUsage(methodDeclaration); - methods.add(methodUsage); - } - }); - - return methods; - } - - @Override - public ResolvedType toRawType() { - if (this.isRawType()) { - return this; - } else { - return new ReferenceTypeImpl(typeDeclaration, typeSolver); - } - } - - @Override - public boolean mention(List typeParameters) { - return typeParametersValues().stream().anyMatch(tp -> tp.mention(typeParameters)); - } - - /** - * Execute a transformation on all the type parameters of this element. - */ - @Override - public ResolvedType transformTypeParameters(ResolvedTypeTransformer transformer) { - ResolvedType result = this; - int i = 0; - for (ResolvedType tp : this.typeParametersValues()) { - ResolvedType transformedTp = transformer.transform(tp); - // Identity comparison on purpose - if (transformedTp != tp) { - List typeParametersCorrected = result.asReferenceType().typeParametersValues(); - typeParametersCorrected.set(i, transformedTp); - result = create(typeDeclaration, typeParametersCorrected); - } - i++; - } - return result; - } - - public List getAllAncestors() { - // We need to go through the inheritance line and propagate the type parametes - - List ancestors = typeDeclaration.getAllAncestors(); - - ancestors = ancestors.stream() - .map(a -> typeParametersMap().replaceAll(a).asReferenceType()) - .collect(Collectors.toList()); - - // Avoid repetitions of Object - ancestors.removeIf(ResolvedReferenceType::isJavaLangObject); - ResolvedReferenceTypeDeclaration objectType = typeSolver.getSolvedJavaLangObject(); - ancestors.add(create(objectType)); - - return ancestors; - } - - public List getDirectAncestors() { - // We need to go through the inheritance line and propagate the type parameters - - List ancestors = typeDeclaration.getAncestors(); - - ancestors = ancestors.stream() - .map(a -> typeParametersMap().replaceAll(a).asReferenceType()) - .collect(Collectors.toList()); - - - // Avoid repetitions of Object -- remove them all and, if appropriate, add it back precisely once. - ancestors.removeIf(ResolvedReferenceType::isJavaLangObject); - - // Conditionally re-insert java.lang.Object as an ancestor. - if(this.getTypeDeclaration().isPresent()) { - ResolvedReferenceTypeDeclaration thisTypeDeclaration = this.getTypeDeclaration().get(); - if (thisTypeDeclaration.isClass()) { - Optional optionalSuperClass = thisTypeDeclaration.asClass().getSuperClass(); - boolean superClassIsJavaLangObject = optionalSuperClass.isPresent() && optionalSuperClass.get().isJavaLangObject(); - boolean thisIsJavaLangObject = thisTypeDeclaration.asClass().isJavaLangObject(); - if (superClassIsJavaLangObject && !thisIsJavaLangObject) { - ancestors.add(create(typeSolver.getSolvedJavaLangObject())); - } - } else { - // If this isn't a class (i.e. is enum or interface (or record?)), add java.lang.Object as a supertype - // TODO: Should we also add the implicit java.lang.Enum ancestor in the case of enums? - // TODO: getDirectAncestors() shouldn't be inserting implicit ancesters...? See also issue #2696 - ancestors.add(create(typeSolver.getSolvedJavaLangObject())); - } - } - - return ancestors; - } - - public ResolvedReferenceType deriveTypeParameters(ResolvedTypeParametersMap typeParametersMap) { - return create(typeDeclaration, typeParametersMap); - } - - @Override - public Set getDeclaredFields() { - Set allFields = new LinkedHashSet<>(); - - if (getTypeDeclaration().isPresent()) { - allFields.addAll(getTypeDeclaration().get().getDeclaredFields()); - } - - return allFields; - } -} diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/MyObjectProvider.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/MyObjectProvider.java deleted file mode 100644 index f79fdf7..0000000 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/MyObjectProvider.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. - * - * This file is part of JavaParser. - * - * JavaParser can be used either under the terms of - * a) the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * b) the terms of the Apache License - * - * You should have received a copy of both licenses in LICENCE.LGPL and - * LICENCE.APACHE. Please refer to those files for details. - * - * JavaParser is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - */ - -package com.github.javaparser.symbolsolver.reflectionmodel; - -import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration; -import com.github.javaparser.resolution.types.ResolvedReferenceType; -import com.github.javaparser.symbolsolver.logic.ObjectProvider; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; -import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl; -import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver; - -/** - * @author Federico Tomassetti - */ -public class MyObjectProvider implements ObjectProvider { - - public static final MyObjectProvider INSTANCE = new MyObjectProvider(); - - private MyObjectProvider() { - // prevent instantiation - } - - @Override - public ResolvedReferenceType object() { - return new ReferenceTypeImpl(new ReflectionClassDeclaration(Object.class, new ReflectionTypeSolver()), new ReflectionTypeSolver()); - } - - @Override - public ResolvedReferenceType byName(String qualifiedName) { - TypeSolver typeSolver = new ReflectionTypeSolver(); - ResolvedReferenceTypeDeclaration typeDeclaration = typeSolver.solveType(qualifiedName); - if (!typeDeclaration.getTypeParameters().isEmpty()) { - throw new UnsupportedOperationException(); - } - return new ReferenceTypeImpl(typeDeclaration, typeSolver); - } - -} diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/ConstructorResolutionLogic.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/ConstructorResolutionLogic.java deleted file mode 100644 index 84848a6..0000000 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/ConstructorResolutionLogic.java +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. - * - * This file is part of JavaParser. - * - * JavaParser can be used either under the terms of - * a) the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * b) the terms of the Apache License - * - * You should have received a copy of both licenses in LICENCE.LGPL and - * LICENCE.APACHE. Please refer to those files for details. - * - * JavaParser is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - */ - -package com.github.javaparser.symbolsolver.resolution; - -import com.github.javaparser.resolution.MethodAmbiguityException; -import com.github.javaparser.resolution.declarations.ResolvedConstructorDeclaration; -import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration; -import com.github.javaparser.resolution.types.ResolvedArrayType; -import com.github.javaparser.resolution.types.ResolvedType; -import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -/** - * @author Fred Lefévère-Laoide - */ -public class ConstructorResolutionLogic { - - private static List groupVariadicParamValues(List argumentsTypes, int startVariadic, - ResolvedType variadicType) { - List res = new ArrayList<>(argumentsTypes.subList(0, startVariadic)); - List variadicValues = argumentsTypes.subList(startVariadic, argumentsTypes.size()); - if (variadicValues.isEmpty()) { - // TODO if there are no variadic values we should default to the bound of the formal type - res.add(variadicType); - } else { - ResolvedType componentType = findCommonType(variadicValues); - res.add(new ResolvedArrayType(componentType)); - } - return res; - } - - private static ResolvedType findCommonType(List variadicValues) { - if (variadicValues.isEmpty()) { - throw new IllegalArgumentException(); - } - // TODO implement this decently - return variadicValues.get(0); - } - - public static boolean isApplicable(ResolvedConstructorDeclaration constructor, List argumentsTypes, - TypeSolver typeSolver) { - return isApplicable(constructor, argumentsTypes, typeSolver, false); - } - - private static boolean isApplicable(ResolvedConstructorDeclaration constructor, List argumentsTypes, - TypeSolver typeSolver, boolean withWildcardTolerance) { - if (constructor.hasVariadicParameter()) { - int pos = constructor.getNumberOfParams() - 1; - if (constructor.getNumberOfParams() == argumentsTypes.size()) { - // check if the last value is directly assignable as an array - ResolvedType expectedType = constructor.getLastParam().getType(); - ResolvedType actualType = argumentsTypes.get(pos); - if (!expectedType.isAssignableBy(actualType)) { - for (ResolvedTypeParameterDeclaration tp : constructor.getTypeParameters()) { - expectedType = MethodResolutionLogic.replaceTypeParam(expectedType, tp, typeSolver); - } - if (!expectedType.isAssignableBy(actualType)) { - if (actualType.isArray() - && expectedType.isAssignableBy(actualType.asArrayType().getComponentType())) { - argumentsTypes.set(pos, actualType.asArrayType().getComponentType()); - } else { - argumentsTypes = groupVariadicParamValues(argumentsTypes, pos, - constructor.getLastParam().getType()); - } - } - } // else it is already assignable, nothing to do - } else { - if (pos > argumentsTypes.size()) { - return false; - } - argumentsTypes = - groupVariadicParamValues(argumentsTypes, pos, constructor.getLastParam().getType()); - } - } - - if (constructor.getNumberOfParams() != argumentsTypes.size()) { - return false; - } - Map matchedParameters = new HashMap<>(); - boolean needForWildCardTolerance = false; - for (int i = 0; i < constructor.getNumberOfParams(); i++) { - ResolvedType expectedType = constructor.getParam(i).getType(); - ResolvedType actualType = argumentsTypes.get(i); - if ((expectedType.isTypeVariable() && !(expectedType.isWildcard())) - && expectedType.asTypeParameter().declaredOnMethod()) { - matchedParameters.put(expectedType.asTypeParameter().getName(), actualType); - continue; - } - boolean isAssignableWithoutSubstitution = - expectedType.isAssignableBy(actualType) || (constructor.getParam(i).isVariadic() - && new ResolvedArrayType(expectedType).isAssignableBy(actualType)); - if (!isAssignableWithoutSubstitution && expectedType.isReferenceType() - && actualType.isReferenceType()) { - isAssignableWithoutSubstitution = MethodResolutionLogic.isAssignableMatchTypeParameters( - expectedType.asReferenceType(), actualType.asReferenceType(), matchedParameters); - } - if (!isAssignableWithoutSubstitution) { - for (ResolvedTypeParameterDeclaration tp : constructor.getTypeParameters()) { - expectedType = MethodResolutionLogic.replaceTypeParam(expectedType, tp, typeSolver); - } - for (ResolvedTypeParameterDeclaration tp : constructor.declaringType().getTypeParameters()) { - expectedType = MethodResolutionLogic.replaceTypeParam(expectedType, tp, typeSolver); - } - - if (!expectedType.isAssignableBy(actualType)) { - if (actualType.isWildcard() && withWildcardTolerance && !expectedType.isPrimitive()) { - needForWildCardTolerance = true; - continue; - } - if (constructor.hasVariadicParameter() && i == constructor.getNumberOfParams() - 1) { - if (new ResolvedArrayType(expectedType).isAssignableBy(actualType)) { - continue; - } - } - return false; - } - } - } - return !withWildcardTolerance || needForWildCardTolerance; - } - - /** - * @param constructors we expect the methods to be ordered such that inherited methods are later in the list - * @param argumentsTypes - * @param typeSolver - * @return - */ - public static SymbolReference findMostApplicable( - List constructors, List argumentsTypes, TypeSolver typeSolver) { - SymbolReference res = - findMostApplicable(constructors, argumentsTypes, typeSolver, false); - if (res.isSolved()) { - return res; - } - return findMostApplicable(constructors, argumentsTypes, typeSolver, true); - } - - public static SymbolReference findMostApplicable( - List constructors, List argumentsTypes, TypeSolver typeSolver, boolean wildcardTolerance) { - List applicableConstructors = constructors.stream().filter((m) -> isApplicable(m, argumentsTypes, typeSolver, wildcardTolerance)).collect(Collectors.toList()); - if (applicableConstructors.isEmpty()) { - return SymbolReference.unsolved(ResolvedConstructorDeclaration.class); - } - if (applicableConstructors.size() == 1) { - return SymbolReference.solved(applicableConstructors.get(0)); - } else { - ResolvedConstructorDeclaration winningCandidate = applicableConstructors.get(0); - ResolvedConstructorDeclaration other = null; - boolean possibleAmbiguity = false; - for (int i = 1; i < applicableConstructors.size(); i++) { - other = applicableConstructors.get(i); - if (isMoreSpecific(winningCandidate, other, typeSolver)) { - possibleAmbiguity = false; - } else if (isMoreSpecific(other, winningCandidate, typeSolver)) { - possibleAmbiguity = false; - winningCandidate = other; - } else { - if (winningCandidate.declaringType().getQualifiedName() - .equals(other.declaringType().getQualifiedName())) { - possibleAmbiguity = true; - } else { - // we expect the methods to be ordered such that inherited methods are later in the list - } - } - if (possibleAmbiguity) { - // pick the first exact match if it exists - if (!MethodResolutionLogic.isExactMatch(winningCandidate, argumentsTypes)) { - if (MethodResolutionLogic.isExactMatch(other, argumentsTypes)) { - winningCandidate = other; - } else { - throw new MethodAmbiguityException("Ambiguous constructor call: cannot find a most applicable constructor: " + winningCandidate + ", " + other); - } - } - } - } - - return SymbolReference.solved(winningCandidate); - } - } - - private static boolean isMoreSpecific(ResolvedConstructorDeclaration constructorA, - ResolvedConstructorDeclaration constructorB, TypeSolver typeSolver) { - boolean oneMoreSpecificFound = false; - if (constructorA.getNumberOfParams() < constructorB.getNumberOfParams()) { - return true; - } - if (constructorA.getNumberOfParams() > constructorB.getNumberOfParams()) { - return false; - } - for (int i = 0; i < constructorA.getNumberOfParams(); i++) { - ResolvedType tdA = constructorA.getParam(i).getType(); - ResolvedType tdB = constructorB.getParam(i).getType(); - // B is more specific - if (tdB.isAssignableBy(tdA) && !tdA.isAssignableBy(tdB)) { - oneMoreSpecificFound = true; - } - // A is more specific - if (tdA.isAssignableBy(tdB) && !tdB.isAssignableBy(tdA)) { - return false; - } - // if it matches a variadic and a not variadic I pick the not variadic - if (!tdA.isArray() && tdB.isArray()) { - return true; - } - // FIXME - if (i == (constructorA.getNumberOfParams() - 1) && tdA.arrayLevel() > tdB.arrayLevel()) { - return true; - } - } - return oneMoreSpecificFound; - } - -} diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/MethodResolutionLogic.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/MethodResolutionLogic.java deleted file mode 100644 index a238948..0000000 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/MethodResolutionLogic.java +++ /dev/null @@ -1,868 +0,0 @@ -/* - * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. - * - * This file is part of JavaParser. - * - * JavaParser can be used either under the terms of - * a) the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * b) the terms of the Apache License - * - * You should have received a copy of both licenses in LICENCE.LGPL and - * LICENCE.APACHE. Please refer to those files for details. - * - * JavaParser is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - */ - -package com.github.javaparser.symbolsolver.resolution; - -import com.github.javaparser.resolution.MethodAmbiguityException; -import com.github.javaparser.resolution.MethodUsage; -import com.github.javaparser.resolution.declarations.*; -import com.github.javaparser.resolution.types.*; -import com.github.javaparser.symbolsolver.logic.MethodResolutionCapability; -import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; -import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl; - -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Function; -import java.util.function.Predicate; -import java.util.stream.Collectors; - -/** - * @author Federico Tomassetti - */ -public class MethodResolutionLogic { - - private static String JAVA_LANG_OBJECT = Object.class.getCanonicalName(); - - private static List groupVariadicParamValues(List argumentsTypes, int startVariadic, ResolvedType variadicType) { - List res = new ArrayList<>(argumentsTypes.subList(0, startVariadic)); - List variadicValues = argumentsTypes.subList(startVariadic, argumentsTypes.size()); - if (variadicValues.isEmpty()) { - // TODO if there are no variadic values we should default to the bound of the formal type - res.add(variadicType); - } else { - ResolvedType componentType = findCommonType(variadicValues); - res.add(new ResolvedArrayType(componentType)); - } - return res; - } - - private static ResolvedType findCommonType(List variadicValues) { - if (variadicValues.isEmpty()) { - throw new IllegalArgumentException(); - } - // TODO implement this decently - return variadicValues.get(0); - } - - public static boolean isApplicable(ResolvedMethodDeclaration method, String name, List argumentsTypes, TypeSolver typeSolver) { - return isApplicable(method, name, argumentsTypes, typeSolver, false); - } - - /** - * Note the specific naming here -- parameters are part of the method declaration, - * while arguments are the values passed when calling a method. - * Note that "needle" refers to that value being used as a search/query term to match against. - * - * @return true, if the given ResolvedMethodDeclaration matches the given name/types (normally obtained from a MethodUsage) - * - * @see {@link MethodResolutionLogic#isApplicable(MethodUsage, String, List, TypeSolver)} - */ - private static boolean isApplicable(ResolvedMethodDeclaration methodDeclaration, String needleName, List needleArgumentTypes, TypeSolver typeSolver, boolean withWildcardTolerance) { - if (!methodDeclaration.getName().equals(needleName)) { - return false; - } - - // The index of the final method parameter (on the method declaration). - int countOfMethodParametersDeclared = methodDeclaration.getNumberOfParams(); - int lastMethodParameterIndex = Math.max(0, countOfMethodParametersDeclared - 1); - - // The index of the final argument passed (on the method usage). - int countOfNeedleArgumentsPassed = needleArgumentTypes.size(); - int lastNeedleArgumentIndex = Math.max(0, countOfNeedleArgumentsPassed - 1); - - boolean methodIsDeclaredWithVariadicParameter = methodDeclaration.hasVariadicParameter(); - - if (!methodIsDeclaredWithVariadicParameter && (countOfNeedleArgumentsPassed != countOfMethodParametersDeclared)) { - // If it is not variadic, and the number of parameters/arguments are unequal -- this is not a match. - return false; - } - - if (methodIsDeclaredWithVariadicParameter) { - // If the method declaration we're considering has a variadic parameter, - // attempt to convert the given list of arguments to fit this pattern - // e.g. foo(String s, String... s2) {} --- consider the first argument, then group the remainder as an array - - ResolvedType expectedVariadicParameterType = methodDeclaration.getLastParam().getType(); - for (ResolvedTypeParameterDeclaration tp : methodDeclaration.getTypeParameters()) { - expectedVariadicParameterType = replaceTypeParam(expectedVariadicParameterType, tp, typeSolver); - } - - if(countOfNeedleArgumentsPassed <= (countOfMethodParametersDeclared - 2)) { - // If it is variadic, and the number of arguments are short by **two or more** -- this is not a match. - // Note that omitting the variadic parameter is treated as an empty array - // (thus being short of only 1 argument is fine, but being short of 2 or more is not). - return false; - } else if (countOfNeedleArgumentsPassed == (countOfMethodParametersDeclared - 1)) { - // If it is variadic and we are short of **exactly one** parameter, this is a match. - // Note that omitting the variadic parameter is treated as an empty array - // (thus being short of only 1 argument is fine, but being short of 2 or more is not). - - // thus group the "empty" value into an empty array... - needleArgumentTypes = groupVariadicParamValues(needleArgumentTypes, lastMethodParameterIndex, methodDeclaration.getLastParam().getType()); - } else if (countOfNeedleArgumentsPassed > countOfMethodParametersDeclared) { - // If it is variadic, and we have an "excess" of arguments, group the "trailing" arguments into an array. - // Confirm all of these grouped "trailing" arguments have the required type -- if not, this is not a valid type. (Maybe this is also done later..?) - for(int variadicArgumentIndex = countOfMethodParametersDeclared; variadicArgumentIndex < countOfNeedleArgumentsPassed; variadicArgumentIndex++) { - ResolvedType currentArgumentType = needleArgumentTypes.get(variadicArgumentIndex); - boolean argumentIsAssignableToVariadicComponentType = expectedVariadicParameterType.asArrayType().getComponentType().isAssignableBy(currentArgumentType); - if(!argumentIsAssignableToVariadicComponentType) { - // If any of the arguments are not assignable to the expected variadic type, this is not a match. - return false; - } - } - needleArgumentTypes = groupVariadicParamValues(needleArgumentTypes, lastMethodParameterIndex, methodDeclaration.getLastParam().getType()); - } else if (countOfNeedleArgumentsPassed == countOfMethodParametersDeclared) { - ResolvedType actualArgumentType = needleArgumentTypes.get(lastNeedleArgumentIndex); - boolean finalArgumentIsArray = actualArgumentType.isArray() && expectedVariadicParameterType.isAssignableBy(actualArgumentType.asArrayType().getComponentType()); - if(finalArgumentIsArray) { - // Treat as an array of values -- in which case the expected parameter type is the common type of this array. - // no need to do anything -// expectedVariadicParameterType = actualArgumentType.asArrayType().getComponentType(); - } else { - // Treat as a single value -- in which case, the expected parameter type is the same as the single value. - needleArgumentTypes = groupVariadicParamValues(needleArgumentTypes, lastMethodParameterIndex, methodDeclaration.getLastParam().getType()); - } - } else { - // Should be unreachable. - } - } - - - // The index of the final argument passed (on the method usage). - int countOfNeedleArgumentsPassedAfterGrouping = needleArgumentTypes.size(); - int lastNeedleArgumentIndexAfterGrouping = Math.max(0, countOfNeedleArgumentsPassed - 1); - - // If variadic parameters are possible then they will have been "grouped" into a single argument. - // At this point, therefore, the number of arguments must be equal -- if they're not, then there is no match. - if (countOfNeedleArgumentsPassedAfterGrouping != countOfMethodParametersDeclared) { - return false; - } - - - Map matchedParameters = new HashMap<>(); - boolean needForWildCardTolerance = false; - for (int i = 0; i < countOfMethodParametersDeclared; i++) { - ResolvedType expectedDeclaredType = methodDeclaration.getParam(i).getType(); - ResolvedType actualArgumentType = needleArgumentTypes.get(i); - if ((expectedDeclaredType.isTypeVariable() && !(expectedDeclaredType.isWildcard())) && expectedDeclaredType.asTypeParameter().declaredOnMethod()) { - matchedParameters.put(expectedDeclaredType.asTypeParameter().getName(), actualArgumentType); - continue; - } - - boolean isAssignableWithoutSubstitution = expectedDeclaredType.isAssignableBy(actualArgumentType) || - (methodDeclaration.getParam(i).isVariadic() && new ResolvedArrayType(expectedDeclaredType).isAssignableBy(actualArgumentType)); - - if (!isAssignableWithoutSubstitution && expectedDeclaredType.isReferenceType() && actualArgumentType.isReferenceType()) { - isAssignableWithoutSubstitution = isAssignableMatchTypeParameters( - expectedDeclaredType.asReferenceType(), - actualArgumentType.asReferenceType(), - matchedParameters); - } - if (!isAssignableWithoutSubstitution) { - List typeParameters = methodDeclaration.getTypeParameters(); - typeParameters.addAll(methodDeclaration.declaringType().getTypeParameters()); - for (ResolvedTypeParameterDeclaration tp : typeParameters) { - expectedDeclaredType = replaceTypeParam(expectedDeclaredType, tp, typeSolver); - } - - if (!expectedDeclaredType.isAssignableBy(actualArgumentType)) { - if (actualArgumentType.isWildcard() && withWildcardTolerance && !expectedDeclaredType.isPrimitive()) { - needForWildCardTolerance = true; - continue; - } - // if the expected is java.lang.Math.max(double,double) and the type parameters are defined with constrain - // for example LambdaConstraintType{bound=TypeVariable {ReflectionTypeParameter{typeVariable=T}}}, LambdaConstraintType{bound=TypeVariable {ReflectionTypeParameter{typeVariable=U}}} - // we want to keep this method for future resolution - if (actualArgumentType.isConstraint() && withWildcardTolerance && expectedDeclaredType.isPrimitive()) { - needForWildCardTolerance = true; - continue; - } - if (methodIsDeclaredWithVariadicParameter && i == countOfMethodParametersDeclared - 1) { - if (new ResolvedArrayType(expectedDeclaredType).isAssignableBy(actualArgumentType)) { - continue; - } - } - return false; - } - } - } - return !withWildcardTolerance || needForWildCardTolerance; - } - - public static boolean isAssignableMatchTypeParameters(ResolvedType expected, ResolvedType actual, - Map matchedParameters) { - if (expected.isReferenceType() && actual.isReferenceType()) { - return isAssignableMatchTypeParameters(expected.asReferenceType(), actual.asReferenceType(), matchedParameters); - } else if (expected.isTypeVariable()) { - matchedParameters.put(expected.asTypeParameter().getName(), actual); - return true; - } else if (expected.isArray()) { - matchedParameters.put(expected.asArrayType().getComponentType().toString(), actual); - return true; - } else { - throw new UnsupportedOperationException(expected.getClass().getCanonicalName() + " " + actual.getClass().getCanonicalName()); - } - } - - public static boolean isAssignableMatchTypeParameters(ResolvedReferenceType expected, ResolvedReferenceType actual, - Map matchedParameters) { - if (actual.getQualifiedName().equals(expected.getQualifiedName())) { - return isAssignableMatchTypeParametersMatchingQName(expected, actual, matchedParameters); - } else { - List ancestors = actual.getAllAncestors(); - for (ResolvedReferenceType ancestor : ancestors) { - if (isAssignableMatchTypeParametersMatchingQName(expected, ancestor, matchedParameters)) { - return true; - } - } - } - return false; - } - - private static boolean isAssignableMatchTypeParametersMatchingQName(ResolvedReferenceType expected, ResolvedReferenceType actual, - Map matchedParameters) { - - if (!expected.getQualifiedName().equals(actual.getQualifiedName())) { - return false; - } - if (expected.typeParametersValues().size() != actual.typeParametersValues().size()) { - throw new UnsupportedOperationException(); - //return true; - } - for (int i = 0; i < expected.typeParametersValues().size(); i++) { - ResolvedType expectedParam = expected.typeParametersValues().get(i); - ResolvedType actualParam = actual.typeParametersValues().get(i); - - // In the case of nested parameterizations eg. List <-> List - // we should peel off one layer and ensure R <-> Integer - if (expectedParam.isReferenceType() && actualParam.isReferenceType()) { - ResolvedReferenceType r1 = expectedParam.asReferenceType(); - ResolvedReferenceType r2 = actualParam.asReferenceType(); - // we can have r1=A and r2=A.B (with B extends A and B is an inner class of A) - // in this case we want to verify expected parameter from the actual parameter ancestors - return isAssignableMatchTypeParameters(r1, r2, matchedParameters); - } - - if (expectedParam.isTypeVariable()) { - String expectedParamName = expectedParam.asTypeParameter().getName(); - if (!actualParam.isTypeVariable() || !actualParam.asTypeParameter().getName().equals(expectedParamName)) { - return matchTypeVariable(expectedParam.asTypeVariable(), actualParam, matchedParameters); - } - } else if (expectedParam.isReferenceType()) { - if (actualParam.isTypeVariable()) { - return matchTypeVariable(actualParam.asTypeVariable(), expectedParam, matchedParameters); - } else if (!expectedParam.equals(actualParam)) { - return false; - } - } else if (expectedParam.isWildcard()) { - if (expectedParam.asWildcard().isExtends()) { - return isAssignableMatchTypeParameters(expectedParam.asWildcard().getBoundedType(), actual, matchedParameters); - } - // TODO verify super bound - return true; - } else { - throw new UnsupportedOperationException(expectedParam.describe()); - } - } - return true; - } - - private static boolean matchTypeVariable(ResolvedTypeVariable typeVariable, ResolvedType type, Map matchedParameters) { - String typeParameterName = typeVariable.asTypeParameter().getName(); - if (matchedParameters.containsKey(typeParameterName)) { - ResolvedType matchedParameter = matchedParameters.get(typeParameterName); - if (matchedParameter.isAssignableBy(type)) { - return true; - } else if (type.isAssignableBy(matchedParameter)) { - // update matchedParameters to contain the more general type - matchedParameters.put(typeParameterName, type); - return true; - } - return false; - } else { - matchedParameters.put(typeParameterName, type); - } - return true; - } - - public static ResolvedType replaceTypeParam(ResolvedType type, ResolvedTypeParameterDeclaration tp, TypeSolver typeSolver) { - if (type.isTypeVariable() || type.isWildcard()) { - if (type.describe().equals(tp.getName())) { - List bounds = tp.getBounds(); - if (bounds.size() > 1) { - throw new UnsupportedOperationException(); - } else if (bounds.size() == 1) { - return bounds.get(0).getType(); - } else { - return new ReferenceTypeImpl(typeSolver.solveType(JAVA_LANG_OBJECT), typeSolver); - } - } - return type; - } else if (type.isPrimitive()) { - return type; - } else if (type.isArray()) { - return new ResolvedArrayType(replaceTypeParam(type.asArrayType().getComponentType(), tp, typeSolver)); - } else if (type.isReferenceType()) { - ResolvedReferenceType result = type.asReferenceType(); - result = result.transformTypeParameters(typeParam -> replaceTypeParam(typeParam, tp, typeSolver)).asReferenceType(); - return result; - } else { - throw new UnsupportedOperationException("Replacing " + type + ", param " + tp + " with " + type.getClass().getCanonicalName()); - } - } - - /** - * Note the specific naming here -- parameters are part of the method declaration, - * while arguments are the values passed when calling a method. - * Note that "needle" refers to that value being used as a search/query term to match against. - * - * @return true, if the given MethodUsage matches the given name/types (normally obtained from a ResolvedMethodDeclaration) - * - * @see {@link MethodResolutionLogic#isApplicable(ResolvedMethodDeclaration, String, List, TypeSolver)} } - * @see {@link MethodResolutionLogic#isApplicable(ResolvedMethodDeclaration, String, List, TypeSolver, boolean)} - */ - public static boolean isApplicable(MethodUsage methodUsage, String needleName, List needleParameterTypes, TypeSolver typeSolver) { - if (!methodUsage.getName().equals(needleName)) { - return false; - } - - // The index of the final method parameter (on the method declaration). - int countOfMethodUsageArgumentsPassed = methodUsage.getNoParams(); - int lastMethodUsageArgumentIndex = Math.max(0, countOfMethodUsageArgumentsPassed - 1); - - // The index of the final argument passed (on the method usage). - int needleParameterCount = needleParameterTypes.size(); - int lastNeedleParameterIndex = Math.max(0, needleParameterCount - 1); - - // TODO: Does the method usage have a declaration at this point..? - boolean methodIsDeclaredWithVariadicParameter = methodUsage.getDeclaration().hasVariadicParameter(); - - // If the counts do not match and the method is not variadic, this is not a match. - if (!methodIsDeclaredWithVariadicParameter && !(needleParameterCount == countOfMethodUsageArgumentsPassed)) { - return false; - } - - // If the counts do not match and we have provided too few arguments, this is not a match. Note that variadic parameters - // allow you to omit the vararg, which would allow a difference of one, but a difference in count of 2 or more is not a match. - if (!(needleParameterCount == countOfMethodUsageArgumentsPassed) && needleParameterCount < lastMethodUsageArgumentIndex) { - return false; - } - - // Iterate over the arguments given to the method, and compare their types against the given method's declared parameter types - for (int i = 0; i < needleParameterCount; i++) { - ResolvedType actualArgumentType = needleParameterTypes.get(i); - - ResolvedType expectedArgumentType; - boolean reachedVariadicParam = methodIsDeclaredWithVariadicParameter && i >= lastMethodUsageArgumentIndex; - if (!reachedVariadicParam) { - // Not yet reached the variadic parameters -- the expected type is just whatever is at that position. - expectedArgumentType = methodUsage.getParamType(i); - } else { - // We have reached the variadic parameters -- the expected type is the type of the last declared parameter. - expectedArgumentType = methodUsage.getParamType(lastMethodUsageArgumentIndex); - // Note that the given variadic value might be an array - if so, use the array's component type rather. - // This is only valid if ONE argument has been given to the vararg parameter. - // Example: {@code void test(String... s) {}} and {@code test(stringArray)} -- {@code String... is assignable by stringArray} - // Example: {@code void test(String[]... s) {}} and {@code test(stringArrayArray)} -- {@code String[]... is assignable by stringArrayArray} - boolean argumentIsArray = (needleParameterCount == countOfMethodUsageArgumentsPassed) && expectedArgumentType.isAssignableBy(actualArgumentType); - if (!argumentIsArray) { - // Get the component type of the declared parameter type. - expectedArgumentType = expectedArgumentType.asArrayType().getComponentType(); - } - } - - // Consider type parameters directly on the method declaration, and ALSO on the enclosing type (e.g. a class) - List typeParameters = methodUsage.getDeclaration().getTypeParameters(); - typeParameters.addAll(methodUsage.declaringType().getTypeParameters()); - - ResolvedType expectedTypeWithoutSubstitutions = expectedArgumentType; - ResolvedType expectedTypeWithInference = expectedArgumentType; - Map derivedValues = new HashMap<>(); - - // For each declared parameter, infer the types that will replace generics (type parameters) - for (int j = 0; j < countOfMethodUsageArgumentsPassed; j++) { - ResolvedParameterDeclaration parameter = methodUsage.getDeclaration().getParam(j); - ResolvedType parameterType = parameter.getType(); - if (parameter.isVariadic()) { - // Don't continue if a vararg parameter is reached and there are no arguments left - if (needleParameterCount == j) { - break; - } - parameterType = parameterType.asArrayType().getComponentType(); - } - inferTypes(needleParameterTypes.get(j), parameterType, derivedValues); - } - - for (Map.Entry entry : derivedValues.entrySet()) { - ResolvedTypeParameterDeclaration tp = entry.getKey(); - expectedTypeWithInference = expectedTypeWithInference.replaceTypeVariables(tp, entry.getValue()); - } - - // Consider cases where type variables can be replaced (e.g. add(E element) vs add(String element)) - for (ResolvedTypeParameterDeclaration tp : typeParameters) { - if (tp.getBounds().isEmpty()) { - //expectedArgumentType = expectedArgumentType.replaceTypeVariables(tp.getName(), new ReferenceTypeUsageImpl(typeSolver.solveType(JAVA_LANG_OBJECT), typeSolver)); - expectedArgumentType = expectedArgumentType.replaceTypeVariables(tp, ResolvedWildcard.extendsBound(new ReferenceTypeImpl(typeSolver.solveType(JAVA_LANG_OBJECT), typeSolver))); - } else if (tp.getBounds().size() == 1) { - ResolvedTypeParameterDeclaration.Bound bound = tp.getBounds().get(0); - if (bound.isExtends()) { - //expectedArgumentType = expectedArgumentType.replaceTypeVariables(tp.getName(), bound.getType()); - expectedArgumentType = expectedArgumentType.replaceTypeVariables(tp, ResolvedWildcard.extendsBound(bound.getType())); - } else { - //expectedArgumentType = expectedArgumentType.replaceTypeVariables(tp.getName(), new ReferenceTypeUsageImpl(typeSolver.solveType(JAVA_LANG_OBJECT), typeSolver)); - expectedArgumentType = expectedArgumentType.replaceTypeVariables(tp, ResolvedWildcard.superBound(bound.getType())); - } - } else { - throw new UnsupportedOperationException(); - } - } - - // Consider cases where type variables involve bounds e.g. super/extends - ResolvedType expectedTypeWithSubstitutions = expectedTypeWithoutSubstitutions; - for (ResolvedTypeParameterDeclaration tp : typeParameters) { - if (tp.getBounds().isEmpty()) { - expectedTypeWithSubstitutions = expectedTypeWithSubstitutions.replaceTypeVariables(tp, new ReferenceTypeImpl(typeSolver.solveType(JAVA_LANG_OBJECT), typeSolver)); - } else if (tp.getBounds().size() == 1) { - ResolvedTypeParameterDeclaration.Bound bound = tp.getBounds().get(0); - if (bound.isExtends()) { - expectedTypeWithSubstitutions = expectedTypeWithSubstitutions.replaceTypeVariables(tp, bound.getType()); - } else { - expectedTypeWithSubstitutions = expectedTypeWithSubstitutions.replaceTypeVariables(tp, new ReferenceTypeImpl(typeSolver.solveType(JAVA_LANG_OBJECT), typeSolver)); - } - } else { - throw new UnsupportedOperationException(); - } - } - - // If the given argument still isn't applicable even after considering type arguments/generics, this is not a match. - if (!expectedArgumentType.isAssignableBy(actualArgumentType) - && !expectedTypeWithSubstitutions.isAssignableBy(actualArgumentType) - && !expectedTypeWithInference.isAssignableBy(actualArgumentType) - && !expectedTypeWithoutSubstitutions.isAssignableBy(actualArgumentType)) { - return false; - } - } - - // If the checks above haven't failed, then we've found a match. - return true; - } - - /** - * Filters by given function {@param keyExtractor} using a stateful filter mechanism. - * - *
-     *      persons.stream().filter(distinctByKey(Person::getName))
-     * 
- *

- * The example above would return a distinct list of persons containing only one person per name. - */ - private static Predicate distinctByKey(Function keyExtractor) { - Set seen = ConcurrentHashMap.newKeySet(); - return t -> seen.add(keyExtractor.apply(t)); - } - - /** - * @param methods we expect the methods to be ordered such that inherited methods are later in the list - */ - public static SymbolReference findMostApplicable(List methods, - String name, List argumentsTypes, TypeSolver typeSolver) { - SymbolReference res = findMostApplicable(methods, name, argumentsTypes, typeSolver, false); - if (res.isSolved()) { - return res; - } - return findMostApplicable(methods, name, argumentsTypes, typeSolver, true); - } - - public static SymbolReference findMostApplicable(List methods, - String name, List argumentsTypes, - TypeSolver typeSolver, - boolean wildcardTolerance - ) { - - List applicableMethods = methods.stream() - // Only consider methods with a matching name - .filter(m -> m.getName().equals(name)) - // Filters out duplicate ResolvedMethodDeclaration by their signature. - .filter(distinctByKey(ResolvedMethodDeclaration::getQualifiedSignature)) - // Checks if ResolvedMethodDeclaration is applicable to argumentsTypes. - .filter((m) -> isApplicable(m, name, argumentsTypes, typeSolver, wildcardTolerance)) - .collect(Collectors.toList()); - - // If no applicable methods found, return as unsolved. - if (applicableMethods.isEmpty()) { - return SymbolReference.unsolved(ResolvedMethodDeclaration.class); - } - - // If there are multiple possible methods found, null arguments can help to eliminate some matches. - if (applicableMethods.size() > 1) { - List nullParamIndexes = new ArrayList<>(); - for (int i = 0; i < argumentsTypes.size(); i++) { - if (argumentsTypes.get(i).isNull()) { - nullParamIndexes.add(i); - } - } - - // If some null arguments have been provided, use this to eliminate some opitons. - if (!nullParamIndexes.isEmpty()) { - // remove method with array param if a non array exists and arg is null - Set removeCandidates = new HashSet<>(); - for (Integer nullParamIndex : nullParamIndexes) { - for (ResolvedMethodDeclaration methDecl : applicableMethods) { - if (methDecl.getParam(nullParamIndex).getType().isArray()) { - removeCandidates.add(methDecl); - } - } - } - - // Where candidiates for removal are found, remove them. - if (!removeCandidates.isEmpty() && removeCandidates.size() < applicableMethods.size()) { - applicableMethods.removeAll(removeCandidates); - } - } - } - - // If only one applicable method found, short-circuit and return it here. - if (applicableMethods.size() == 1) { - return SymbolReference.solved(applicableMethods.get(0)); - } - - // Examine the applicable methods found, and evaluate each to determine the "best" one - ResolvedMethodDeclaration winningCandidate = applicableMethods.get(0); - ResolvedMethodDeclaration other = null; - boolean possibleAmbiguity = false; - for (int i = 1; i < applicableMethods.size(); i++) { - other = applicableMethods.get(i); - if (isMoreSpecific(winningCandidate, other, argumentsTypes)) { - possibleAmbiguity = false; - } else if (isMoreSpecific(other, winningCandidate, argumentsTypes)) { - possibleAmbiguity = false; - winningCandidate = other; - } else { - // 15.12.2.5. Choosing the Most Specific Method - // One applicable method m1 is more specific than another applicable method m2, for an invocation with argument - // expressions e1, ..., ek, if any of the following are true: - // m2 is generic, and m1 is inferred to be more specific than m2 for argument expressions e1, ..., ek by §18.5.4. - // 18.5.4. More Specific Method Inference should be verified - // ... - if (winningCandidate.isGeneric() && !other.isGeneric()) { - winningCandidate = other; - } else if (!winningCandidate.isGeneric() && other.isGeneric()) { - // nothing to do at this stage winningCandidate is the winner - } else if (winningCandidate.declaringType().getQualifiedName().equals(other.declaringType().getQualifiedName())) { - possibleAmbiguity = true; - } else { - // we expect the methods to be ordered such that inherited methods are later in the list - } - } - } - - if (possibleAmbiguity) { - // pick the first exact match if it exists - if (!isExactMatch(winningCandidate, argumentsTypes)) { - if (isExactMatch(other, argumentsTypes)) { - winningCandidate = other; - } else { - throw new MethodAmbiguityException( - "Ambiguous method call: cannot find a most applicable method: " + winningCandidate - + ", " + other); - } - } - } - - return SymbolReference.solved(winningCandidate); - } - - protected static boolean isExactMatch(ResolvedMethodLikeDeclaration method, List argumentsTypes) { - for (int i = 0; i < method.getNumberOfParams(); i++) { - if (!method.getParam(i).getType().equals(argumentsTypes.get(i))) { - return false; - } - } - return true; - } - - private static ResolvedType getMethodsExplicitAndVariadicParameterType(ResolvedMethodDeclaration method, int i) { - int numberOfParams = method.getNumberOfParams(); - - if (i < numberOfParams) { - return method.getParam(i).getType(); - } else if (method.hasVariadicParameter()) { - return method.getParam(numberOfParams - 1).getType(); - } else { - return null; - } - } - - private static boolean isMoreSpecific(ResolvedMethodDeclaration methodA, ResolvedMethodDeclaration methodB, - List argumentTypes) { - - final boolean aVariadic = methodA.hasVariadicParameter(); - final boolean bVariadic = methodB.hasVariadicParameter(); - final int aNumberOfParams = methodA.getNumberOfParams(); - final int bNumberOfParams = methodB.getNumberOfParams(); - final int numberOfArgs = argumentTypes.size(); - final ResolvedType lastArgType = numberOfArgs > 0 ? argumentTypes.get(numberOfArgs - 1) : null; - final boolean isLastArgArray = lastArgType != null && lastArgType.isArray(); - int omittedArgs = 0; - boolean isMethodAMoreSpecific = false; - - // If one method declaration has exactly the correct amount of parameters and is not variadic then it is always - // preferred to a declaration that is variadic (and hence possibly also has a different amount of parameters). - if (!aVariadic && aNumberOfParams == numberOfArgs && (bVariadic && (bNumberOfParams != numberOfArgs || - !isLastArgArray))) { - return true; - } else if (!bVariadic && bNumberOfParams == numberOfArgs && (aVariadic && (aNumberOfParams != numberOfArgs || - !isLastArgArray))) { - return false; - } - - // If both methods are variadic but the calling method omits any varArgs, bump the omitted args to - // ensure the varargs type is considered when determining which method is more specific - if (aVariadic && bVariadic && aNumberOfParams == bNumberOfParams && numberOfArgs == aNumberOfParams - 1) { - omittedArgs++; - } - - // Either both methods are variadic or neither is. So we must compare the parameter types. - for (int i = 0; i < numberOfArgs + omittedArgs; i++) { - ResolvedType paramTypeA = getMethodsExplicitAndVariadicParameterType(methodA, i); - ResolvedType paramTypeB = getMethodsExplicitAndVariadicParameterType(methodB, i); - - ResolvedType argType = null; - if (i < argumentTypes.size()) { - argType = argumentTypes.get(i); - } - - // Safety: if a type is null it means a signature with too few parameters managed to get to this point. - // This should not happen but it also means that this signature is immediately disqualified. - if (paramTypeA == null) { - return false; - } else if (paramTypeB == null) { - return true; - } - // Widening primitive conversions have priority over boxing/unboxing conversions when finding the most - // applicable method. E.g. assume we have method call foo(1) and declarations foo(long) and foo(Integer). - // The method call will call foo(long), as it requires a widening primitive conversion from int to long - // instead of a boxing conversion from int to Integer. See JLS §15.12.2. - // This is what we check here. - else if (argType != null && - paramTypeA.isPrimitive() == argType.isPrimitive() && - paramTypeB.isPrimitive() != argType.isPrimitive() && - paramTypeA.isAssignableBy(argType)) { - - return true; - } else if (argType != null && - paramTypeB.isPrimitive() == argType.isPrimitive() && - paramTypeA.isPrimitive() != argType.isPrimitive() && - paramTypeB.isAssignableBy(argType)) { - - return false; - // if paramA and paramB are not the last parameters - // and the type of paramA or paramB (which are not more specific at this stage) is java.lang.Object - // then we have to consider others parameters before concluding - } else if ((i < numberOfArgs - 1) - && (isJavaLangObject(paramTypeB) || (isJavaLangObject(paramTypeA)))) { - // consider others parameters - // but eventually mark the method A as more specific if the methodB has an argument of type java.lang.Object - isMethodAMoreSpecific = isMethodAMoreSpecific || isJavaLangObject(paramTypeB); - } - // If we get to this point then we check whether one of the methods contains a parameter type that is more - // specific. If it does, we can assume the entire declaration is more specific as we would otherwise have - // a situation where the declarations are ambiguous in the given context. - else { - boolean aAssignableFromB = paramTypeA.isAssignableBy(paramTypeB); - boolean bAssignableFromA = paramTypeB.isAssignableBy(paramTypeA); - - if (bAssignableFromA && !aAssignableFromB) { - // A's parameter is more specific - return true; - } else if (aAssignableFromB && !bAssignableFromA) { - // B's parameter is more specific - return false; - } - } - } - - if (aVariadic && !bVariadic) { - // if the last argument is an array then m1 is more specific - return isLastArgArray; - } else if (!aVariadic && bVariadic) { - // if the last argument is an array and m1 is not variadic then - // it is not more specific - return !isLastArgArray; - } - - return isMethodAMoreSpecific; - } - - private static boolean isJavaLangObject(ResolvedType paramType ) { - return paramType.isReferenceType() && paramType.asReferenceType().getQualifiedName().equals("java.lang.Object"); - } - - private static boolean isMoreSpecific(MethodUsage methodA, MethodUsage methodB) { - boolean oneMoreSpecificFound = false; - for (int i = 0; i < methodA.getNoParams(); i++) { - ResolvedType tdA = methodA.getParamType(i); - ResolvedType tdB = methodB.getParamType(i); - - boolean aIsAssignableByB = tdA.isAssignableBy(tdB); - boolean bIsAssignableByA = tdB.isAssignableBy(tdA); - - // A is more specific - if (bIsAssignableByA && !aIsAssignableByB) { - oneMoreSpecificFound = true; - } - // B is more specific - if (aIsAssignableByB && !bIsAssignableByA) { - return false; - } - - // If B is vararg and A is not, A is more specific - if (tdB.isArray() && tdB.asArrayType().getComponentType().isAssignableBy(tdA)) { - oneMoreSpecificFound = true; - } - } - return oneMoreSpecificFound; - } - - public static Optional findMostApplicableUsage(List methods, String name, List argumentsTypes, TypeSolver typeSolver) { - List applicableMethods = methods.stream().filter((m) -> isApplicable(m, name, argumentsTypes, typeSolver)).collect(Collectors.toList()); - - if (applicableMethods.isEmpty()) { - return Optional.empty(); - } - if (applicableMethods.size() == 1) { - return Optional.of(applicableMethods.get(0)); - } else { - MethodUsage winningCandidate = applicableMethods.get(0); - for (int i = 1; i < applicableMethods.size(); i++) { - MethodUsage other = applicableMethods.get(i); - if (isMoreSpecific(winningCandidate, other)) { - // nothing to do - } else if (isMoreSpecific(other, winningCandidate)) { - winningCandidate = other; - } else { - if (winningCandidate.declaringType().getQualifiedName().equals(other.declaringType().getQualifiedName())) { - if (!areOverride(winningCandidate, other)) { - throw new MethodAmbiguityException("Ambiguous method call: cannot find a most applicable method: " + winningCandidate + ", " + other + ". First declared in " + winningCandidate.declaringType().getQualifiedName()); - } - } else { - // we expect the methods to be ordered such that inherited methods are later in the list - //throw new UnsupportedOperationException(); - } - } - } - return Optional.of(winningCandidate); - } - } - - private static boolean areOverride(MethodUsage winningCandidate, MethodUsage other) { - if (!winningCandidate.getName().equals(other.getName())) { - return false; - } - if (winningCandidate.getNoParams() != other.getNoParams()) { - return false; - } - for (int i = 0; i < winningCandidate.getNoParams(); i++) { - if (!winningCandidate.getParamTypes().get(i).equals(other.getParamTypes().get(i))) { - return false; - } - } - return true; - } - - public static SymbolReference solveMethodInType(ResolvedTypeDeclaration typeDeclaration, - String name, - List argumentsTypes) { - return solveMethodInType(typeDeclaration, name, argumentsTypes, false); - } - - // TODO: Replace TypeDeclaration.solveMethod - public static SymbolReference solveMethodInType(ResolvedTypeDeclaration typeDeclaration, - String name, - List argumentsTypes, - boolean staticOnly) { - - if (typeDeclaration instanceof MethodResolutionCapability) { - return ((MethodResolutionCapability) typeDeclaration).solveMethod(name, argumentsTypes, - staticOnly); - } else { - throw new UnsupportedOperationException(typeDeclaration.getClass().getCanonicalName()); - } - } - - private static void inferTypes(ResolvedType source, ResolvedType target, Map mappings) { - if (source.equals(target)) { - return; - } - if (source.isReferenceType() && target.isReferenceType()) { - ResolvedReferenceType sourceRefType = source.asReferenceType(); - ResolvedReferenceType targetRefType = target.asReferenceType(); - if (sourceRefType.getQualifiedName().equals(targetRefType.getQualifiedName())) { - if (!sourceRefType.isRawType() && !targetRefType.isRawType()) { - for (int i = 0; i < sourceRefType.typeParametersValues().size(); i++) { - inferTypes(sourceRefType.typeParametersValues().get(i), targetRefType.typeParametersValues().get(i), mappings); - } - } - } - return; - } - if (source.isReferenceType() && target.isWildcard()) { - if (target.asWildcard().isBounded()) { - inferTypes(source, target.asWildcard().getBoundedType(), mappings); - return; - } - return; - } - if (source.isWildcard() && target.isWildcard()) { - return; - } - if (source.isReferenceType() && target.isTypeVariable()) { - mappings.put(target.asTypeParameter(), source); - return; - } - - if (source.isWildcard() && target.isReferenceType()) { - if (source.asWildcard().isBounded()) { - inferTypes(source.asWildcard().getBoundedType(), target, mappings); - } - return; - } - - if (source.isWildcard() && target.isTypeVariable()) { - mappings.put(target.asTypeParameter(), source); - return; - } - if (source.isTypeVariable() && target.isTypeVariable()) { - mappings.put(target.asTypeParameter(), source); - return; - } - if (source.isPrimitive() || target.isPrimitive()) { - return; - } - if (source.isNull()) { - return; - } - } - - -} diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/utils/FileUtils.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/utils/FileUtils.java deleted file mode 100755 index d3a6b7d..0000000 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/utils/FileUtils.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.github.javaparser.symbolsolver.utils; - -import com.github.javaparser.utils.Utils; - -import java.io.File; - -public class FileUtils { - - /* - * returns true if the filename exists otherwise return false - */ - public static boolean isValidPath(String filename) { - File file = new File(filename); - return file.exists(); - } - - /* - * returns the parent path from the filename as string - */ - public static String getParentPath(String filename) { - Utils.assertNotNull(filename); - int lastIndex = filename.lastIndexOf(File.separator); - return filename.substring(0, lastIndex); - } - -} diff --git a/javaparser-symbol-solver-core/src/main/java/module-info.java b/javaparser-symbol-solver-core/src/main/java/module-info.java deleted file mode 100644 index 055bb08..0000000 --- a/javaparser-symbol-solver-core/src/main/java/module-info.java +++ /dev/null @@ -1,10 +0,0 @@ -module com.github.javaparser.symbolsolver { - requires com.github.javaparser.core; - requires com.google.common; - requires javassist; - exports com.github.javaparser.symbolsolver; - exports com.github.javaparser.symbolsolver.javaparsermodel.declarations; - exports com.github.javaparser.symbolsolver.model.resolution; - exports com.github.javaparser.symbolsolver.resolution.typesolvers; - exports com.github.javaparser.symbolsolver.model.typesystem; -} \ No newline at end of file diff --git a/pom.xml b/pom.xml index 0466311..951fd73 100644 --- a/pom.xml +++ b/pom.xml @@ -1,45 +1,52 @@ - 4.0.0 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 - es.upv.mist.slicing - sdg - pom - 1.3.0 + es.upv.mist.slicing + sdg + pom + 1.3.0 - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.8.1 - - 11 - 11 - - - - org.apache.maven.plugins - maven-surefire-plugin - - 3.0.0-M5 - - - - + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 11 + 11 + + + + org.apache.maven.plugins + maven-surefire-plugin + + 3.0.0-M5 + + + + - - 11 - 11 - + + 11 + 11 + - - sdg-core - sdg-cli - javaparser-symbol-solver-core - sdg-bench - - + + sdg-core + sdg-cli + sdg-bench + + + + + com.github.javaparser + javaparser-core + 3.25.4 + + + \ No newline at end of file diff --git a/sdg-bench/pom.xml b/sdg-bench/pom.xml index eb2e36e..4f7e21e 100644 --- a/sdg-bench/pom.xml +++ b/sdg-bench/pom.xml @@ -25,7 +25,7 @@ com.github.javaparser javaparser-core - 3.23.1 + 3.25.4 @@ -58,4 +58,4 @@ - \ No newline at end of file + diff --git a/sdg-core/pom.xml b/sdg-core/pom.xml index 68114d8..abc5229 100644 --- a/sdg-core/pom.xml +++ b/sdg-core/pom.xml @@ -1,57 +1,62 @@ - 4.0.0 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 - sdg-core + sdg-core - - sdg - es.upv.mist.slicing - 1.3.0 - + + sdg + es.upv.mist.slicing + 1.3.0 + - - 11 - 11 - + + 11 + 11 + - - - - src/test/res - - **/*.java - **/*.java.*.criterion - **/*.java.*.sliced - **/*.java.*.sliced.* - - - - + + + + src/test/res + + **/*.java + **/*.java.*.criterion + **/*.java.*.sliced + **/*.java.*.sliced.* + + + + - - - com.github.javaparser - javaparser-core - 3.23.1 - - - com.github.javaparser - javaparser-symbol-solver-core - 3.23.2 - - - org.jgrapht - jgrapht-core - 1.5.0 - - - org.junit.jupiter - junit-jupiter - RELEASE - test - - - + + + com.github.javaparser + javaparser-core + 3.23.1 + + + com.github.javaparser + javaparser-symbol-solver-core + 3.25.4 + + + com.github.javaparser + javaparser-core + 3.25.4 + + + org.jgrapht + jgrapht-core + 1.5.0 + + + org.junit.jupiter + junit-jupiter + RELEASE + test + + + \ No newline at end of file diff --git a/sdg-core/src/main/java/es/upv/mist/slicing/utils/ASTUtils.java b/sdg-core/src/main/java/es/upv/mist/slicing/utils/ASTUtils.java index 55c3037..f58db80 100644 --- a/sdg-core/src/main/java/es/upv/mist/slicing/utils/ASTUtils.java +++ b/sdg-core/src/main/java/es/upv/mist/slicing/utils/ASTUtils.java @@ -13,7 +13,7 @@ import com.github.javaparser.resolution.declarations.ResolvedMethodLikeDeclaration; import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration; import com.github.javaparser.resolution.types.ResolvedType; -import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl; +import com.github.javaparser.resolution.model.typesystem.ReferenceTypeImpl; import es.upv.mist.slicing.nodes.GraphNode; import java.util.*; @@ -135,7 +135,7 @@ public static Optional getResolvableScope(Resolvable> getResolvedAST(ResolvedMethodLikeDeclaration resolvedDeclaration) { + public static Optional getResolvedAST(ResolvedMethodLikeDeclaration resolvedDeclaration) { if (resolvedDeclaration instanceof ResolvedMethodDeclaration) return ((ResolvedMethodDeclaration) resolvedDeclaration).toAst(); if (resolvedDeclaration instanceof ResolvedConstructorDeclaration) @@ -188,7 +188,7 @@ public static Map newIdentityHashMap() { /** Converts a type declaration into just a type. */ public static ResolvedType resolvedTypeDeclarationToResolvedType(ResolvedReferenceTypeDeclaration decl) { - return new ReferenceTypeImpl(decl, StaticTypeSolver.getTypeSolver()); + return new ReferenceTypeImpl(decl); } /** diff --git a/sdg-core/src/main/java/es/upv/mist/slicing/utils/StaticTypeSolver.java b/sdg-core/src/main/java/es/upv/mist/slicing/utils/StaticTypeSolver.java index 4a9a4ba..496a964 100644 --- a/sdg-core/src/main/java/es/upv/mist/slicing/utils/StaticTypeSolver.java +++ b/sdg-core/src/main/java/es/upv/mist/slicing/utils/StaticTypeSolver.java @@ -2,7 +2,7 @@ import com.github.javaparser.StaticJavaParser; import com.github.javaparser.symbolsolver.JavaSymbolSolver; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver; import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver; diff --git a/sdg-core/src/main/java/module-info.java b/sdg-core/src/main/java/module-info.java index 6b2054a..b00c1ea 100644 --- a/sdg-core/src/main/java/module-info.java +++ b/sdg-core/src/main/java/module-info.java @@ -1,8 +1,7 @@ module sdg.core { requires com.github.javaparser.core; - requires com.github.javaparser.symbolsolver; + requires com.github.javaparser.symbolsolver.core; requires org.jgrapht.core; - requires java.logging; exports es.upv.mist.slicing.slicing; exports es.upv.mist.slicing.graphs; diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/JavaSymbolSolver.java b/src/main/java/com/github/javaparser/symbolsolver/JavaSymbolSolver.java similarity index 88% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/JavaSymbolSolver.java rename to src/main/java/com/github/javaparser/symbolsolver/JavaSymbolSolver.java index d93a52c..9559895 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/JavaSymbolSolver.java +++ b/src/main/java/com/github/javaparser/symbolsolver/JavaSymbolSolver.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -21,22 +21,25 @@ package com.github.javaparser.symbolsolver; +import static com.github.javaparser.resolution.Navigator.demandParentNode; + import com.github.javaparser.ast.CompilationUnit; import com.github.javaparser.ast.Node; import com.github.javaparser.ast.body.*; import com.github.javaparser.ast.expr.*; import com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt; import com.github.javaparser.ast.type.Type; +import com.github.javaparser.ast.type.TypeParameter; +import com.github.javaparser.quality.NotNull; import com.github.javaparser.resolution.SymbolResolver; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.UnsolvedSymbolException; import com.github.javaparser.resolution.declarations.*; +import com.github.javaparser.resolution.model.SymbolReference; import com.github.javaparser.resolution.types.ResolvedPrimitiveType; import com.github.javaparser.resolution.types.ResolvedType; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade; -import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory; import com.github.javaparser.symbolsolver.javaparsermodel.declarations.*; -import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; /** * This implementation of the SymbolResolver wraps the functionality of the library to make them easily usable @@ -72,7 +75,7 @@ public ResolvedType getType() { private TypeSolver typeSolver; - public JavaSymbolSolver(TypeSolver typeSolver) { + public JavaSymbolSolver(@NotNull TypeSolver typeSolver) { this.typeSolver = typeSolver; } @@ -90,13 +93,13 @@ public T resolveDeclaration(Node node, Class resultClass) { return resultClass.cast(new JavaParserMethodDeclaration((MethodDeclaration) node, typeSolver)); } if (node instanceof ClassOrInterfaceDeclaration) { - ResolvedReferenceTypeDeclaration resolved = JavaParserFactory.toTypeDeclaration(node, typeSolver); + ResolvedReferenceTypeDeclaration resolved = toTypeDeclaration(node); if (resultClass.isInstance(resolved)) { return resultClass.cast(resolved); } } if (node instanceof EnumDeclaration) { - ResolvedReferenceTypeDeclaration resolved = JavaParserFactory.toTypeDeclaration(node, typeSolver); + ResolvedReferenceTypeDeclaration resolved = toTypeDeclaration(node); if (resultClass.isInstance(resolved)) { return resultClass.cast(resolved); } @@ -122,7 +125,7 @@ public T resolveDeclaration(Node node, Class resultClass) { } } if (node instanceof AnnotationDeclaration) { - ResolvedReferenceTypeDeclaration resolved = JavaParserFactory.toTypeDeclaration(node, typeSolver); + ResolvedReferenceTypeDeclaration resolved = toTypeDeclaration(node); if (resultClass.isInstance(resolved)) { return resultClass.cast(resolved); } @@ -278,7 +281,7 @@ public T resolveDeclaration(Node node, Class resultClass) { @Override public T toResolvedType(Type javaparserType, Class resultClass) { - ResolvedType resolvedType = JavaParserFacade.get(typeSolver).convertToUsage(javaparserType, javaparserType); + ResolvedType resolvedType = JavaParserFacade.get(typeSolver).convertToUsage(javaparserType); if (resultClass.isInstance(resolvedType)) { return resultClass.cast(resolvedType); } @@ -290,4 +293,27 @@ public T toResolvedType(Type javaparserType, Class resultClass) { public ResolvedType calculateType(Expression expression) { return JavaParserFacade.get(typeSolver).getType(expression); } + + @Override + public ResolvedReferenceTypeDeclaration toTypeDeclaration(Node node) { + if (node instanceof ClassOrInterfaceDeclaration) { + if (((ClassOrInterfaceDeclaration) node).isInterface()) { + return new JavaParserInterfaceDeclaration((ClassOrInterfaceDeclaration) node, typeSolver); + } + return new JavaParserClassDeclaration((ClassOrInterfaceDeclaration) node, typeSolver); + } + if (node instanceof TypeParameter) { + return new JavaParserTypeParameter((TypeParameter) node, typeSolver); + } + if (node instanceof EnumDeclaration) { + return new JavaParserEnumDeclaration((EnumDeclaration) node, typeSolver); + } + if (node instanceof AnnotationDeclaration) { + return new JavaParserAnnotationDeclaration((AnnotationDeclaration) node, typeSolver); + } + if (node instanceof EnumConstantDeclaration) { + return new JavaParserEnumDeclaration((EnumDeclaration) demandParentNode(node), typeSolver); + } + throw new IllegalArgumentException("Cannot get a reference type declaration from " + node.getClass().getCanonicalName()); + } } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/SourceFileInfoExtractor.java b/src/main/java/com/github/javaparser/symbolsolver/SourceFileInfoExtractor.java similarity index 96% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/SourceFileInfoExtractor.java rename to src/main/java/com/github/javaparser/symbolsolver/SourceFileInfoExtractor.java index 03f23c4..22e86f6 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/SourceFileInfoExtractor.java +++ b/src/main/java/com/github/javaparser/symbolsolver/SourceFileInfoExtractor.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -32,13 +32,13 @@ import com.github.javaparser.ast.expr.MethodCallExpr; import com.github.javaparser.ast.stmt.Statement; import com.github.javaparser.ast.stmt.SwitchEntry; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration; import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration; +import com.github.javaparser.resolution.model.SymbolReference; 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.model.resolution.SymbolReference; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; import java.io.IOException; import java.io.PrintStream; @@ -51,7 +51,7 @@ import java.util.List; import static com.github.javaparser.StaticJavaParser.parse; -import static com.github.javaparser.symbolsolver.javaparser.Navigator.demandParentNode; +import static com.github.javaparser.resolution.Navigator.demandParentNode; import static java.util.Comparator.comparing; /** @@ -173,9 +173,8 @@ private String toString(MethodCallExpr node) { private String toString(SymbolReference methodDeclarationSymbolReference) { if (methodDeclarationSymbolReference.isSolved()) { return methodDeclarationSymbolReference.getCorrespondingDeclaration().getQualifiedSignature(); - } else { - return "UNSOLVED"; } + return "UNSOLVED"; } private List collectAllNodes(Node node) { diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/cache/Cache.java b/src/main/java/com/github/javaparser/symbolsolver/cache/Cache.java similarity index 98% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/cache/Cache.java rename to src/main/java/com/github/javaparser/symbolsolver/cache/Cache.java index d0846e2..0949a77 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/cache/Cache.java +++ b/src/main/java/com/github/javaparser/symbolsolver/cache/Cache.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2007-2010 Júlio Vilmar Gesser. - * Copyright (C) 2011, 2013-2021 The JavaParser Team. + * Copyright (C) 2011, 2013-2023 The JavaParser Team. * * This file is part of JavaParser. * diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/cache/GuavaCache.java b/src/main/java/com/github/javaparser/symbolsolver/cache/GuavaCache.java similarity index 97% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/cache/GuavaCache.java rename to src/main/java/com/github/javaparser/symbolsolver/cache/GuavaCache.java index 8894330..c4c2cdd 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/cache/GuavaCache.java +++ b/src/main/java/com/github/javaparser/symbolsolver/cache/GuavaCache.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2007-2010 Júlio Vilmar Gesser. - * Copyright (C) 2011, 2013-2021 The JavaParser Team. + * Copyright (C) 2011, 2013-2023 The JavaParser Team. * * This file is part of JavaParser. * diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/cache/InMemoryCache.java b/src/main/java/com/github/javaparser/symbolsolver/cache/InMemoryCache.java similarity index 90% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/cache/InMemoryCache.java rename to src/main/java/com/github/javaparser/symbolsolver/cache/InMemoryCache.java index d0e4391..4ef77a1 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/cache/InMemoryCache.java +++ b/src/main/java/com/github/javaparser/symbolsolver/cache/InMemoryCache.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2007-2010 Júlio Vilmar Gesser. - * Copyright (C) 2011, 2013-2021 The JavaParser Team. + * Copyright (C) 2011, 2013-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -21,6 +21,7 @@ package com.github.javaparser.symbolsolver.cache; +import java.util.Collections; import java.util.Map; import java.util.Optional; import java.util.WeakHashMap; @@ -47,7 +48,11 @@ public static InMemoryCache create( return new InMemoryCache<>(); } - private final Map mappedValues = new WeakHashMap<>(); + private final Map mappedValues; + + private InMemoryCache() { + mappedValues = Collections.synchronizedMap(new WeakHashMap<>()); + } @Override public void put(K key, V value) { diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/cache/NoCache.java b/src/main/java/com/github/javaparser/symbolsolver/cache/NoCache.java similarity index 97% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/cache/NoCache.java rename to src/main/java/com/github/javaparser/symbolsolver/cache/NoCache.java index 3fb4931..b4f2b24 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/cache/NoCache.java +++ b/src/main/java/com/github/javaparser/symbolsolver/cache/NoCache.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2007-2010 Júlio Vilmar Gesser. - * Copyright (C) 2011, 2013-2021 The JavaParser Team. + * Copyright (C) 2011, 2013-2023 The JavaParser Team. * * This file is part of JavaParser. * diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/core/resolution/MethodUsageResolutionCapability.java b/src/main/java/com/github/javaparser/symbolsolver/core/resolution/MethodUsageResolutionCapability.java similarity index 92% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/core/resolution/MethodUsageResolutionCapability.java rename to src/main/java/com/github/javaparser/symbolsolver/core/resolution/MethodUsageResolutionCapability.java index c3ce36d..ad685c8 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/core/resolution/MethodUsageResolutionCapability.java +++ b/src/main/java/com/github/javaparser/symbolsolver/core/resolution/MethodUsageResolutionCapability.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -21,6 +21,7 @@ package com.github.javaparser.symbolsolver.core.resolution; +import com.github.javaparser.resolution.Context; import com.github.javaparser.resolution.MethodUsage; import com.github.javaparser.resolution.types.ResolvedType; diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/SymbolDeclarator.java b/src/main/java/com/github/javaparser/symbolsolver/core/resolution/SymbolResolutionCapability.java similarity index 55% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/SymbolDeclarator.java rename to src/main/java/com/github/javaparser/symbolsolver/core/resolution/SymbolResolutionCapability.java index 9a696ad..7e42c03 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/SymbolDeclarator.java +++ b/src/main/java/com/github/javaparser/symbolsolver/core/resolution/SymbolResolutionCapability.java @@ -1,6 +1,5 @@ /* - * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2013-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -19,17 +18,20 @@ * GNU Lesser General Public License for more details. */ -package com.github.javaparser.symbolsolver.resolution; +package com.github.javaparser.symbolsolver.core.resolution; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration; - -import java.util.List; +import com.github.javaparser.resolution.model.SymbolReference; /** - * @author Federico Tomassetti + * Allows for an implementing declaration type to support solving for field (symbol) usage. */ -public interface SymbolDeclarator { - - List getSymbolDeclarations(); - +public interface SymbolResolutionCapability { + /** + * @param name Field / symbol name. + * @param typeSolver Symbol solver to resolve type usage. + * @return Symbol reference of the resolved value. + */ + SymbolReference solveSymbol(String name, TypeSolver typeSolver); } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/core/resolution/TypeVariableResolutionCapability.java b/src/main/java/com/github/javaparser/symbolsolver/core/resolution/TypeVariableResolutionCapability.java similarity index 91% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/core/resolution/TypeVariableResolutionCapability.java rename to src/main/java/com/github/javaparser/symbolsolver/core/resolution/TypeVariableResolutionCapability.java index a7dab94..330fb23 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/core/resolution/TypeVariableResolutionCapability.java +++ b/src/main/java/com/github/javaparser/symbolsolver/core/resolution/TypeVariableResolutionCapability.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -21,6 +21,7 @@ package com.github.javaparser.symbolsolver.core.resolution; +import com.github.javaparser.resolution.Context; import com.github.javaparser.resolution.MethodUsage; import com.github.javaparser.resolution.types.ResolvedType; diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/declarations/common/MethodDeclarationCommonLogic.java b/src/main/java/com/github/javaparser/symbolsolver/declarations/common/MethodDeclarationCommonLogic.java similarity index 92% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/declarations/common/MethodDeclarationCommonLogic.java rename to src/main/java/com/github/javaparser/symbolsolver/declarations/common/MethodDeclarationCommonLogic.java index e0d0d3b..0514418 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/declarations/common/MethodDeclarationCommonLogic.java +++ b/src/main/java/com/github/javaparser/symbolsolver/declarations/common/MethodDeclarationCommonLogic.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -21,16 +21,15 @@ package com.github.javaparser.symbolsolver.declarations.common; +import com.github.javaparser.resolution.Context; import com.github.javaparser.resolution.MethodUsage; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration; import com.github.javaparser.resolution.declarations.ResolvedParameterDeclaration; import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration; +import com.github.javaparser.resolution.logic.InferenceContext; import com.github.javaparser.resolution.types.ResolvedType; import com.github.javaparser.resolution.types.ResolvedTypeVariable; -import com.github.javaparser.symbolsolver.core.resolution.Context; -import com.github.javaparser.symbolsolver.logic.InferenceContext; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; -import com.github.javaparser.symbolsolver.reflectionmodel.MyObjectProvider; import java.util.ArrayList; import java.util.List; @@ -60,7 +59,7 @@ public MethodUsage resolveTypeVariables(Context context, List para // We now look at the type parameter for the method which we can derive from the parameter types // and then we replace them in the return type // Map determinedTypeParameters = new HashMap<>(); - InferenceContext inferenceContext = new InferenceContext(MyObjectProvider.INSTANCE); + InferenceContext inferenceContext = new InferenceContext(typeSolver); for (int i = 0; i < methodDeclaration.getNumberOfParams(); i++) { ResolvedParameterDeclaration formalParamDecl = methodDeclaration.getParam(i); ResolvedType formalParamType = formalParamDecl.getType(); diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparser/package-info.java b/src/main/java/com/github/javaparser/symbolsolver/javaparser/package-info.java similarity index 94% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparser/package-info.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparser/package-info.java index cbeea03..b1de28a 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparser/package-info.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparser/package-info.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/DefaultVisitorAdapter.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/DefaultVisitorAdapter.java similarity index 99% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/DefaultVisitorAdapter.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/DefaultVisitorAdapter.java index 6975aab..d6b4cc3 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/DefaultVisitorAdapter.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/DefaultVisitorAdapter.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * diff --git a/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/FailureHandler.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/FailureHandler.java new file mode 100644 index 0000000..d76ae0f --- /dev/null +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/FailureHandler.java @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2015-2016 Federico Tomassetti + * Copyright (C) 2017-2023 The JavaParser Team. + * + * This file is part of JavaParser. + * + * JavaParser can be used either under the terms of + * a) the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * b) the terms of the Apache License + * + * You should have received a copy of both licenses in LICENCE.LGPL and + * LICENCE.APACHE. Please refer to those files for details. + * + * JavaParser is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + */ + +package com.github.javaparser.symbolsolver.javaparsermodel; + +import com.github.javaparser.resolution.UnsolvedSymbolException; + +import java.util.HashMap; +import java.util.Map; +import java.util.function.Function; + +/* + * This class allows exceptions to be handled either by casting particular exceptions + * or by throwing new runtime exceptions. + */ +public class FailureHandler { + + private static final Map, Function> FAILURE_CONVERTER = new HashMap<>(); + static { + FAILURE_CONVERTER.put(UnsolvedSymbolException.class, + (Throwable th) -> (RuntimeException)th); + } + + public RuntimeException handle(Throwable th) { + return handle(th, null); + } + + public RuntimeException handle(Throwable th, String message) { + // searching for exact mapping + Function converter = FAILURE_CONVERTER.get(findRootCause(th).getClass()); + if (converter != null) { + return converter.apply(th); + } + // handle runtime exceptions + if (RuntimeException.class.isAssignableFrom(th.getClass())) { + return (RuntimeException) th; + } + return getRuntimeExceptionFrom(findRootCause(th), message); + } + + protected final E findRootCause(Throwable failure) { + while (failure != null) { + if (isRootCause(failure)) { + return (E) failure; + } + failure = failure.getCause(); + } + return null; + } + + private boolean isRootCause(Throwable th) { + return th.getCause() == null; + } + + private RuntimeException getRuntimeExceptionFrom(Throwable th, String message) { + if (message == null || message.isEmpty()) + return new RuntimeException(findRootCause(th)); + return new RuntimeException(message, findRootCause(th)); + } + +} diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/JavaParserFacade.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/JavaParserFacade.java similarity index 72% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/JavaParserFacade.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/JavaParserFacade.java index b07283f..3c80746 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/JavaParserFacade.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/JavaParserFacade.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -21,6 +21,13 @@ package com.github.javaparser.symbolsolver.javaparsermodel; +import static com.github.javaparser.resolution.Navigator.demandParentNode; +import static com.github.javaparser.resolution.model.SymbolReference.solved; +import static com.github.javaparser.resolution.model.SymbolReference.unsolved; + +import java.util.*; +import java.util.stream.Collectors; + import com.github.javaparser.ast.CompilationUnit; import com.github.javaparser.ast.DataKey; import com.github.javaparser.ast.Node; @@ -28,36 +35,25 @@ import com.github.javaparser.ast.body.*; import com.github.javaparser.ast.expr.*; import com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt; -import com.github.javaparser.ast.type.*; -import com.github.javaparser.resolution.MethodAmbiguityException; -import com.github.javaparser.resolution.MethodUsage; -import com.github.javaparser.resolution.UnsolvedSymbolException; +import com.github.javaparser.ast.stmt.ForEachStmt; +import com.github.javaparser.ast.type.Type; +import com.github.javaparser.resolution.*; import com.github.javaparser.resolution.declarations.*; -import com.github.javaparser.resolution.types.*; -import com.github.javaparser.symbolsolver.core.resolution.Context; +import com.github.javaparser.resolution.logic.ConstructorResolutionLogic; +import com.github.javaparser.resolution.logic.MethodResolutionLogic; +import com.github.javaparser.resolution.model.LambdaArgumentTypePlaceholder; +import com.github.javaparser.resolution.model.SymbolReference; +import com.github.javaparser.resolution.model.typesystem.ReferenceTypeImpl; +import com.github.javaparser.resolution.types.ResolvedReferenceType; +import com.github.javaparser.resolution.types.ResolvedType; +import com.github.javaparser.symbolsolver.JavaSymbolSolver; import com.github.javaparser.symbolsolver.javaparsermodel.contexts.FieldAccessContext; import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserAnonymousClassDeclaration; import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserEnumDeclaration; -import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeVariableDeclaration; -import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; -import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl; -import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionAnnotationDeclaration; -import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassDeclaration; -import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionEnumDeclaration; -import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionInterfaceDeclaration; -import com.github.javaparser.symbolsolver.resolution.ConstructorResolutionLogic; -import com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic; import com.github.javaparser.symbolsolver.resolution.SymbolSolver; +import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver; import com.github.javaparser.utils.Log; -import java.util.*; -import java.util.stream.Collectors; - -import static com.github.javaparser.symbolsolver.javaparser.Navigator.demandParentNode; -import static com.github.javaparser.symbolsolver.model.resolution.SymbolReference.solved; -import static com.github.javaparser.symbolsolver.model.resolution.SymbolReference.unsolved; - /** * Class to be used by final users to solve symbols for JavaParser ASTs. * @@ -65,32 +61,16 @@ */ public class JavaParserFacade { + // Start of static class + private static final DataKey TYPE_WITH_LAMBDAS_RESOLVED = new DataKey() { }; private static final DataKey TYPE_WITHOUT_LAMBDAS_RESOLVED = new DataKey() { }; private static final Map instances = new WeakHashMap<>(); - - private static String JAVA_LANG_STRING = String.class.getCanonicalName(); - - private final TypeSolver typeSolver; - private final TypeExtractor typeExtractor; - private final SymbolSolver symbolSolver; - private JavaParserFacade(TypeSolver typeSolver) { - this.typeSolver = typeSolver.getRoot(); - this.symbolSolver = new SymbolSolver(typeSolver); - this.typeExtractor = new TypeExtractor(typeSolver, this); - } - - public TypeSolver getTypeSolver() { - return typeSolver; - } - - public SymbolSolver getSymbolSolver() { - return symbolSolver; - } + private static final String JAVA_LANG_STRING = String.class.getCanonicalName(); /** * Note that the addition of the modifier {@code synchronized} is specific and directly in response to issue #2668. @@ -102,8 +82,8 @@ public SymbolSolver getSymbolSolver() { * @see https://github.com/javaparser/javaparser/issues/2668 * @see https://github.com/javaparser/javaparser/issues/2671 */ - public synchronized static JavaParserFacade get(TypeSolver typeSolver) { - return instances.computeIfAbsent(typeSolver, JavaParserFacade::new); + public static synchronized JavaParserFacade get(TypeSolver typeSolver) { + return instances.computeIfAbsent(typeSolver.getRoot(), JavaParserFacade::new); } /** @@ -113,22 +93,29 @@ public static void clearInstances() { instances.clear(); } - protected static ResolvedType solveGenericTypes(ResolvedType type, Context context) { - if (type.isTypeVariable()) { - return context.solveGenericType(type.describe()).orElse(type); - } - if (type.isWildcard()) { - if (type.asWildcard().isExtends() || type.asWildcard().isSuper()) { - ResolvedWildcard wildcardUsage = type.asWildcard(); - ResolvedType boundResolved = solveGenericTypes(wildcardUsage.getBoundedType(), context); - if (wildcardUsage.isExtends()) { - return ResolvedWildcard.extendsBound(boundResolved); - } else { - return ResolvedWildcard.superBound(boundResolved); - } - } - } - return type; + // End of static class + + private final TypeSolver typeSolver; + private final TypeExtractor typeExtractor; + private final Solver symbolSolver; + private final SymbolResolver symbolResolver; + + private FailureHandler failureHandler; + + private JavaParserFacade(TypeSolver typeSolver) { + this.typeSolver = typeSolver.getRoot(); + this.symbolSolver = new SymbolSolver(typeSolver); + this.typeExtractor = new TypeExtractor(this.typeSolver, this); + this.failureHandler = new FailureHandler(); + this.symbolResolver = new JavaSymbolSolver(this.typeSolver); + } + + public TypeSolver getTypeSolver() { + return typeSolver; + } + + public Solver getSymbolSolver() { + return symbolSolver; } public SymbolReference solve(NameExpr nameExpr) { @@ -163,7 +150,7 @@ public SymbolReference solve(ExplicitConstructor // Constructor invocation must exist within a class (not interface). Optional optAncestorClassOrInterfaceNode = explicitConstructorInvocationStmt.findAncestor(ClassOrInterfaceDeclaration.class); if (!optAncestorClassOrInterfaceNode.isPresent()) { - return unsolved(ResolvedConstructorDeclaration.class); + return unsolved(); } ClassOrInterfaceDeclaration classOrInterfaceNode = optAncestorClassOrInterfaceNode.get(); @@ -184,7 +171,7 @@ public SymbolReference solve(ExplicitConstructor } } if (typeDecl == null) { - return unsolved(ResolvedConstructorDeclaration.class); + return unsolved(); } // Solve each of the arguments being passed into this constructor invocation. @@ -242,7 +229,7 @@ public SymbolReference solve(ObjectCreationExpr } } if (typeDecl == null) { - return unsolved(ResolvedConstructorDeclaration.class); + return unsolved(); } SymbolReference res = ConstructorResolutionLogic.findMostApplicable(typeDecl.getConstructors(), argumentTypes, typeSolver); for (LambdaArgumentTypePlaceholder placeholder : placeholders) { @@ -255,18 +242,19 @@ private void solveArguments(Node node, NodeList args, boolean solveL List placeholders) { int i = 0; for (Expression parameterValue : args) { - if (parameterValue instanceof LambdaExpr || parameterValue instanceof MethodReferenceExpr) { + while (parameterValue instanceof EnclosedExpr) { + parameterValue = ((EnclosedExpr) parameterValue).getInner(); + } + if (parameterValue.isLambdaExpr() || parameterValue.isMethodReferenceExpr()) { LambdaArgumentTypePlaceholder placeholder = new LambdaArgumentTypePlaceholder(i); argumentTypes.add(placeholder); placeholders.add(placeholder); } else { try { argumentTypes.add(JavaParserFacade.get(typeSolver).getType(parameterValue, solveLambdas)); - } catch (UnsolvedSymbolException e) { - throw e; } catch (Exception e) { - throw new RuntimeException(String.format("Unable to calculate the type of a parameter of a method call. Method call: %s, Parameter: %s", - node, parameterValue), e); + throw failureHandler.handle(e, String.format("Unable to calculate the type of a parameter of a method call. Method call: %s, Parameter: %s", + node, parameterValue)); } } i++; @@ -304,9 +292,8 @@ public SymbolReference solve(AnnotationExpr annot if (typeDeclarationSymbolReference.isSolved()) { ResolvedAnnotationDeclaration annotationDeclaration = (ResolvedAnnotationDeclaration) typeDeclarationSymbolReference.getCorrespondingDeclaration(); return solved(annotationDeclaration); - } else { - return unsolved(ResolvedAnnotationDeclaration.class); } + return unsolved(); } public SymbolReference solve(FieldAccessExpr fieldAccessExpr) { @@ -349,10 +336,10 @@ public ResolvedType getType(Node node) { .solveType(nameExpr.getNameAsString()); if (typeDeclaration.isSolved() && typeDeclaration.getCorrespondingDeclaration() instanceof ResolvedReferenceTypeDeclaration) { ResolvedReferenceTypeDeclaration resolvedReferenceTypeDeclaration = (ResolvedReferenceTypeDeclaration) typeDeclaration.getCorrespondingDeclaration(); - return ReferenceTypeImpl.undeterminedParameters(resolvedReferenceTypeDeclaration, typeSolver); + return ReferenceTypeImpl.undeterminedParameters(resolvedReferenceTypeDeclaration); } } - throw e; + throw failureHandler.handle(e); } } @@ -382,21 +369,20 @@ public ResolvedType getType(Node node, boolean solveLambdas) { Log.trace("getType on %s -> %s", () -> node, () -> res); } return node.getData(TYPE_WITH_LAMBDAS_RESOLVED); - } else { - Optional res = find(TYPE_WITH_LAMBDAS_RESOLVED, node); - if (res.isPresent()) { + } + Optional res = find(TYPE_WITH_LAMBDAS_RESOLVED, node); + if (res.isPresent()) { return res.get(); } - res = find(TYPE_WITHOUT_LAMBDAS_RESOLVED, node); - if (!res.isPresent()) { + res = find(TYPE_WITHOUT_LAMBDAS_RESOLVED, node); + if (!res.isPresent()) { ResolvedType resType = getTypeConcrete(node, solveLambdas); node.setData(TYPE_WITHOUT_LAMBDAS_RESOLVED, resType); Optional finalRes = res; Log.trace("getType on %s (no solveLambdas) -> %s", () -> node, () -> finalRes); return resType; } - return res.get(); - } + return res.get(); } private Optional find(DataKey dataKey, Node node) { @@ -414,11 +400,11 @@ protected MethodUsage toMethodUsage(MethodReferenceExpr methodReferenceExpr, Lis } Optional result; - Set allMethods = typeOfScope.asReferenceType().getTypeDeclaration() - .orElseThrow(() -> new RuntimeException("TypeDeclaration unexpectedly empty.")) - .getAllMethods(); + ResolvedReferenceTypeDeclaration resolvedTypdeDecl = typeOfScope.asReferenceType().getTypeDeclaration() + .orElseThrow(() -> new RuntimeException("TypeDeclaration unexpectedly empty.")); + Set allMethods = resolvedTypdeDecl.getAllMethods(); - if (scope instanceof TypeExpr) { + if (scope.isTypeExpr()) { // static methods should match all params List staticMethodUsages = allMethods.stream() .filter(it -> it.getDeclaration().isStatic()) @@ -572,10 +558,10 @@ protected Node findContainingTypeDeclOrObjectCreationExpr(Node node) { if (parent instanceof BodyDeclaration) { if (parent instanceof TypeDeclaration) { return parent; - } else { - detachFlag = true; } - } else if (parent instanceof ObjectCreationExpr) { + detachFlag = true; + } + if (parent instanceof ObjectCreationExpr) { if (detachFlag) { return parent; } @@ -595,10 +581,10 @@ protected Node findContainingTypeDeclOrObjectCreationExpr(Node node, String clas if (parent instanceof BodyDeclaration) { if (parent instanceof TypeDeclaration && ((TypeDeclaration) parent).getFullyQualifiedName().get().endsWith(className)) { return parent; - } else { - detachFlag = true; } - } else if (parent instanceof ObjectCreationExpr) { + detachFlag = true; + } + if (parent instanceof ObjectCreationExpr && ((ObjectCreationExpr) parent).getType().getName().asString().equals(className)) { if (detachFlag) { return parent; } @@ -606,93 +592,45 @@ protected Node findContainingTypeDeclOrObjectCreationExpr(Node node, String clas } } - - public ResolvedType convertToUsageVariableType(VariableDeclarator var) { - return get(typeSolver).convertToUsage(var.getType(), var); - } - - public ResolvedType convertToUsage(Type type, Node context) { - if (type.isUnknownType()) { - throw new IllegalArgumentException("Inferred lambda parameter type"); + /** + * Convert a {@link Type} into the corresponding {@link ResolvedType}. + * + * @param type The type to be converted. + * @param context The current context. + * + * @return The type resolved. + */ + protected ResolvedType convertToUsage(Type type, Context context) { + if (context == null) { + throw new NullPointerException("Context should not be null"); } - return convertToUsage(type, JavaParserFactory.getContext(context, typeSolver)); + return type.convertToUsage(context); } + /** + * Convert a {@link Type} into the corresponding {@link ResolvedType}. + * + * @param type The type to be converted. + * + * @return The type resolved. + */ public ResolvedType convertToUsage(Type type) { - return convertToUsage(type, type); + return convertToUsage(type, JavaParserFactory.getContext(type, typeSolver)); } - // This is an hack around an issue in JavaParser - private String qName(ClassOrInterfaceType classOrInterfaceType) { - String name = classOrInterfaceType.getName().getId(); - if (classOrInterfaceType.getScope().isPresent()) { - return qName(classOrInterfaceType.getScope().get()) + "." + name; + private Optional forEachStmtWithVariableDeclarator( + VariableDeclarator variableDeclarator) { + Optional node = variableDeclarator.getParentNode(); + if (!node.isPresent() || !(node.get() instanceof VariableDeclarationExpr)) { + return Optional.empty(); } - return name; - } - - protected ResolvedType convertToUsage(Type type, Context context) { - if (context == null) { - throw new NullPointerException("Context should not be null"); - } - if (type instanceof ClassOrInterfaceType) { - ClassOrInterfaceType classOrInterfaceType = (ClassOrInterfaceType) type; - String name = qName(classOrInterfaceType); - SymbolReference ref = context.solveType(name); - if (!ref.isSolved()) { - throw new UnsolvedSymbolException(name); - } - ResolvedTypeDeclaration typeDeclaration = ref.getCorrespondingDeclaration(); - List typeParameters = Collections.emptyList(); - if (classOrInterfaceType.getTypeArguments().isPresent()) { - typeParameters = classOrInterfaceType.getTypeArguments().get().stream().map((pt) -> convertToUsage(pt, context)).collect(Collectors.toList()); - } - if (typeDeclaration.isTypeParameter()) { - if (typeDeclaration instanceof ResolvedTypeParameterDeclaration) { - return new ResolvedTypeVariable((ResolvedTypeParameterDeclaration) typeDeclaration); - } else { - JavaParserTypeVariableDeclaration javaParserTypeVariableDeclaration = (JavaParserTypeVariableDeclaration) typeDeclaration; - return new ResolvedTypeVariable(javaParserTypeVariableDeclaration.asTypeParameter()); - } - } else { - return new ReferenceTypeImpl((ResolvedReferenceTypeDeclaration) typeDeclaration, typeParameters, typeSolver); - } - } else if (type instanceof PrimitiveType) { - return ResolvedPrimitiveType.byName(((PrimitiveType) type).getType().name()); - } else if (type instanceof WildcardType) { - WildcardType wildcardType = (WildcardType) type; - if (wildcardType.getExtendedType().isPresent() && !wildcardType.getSuperType().isPresent()) { - return ResolvedWildcard.extendsBound(convertToUsage(wildcardType.getExtendedType().get(), context)); // removed (ReferenceTypeImpl) - } else if (!wildcardType.getExtendedType().isPresent() && wildcardType.getSuperType().isPresent()) { - return ResolvedWildcard.superBound(convertToUsage(wildcardType.getSuperType().get(), context)); // removed (ReferenceTypeImpl) - } else if (!wildcardType.getExtendedType().isPresent() && !wildcardType.getSuperType().isPresent()) { - return ResolvedWildcard.UNBOUNDED; - } else { - throw new UnsupportedOperationException(wildcardType.toString()); - } - } else if (type instanceof VoidType) { - return ResolvedVoidType.INSTANCE; - } else if (type instanceof ArrayType) { - ArrayType jpArrayType = (ArrayType) type; - return new ResolvedArrayType(convertToUsage(jpArrayType.getComponentType(), context)); - } else if (type instanceof UnionType) { - UnionType unionType = (UnionType) type; - return new ResolvedUnionType(unionType.getElements().stream().map(el -> convertToUsage(el, context)).collect(Collectors.toList())); - } else if (type instanceof VarType) { - Node parent = type.getParentNode().get(); - if (!(parent instanceof VariableDeclarator)) { - throw new IllegalStateException("Trying to resolve a `var` which is not in a variable declaration."); - } - final VariableDeclarator variableDeclarator = (VariableDeclarator) parent; - return variableDeclarator.getInitializer() - .map(Expression::calculateResolvedType) - .orElseThrow(() -> new IllegalStateException("Cannot resolve `var` which has no initializer.")); - } else { - throw new UnsupportedOperationException(type.getClass().getCanonicalName()); + node = node.get().getParentNode(); + if (!node.isPresent() || !(node.get() instanceof ForEachStmt)) { + return Optional.empty(); } + return Optional.of((ForEachStmt)node.get()); } - public ResolvedType convert(Type type, Node node) { return convert(type, JavaParserFactory.getContext(node, typeSolver)); } @@ -709,7 +647,7 @@ public MethodUsage solveMethodAsUsage(MethodCallExpr call) { try { params.add(getType(param, false)); } catch (Exception e) { - throw new RuntimeException(String.format("Error calculating the type of parameter %s of method call %s", param, call), e); + throw failureHandler.handle(e, String.format("Error calculating the type of parameter %s of method call %s", param, call)); } //params.add(getTypeConcrete(param, false)); } @@ -726,15 +664,15 @@ public MethodUsage solveMethodAsUsage(MethodCallExpr call) { public ResolvedReferenceTypeDeclaration getTypeDeclaration(Node node) { if (node instanceof TypeDeclaration) { return getTypeDeclaration((TypeDeclaration) node); - } else if (node instanceof ObjectCreationExpr) { + } + if (node instanceof ObjectCreationExpr) { return new JavaParserAnonymousClassDeclaration((ObjectCreationExpr) node, typeSolver); - } else { - throw new IllegalArgumentException(); } + throw new IllegalArgumentException(); } public ResolvedReferenceTypeDeclaration getTypeDeclaration(ClassOrInterfaceDeclaration classOrInterfaceDeclaration) { - return JavaParserFactory.toTypeDeclaration(classOrInterfaceDeclaration, typeSolver); + return symbolResolver.toTypeDeclaration(classOrInterfaceDeclaration); } /** @@ -743,37 +681,36 @@ public ResolvedReferenceTypeDeclaration getTypeDeclaration(ClassOrInterfaceDecla public ResolvedType getTypeOfThisIn(Node node) { // TODO consider static methods if (node instanceof ClassOrInterfaceDeclaration) { - return new ReferenceTypeImpl(getTypeDeclaration((ClassOrInterfaceDeclaration) node), typeSolver); - } else if (node instanceof EnumDeclaration) { + return new ReferenceTypeImpl(getTypeDeclaration((ClassOrInterfaceDeclaration) node)); + } + if (node instanceof EnumDeclaration) { JavaParserEnumDeclaration enumDeclaration = new JavaParserEnumDeclaration((EnumDeclaration) node, typeSolver); - return new ReferenceTypeImpl(enumDeclaration, typeSolver); - } else if (node instanceof ObjectCreationExpr && ((ObjectCreationExpr) node).getAnonymousClassBody().isPresent()) { + return new ReferenceTypeImpl(enumDeclaration); + } + if (node instanceof ObjectCreationExpr && ((ObjectCreationExpr) node).getAnonymousClassBody().isPresent()) { JavaParserAnonymousClassDeclaration anonymousDeclaration = new JavaParserAnonymousClassDeclaration((ObjectCreationExpr) node, typeSolver); - return new ReferenceTypeImpl(anonymousDeclaration, typeSolver); + return new ReferenceTypeImpl(anonymousDeclaration); } return getTypeOfThisIn(demandParentNode(node)); } public ResolvedReferenceTypeDeclaration getTypeDeclaration(TypeDeclaration typeDeclaration) { - return JavaParserFactory.toTypeDeclaration(typeDeclaration, typeSolver); + return symbolResolver.toTypeDeclaration(typeDeclaration); } + /** + * Convert a {@link Class} into the corresponding {@link ResolvedType}. + * + * @param clazz The class to be converted. + * + * @return The class resolved. + * + * @deprecated instead consider SymbolSolver.classToResolvedType(Class clazz) + */ + @Deprecated public ResolvedType classToResolvedType(Class clazz) { - if (clazz.isPrimitive()) { - return ResolvedPrimitiveType.byName(clazz.getName()); - } - - ResolvedReferenceTypeDeclaration declaration; - if (clazz.isAnnotation()) { - declaration = new ReflectionAnnotationDeclaration(clazz, typeSolver); - } else if (clazz.isEnum()) { - declaration = new ReflectionEnumDeclaration(clazz, typeSolver); - } else if (clazz.isInterface()) { - declaration = new ReflectionInterfaceDeclaration(clazz, typeSolver); - } else { - declaration = new ReflectionClassDeclaration(clazz, typeSolver); - } - return new ReferenceTypeImpl(declaration, typeSolver); + Solver symbolSolver = new SymbolSolver(new ReflectionTypeSolver()); + return symbolSolver.classToResolvedType(clazz); } } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/JavaParserFactory.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/JavaParserFactory.java similarity index 61% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/JavaParserFactory.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/JavaParserFactory.java index ea00fba..de9b567 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/JavaParserFactory.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/JavaParserFactory.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -27,16 +27,13 @@ import com.github.javaparser.ast.expr.*; import com.github.javaparser.ast.stmt.*; import com.github.javaparser.ast.type.ClassOrInterfaceType; -import com.github.javaparser.ast.type.TypeParameter; -import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration; -import com.github.javaparser.symbolsolver.core.resolution.Context; +import com.github.javaparser.resolution.Context; +import com.github.javaparser.resolution.SymbolDeclarator; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.symbolsolver.javaparsermodel.contexts.*; -import com.github.javaparser.symbolsolver.javaparsermodel.declarations.*; import com.github.javaparser.symbolsolver.javaparsermodel.declarators.*; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; -import com.github.javaparser.symbolsolver.resolution.SymbolDeclarator; -import static com.github.javaparser.symbolsolver.javaparser.Navigator.demandParentNode; +import static com.github.javaparser.resolution.Navigator.demandParentNode; /** * @author Federico Tomassetti @@ -48,64 +45,90 @@ public static Context getContext(Node node, TypeSolver typeSolver) { throw new NullPointerException("Node should not be null"); } - // TODO: Is order important here? + if (node instanceof ArrayAccessExpr) { return new ArrayAccessExprContext((ArrayAccessExpr) node, typeSolver); - } else if (node instanceof AnnotationDeclaration) { + } + if (node instanceof AnnotationDeclaration) { return new AnnotationDeclarationContext((AnnotationDeclaration) node, typeSolver); - } else if (node instanceof BinaryExpr) { + } + if (node instanceof BinaryExpr) { return new BinaryExprContext((BinaryExpr) node, typeSolver); - } else if (node instanceof BlockStmt) { + } + if (node instanceof BlockStmt) { return new BlockStmtContext((BlockStmt) node, typeSolver); - } else if (node instanceof CompilationUnit) { + } + if (node instanceof CompilationUnit) { return new CompilationUnitContext((CompilationUnit) node, typeSolver); - } else if (node instanceof EnclosedExpr) { + } + if (node instanceof EnclosedExpr) { return new EnclosedExprContext((EnclosedExpr) node, typeSolver); - } else if (node instanceof ForEachStmt) { + } + if (node instanceof ForEachStmt) { return new ForEachStatementContext((ForEachStmt) node, typeSolver); - } else if (node instanceof ForStmt) { + } + if (node instanceof ForStmt) { return new ForStatementContext((ForStmt) node, typeSolver); - } else if (node instanceof IfStmt) { + } + if (node instanceof IfStmt) { return new IfStatementContext((IfStmt) node, typeSolver); - } else if (node instanceof InstanceOfExpr) { + } + if (node instanceof InstanceOfExpr) { return new InstanceOfExprContext((InstanceOfExpr) node, typeSolver); - } else if (node instanceof LambdaExpr) { + } + if (node instanceof LambdaExpr) { return new LambdaExprContext((LambdaExpr) node, typeSolver); - } else if (node instanceof MethodDeclaration) { + } + if (node instanceof MethodDeclaration) { return new MethodContext((MethodDeclaration) node, typeSolver); - } else if (node instanceof ConstructorDeclaration) { + } + if (node instanceof ConstructorDeclaration) { return new ConstructorContext((ConstructorDeclaration) node, typeSolver); - } else if (node instanceof ClassOrInterfaceDeclaration) { + } + if (node instanceof ClassOrInterfaceDeclaration) { return new ClassOrInterfaceDeclarationContext((ClassOrInterfaceDeclaration) node, typeSolver); - } else if (node instanceof MethodCallExpr) { + } + if (node instanceof MethodCallExpr) { return new MethodCallExprContext((MethodCallExpr) node, typeSolver); - } else if (node instanceof MethodReferenceExpr) { + } + if (node instanceof MethodReferenceExpr) { return new MethodReferenceExprContext((MethodReferenceExpr) node, typeSolver); - } else if (node instanceof EnumDeclaration) { + } + if (node instanceof EnumDeclaration) { return new EnumDeclarationContext((EnumDeclaration) node, typeSolver); - } else if (node instanceof FieldAccessExpr) { + } + if (node instanceof FieldAccessExpr) { return new FieldAccessContext((FieldAccessExpr) node, typeSolver); - } else if (node instanceof SwitchEntry) { + } + if (node instanceof SwitchEntry) { return new SwitchEntryContext((SwitchEntry) node, typeSolver); - } else if (node instanceof TryStmt) { + } + if (node instanceof TryStmt) { return new TryWithResourceContext((TryStmt) node, typeSolver); - } else if (node instanceof Statement) { + } + if (node instanceof Statement) { return new StatementContext<>((Statement) node, typeSolver); - } else if (node instanceof CatchClause) { + } + if (node instanceof CatchClause) { return new CatchClauseContext((CatchClause) node, typeSolver); - } else if (node instanceof UnaryExpr) { + } + if (node instanceof UnaryExpr) { return new UnaryExprContext((UnaryExpr) node, typeSolver); - } else if (node instanceof VariableDeclarator) { + } + if (node instanceof VariableDeclarator) { return new VariableDeclaratorContext((VariableDeclarator) node, typeSolver); - } else if (node instanceof VariableDeclarationExpr) { + } + if (node instanceof VariableDeclarationExpr) { return new VariableDeclarationExprContext((VariableDeclarationExpr) node, typeSolver); - } else if (node instanceof ObjectCreationExpr && + } + if (node instanceof ObjectCreationExpr && ((ObjectCreationExpr) node).getAnonymousClassBody().isPresent()) { return new AnonymousClassDeclarationContext((ObjectCreationExpr) node, typeSolver); - } else if (node instanceof ObjectCreationExpr) { + } + if (node instanceof ObjectCreationExpr) { return new ObjectCreationContext((ObjectCreationExpr)node, typeSolver); - } else { - if (node instanceof NameExpr) { + } + if (node instanceof NameExpr) { // to resolve a name when in a fieldAccess context, we can go up until we get a node other than FieldAccessExpr, // in order to prevent a infinite loop if the name is the same as the field (ie x.x, x.y.x, or x.y.z.x) if (node.getParentNode().isPresent() && node.getParentNode().get() instanceof FieldAccessExpr) { @@ -122,8 +145,8 @@ public static Context getContext(Node node, TypeSolver typeSolver) { return getContext(node.getParentNode().get().getParentNode().get(), typeSolver); } } - final Node parentNode = demandParentNode(node); - if (node instanceof ClassOrInterfaceType && parentNode instanceof ClassOrInterfaceDeclaration) { + final Node parentNode = demandParentNode(node); + if (node instanceof ClassOrInterfaceType && parentNode instanceof ClassOrInterfaceDeclaration) { ClassOrInterfaceDeclaration parentDeclaration = (ClassOrInterfaceDeclaration) parentNode; if (parentDeclaration.getImplementedTypes().contains(node) || parentDeclaration.getExtendedTypes().contains(node)) { @@ -132,49 +155,32 @@ public static Context getContext(Node node, TypeSolver typeSolver) { return new ClassOrInterfaceDeclarationExtendsContext(parentDeclaration, typeSolver); } } - return getContext(parentNode, typeSolver); - } + return getContext(parentNode, typeSolver); } public static SymbolDeclarator getSymbolDeclarator(Node node, TypeSolver typeSolver) { if (node instanceof FieldDeclaration) { return new FieldSymbolDeclarator((FieldDeclaration) node, typeSolver); - } else if (node instanceof Parameter) { + } + if (node instanceof Parameter) { return new ParameterSymbolDeclarator((Parameter) node, typeSolver); - } else if (node instanceof PatternExpr) { + } + if (node instanceof PatternExpr) { return new PatternSymbolDeclarator((PatternExpr) node, typeSolver); - } else if (node instanceof ExpressionStmt) { + } + if (node instanceof ExpressionStmt) { ExpressionStmt expressionStmt = (ExpressionStmt) node; if (expressionStmt.getExpression() instanceof VariableDeclarationExpr) { - return new VariableSymbolDeclarator((VariableDeclarationExpr) (expressionStmt.getExpression()), typeSolver); - } else { - return new NoSymbolDeclarator<>(expressionStmt, typeSolver); + return new VariableSymbolDeclarator((VariableDeclarationExpr) (expressionStmt.getExpression()), + typeSolver); } - } else if (node instanceof ForEachStmt) { + return new NoSymbolDeclarator<>(expressionStmt, typeSolver); + } + if (node instanceof ForEachStmt) { ForEachStmt foreachStmt = (ForEachStmt) node; return new VariableSymbolDeclarator(foreachStmt.getVariable(), typeSolver); - } else { - return new NoSymbolDeclarator<>(node, typeSolver); } + return new NoSymbolDeclarator<>(node, typeSolver); } - public static ResolvedReferenceTypeDeclaration toTypeDeclaration(Node node, TypeSolver typeSolver) { - if (node instanceof ClassOrInterfaceDeclaration) { - if (((ClassOrInterfaceDeclaration) node).isInterface()) { - return new JavaParserInterfaceDeclaration((ClassOrInterfaceDeclaration) node, typeSolver); - } else { - return new JavaParserClassDeclaration((ClassOrInterfaceDeclaration) node, typeSolver); - } - } else if (node instanceof TypeParameter) { - return new JavaParserTypeParameter((TypeParameter) node, typeSolver); - } else if (node instanceof EnumDeclaration) { - return new JavaParserEnumDeclaration((EnumDeclaration) node, typeSolver); - } else if (node instanceof AnnotationDeclaration) { - return new JavaParserAnnotationDeclaration((AnnotationDeclaration) node, typeSolver); - } else if (node instanceof EnumConstantDeclaration) { - return new JavaParserEnumDeclaration((EnumDeclaration) demandParentNode((EnumConstantDeclaration) node), typeSolver); - } else { - throw new IllegalArgumentException(node.getClass().getCanonicalName()); - } - } } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/TypeExtractor.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/TypeExtractor.java similarity index 53% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/TypeExtractor.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/TypeExtractor.java index 88b8f72..5452854 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/TypeExtractor.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/TypeExtractor.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -21,6 +21,15 @@ package com.github.javaparser.symbolsolver.javaparsermodel; +import static com.github.javaparser.ast.expr.Expression.EXCLUDE_ENCLOSED_EXPR; +import static com.github.javaparser.ast.expr.Expression.IS_NOT_ENCLOSED_EXPR; +import static com.github.javaparser.resolution.Navigator.demandParentNode; + +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + import com.github.javaparser.ast.CompilationUnit; import com.github.javaparser.ast.Node; import com.github.javaparser.ast.body.FieldDeclaration; @@ -31,61 +40,52 @@ import com.github.javaparser.ast.stmt.ExpressionStmt; import com.github.javaparser.ast.stmt.ReturnStmt; import com.github.javaparser.ast.type.ClassOrInterfaceType; -import com.github.javaparser.ast.type.Type; import com.github.javaparser.ast.type.UnknownType; -import com.github.javaparser.resolution.MethodUsage; -import com.github.javaparser.resolution.UnsolvedSymbolException; +import com.github.javaparser.resolution.*; import com.github.javaparser.resolution.declarations.*; +import com.github.javaparser.resolution.logic.FunctionalInterfaceLogic; +import com.github.javaparser.resolution.logic.InferenceContext; +import com.github.javaparser.resolution.model.SymbolReference; +import com.github.javaparser.resolution.model.Value; +import com.github.javaparser.resolution.model.typesystem.LazyType; +import com.github.javaparser.resolution.model.typesystem.NullType; +import com.github.javaparser.resolution.model.typesystem.ReferenceTypeImpl; +import com.github.javaparser.resolution.promotion.ConditionalExprHandler; import com.github.javaparser.resolution.types.ResolvedArrayType; import com.github.javaparser.resolution.types.ResolvedPrimitiveType; import com.github.javaparser.resolution.types.ResolvedType; import com.github.javaparser.resolution.types.ResolvedVoidType; -import com.github.javaparser.symbolsolver.core.resolution.Context; -import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserSymbolDeclaration; -import com.github.javaparser.symbolsolver.logic.FunctionalInterfaceLogic; -import com.github.javaparser.symbolsolver.logic.InferenceContext; -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.MyObjectProvider; -import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassDeclaration; import com.github.javaparser.symbolsolver.resolution.SymbolSolver; -import com.github.javaparser.symbolsolver.resolution.typeinference.TypeHelper; -import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver; +import com.github.javaparser.symbolsolver.resolution.promotion.ConditionalExprResolver; +import com.github.javaparser.symbolsolver.resolution.typeinference.LeastUpperBoundLogic; import com.github.javaparser.utils.Log; import com.github.javaparser.utils.Pair; import com.google.common.collect.ImmutableList; -import java.util.List; -import java.util.Optional; - -import static com.github.javaparser.symbolsolver.javaparser.Navigator.demandParentNode; -import static com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.solveGenericTypes; - public class TypeExtractor extends DefaultVisitorAdapter { private static final String JAVA_LANG_STRING = String.class.getCanonicalName(); - + private final ResolvedType stringReferenceType; + private TypeSolver typeSolver; private JavaParserFacade facade; - - private ReferenceTypeImpl StringReferenceType; + public TypeExtractor(TypeSolver typeSolver, JavaParserFacade facade) { this.typeSolver = typeSolver; this.facade = facade; - //pre-calculate the String reference (optimization) - StringReferenceType = new ReferenceTypeImpl(new ReflectionTypeSolver().solveType(JAVA_LANG_STRING), typeSolver); + // pre-calculate the String reference (optimization) + // consider a LazyType to avoid having to systematically declare a ReflectionTypeSolver + stringReferenceType = new LazyType(v -> new ReferenceTypeImpl(typeSolver.solveType(JAVA_LANG_STRING))); } @Override public ResolvedType visit(VariableDeclarator node, Boolean solveLambdas) { if (demandParentNode(node) instanceof FieldDeclaration) { - return facade.convertToUsageVariableType(node); - } else if (demandParentNode(node) instanceof VariableDeclarationExpr) { - return facade.convertToUsageVariableType(node); + return facade.convertToUsage(node.getType()); + } + if (demandParentNode(node) instanceof VariableDeclarationExpr) { + return facade.convertToUsage(node.getType()); } throw new UnsupportedOperationException(demandParentNode(node).getClass().getCanonicalName()); } @@ -95,7 +95,7 @@ public ResolvedType visit(Parameter node, Boolean solveLambdas) { if (node.getType() instanceof UnknownType) { throw new IllegalStateException("Parameter has unknown type: " + node); } - return facade.convertToUsage(node.getType(), node); + return facade.convertToUsage(node.getType()); } @@ -167,9 +167,8 @@ public ResolvedType visit(CastExpr node, Boolean solveLambdas) { @Override public ResolvedType visit(ClassExpr node, Boolean solveLambdas) { // This implementation does not regard the actual type argument of the ClassExpr. - Type astType = node.getType(); - ResolvedType jssType = facade.convertToUsage(astType, node.getType()); - return new ReferenceTypeImpl(new ReflectionClassDeclaration(Class.class, typeSolver), ImmutableList.of(jssType), typeSolver); + ResolvedType jssType = facade.convertToUsage(node.getType()); + return new ReferenceTypeImpl(typeSolver.solveType(Class.class.getCanonicalName()), ImmutableList.of(jssType)); } /* @@ -189,182 +188,16 @@ public ResolvedType visit(ClassExpr node, Boolean solveLambdas) { public ResolvedType visit(ConditionalExpr node, Boolean solveLambdas) { ResolvedType thenExpr = node.getThenExpr().accept(this, solveLambdas); ResolvedType elseExpr = node.getElseExpr().accept(this, solveLambdas); - - // manage null expression - if ( thenExpr.isNull()) { - return elseExpr; - } - if ( elseExpr.isNull()) { - return thenExpr; - } - /* - * Boolean conditional expressions are standalone expressions - * The type of a boolean conditional expression is determined as follows: - * If the second and third operands are both of type Boolean, the conditional expression has type Boolean. - * Otherwise, the conditional expression has type boolean. - */ - if ( thenExpr.isAssignableBy(ResolvedPrimitiveType.BOOLEAN) - && elseExpr.isAssignableBy(ResolvedPrimitiveType.BOOLEAN)) { - if (thenExpr.isReferenceType() && elseExpr.isReferenceType()) { - return thenExpr.asReferenceType(); - } - return thenExpr.isPrimitive() ? thenExpr : elseExpr; - } - - /* - * Numeric conditional expressions are standalone expressions (§15.2). - * The type of a numeric conditional expression is determined as follows: - * If the second and third operands have the same type, then that is the type of the conditional expression. - * If one of the second and third operands is of primitive type T, and the type of the other is the result of - * applying boxing conversion (§5.1.7) to T, then the type of the conditional expression is T. - * If one of the operands is of type byte or Byte and the other is of type short or Short, then the type of the - * conditional expression is short. - * If one of the operands is of type T where T is byte, short, or char, and the other operand is a constant - * expression (§15.28) of type int whose value is representable in type T, then the type of the conditional - * expression is T. - * If one of the operands is of type T, where T is Byte, Short, or Character, and the other operand is a - * constant expression of type int whose value is representable in the type U which is the result of applying - * unboxing conversion to T, then the type of the conditional expression is U. - * Otherwise, binary numeric promotion (§5.6.2) is applied to the operand types, and the type of the - * conditional expression is the promoted type of the second and third operands. - */ - if (thenExpr.isNumericType() && elseExpr.isNumericType()) { - ResolvedPrimitiveType[] resolvedPrimitiveTypeSubList = new ResolvedPrimitiveType[] {ResolvedPrimitiveType.BYTE, ResolvedPrimitiveType.SHORT, ResolvedPrimitiveType.CHAR}; - /* - * If the second and third operands have the same type, then that is the type of the conditional expression. - */ - String qnameTypeThenExpr = thenExpr.isPrimitive() ? thenExpr.asPrimitive().describe() - : thenExpr.asReferenceType().describe(); - String qnameTypeElseExpr = elseExpr.isPrimitive() ? elseExpr.asPrimitive().describe() - : elseExpr.asReferenceType().describe(); - if (qnameTypeThenExpr.equals(qnameTypeElseExpr)) { - return thenExpr; - } - /* - * If one of the second and third operands is of primitive type T, and the type of the other is the result of - * applying boxing conversion (§5.1.7) to T, then the type of the conditional expression is T. - */ - else if ((thenExpr.isPrimitive() && elseExpr.isReferenceType() - && isCompatible(elseExpr.asReferenceType(), thenExpr.asPrimitive()))) { - return thenExpr; - } else if ((elseExpr.isPrimitive() && thenExpr.isReferenceType() - && isCompatible(thenExpr.asReferenceType(), elseExpr.asPrimitive()))) { - return elseExpr; - } - /* - * If one of the operands is of type byte or Byte and the other is of type short or Short, then the type of the - * conditional expression is short. - */ - else if ((isCompatible(thenExpr, ResolvedPrimitiveType.BYTE) && isCompatible(elseExpr, ResolvedPrimitiveType.SHORT)) - || (isCompatible(elseExpr, ResolvedPrimitiveType.BYTE) && isCompatible(thenExpr, ResolvedPrimitiveType.SHORT))) { - return ResolvedPrimitiveType.SHORT; - } - /* - * If one of the operands is of type T where T is byte, short, or char, and the - * other operand is a constant expression (§15.28) of type int whose value is - * representable in type T, then the type of the conditional expression is T - * How can we know if the constant expression of type int is representable in type T ? - * "The constant expression of type int is representable in type T" is a runtime decision! - */ - else if (thenExpr.isPrimitive() && elseExpr.isPrimitive()) { - if (((ResolvedPrimitiveType)thenExpr).in(resolvedPrimitiveTypeSubList) - && ((ResolvedPrimitiveType)elseExpr).equals(ResolvedPrimitiveType.INT)) { - return thenExpr; - } else if (((ResolvedPrimitiveType)elseExpr).in(resolvedPrimitiveTypeSubList) - && ((ResolvedPrimitiveType)thenExpr).equals(ResolvedPrimitiveType.INT)) { - return elseExpr; - } - } - /* If one of the operands is of type T, where T is Byte, Short, or Character, - * and the other operand is a constant expression of type int whose value is - * representable in the type U which is the result of applying unboxing - * conversion to T, then the type of the conditional expression is U. - * A priori this is a runtime decision! - */ - else if (thenExpr.isReference() && elseExpr.isPrimitive() - && thenExpr.asReferenceType().isUnboxable() - && thenExpr.asReferenceType().toUnboxedType().get().in(resolvedPrimitiveTypeSubList) - && ((ResolvedPrimitiveType)elseExpr).equals(ResolvedPrimitiveType.INT)) { - return thenExpr.asReferenceType().toUnboxedType().get(); - } else if (elseExpr.isReference() && thenExpr.isPrimitive() - && elseExpr.asReferenceType().isUnboxable() - && elseExpr.asReferenceType().toUnboxedType().get().in(resolvedPrimitiveTypeSubList) - && ((ResolvedPrimitiveType)thenExpr).equals(ResolvedPrimitiveType.INT)) { - return elseExpr.asReferenceType().toUnboxedType().get(); - } - - /* Otherwise, binary numeric promotion (§5.6.2) is applied to the operand types, - * and the type of the conditional expression is the promoted type of the second - * and third operands. - */ - ResolvedPrimitiveType PrimitiveThenExpr = thenExpr.isPrimitive() ? thenExpr.asPrimitive() - : thenExpr.asReferenceType().toUnboxedType().get(); - ResolvedPrimitiveType PrimitiveElseExpr = elseExpr.isPrimitive() ? elseExpr.asPrimitive() - : elseExpr.asReferenceType().toUnboxedType().get(); - return PrimitiveThenExpr.bnp(PrimitiveElseExpr); - } - - /* - * Otherwise, the conditional expression is a reference conditional expression. - * A reference conditional expression is a poly expression if it appears in an assignment context or an - * invocation context (§5.2. §5.3). - * Otherwise, it is a standalone expression. - * The type of a poly reference conditional expression is the same as its target type. - * The type of a standalone reference conditional expression is determined as follows: - * If the second and third operands have the same type (which may be the null type), then that is the type of - * the conditional expression. - * If the type of one of the second and third operands is the null type, and the type of the other operand is a - * reference type, then the type of the conditional expression is that reference type. - * Otherwise, the second and third operands are of types S1 and S2 respectively. Let T1 be the type that - * results from applying boxing conversion to S1, and let T2 be the type that results from applying boxing - * conversion to S2. The type of the conditional expression is the result of applying capture conversion - * (§5.1.10) to lub(T1, T2). - * TODO : must be implemented - */ - if (node.isPolyExpression()) { - // The type of a poly reference conditional expression is the same as its target type. - Optional parentNode = node.getParentNode(); - if (parentNode.isPresent()) { - Node parent = parentNode.get(); - if (parent instanceof AssignExpr) { - return visit((AssignExpr)parent, solveLambdas); - } else if (parent instanceof MethodCallExpr) { - // how to define the target type? - // a priori it is the type of the parameter of the method which takes the value of the conditional expression - // TODO for the moment we keep the original return type - return thenExpr; - } - throw new RuntimeException("Cannot resolve type of poly expression "+ node.toString()); - } else { - throw new RuntimeException("Parent node unexpectedly empty"); - } - - } - - // The type of a standalone reference conditional expression is determined as follows: - - // If the second and third operands have the same type (which may be the null type), then that is the type of - // the conditional expression. - if (thenExpr.equals(elseExpr)) { - return thenExpr; + + ConditionalExprHandler rce = ConditionalExprResolver.getConditionExprHandler(thenExpr, elseExpr); + try { + return rce.resolveType(); + } catch (UnsupportedOperationException e) { + // There is nothing to do because, for the moment, we want to run actual implementation } - // If the type of one of the second and third operands is the null type, and the type of the other operand is a - // reference type, then the type of the conditional expression is that reference type. - // this case is already supported above - - // Otherwise, the second and third operands are of types S1 and S2 respectively. Let T1 be the type that - // results from applying boxing conversion to S1, and let T2 be the type that results from applying boxing - // conversion to S2. The type of the conditional expression is the result of applying capture conversion - // (§5.1.10) to lub(T1, T2). - ResolvedType resolvedThenType = thenExpr.isPrimitive() ? TypeHelper.toBoxedType(thenExpr.asPrimitive(), typeSolver) : thenExpr; - ResolvedType resolvedElseType = elseExpr.isPrimitive() ? TypeHelper.toBoxedType(elseExpr.asPrimitive(), typeSolver) : elseExpr; - - // TypeHelper.leastUpperBound method is not yet implemented so for the moment we keep the original return type of this method - // TODO implement TypeHelper.leastUpperBound method - // return TypeHelper.leastUpperBound(new HashSet(Arrays.asList(resolvedThenType, resolvedElseType))); return node.getThenExpr().accept(this, solveLambdas); } - + private boolean isCompatible(ResolvedType resolvedType, ResolvedPrimitiveType primitiveType) { return (resolvedType.isPrimitive() && resolvedType.asPrimitive().equals(primitiveType)) || (resolvedType.isReferenceType() && resolvedType.asReferenceType().isUnboxableTo(primitiveType)); @@ -381,16 +214,17 @@ public ResolvedType visit(EnclosedExpr node, Boolean solveLambdas) { */ private ResolvedType solveDotExpressionType(ResolvedReferenceTypeDeclaration parentType, FieldAccessExpr node) { // Fields and internal type declarations cannot have the same name. - // Thus, these checks will always be mutually exclusive. + if (parentType.isEnum() && parentType.asEnum().hasEnumConstant(node.getName().getId())) { return parentType.asEnum().getEnumConstant(node.getName().getId()).getType(); - } else if (parentType.hasField(node.getName().getId())) { + } + if (parentType.hasField(node.getName().getId())) { return parentType.getField(node.getName().getId()).getType(); - } else if (parentType.hasInternalType(node.getName().getId())) { - return new ReferenceTypeImpl(parentType.getInternalType(node.getName().getId()), typeSolver); - } else { - throw new UnsolvedSymbolException(node.getName().getId()); } + if (parentType.hasInternalType(node.getName().getId())) { + return new ReferenceTypeImpl(parentType.getInternalType(node.getName().getId())); + } + throw new UnsolvedSymbolException(node.getName().getId()); } @Override @@ -426,13 +260,13 @@ public ResolvedType visit(FieldAccessExpr node, Boolean solveLambdas) { } Optional value = Optional.empty(); try { - value = new SymbolSolver(typeSolver).solveSymbolAsValue(node.getName().getId(), node); + value = createSolver().solveSymbolAsValue(node.getName().getId(), node); } catch (UnsolvedSymbolException use) { // This node may have a package name as part of its fully qualified name. // We should solve for the type declaration inside this package. SymbolReference sref = typeSolver.tryToSolveType(node.toString()); if (sref.isSolved()) { - return new ReferenceTypeImpl(sref.getCorrespondingDeclaration(), typeSolver); + return new ReferenceTypeImpl(sref.getCorrespondingDeclaration()); } } if (value.isPresent()) { @@ -448,7 +282,7 @@ public ResolvedType visit(InstanceOfExpr node, Boolean solveLambdas) { @Override public ResolvedType visit(StringLiteralExpr node, Boolean solveLambdas) { - return StringReferenceType; + return stringReferenceType; } @Override @@ -498,12 +332,11 @@ public ResolvedType visit(MethodCallExpr node, Boolean solveLambdas) { @Override public ResolvedType visit(NameExpr node, Boolean solveLambdas) { Log.trace("getType on name expr %s", ()-> node); - Optional value = new SymbolSolver(typeSolver).solveSymbolAsValue(node.getName().getId(), node); + Optional value = createSolver().solveSymbolAsValue(node.getName().getId(), node); if (!value.isPresent()) { throw new UnsolvedSymbolException("Solving " + node, node.getName().getId()); - } else { - return value.get().getType(); } + return value.get().getType(); } @Override @@ -521,11 +354,11 @@ public ResolvedType visit(TypeExpr node, Boolean solveLambdas) { .getContext(classOrInterfaceType, typeSolver) .solveType(nameWithScope); if (typeDeclarationSymbolReference.isSolved()) { - return new ReferenceTypeImpl(typeDeclarationSymbolReference.getCorrespondingDeclaration().asReferenceType(), typeSolver); + return new ReferenceTypeImpl(typeDeclarationSymbolReference.getCorrespondingDeclaration().asReferenceType()); } // JLS 15.13 - ExpressionName :: [TypeArguments] Identifier - Optional value = new SymbolSolver(typeSolver).solveSymbolAsValue(nameWithScope, node); + Optional value = createSolver().solveSymbolAsValue(nameWithScope, node); if (value.isPresent()) { return value.get().getType(); } @@ -535,7 +368,7 @@ public ResolvedType visit(TypeExpr node, Boolean solveLambdas) { @Override public ResolvedType visit(ObjectCreationExpr node, Boolean solveLambdas) { - return facade.convertToUsage(node.getType(), node); + return facade.convertToUsage(node.getType()); } @Override @@ -548,18 +381,17 @@ public ResolvedType visit(ThisExpr node, Boolean solveLambdas) { // first try a buttom/up approach try { return new ReferenceTypeImpl( - facade.getTypeDeclaration(facade.findContainingTypeDeclOrObjectCreationExpr(node, className)), - typeSolver); + facade.getTypeDeclaration(facade.findContainingTypeDeclOrObjectCreationExpr(node, className))); } catch (IllegalStateException e) { // trying another approach from type solver Optional cu = node.findAncestor(CompilationUnit.class); SymbolReference clazz = typeSolver.tryToSolveType(className); if (clazz.isSolved()) { - return new ReferenceTypeImpl(clazz.getCorrespondingDeclaration(), typeSolver); + return new ReferenceTypeImpl(clazz.getCorrespondingDeclaration()); } } } - return new ReferenceTypeImpl(facade.getTypeDeclaration(facade.findContainingTypeDeclOrObjectCreationExpr(node)), typeSolver); + return new ReferenceTypeImpl(facade.getTypeDeclaration(facade.findContainingTypeDeclOrObjectCreationExpr(node))); } @Override @@ -572,25 +404,23 @@ public ResolvedType visit(SuperExpr node, Boolean solveLambdas) { // Cfr JLS $15.12.1 ResolvedTypeDeclaration resolvedTypeName = resolvedTypeNameRef.getCorrespondingDeclaration(); if (resolvedTypeName.isInterface()) { - return new ReferenceTypeImpl(resolvedTypeName.asInterface(), typeSolver); - } else if (resolvedTypeName.isClass()) { + return new ReferenceTypeImpl(resolvedTypeName.asInterface()); + } + if (resolvedTypeName.isClass()) { // TODO: Maybe include a presence check? e.g. in the case of `java.lang.Object` there will be no superclass. return resolvedTypeName.asClass().getSuperClass().orElseThrow(() -> new RuntimeException("super class unexpectedly empty")); - } else { - throw new UnsupportedOperationException(node.getClass().getCanonicalName()); } - } else { - throw new UnsolvedSymbolException(className); + throw new UnsupportedOperationException(node.getClass().getCanonicalName()); } + throw new UnsolvedSymbolException(className); } ResolvedTypeDeclaration typeOfNode = facade.getTypeDeclaration(facade.findContainingTypeDeclOrObjectCreationExpr(node)); if (typeOfNode instanceof ResolvedClassDeclaration) { // TODO: Maybe include a presence check? e.g. in the case of `java.lang.Object` there will be no superclass. return ((ResolvedClassDeclaration) typeOfNode).getSuperClass().orElseThrow(() -> new RuntimeException("super class unexpectedly empty")); - } else { - throw new UnsupportedOperationException(node.getClass().getCanonicalName()); } + throw new UnsupportedOperationException(node.getClass().getCanonicalName()); } @Override @@ -617,25 +447,26 @@ public ResolvedType visit(VariableDeclarationExpr node, Boolean solveLambdas) { if (node.getVariables().size() != 1) { throw new UnsupportedOperationException(); } - return facade.convertToUsageVariableType(node.getVariables().get(0)); + return facade.convertToUsage(node.getVariables().get(0).getType()); } @Override public ResolvedType visit(LambdaExpr node, Boolean solveLambdas) { - if (demandParentNode(node) instanceof MethodCallExpr) { - MethodCallExpr callExpr = (MethodCallExpr) demandParentNode(node); - int pos = JavaParserSymbolDeclaration.getParamPos(node); + Node parentNode = demandParentNode(node, IS_NOT_ENCLOSED_EXPR); + if (parentNode instanceof MethodCallExpr) { + MethodCallExpr callExpr = (MethodCallExpr) parentNode; + int pos = getParamPos(node); SymbolReference refMethod = facade.solve(callExpr); if (!refMethod.isSolved()) { - throw new UnsolvedSymbolException(demandParentNode(node).toString(), callExpr.getName().getId()); + throw new UnsolvedSymbolException(parentNode.toString(), callExpr.getName().getId()); } Log.trace("getType on lambda expr %s", ()-> refMethod.getCorrespondingDeclaration().getName()); - if (solveLambdas) { - // The type parameter referred here should be the java.util.stream.Stream.T - ResolvedType result = refMethod.getCorrespondingDeclaration().getParam(pos).getType(); + // The type parameter referred here should be the java.util.stream.Stream.T + ResolvedType result = refMethod.getCorrespondingDeclaration().getParam(pos).getType(); + if (solveLambdas) { if (callExpr.hasScope()) { Expression scope = callExpr.getScope().get(); @@ -661,85 +492,109 @@ public ResolvedType visit(LambdaExpr node, Boolean solveLambdas) { } } - // We need to replace the type variables - Context ctx = JavaParserFactory.getContext(node, typeSolver); - result = solveGenericTypes(result, ctx); - - //We should find out which is the functional method (e.g., apply) and replace the params of the - //solveLambdas with it, to derive so the values. We should also consider the value returned by the - //lambdas - Optional functionalMethod = FunctionalInterfaceLogic.getFunctionalMethod(result); - if (functionalMethod.isPresent()) { - LambdaExpr lambdaExpr = node; - - InferenceContext lambdaCtx = new InferenceContext(MyObjectProvider.INSTANCE); - InferenceContext funcInterfaceCtx = new InferenceContext(MyObjectProvider.INSTANCE); + result = resolveLambda(node, result); + } + return result; + } + if (demandParentNode(node) instanceof VariableDeclarator) { + VariableDeclarator decExpr = (VariableDeclarator) demandParentNode(node); + ResolvedType result = decExpr.getType().resolve(); - // At this point parameterType - // if Function - // we should replace Stream.T - ResolvedType functionalInterfaceType = ReferenceTypeImpl.undeterminedParameters(functionalMethod.get().getDeclaration().declaringType(), typeSolver); + if (solveLambdas) { + result = resolveLambda(node, result); + } + return result; + } + if (demandParentNode(node) instanceof AssignExpr) { + AssignExpr assExpr = (AssignExpr) demandParentNode(node); + ResolvedType result = assExpr.calculateResolvedType(); - lambdaCtx.addPair(result, functionalInterfaceType); + if (solveLambdas) { + result = resolveLambda(node, result); + } + return result; + } + throw new UnsupportedOperationException("The type of a lambda expr depends on the position and its return value"); + } - ResolvedType actualType; + private ResolvedType resolveLambda(LambdaExpr node, ResolvedType result) { + // We need to replace the type variables + Context ctx = JavaParserFactory.getContext(node, typeSolver); + result = result.solveGenericTypes(ctx); - if (lambdaExpr.getBody() instanceof ExpressionStmt) { - actualType = facade.getType(((ExpressionStmt) lambdaExpr.getBody()).getExpression()); - } else if (lambdaExpr.getBody() instanceof BlockStmt) { - BlockStmt blockStmt = (BlockStmt) lambdaExpr.getBody(); + //We should find out which is the functional method (e.g., apply) and replace the params of the + //solveLambdas with it, to derive so the values. We should also consider the value returned by the + //lambdas + Optional functionalMethod = FunctionalInterfaceLogic.getFunctionalMethod(result); + if (functionalMethod.isPresent()) { + LambdaExpr lambdaExpr = node; - // Get all the return statements in the lambda block - List returnStmts = blockStmt.findAll(ReturnStmt.class); + InferenceContext lambdaCtx = new InferenceContext(typeSolver); + InferenceContext funcInterfaceCtx = new InferenceContext(typeSolver); - if (returnStmts.size() > 0) { - actualType = returnStmts.stream() - .map(returnStmt -> returnStmt.getExpression().map(e -> facade.getType(e)).orElse(ResolvedVoidType.INSTANCE)) - .filter(x -> x != null && !x.isVoid() && !x.isNull()) - .findFirst() - .orElse(ResolvedVoidType.INSTANCE); + // At this point parameterType + // if Function + // we should replace Stream.T + ResolvedType functionalInterfaceType = ReferenceTypeImpl.undeterminedParameters(functionalMethod.get().getDeclaration().declaringType()); - } else { - actualType = ResolvedVoidType.INSTANCE; - } + lambdaCtx.addPair(result, functionalInterfaceType); + ResolvedType actualType; - } else { - throw new UnsupportedOperationException(); - } + if (lambdaExpr.getBody() instanceof ExpressionStmt) { + actualType = facade.getType(((ExpressionStmt) lambdaExpr.getBody()).getExpression()); + } else if (lambdaExpr.getBody() instanceof BlockStmt) { + BlockStmt blockStmt = (BlockStmt) lambdaExpr.getBody(); - ResolvedType formalType = functionalMethod.get().returnType(); + // Get all the return statements in the lambda block + List returnStmts = blockStmt.findAll(ReturnStmt.class); - // Infer the functional interfaces' return vs actual type - funcInterfaceCtx.addPair(formalType, actualType); - // Substitute to obtain a new type - ResolvedType functionalTypeWithReturn = funcInterfaceCtx.resolve(funcInterfaceCtx.addSingle(functionalInterfaceType)); + if (returnStmts.size() > 0) { + Set resolvedTypes = returnStmts.stream() + .map(returnStmt -> returnStmt.getExpression() + .map(e -> facade.getType(e)) + .orElse(ResolvedVoidType.INSTANCE)) + .collect(Collectors.toSet()); + actualType = LeastUpperBoundLogic.of().lub(resolvedTypes); - // if the functional method returns void anyway - // we don't need to bother inferring types - if (!(formalType instanceof ResolvedVoidType)) { - lambdaCtx.addPair(result, functionalTypeWithReturn); - result = lambdaCtx.resolve(lambdaCtx.addSingle(result)); - } + } else { + actualType = ResolvedVoidType.INSTANCE; } - return result; + } else { - return refMethod.getCorrespondingDeclaration().getParam(pos).getType(); + throw new UnsupportedOperationException(); + } + + ResolvedType formalType = functionalMethod.get().returnType(); + + // Infer the functional interfaces' return vs actual type + funcInterfaceCtx.addPair(formalType, actualType); + // Substitute to obtain a new type + ResolvedType functionalTypeWithReturn = funcInterfaceCtx.resolve(funcInterfaceCtx.addSingle(functionalInterfaceType)); + + // if the functional method returns void anyway + // we don't need to bother inferring types + if (!(formalType instanceof ResolvedVoidType)) { + lambdaCtx.addPair(result, functionalTypeWithReturn); + result = lambdaCtx.resolve(lambdaCtx.addSingle(result)); } - } else { - throw new UnsupportedOperationException("The type of a lambda expr depends on the position and its return value"); } + return result; } @Override public ResolvedType visit(MethodReferenceExpr node, Boolean solveLambdas) { - if (demandParentNode(node) instanceof MethodCallExpr) { - MethodCallExpr callExpr = (MethodCallExpr) demandParentNode(node); - int pos = JavaParserSymbolDeclaration.getParamPos(node); + if ("new".equals(node.getIdentifier())) { + return node.getScope().calculateResolvedType(); + } + Node parentNode = demandParentNode(node); + if (parentNode instanceof MethodCallExpr) { + MethodCallExpr callExpr = (MethodCallExpr) parentNode; + int pos = getParamPos(node); SymbolReference refMethod = facade.solve(callExpr, false); if (!refMethod.isSolved()) { - throw new UnsolvedSymbolException(demandParentNode(node).toString(), callExpr.getName().getId()); + throw new UnsolvedSymbolException(parentNode.toString(), callExpr.getName().getId()); } Log.trace("getType on method reference expr %s", ()-> refMethod.getCorrespondingDeclaration().getName()); if (solveLambdas) { @@ -747,7 +602,7 @@ public ResolvedType visit(MethodReferenceExpr node, Boolean solveLambdas) { ResolvedType result = usage.getParamType(pos); // We need to replace the type variables Context ctx = JavaParserFactory.getContext(node, typeSolver); - result = solveGenericTypes(result, ctx); + result = result.solveGenericTypes(ctx); //We should find out which is the functional method (e.g., apply) and replace the params of the //solveLambdas with it, to derive so the values. We should also consider the value returned by the @@ -772,14 +627,21 @@ public ResolvedType visit(MethodReferenceExpr node, Boolean solveLambdas) { ResolvedType actualType = facade.toMethodUsage(node, functionalMethod.getParamTypes()).returnType(); ResolvedType formalType = functionalMethod.returnType(); - InferenceContext inferenceContext = new InferenceContext(MyObjectProvider.INSTANCE); + InferenceContext inferenceContext = new InferenceContext(typeSolver); inferenceContext.addPair(formalType, actualType); result = inferenceContext.resolve(inferenceContext.addSingle(result)); } return result; } - return refMethod.getCorrespondingDeclaration().getParam(pos).getType(); + // Since variable parameters are represented by an array, in case we deal with + // the variadic parameter we have to take into account the base type of the + // array. + ResolvedMethodDeclaration rmd = refMethod.getCorrespondingDeclaration(); + if (rmd.hasVariadicParameter() && pos >= rmd.getNumberOfParams() - 1) { + return rmd.getLastParam().getType().asArrayType().getComponentType(); + } + return rmd.getParam(pos).getType(); } throw new UnsupportedOperationException("The type of a method reference expr depends on the position and its return value"); } @@ -791,4 +653,17 @@ public ResolvedType visit(FieldDeclaration node, Boolean solveLambdas) { } throw new IllegalArgumentException("Cannot resolve the type of a field with multiple variable declarations. Pick one"); } + + private static int getParamPos(Expression node) { + Node parentNode = demandParentNode(node, IS_NOT_ENCLOSED_EXPR); + if (parentNode instanceof MethodCallExpr) { + MethodCallExpr call = (MethodCallExpr) parentNode; + return call.getArgumentPosition(node, EXCLUDE_ENCLOSED_EXPR); + } + throw new IllegalArgumentException(); + } + + protected Solver createSolver() { + return new SymbolSolver(typeSolver); + } } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/AbstractJavaParserContext.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/AbstractJavaParserContext.java similarity index 79% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/AbstractJavaParserContext.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/AbstractJavaParserContext.java index b71ea5c..fc00797 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/AbstractJavaParserContext.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/AbstractJavaParserContext.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -21,31 +21,25 @@ package com.github.javaparser.symbolsolver.javaparsermodel.contexts; +import static com.github.javaparser.resolution.Navigator.demandParentNode; +import static java.util.Collections.singletonList; + +import java.util.*; + import com.github.javaparser.ast.Node; import com.github.javaparser.ast.expr.*; import com.github.javaparser.ast.nodeTypes.NodeWithOptionalScope; -import com.github.javaparser.resolution.UnsolvedSymbolException; -import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration; -import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration; -import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration; -import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration; +import com.github.javaparser.resolution.*; +import com.github.javaparser.resolution.declarations.*; +import com.github.javaparser.resolution.model.SymbolReference; +import com.github.javaparser.resolution.model.Value; import com.github.javaparser.resolution.types.ResolvedReferenceType; import com.github.javaparser.resolution.types.ResolvedType; -import com.github.javaparser.symbolsolver.core.resolution.Context; +import com.github.javaparser.symbolsolver.core.resolution.TypeVariableResolutionCapability; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory; import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserPatternDeclaration; import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserSymbolDeclaration; -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.reflectionmodel.ReflectionClassDeclaration; -import com.github.javaparser.symbolsolver.resolution.SymbolDeclarator; - -import java.util.*; - -import static com.github.javaparser.symbolsolver.javaparser.Navigator.demandParentNode; -import static java.util.Collections.singletonList; /** * @author Federico Tomassetti @@ -58,7 +52,7 @@ public abstract class AbstractJavaParserContext implements Conte /// /// Static methods /// - + protected static boolean isQualifiedName(String name) { return name.contains("."); } @@ -69,7 +63,7 @@ public static SymbolReference solveWith(SymbolDeclarat return SymbolReference.solved(decl); } } - return SymbolReference.unsolved(ResolvedValueDeclaration.class); + return SymbolReference.unsolved(); } /// @@ -127,7 +121,7 @@ public final Optional getParent() { } } Node notMethodNode = parentNode; - // to avoid an infinite loop if parent scope is the same as wrapped node + // to avoid an infinite loop if parent scope is the same as wrapped node while (notMethodNode instanceof MethodCallExpr || notMethodNode instanceof FieldAccessExpr || (notMethodNode != null && notMethodNode.hasScope() && getScope(notMethodNode).equals(wrappedNode)) ) { notMethodNode = notMethodNode.getParentNode().orElse(null); @@ -138,8 +132,8 @@ public final Optional getParent() { Context parentContext = JavaParserFactory.getContext(notMethodNode, typeSolver); return Optional.of(parentContext); } - - // before to call this method verify the node has a scope + + // before to call this method verify the node has a scope protected Node getScope(Node node) { return (Node) ((NodeWithOptionalScope)node).getScope().get(); } @@ -149,7 +143,7 @@ protected Node getScope(Node node) { public SymbolReference solveSymbolInParentContext(String name) { Optional optionalParentContext = getParent(); if (!optionalParentContext.isPresent()) { - return SymbolReference.unsolved(ResolvedValueDeclaration.class); + return SymbolReference.unsolved(); } // First check if there are any pattern expressions available to this node. @@ -163,10 +157,11 @@ public SymbolReference solveSymbolInParentCo .findFirst(); if (localResolutionResults.isPresent()) { - if(patternExprs.size() == 1) { + if (patternExprs.size() == 1) { JavaParserPatternDeclaration decl = JavaParserSymbolDeclaration.patternVar(localResolutionResults.get(), typeSolver); return SymbolReference.solved(decl); - } else if(patternExprs.size() > 1) { + } + if(patternExprs.size() > 1) { throw new IllegalStateException("Unexpectedly more than one reference in scope"); } } @@ -223,13 +218,14 @@ protected Collection findTypeDeclarations(Opti .getTypeDeclaration() .orElseThrow(() -> new RuntimeException("TypeDeclaration unexpectedly empty.")) ); - } else { - return singletonList(new ReflectionClassDeclaration(Object.class, typeSolver).asReferenceType()); } - } else if (typeOfScope.isArray()) { + return singletonList(typeSolver.getSolvedJavaLangObject()); + } + if (typeOfScope.isArray()) { // method call on array are Object methods - return singletonList(new ReflectionClassDeclaration(Object.class, typeSolver).asReferenceType()); - } else if (typeOfScope.isTypeVariable()) { + return singletonList(typeSolver.getSolvedJavaLangObject()); + } + if (typeOfScope.isTypeVariable()) { Collection result = new ArrayList<>(); for (ResolvedTypeParameterDeclaration.Bound bound : typeOfScope.asTypeParameter().getBounds()) { // TODO: Figure out if it is appropriate to remove the orElseThrow() -- if so, how... @@ -241,16 +237,19 @@ protected Collection findTypeDeclarations(Opti ); } return result; - } else if (typeOfScope.isConstraint()) { + } + if (typeOfScope.isConstraint()) { // TODO: Figure out if it is appropriate to remove the orElseThrow() -- if so, how... - return singletonList( - typeOfScope.asConstraintType() - .getBound() - .asReferenceType() - .getTypeDeclaration() - .orElseThrow(() -> new RuntimeException("TypeDeclaration unexpectedly empty.")) - ); - } else if (typeOfScope.isUnionType()) { + ResolvedType type = typeOfScope.asConstraintType().getBound(); + if (type.isReferenceType()) { + return singletonList( + type.asReferenceType().getTypeDeclaration() + .orElseThrow(() -> new RuntimeException("TypeDeclaration unexpectedly empty.")) + ); + } + throw new UnsupportedOperationException("The type declaration cannot be found on constraint "+ type.describe()); + } + if (typeOfScope.isUnionType()) { return typeOfScope.asUnionType().getCommonAncestor() .flatMap(ResolvedReferenceType::getTypeDeclaration) .map(Collections::singletonList) @@ -275,6 +274,29 @@ protected Collection findTypeDeclarations(Opti ); } + /** + * Similar to solveMethod but we return a MethodUsage. + * A MethodUsage corresponds to a MethodDeclaration plus the resolved type variables. + */ + @Override + public Optional solveMethodAsUsage(String name, List argumentsTypes) { + SymbolReference methodSolved = solveMethod(name, argumentsTypes, false); + if (methodSolved.isSolved()) { + ResolvedMethodDeclaration methodDeclaration = methodSolved.getCorrespondingDeclaration(); + if (!(methodDeclaration instanceof TypeVariableResolutionCapability)) { + throw new UnsupportedOperationException(String.format( + "Resolved method declarations must implement %s.", + TypeVariableResolutionCapability.class.getName() + )); + } + + MethodUsage methodUsage = ((TypeVariableResolutionCapability) methodDeclaration).resolveTypeVariables(this, argumentsTypes); + return Optional.of(methodUsage); + } + return Optional.empty(); + } + + @Override public N getWrappedNode() { return wrappedNode; } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/AbstractMethodLikeDeclarationContext.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/AbstractMethodLikeDeclarationContext.java similarity index 91% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/AbstractMethodLikeDeclarationContext.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/AbstractMethodLikeDeclarationContext.java index 6a3b8af..cce4dd8 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/AbstractMethodLikeDeclarationContext.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/AbstractMethodLikeDeclarationContext.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -27,18 +27,18 @@ import com.github.javaparser.ast.nodeTypes.NodeWithParameters; import com.github.javaparser.ast.nodeTypes.NodeWithTypeParameters; import com.github.javaparser.ast.type.TypeParameter; +import com.github.javaparser.resolution.SymbolDeclarator; +import com.github.javaparser.resolution.TypeSolver; 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.model.SymbolReference; +import com.github.javaparser.resolution.model.Value; import com.github.javaparser.resolution.types.ResolvedType; import com.github.javaparser.resolution.types.ResolvedTypeVariable; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory; import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeParameter; -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.SymbolDeclarator; import java.util.List; import java.util.Optional; @@ -97,7 +97,7 @@ public final Optional solveSymbolAsValue(String name) { } @Override - public final SymbolReference solveType(String name) { + public final SymbolReference solveType(String name, List typeArguments) { // TODO: Is null check required? if (wrappedNode.getTypeParameters() != null) { for (TypeParameter tp : wrappedNode.getTypeParameters()) { @@ -113,13 +113,14 @@ public final SymbolReference solveType(String name) { if (localType.getName().getId().equals(name)) { return SymbolReference.solved(JavaParserFacade.get(typeSolver) .getTypeDeclaration(localType)); - } else if (name.startsWith(String.format("%s.", localType.getName()))) { + } + if (name.startsWith(String.format("%s.", localType.getName()))) { return JavaParserFactory.getContext(localType, typeSolver) .solveType(name.substring(localType.getName().getId().length() + 1)); } } - return solveTypeInParentContext(name); + return solveTypeInParentContext(name, typeArguments); } @Override diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/AnnotationDeclarationContext.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/AnnotationDeclarationContext.java similarity index 90% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/AnnotationDeclarationContext.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/AnnotationDeclarationContext.java index d189976..a31032e 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/AnnotationDeclarationContext.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/AnnotationDeclarationContext.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -22,14 +22,14 @@ package com.github.javaparser.symbolsolver.javaparsermodel.contexts; import com.github.javaparser.ast.body.AnnotationDeclaration; +import com.github.javaparser.resolution.TypeSolver; 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.model.SymbolReference; import com.github.javaparser.resolution.types.ResolvedType; import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserAnnotationDeclaration; -import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; import java.util.List; @@ -59,8 +59,8 @@ public SymbolReference solveSymbol(String na } @Override - public SymbolReference solveType(String name) { - return javaParserTypeDeclarationAdapter.solveType(name); + public SymbolReference solveType(String name, List resolvedTypes) { + return javaParserTypeDeclarationAdapter.solveType(name, resolvedTypes); } @Override diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/AnonymousClassDeclarationContext.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/AnonymousClassDeclarationContext.java similarity index 96% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/AnonymousClassDeclarationContext.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/AnonymousClassDeclarationContext.java index ca4ea87..c90e59d 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/AnonymousClassDeclarationContext.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/AnonymousClassDeclarationContext.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -26,20 +26,20 @@ import com.github.javaparser.ast.expr.ObjectCreationExpr; import com.github.javaparser.ast.nodeTypes.NodeWithTypeArguments; import com.github.javaparser.ast.type.TypeParameter; +import com.github.javaparser.resolution.TypeSolver; 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.logic.MethodResolutionLogic; +import com.github.javaparser.resolution.model.SymbolReference; import com.github.javaparser.resolution.types.ResolvedReferenceType; import com.github.javaparser.resolution.types.ResolvedType; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory; import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserAnonymousClassDeclaration; import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeParameter; -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.MethodResolutionLogic; import com.google.common.base.Preconditions; import java.util.List; @@ -122,7 +122,7 @@ public SymbolReference solveMethod(String name, } @Override - public SymbolReference solveType(String name) { + public SymbolReference solveType(String name, List typeArguments) { List typeDeclarations = myDeclaration.findMembersOfKind(TypeDeclaration.class); Optional> exactMatch = @@ -193,7 +193,7 @@ public SymbolReference solveType(String name) { } } - return solveTypeInParentContext(name); + return solveTypeInParentContext(name, typeArguments); } @Override diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ArrayAccessExprContext.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ArrayAccessExprContext.java similarity index 94% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ArrayAccessExprContext.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ArrayAccessExprContext.java index 400b89e..7b96c8b 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ArrayAccessExprContext.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ArrayAccessExprContext.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -22,9 +22,9 @@ package com.github.javaparser.symbolsolver.javaparsermodel.contexts; import com.github.javaparser.ast.expr.ArrayAccessExpr; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration; -import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; +import com.github.javaparser.resolution.model.SymbolReference; /** *

diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/BinaryExprContext.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/BinaryExprContext.java similarity index 92% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/BinaryExprContext.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/BinaryExprContext.java index 4f7e1e3..cc93349 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/BinaryExprContext.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/BinaryExprContext.java @@ -1,12 +1,32 @@ +/* + * Copyright (C) 2013-2023 The JavaParser Team. + * + * This file is part of JavaParser. + * + * JavaParser can be used either under the terms of + * a) the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * b) the terms of the Apache License + * + * You should have received a copy of both licenses in LICENCE.LGPL and + * LICENCE.APACHE. Please refer to those files for details. + * + * JavaParser is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + */ + package com.github.javaparser.symbolsolver.javaparsermodel.contexts; import com.github.javaparser.ast.Node; import com.github.javaparser.ast.expr.BinaryExpr; import com.github.javaparser.ast.expr.Expression; import com.github.javaparser.ast.expr.PatternExpr; -import com.github.javaparser.symbolsolver.core.resolution.Context; +import com.github.javaparser.resolution.Context; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; import java.util.ArrayList; import java.util.List; diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/BlockStmtContext.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/BlockStmtContext.java similarity index 93% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/BlockStmtContext.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/BlockStmtContext.java index ccaed5a..acef8b9 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/BlockStmtContext.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/BlockStmtContext.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -27,11 +27,11 @@ import com.github.javaparser.ast.stmt.BlockStmt; import com.github.javaparser.ast.stmt.ExpressionStmt; import com.github.javaparser.ast.stmt.Statement; +import com.github.javaparser.resolution.Context; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration; -import com.github.javaparser.symbolsolver.core.resolution.Context; +import com.github.javaparser.resolution.model.SymbolReference; import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserSymbolDeclaration; -import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; import java.util.Collections; import java.util.LinkedList; @@ -74,7 +74,7 @@ private List localVariablesDeclaredIn(Statement statement) { public SymbolReference solveSymbol(String name) { Optional optionalParent = getParent(); if (!optionalParent.isPresent()) { - return SymbolReference.unsolved(ResolvedValueDeclaration.class); + return SymbolReference.unsolved(); } if (wrappedNode.getStatements().size() > 0) { diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/CatchClauseContext.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/CatchClauseContext.java similarity index 91% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/CatchClauseContext.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/CatchClauseContext.java index f909267..809cbe0 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/CatchClauseContext.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/CatchClauseContext.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -25,14 +25,14 @@ import com.github.javaparser.ast.body.Parameter; import com.github.javaparser.ast.body.VariableDeclarator; import com.github.javaparser.ast.stmt.CatchClause; +import com.github.javaparser.resolution.SymbolDeclarator; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration; import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration; +import com.github.javaparser.resolution.model.SymbolReference; +import com.github.javaparser.resolution.model.Value; import com.github.javaparser.resolution.types.ResolvedType; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory; -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.SymbolDeclarator; import java.util.Collections; import java.util.List; diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ClassOrInterfaceDeclarationContext.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ClassOrInterfaceDeclarationContext.java similarity index 90% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ClassOrInterfaceDeclarationContext.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ClassOrInterfaceDeclarationContext.java index 308fb7b..78b95c6 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ClassOrInterfaceDeclarationContext.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ClassOrInterfaceDeclarationContext.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -24,14 +24,14 @@ import com.github.javaparser.ast.Node; import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; import com.github.javaparser.ast.type.TypeParameter; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.*; +import com.github.javaparser.resolution.model.SymbolReference; +import com.github.javaparser.resolution.model.Value; import com.github.javaparser.resolution.types.ResolvedType; import com.github.javaparser.resolution.types.ResolvedTypeVariable; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade; import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeParameter; -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 java.util.LinkedList; import java.util.List; @@ -97,8 +97,8 @@ public Optional solveGenericType(String name) { } @Override - public SymbolReference solveType(String name) { - return javaParserTypeDeclarationAdapter.solveType(name); + public SymbolReference solveType(String name, List typeArguments) { + return javaParserTypeDeclarationAdapter.solveType(name, typeArguments); } @Override @@ -114,8 +114,8 @@ public SymbolReference solveConstructor(List fieldsExposedToChild(Node child) { List fields = new LinkedList<>(); fields.addAll(this.wrappedNode.resolve().getDeclaredFields()); - this.wrappedNode.getExtendedTypes().forEach(i -> fields.addAll(i.resolve().getAllFieldsVisibleToInheritors())); - this.wrappedNode.getImplementedTypes().forEach(i -> fields.addAll(i.resolve().getAllFieldsVisibleToInheritors())); + this.wrappedNode.getExtendedTypes().forEach(i -> fields.addAll(i.resolve().asReferenceType().getAllFieldsVisibleToInheritors())); + this.wrappedNode.getImplementedTypes().forEach(i -> fields.addAll(i.resolve().asReferenceType().getAllFieldsVisibleToInheritors())); return fields; } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ClassOrInterfaceDeclarationExtendsContext.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ClassOrInterfaceDeclarationExtendsContext.java similarity index 84% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ClassOrInterfaceDeclarationExtendsContext.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ClassOrInterfaceDeclarationExtendsContext.java index 62b344c..32e4844 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ClassOrInterfaceDeclarationExtendsContext.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ClassOrInterfaceDeclarationExtendsContext.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2007-2010 Júlio Vilmar Gesser. - * Copyright (C) 2011, 2013-2021 The JavaParser Team. + * Copyright (C) 2011, 2013-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -23,10 +23,13 @@ import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; import com.github.javaparser.ast.type.TypeParameter; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration; +import com.github.javaparser.resolution.model.SymbolReference; +import com.github.javaparser.resolution.types.ResolvedType; import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeParameter; -import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; + +import java.util.List; /** * Limited version of ClassOrInterfaceDeclarationContext that only resolves type parameters for use by @@ -38,13 +41,13 @@ public ClassOrInterfaceDeclarationExtendsContext(ClassOrInterfaceDeclaration wra } @Override - public SymbolReference solveType(String name) { + public SymbolReference solveType(String name, List typeArguments) { for (TypeParameter typeParameter : wrappedNode.getTypeParameters()) { if (typeParameter.getName().getId().equals(name)) { return SymbolReference.solved(new JavaParserTypeParameter(typeParameter, typeSolver)); } } - return super.solveType(name); + return super.solveType(name, typeArguments); } } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/CompilationUnitContext.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/CompilationUnitContext.java similarity index 87% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/CompilationUnitContext.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/CompilationUnitContext.java index 0eaf871..8a7be56 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/CompilationUnitContext.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/CompilationUnitContext.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -31,21 +31,20 @@ import com.github.javaparser.ast.body.TypeDeclaration; import com.github.javaparser.ast.expr.Name; import com.github.javaparser.ast.type.ClassOrInterfaceType; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.*; +import com.github.javaparser.resolution.logic.MethodResolutionLogic; +import com.github.javaparser.resolution.model.SymbolReference; import com.github.javaparser.resolution.types.ResolvedType; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade; import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserAnnotationDeclaration; import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration; import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserEnumDeclaration; import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserInterfaceDeclaration; -import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; -import com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic; import com.github.javaparser.symbolsolver.resolution.SymbolSolver; import java.util.LinkedList; import java.util.List; -import java.util.Optional; import java.util.stream.Collectors; /** @@ -53,6 +52,8 @@ */ public class CompilationUnitContext extends AbstractJavaParserContext { + private static final String DEFAULT_PACKAGE = "java.lang"; + /// /// Static methods /// @@ -80,9 +81,8 @@ public SymbolReference solveSymbol(String na SymbolReference type = this.solveType(typeName); if (type.isSolved()) { return new SymbolSolver(typeSolver).solveSymbolInType(type.getCorrespondingDeclaration(), memberName); - } else { - itName = typeName; } + itName = typeName; } // Look among statically imported values @@ -114,11 +114,11 @@ public SymbolReference solveSymbol(String na } } - return SymbolReference.unsolved(ResolvedValueDeclaration.class); + return SymbolReference.unsolved(); } @Override - public SymbolReference solveType(String name) { + public SymbolReference solveType(String name, List typeArguments) { if (wrappedNode.getTypes() != null) { // Look for types in this compilation unit. For instance, if the given name is "A", there may be a class or @@ -128,13 +128,16 @@ public SymbolReference solveType(String name) { || type.getFullyQualifiedName().map(qualified -> qualified.equals(name)).orElse(false)) { if (type instanceof ClassOrInterfaceDeclaration) { return SymbolReference.solved(JavaParserFacade.get(typeSolver).getTypeDeclaration((ClassOrInterfaceDeclaration) type)); - } else if (type instanceof AnnotationDeclaration) { + } + + if (type instanceof AnnotationDeclaration) { return SymbolReference.solved(new JavaParserAnnotationDeclaration((AnnotationDeclaration) type, typeSolver)); - } else if (type instanceof EnumDeclaration) { + } + + if (type instanceof EnumDeclaration) { return SymbolReference.solved(new JavaParserEnumDeclaration((EnumDeclaration) type, typeSolver)); - } else { - throw new UnsupportedOperationException(type.getClass().getCanonicalName()); } + throw new UnsupportedOperationException(type.getClass().getCanonicalName()); } } @@ -191,7 +194,7 @@ public SymbolReference solveType(String name) { // Look in current package if (this.wrappedNode.getPackageDeclaration().isPresent()) { - String qName = this.wrappedNode.getPackageDeclaration().get().getName().toString() + "." + name; + String qName = this.wrappedNode.getPackageDeclaration().get().getNameAsString() + "." + name; SymbolReference ref = typeSolver.tryToSolveType(qName); if (ref != null && ref.isSolved()) { return SymbolReference.adapt(ref, ResolvedTypeDeclaration.class); @@ -217,33 +220,30 @@ public SymbolReference solveType(String name) { } // Look in the java.lang package - SymbolReference ref = typeSolver.tryToSolveType("java.lang." + name); + SymbolReference ref = typeSolver.tryToSolveType(DEFAULT_PACKAGE+ "." + name); if (ref != null && ref.isSolved()) { return SymbolReference.adapt(ref, ResolvedTypeDeclaration.class); } - // DO NOT look for absolute name if this name is not qualified: you cannot import classes from the default package + if (isQualifiedName(name)) { return SymbolReference.adapt(typeSolver.tryToSolveType(name), ResolvedTypeDeclaration.class); - } else { - return SymbolReference.unsolved(ResolvedReferenceTypeDeclaration.class); } + return SymbolReference.unsolved(); } private String qName(ClassOrInterfaceType type) { if (type.getScope().isPresent()) { return qName(type.getScope().get()) + "." + type.getName().getId(); - } else { - return type.getName().getId(); } + return type.getName().getId(); } private String qName(Name name) { if (name.getQualifier().isPresent()) { return qName(name.getQualifier().get()) + "." + name.getId(); - } else { - return name.getId(); } + return name.getId(); } private String toSimpleName(String qName) { @@ -255,9 +255,8 @@ private String packageName(String qName) { int lastDot = qName.lastIndexOf('.'); if (lastDot == -1) { throw new UnsupportedOperationException(); - } else { - return qName.substring(0, lastDot); } + return qName.substring(0, lastDot); } @Override @@ -272,7 +271,7 @@ public SymbolReference solveMethod(String name, List< && this.wrappedNode.getTypes().stream().anyMatch(it -> it.getName().getIdentifier().equals(toSimpleName(importString)))) { // We are using a static import on a type defined in this file. It means the value was not found at // a lower level so this will fail - return SymbolReference.unsolved(ResolvedMethodDeclaration.class); + return SymbolReference.unsolved(); } ResolvedTypeDeclaration ref = typeSolver.solveType(importString); @@ -292,14 +291,13 @@ public SymbolReference solveMethod(String name, List< SymbolReference method = MethodResolutionLogic.solveMethodInType(ref, name, argumentsTypes, true); if (method.isSolved()) { return method; - } else { - return SymbolReference.unsolved(ResolvedMethodDeclaration.class); } + return SymbolReference.unsolved(); } } } } - return SymbolReference.unsolved(ResolvedMethodDeclaration.class); + return SymbolReference.unsolved(); } @Override @@ -343,18 +341,9 @@ private String getMember(String qName) { } private boolean isAncestorOf(ResolvedTypeDeclaration descendant) { - if (descendant instanceof AssociableToAST) { - Optional astOpt = ((AssociableToAST) descendant).toAst(); - if (astOpt.isPresent()) { - return wrappedNode.isAncestorOf(astOpt.get()); - } else { - return false; - } - } else if (descendant instanceof JavaParserEnumDeclaration) { - return wrappedNode.isAncestorOf(((JavaParserEnumDeclaration) descendant).getWrappedNode()); - } else { - throw new UnsupportedOperationException(); - } + return descendant.toAst() + .filter(node -> wrappedNode.isAncestorOf(node)) + .isPresent(); } } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ConstructorContext.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ConstructorContext.java similarity index 93% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ConstructorContext.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ConstructorContext.java index 1c67561..520dbe5 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ConstructorContext.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ConstructorContext.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -24,7 +24,7 @@ import com.github.javaparser.ast.Node; import com.github.javaparser.ast.body.ConstructorDeclaration; import com.github.javaparser.ast.body.Parameter; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; +import com.github.javaparser.resolution.TypeSolver; import java.util.Collections; import java.util.List; diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ContextHelper.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ContextHelper.java similarity index 89% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ContextHelper.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ContextHelper.java index 86360c1..6d82865 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ContextHelper.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ContextHelper.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -21,10 +21,10 @@ package com.github.javaparser.symbolsolver.javaparsermodel.contexts; +import com.github.javaparser.resolution.Context; import com.github.javaparser.resolution.MethodUsage; import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration; import com.github.javaparser.resolution.types.ResolvedType; -import com.github.javaparser.symbolsolver.core.resolution.Context; import com.github.javaparser.symbolsolver.core.resolution.MethodUsageResolutionCapability; import java.util.List; @@ -46,8 +46,7 @@ public static Optional solveMethodAsUsage(ResolvedTypeDeclaration t if (typeDeclaration instanceof MethodUsageResolutionCapability) { return ((MethodUsageResolutionCapability) typeDeclaration) .solveMethodAsUsage(name, argumentsTypes, invokationContext, typeParameters); - } else { - throw new UnsupportedOperationException(typeDeclaration.toString()); } + throw new UnsupportedOperationException(typeDeclaration.toString()); } } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/EnclosedExprContext.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/EnclosedExprContext.java similarity index 71% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/EnclosedExprContext.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/EnclosedExprContext.java index e875bfa..e81bc4e 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/EnclosedExprContext.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/EnclosedExprContext.java @@ -1,10 +1,30 @@ +/* + * Copyright (C) 2013-2023 The JavaParser Team. + * + * This file is part of JavaParser. + * + * JavaParser can be used either under the terms of + * a) the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * b) the terms of the Apache License + * + * You should have received a copy of both licenses in LICENCE.LGPL and + * LICENCE.APACHE. Please refer to those files for details. + * + * JavaParser is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + */ + package com.github.javaparser.symbolsolver.javaparsermodel.contexts; import com.github.javaparser.ast.expr.EnclosedExpr; import com.github.javaparser.ast.expr.PatternExpr; -import com.github.javaparser.symbolsolver.core.resolution.Context; +import com.github.javaparser.resolution.Context; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; import java.util.ArrayList; import java.util.List; diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/EnumDeclarationContext.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/EnumDeclarationContext.java similarity index 91% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/EnumDeclarationContext.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/EnumDeclarationContext.java index 9060e03..6d56171 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/EnumDeclarationContext.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/EnumDeclarationContext.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -23,15 +23,15 @@ import com.github.javaparser.ast.body.EnumConstantDeclaration; import com.github.javaparser.ast.body.EnumDeclaration; +import com.github.javaparser.resolution.TypeSolver; 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.model.SymbolReference; import com.github.javaparser.resolution.types.ResolvedType; import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserEnumConstantDeclaration; import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserEnumDeclaration; -import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; import java.util.List; @@ -68,8 +68,8 @@ public SymbolReference solveSymbol(String na } @Override - public SymbolReference solveType(String name) { - return javaParserTypeDeclarationAdapter.solveType(name); + public SymbolReference solveType(String name, List resolvedTypes) { + return javaParserTypeDeclarationAdapter.solveType(name, resolvedTypes); } @Override diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/FieldAccessContext.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/FieldAccessContext.java similarity index 89% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/FieldAccessContext.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/FieldAccessContext.java index 0519278..54eed28 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/FieldAccessContext.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/FieldAccessContext.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -24,22 +24,22 @@ import com.github.javaparser.ast.expr.Expression; import com.github.javaparser.ast.expr.FieldAccessExpr; import com.github.javaparser.ast.expr.ThisExpr; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.*; +import com.github.javaparser.resolution.model.SymbolReference; +import com.github.javaparser.resolution.model.Value; import com.github.javaparser.resolution.types.ResolvedPrimitiveType; import com.github.javaparser.resolution.types.ResolvedReferenceType; import com.github.javaparser.resolution.types.ResolvedType; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory; -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.SymbolSolver; import java.util.Collection; import java.util.List; import java.util.Optional; -import static com.github.javaparser.symbolsolver.javaparser.Navigator.demandParentNode; +import static com.github.javaparser.resolution.Navigator.demandParentNode; /** * @author Federico Tomassetti @@ -69,8 +69,8 @@ public SymbolReference solveSymbol(String na } @Override - public SymbolReference solveType(String name) { - return JavaParserFactory.getContext(demandParentNode(wrappedNode), typeSolver).solveType(name); + public SymbolReference solveType(String name, List typeArguments) { + return JavaParserFactory.getContext(demandParentNode(wrappedNode), typeSolver).solveType(name, typeArguments); } @Override @@ -88,14 +88,13 @@ public Optional solveSymbolAsValue(String name) { } if (typeOfScope.isReferenceType()) { return solveSymbolAsValue(name, typeOfScope.asReferenceType()); - } else if (typeOfScope.isConstraint()) { + } + if (typeOfScope.isConstraint()) { return solveSymbolAsValue(name, typeOfScope.asConstraintType().getBound().asReferenceType()); - } else { - return Optional.empty(); } - } else { - return solveSymbolAsValueInParentContext(name); + return Optional.empty(); } + return solveSymbolAsValueInParentContext(name); } /* @@ -130,6 +129,6 @@ public SymbolReference solveField(String name) { } catch (Throwable t) { } } - return SymbolReference.unsolved(ResolvedFieldDeclaration.class); + return SymbolReference.unsolved(); } } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ForEachStatementContext.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ForEachStatementContext.java similarity index 86% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ForEachStatementContext.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ForEachStatementContext.java index 8a30658..378500f 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ForEachStatementContext.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ForEachStatementContext.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -25,17 +25,17 @@ import com.github.javaparser.ast.body.VariableDeclarator; import com.github.javaparser.ast.stmt.BlockStmt; import com.github.javaparser.ast.stmt.ForEachStmt; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration; import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration; +import com.github.javaparser.resolution.model.SymbolReference; import com.github.javaparser.resolution.types.ResolvedType; import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserSymbolDeclaration; -import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; import java.util.Collections; import java.util.List; -import static com.github.javaparser.symbolsolver.javaparser.Navigator.demandParentNode; +import static com.github.javaparser.resolution.Navigator.demandParentNode; public class ForEachStatementContext extends AbstractJavaParserContext { @@ -51,13 +51,11 @@ public SymbolReference solveSymbol(String na VariableDeclarator variableDeclarator = wrappedNode.getVariable().getVariables().get(0); if (variableDeclarator.getName().getId().equals(name)) { return SymbolReference.solved(JavaParserSymbolDeclaration.localVar(variableDeclarator, typeSolver)); - } else { - if (demandParentNode(wrappedNode) instanceof BlockStmt) { + } + if (demandParentNode(wrappedNode) instanceof BlockStmt) { return StatementContext.solveInBlock(name, typeSolver, wrappedNode); - } else { - return solveSymbolInParentContext(name); } - } + return solveSymbolInParentContext(name); } @Override diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ForStatementContext.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ForStatementContext.java similarity index 91% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ForStatementContext.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ForStatementContext.java index 51e0e71..206074f 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ForStatementContext.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ForStatementContext.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -26,17 +26,17 @@ import com.github.javaparser.ast.expr.*; import com.github.javaparser.ast.nodeTypes.NodeWithStatements; import com.github.javaparser.ast.stmt.ForStmt; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration; import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration; +import com.github.javaparser.resolution.model.SymbolReference; import com.github.javaparser.resolution.types.ResolvedType; import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserSymbolDeclaration; -import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; import java.util.LinkedList; import java.util.List; -import static com.github.javaparser.symbolsolver.javaparser.Navigator.demandParentNode; +import static com.github.javaparser.resolution.Navigator.demandParentNode; public class ForStatementContext extends AbstractJavaParserContext { @@ -61,9 +61,8 @@ public SymbolReference solveSymbol(String na if (demandParentNode(wrappedNode) instanceof NodeWithStatements) { return StatementContext.solveInBlock(name, typeSolver, wrappedNode); - } else { - return solveSymbolInParentContext(name); } + return solveSymbolInParentContext(name); } @Override diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/IfStatementContext.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/IfStatementContext.java similarity index 87% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/IfStatementContext.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/IfStatementContext.java index 893fc09..38cd9c0 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/IfStatementContext.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/IfStatementContext.java @@ -1,12 +1,32 @@ +/* + * Copyright (C) 2013-2023 The JavaParser Team. + * + * This file is part of JavaParser. + * + * JavaParser can be used either under the terms of + * a) the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * b) the terms of the Apache License + * + * You should have received a copy of both licenses in LICENCE.LGPL and + * LICENCE.APACHE. Please refer to those files for details. + * + * JavaParser is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + */ + package com.github.javaparser.symbolsolver.javaparsermodel.contexts; import com.github.javaparser.ast.Node; import com.github.javaparser.ast.expr.Expression; import com.github.javaparser.ast.expr.PatternExpr; import com.github.javaparser.ast.stmt.IfStmt; -import com.github.javaparser.symbolsolver.core.resolution.Context; +import com.github.javaparser.resolution.Context; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; import java.util.ArrayList; import java.util.List; diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/InstanceOfExprContext.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/InstanceOfExprContext.java similarity index 71% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/InstanceOfExprContext.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/InstanceOfExprContext.java index c63f6b3..d3fe755 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/InstanceOfExprContext.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/InstanceOfExprContext.java @@ -1,13 +1,33 @@ +/* + * Copyright (C) 2013-2023 The JavaParser Team. + * + * This file is part of JavaParser. + * + * JavaParser can be used either under the terms of + * a) the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * b) the terms of the Apache License + * + * You should have received a copy of both licenses in LICENCE.LGPL and + * LICENCE.APACHE. Please refer to those files for details. + * + * JavaParser is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + */ + package com.github.javaparser.symbolsolver.javaparsermodel.contexts; import com.github.javaparser.ast.expr.InstanceOfExpr; import com.github.javaparser.ast.expr.PatternExpr; +import com.github.javaparser.resolution.Context; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration; -import com.github.javaparser.symbolsolver.core.resolution.Context; +import com.github.javaparser.resolution.model.SymbolReference; import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserPatternDeclaration; import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserSymbolDeclaration; -import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; import java.util.ArrayList; import java.util.List; @@ -35,7 +55,7 @@ public SymbolReference solveSymbol(String na Optional optionalParentContext = getParent(); if (!optionalParentContext.isPresent()) { - return SymbolReference.unsolved(ResolvedValueDeclaration.class); + return SymbolReference.unsolved(); } Context parentContext = optionalParentContext.get(); diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/JavaParserTypeDeclarationAdapter.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/JavaParserTypeDeclarationAdapter.java similarity index 68% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/JavaParserTypeDeclarationAdapter.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/JavaParserTypeDeclarationAdapter.java index ebc5093..8d7dce3 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/JavaParserTypeDeclarationAdapter.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/JavaParserTypeDeclarationAdapter.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -21,30 +21,32 @@ package com.github.javaparser.symbolsolver.javaparsermodel.contexts; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + import com.github.javaparser.ast.AccessSpecifier; +import com.github.javaparser.ast.NodeList; import com.github.javaparser.ast.body.BodyDeclaration; import com.github.javaparser.ast.body.TypeDeclaration; import com.github.javaparser.ast.nodeTypes.NodeWithExtends; import com.github.javaparser.ast.nodeTypes.NodeWithImplements; +import com.github.javaparser.ast.nodeTypes.NodeWithTypeArguments; import com.github.javaparser.ast.nodeTypes.NodeWithTypeParameters; import com.github.javaparser.ast.type.ClassOrInterfaceType; +import com.github.javaparser.ast.type.Type; import com.github.javaparser.ast.type.TypeParameter; +import com.github.javaparser.resolution.Context; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.*; +import com.github.javaparser.resolution.logic.ConstructorResolutionLogic; +import com.github.javaparser.resolution.logic.MethodResolutionLogic; +import com.github.javaparser.resolution.model.SymbolReference; import com.github.javaparser.resolution.types.ResolvedReferenceType; import com.github.javaparser.resolution.types.ResolvedType; -import com.github.javaparser.symbolsolver.core.resolution.Context; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory; import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeParameter; -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.ConstructorResolutionLogic; -import com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic; - -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; /** * @author Federico Tomassetti @@ -65,67 +67,128 @@ public JavaParserTypeDeclarationAdapter(com.github.javaparser.ast.body.TypeDecla this.context = context; } + /** + * @deprecated Consider using {@link #solveType(String, List)} to consider type arguments. + */ + @Deprecated public SymbolReference solveType(String name) { + return solveType(name, null); + } + + public SymbolReference solveType(String name, List typeArguments) { if (this.wrappedNode.getName().getId().equals(name)) { return SymbolReference.solved(JavaParserFacade.get(typeSolver).getTypeDeclaration(wrappedNode)); } // Internal classes for (BodyDeclaration member : this.wrappedNode.getMembers()) { - if (member instanceof TypeDeclaration) { - TypeDeclaration internalType = (TypeDeclaration) member; - if (internalType.getName().getId().equals(name)) { + if (member.isTypeDeclaration()) { + TypeDeclaration internalType = member.asTypeDeclaration(); + if (internalType.getName().getId().equals(name) && compareTypeParameters(internalType, typeArguments)) { return SymbolReference.solved(JavaParserFacade.get(typeSolver).getTypeDeclaration(internalType)); - } else if (name.startsWith(wrappedNode.getName().getId() + "." + internalType.getName().getId())) { - return JavaParserFactory.getContext(internalType, typeSolver).solveType(name.substring(wrappedNode.getName().getId().length() + 1)); - } else if (name.startsWith(internalType.getName().getId() + ".")) { - return JavaParserFactory.getContext(internalType, typeSolver).solveType(name.substring(internalType.getName().getId().length() + 1)); + } + if (name.startsWith(wrappedNode.getName().getId() + "." + internalType.getName().getId())) { + return JavaParserFactory.getContext(internalType, typeSolver).solveType(name.substring(wrappedNode.getName().getId().length() + 1), typeArguments); + } + if (name.startsWith(internalType.getName().getId() + ".")) { + return JavaParserFactory.getContext(internalType, typeSolver).solveType(name.substring(internalType.getName().getId().length() + 1), typeArguments); } } } + // Check if is a type parameter if (wrappedNode instanceof NodeWithTypeParameters) { NodeWithTypeParameters nodeWithTypeParameters = (NodeWithTypeParameters) wrappedNode; for (TypeParameter astTpRaw : nodeWithTypeParameters.getTypeParameters()) { - TypeParameter astTp = astTpRaw; - if (astTp.getName().getId().equals(name)) { - return SymbolReference.solved(new JavaParserTypeParameter(astTp, typeSolver)); + if (astTpRaw.getName().getId().equals(name)) { + return SymbolReference.solved(new JavaParserTypeParameter(astTpRaw, typeSolver)); } } } + // Check if the node implements other types if (wrappedNode instanceof NodeWithImplements) { NodeWithImplements nodeWithImplements = (NodeWithImplements) wrappedNode; for (ClassOrInterfaceType implementedType : nodeWithImplements.getImplementedTypes()) { if (implementedType.getName().getId().equals(name)) { return context.getParent() .orElseThrow(() -> new RuntimeException("Parent context unexpectedly empty.")) - .solveType(implementedType.getNameWithScope()); + .solveType(implementedType.getNameWithScope(), typeArguments); } } } + // Check if the node extends other types if (wrappedNode instanceof NodeWithExtends) { NodeWithExtends nodeWithExtends = (NodeWithExtends) wrappedNode; for (ClassOrInterfaceType extendedType : nodeWithExtends.getExtendedTypes()) { - if (extendedType.getName().getId().equals(name)) { + if (extendedType.getName().getId().equals(name) && compareTypeArguments(extendedType, typeArguments)) { return context.getParent() - .orElseThrow(() -> new RuntimeException("Parent context unexpectedly empty.")) - .solveType(extendedType.getNameWithScope()); + .orElseThrow(() -> new RuntimeException("Parent context unexpectedly empty.")) + .solveType(extendedType.getNameWithScope(), typeArguments); } } } - // Look into extended classes and implemented interfaces - ResolvedTypeDeclaration type = checkAncestorsForType(name, this.typeDeclaration); - if (type != null) { - return SymbolReference.solved(type); - } + // Looking at extended classes and implemented interfaces + String typeName = isCompositeName(name) ? innerMostPartOfName(name) : name; + ResolvedTypeDeclaration type = checkAncestorsForType(typeName, this.typeDeclaration); + // Before accepting this value we need to ensure that + // - the name is not a composite name (this is probably a local class which is discovered + // by the check of ancestors + // - or the outer most part of the name is equals to the type declaration name. + // it could be the case when the name is prefixed by the outer class name (eg outerclass.innerClass) + // - or the qualified name of the type is the same as the name (in case when the name is + // a fully qualified class name like java.util.Iterator + if (type != null + && (!isCompositeName(name) + || outerMostPartOfName(name).equals(this.typeDeclaration.getName()) + || type.getQualifiedName().equals(name))) { + return SymbolReference.solved(type); + } // Else check parents return context.getParent() .orElseThrow(() -> new RuntimeException("Parent context unexpectedly empty.")) - .solveType(name); + .solveType(name, typeArguments); + } + + private boolean isCompositeName(String name) { + return name.indexOf('.') > -1; + } + + private String innerMostPartOfName(String name) { + return isCompositeName(name) ? name.substring(name.lastIndexOf(".")+1) : name; + } + + private String outerMostPartOfName(String name) { + return isCompositeName(name) ? name.substring(0, name.lastIndexOf(".")) : name; + } + + private > boolean compareTypes(List types, + List resolvedTypeArguments) { + // If the user want's to solve the type without having prior knowledge of the type arguments. + if (resolvedTypeArguments == null) { + return true; + } + + return types.size() == resolvedTypeArguments.size(); + } + + private > boolean compareTypeArguments(T type, List resolvedTypeArguments) { + return compareTypes(type.getTypeArguments().orElse(new NodeList<>()), resolvedTypeArguments); + } + + private > boolean compareTypeParameters(T type, + List resolvedTypeArguments) { + return compareTypes(type.getTypeParameters(), resolvedTypeArguments); + } + + private boolean compareTypeParameters(TypeDeclaration typeDeclaration, List resolvedTypeArguments) { + if (typeDeclaration instanceof NodeWithTypeParameters) { + return compareTypeParameters((NodeWithTypeParameters) typeDeclaration, resolvedTypeArguments); + } + return true; } /** @@ -153,9 +216,8 @@ private ResolvedTypeDeclaration checkAncestorsForType(String name, ResolvedRefer if (internalTypeDeclaration.getName().equals(name)) { if (visible) { return internalTypeDeclaration; - } else { - return null; // FIXME -- Avoid returning null. } + return null; } } @@ -218,7 +280,7 @@ public SymbolReference solveMethod(String name, List< // if is interface and candidate method list is empty, we should check the Object Methods if (candidateMethods.isEmpty() && typeDeclaration.isInterface()) { - SymbolReference res = MethodResolutionLogic.solveMethodInType(new ReflectionClassDeclaration(Object.class, typeSolver), name, argumentsTypes, false); + SymbolReference res = MethodResolutionLogic.solveMethodInType(typeSolver.getSolvedJavaLangObject(), name, argumentsTypes, false); if (res.isSolved()) { candidateMethods.add(res.getCorrespondingDeclaration()); } @@ -231,6 +293,6 @@ public SymbolReference solveConstructor(List { - + public LambdaExprContext(LambdaExpr wrappedNode, TypeSolver typeSolver) { super(wrappedNode, typeSolver); } @Override public Optional solveSymbolAsValue(String name) { + int index = -1; for (Parameter parameter : wrappedNode.getParameters()) { + index++; SymbolDeclarator sb = JavaParserFactory.getSymbolDeclarator(parameter, typeSolver); - int index = 0; for (ResolvedValueDeclaration decl : sb.getSymbolDeclarations()) { if (decl.getName().equals(name)) { - Node parentNode = demandParentNode(wrappedNode); + Node parentNode = demandParentNode(wrappedNode, IS_NOT_ENCLOSED_EXPR); if (parentNode instanceof MethodCallExpr) { MethodCallExpr methodCallExpr = (MethodCallExpr) parentNode; MethodUsage methodUsage = JavaParserFacade.get(typeSolver).solveMethodAsUsage(methodCallExpr); - int i = pos(methodCallExpr, wrappedNode); + int i = methodCallExpr.getArgumentPosition(wrappedNode, EXCLUDE_ENCLOSED_EXPR); ResolvedType lambdaType = methodUsage.getParamTypes().get(i); // Get the functional method in order for us to resolve it's type arguments properly Optional functionalMethodOpt = FunctionalInterfaceLogic.getFunctionalMethod(lambdaType); - if (functionalMethodOpt.isPresent()){ + if (functionalMethodOpt.isPresent()) { MethodUsage functionalMethod = functionalMethodOpt.get(); - InferenceContext inferenceContext = new InferenceContext(MyObjectProvider.INSTANCE); + InferenceContext inferenceContext = new InferenceContext(typeSolver); // Resolve each type variable of the lambda, and use this later to infer the type of each // implicit parameter lambdaType.asReferenceType().getTypeDeclaration().ifPresent(typeDeclaration -> { inferenceContext.addPair( lambdaType, - new ReferenceTypeImpl(typeDeclaration, typeSolver) + new ReferenceTypeImpl(typeDeclaration) ); }); @@ -111,12 +112,12 @@ public Optional solveSymbolAsValue(String name) { } Value value = new Value(conType, name); return Optional.of(value); - } else{ - return Optional.empty(); } - } else if (parentNode instanceof VariableDeclarator) { + return Optional.empty(); + } + if (parentNode instanceof VariableDeclarator) { VariableDeclarator variableDeclarator = (VariableDeclarator) parentNode; - ResolvedType t = JavaParserFacade.get(typeSolver).convertToUsageVariableType(variableDeclarator); + ResolvedType t = JavaParserFacade.get(typeSolver).convertToUsage(variableDeclarator.getType()); Optional functionalMethod = FunctionalInterfaceLogic.getFunctionalMethod(t); if (functionalMethod.isPresent()) { ResolvedType lambdaType = functionalMethod.get().getParamType(index); @@ -136,10 +137,10 @@ public Optional solveSymbolAsValue(String name) { Value value = new Value(lambdaType, name); return Optional.of(value); - } else { - throw new UnsupportedOperationException(); } - } else if (parentNode instanceof ReturnStmt) { + throw new UnsupportedOperationException(); + } + if (parentNode instanceof ReturnStmt) { ReturnStmt returnStmt = (ReturnStmt) parentNode; Optional optDeclaration = returnStmt.findAncestor(MethodDeclaration.class); if (optDeclaration.isPresent()) { @@ -164,11 +165,11 @@ public Optional solveSymbolAsValue(String name) { Value value = new Value(lambdaType, name); return Optional.of(value); - } else { - throw new UnsupportedOperationException(); } + throw new UnsupportedOperationException(); } - } else if (parentNode instanceof CastExpr) { + } + if (parentNode instanceof CastExpr) { CastExpr castExpr = (CastExpr) parentNode; ResolvedType t = JavaParserFacade.get(typeSolver).convertToUsage(castExpr.getType()); Optional functionalMethod = FunctionalInterfaceLogic.getFunctionalMethod(t); @@ -191,14 +192,11 @@ public Optional solveSymbolAsValue(String name) { Value value = new Value(lambdaType, name); return Optional.of(value); - } else { - throw new UnsupportedOperationException(); } - } else { throw new UnsupportedOperationException(); } + throw new UnsupportedOperationException(); } - index++; } } @@ -248,19 +246,4 @@ protected final Optional solveWithAsValue(SymbolDeclarator symbolDeclarat } return Optional.empty(); } - - /// - /// Private methods - /// - - private int pos(MethodCallExpr callExpr, Expression param) { - int i = 0; - for (Expression p : callExpr.getArguments()) { - if (p == param) { - return i; - } - i++; - } - throw new IllegalArgumentException(); - } } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/MethodCallExprContext.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/MethodCallExprContext.java similarity index 80% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/MethodCallExprContext.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/MethodCallExprContext.java index 7304a16..08d8266 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/MethodCallExprContext.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/MethodCallExprContext.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -21,26 +21,25 @@ package com.github.javaparser.symbolsolver.javaparsermodel.contexts; +import java.util.*; + 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.resolution.Context; import com.github.javaparser.resolution.MethodUsage; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.UnsolvedSymbolException; import com.github.javaparser.resolution.declarations.*; +import com.github.javaparser.resolution.logic.MethodResolutionLogic; +import com.github.javaparser.resolution.model.SymbolReference; +import com.github.javaparser.resolution.model.Value; +import com.github.javaparser.resolution.model.typesystem.LazyType; +import com.github.javaparser.resolution.model.typesystem.ReferenceTypeImpl; import com.github.javaparser.resolution.types.*; -import com.github.javaparser.symbolsolver.core.resolution.Context; 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.model.resolution.Value; -import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl; -import com.github.javaparser.symbolsolver.reflectionmodel.MyObjectProvider; -import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassDeclaration; -import com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic; import com.github.javaparser.utils.Pair; -import java.util.*; - public class MethodCallExprContext extends AbstractJavaParserContext { /// @@ -91,10 +90,9 @@ public Optional solveMethodAsUsage(String name, List methodUsage = resolveMethodTypeParametersFromExplicitList(typeSolver, methodUsage); methodUsage = resolveMethodTypeParameters(methodUsage, argumentsTypes); return Optional.of(methodUsage); - } else { - throw new UnsolvedSymbolException(ref.getCorrespondingDeclaration().toString(), - "Method '" + name + "' with parameterTypes " + argumentsTypes); } + throw new UnsolvedSymbolException(ref.getCorrespondingDeclaration().toString(), + "Method '" + name + "' with parameterTypes " + argumentsTypes); } } @@ -164,7 +162,7 @@ public SymbolReference solveMethod(String name, List< } } - return SymbolReference.unsolved(ResolvedMethodDeclaration.class); + return SymbolReference.unsolved(); } /// @@ -230,9 +228,8 @@ private Optional solveMethodAsUsage(ResolvedReferenceType refType, methodUsage = methodUsage.replaceParamType(i, replaced); } return Optional.of(methodUsage); - } else { - return ref; } + return ref; } private void inferTypes(ResolvedType source, ResolvedType target, Map mappings) { @@ -319,6 +316,13 @@ private void inferTypes(ResolvedType source, ResolvedType target, Map - ResolvedType actualType = - actualParamTypes.get(actualParamTypes.size() - 1).isArray() ? - actualParamTypes.get(actualParamTypes.size() - 1).asArrayType().getComponentType() : + // for example + // Arrays.aslist(int[]{1}) must returns List + // but Arrays.aslist(String[]{""}) must returns List + // Arrays.asList() accept generic type T. Since Java generics work only on + // reference types (object types), not on primitives, and int[] is an object + // then Arrays.aslist(int[]{1}) returns List + ResolvedType lastActualParamType = actualParamTypes.get(actualParamTypes.size() - 1); + ResolvedType actualType = lastActualParamType; + if (lastActualParamType.isArray()) { + ResolvedType componentType = lastActualParamType.asArrayType().getComponentType(); + // in cases where, the expected type is a generic type (Arrays.asList(T... a)) and the component type of the array type is a reference type + // or the expected type is not a generic (IntStream.of(int... values)) and the component type is not a reference type + // then the actual type is the component type (in the example above 'int') + if ((componentType.isReferenceType() + && ResolvedTypeVariable.class.isInstance(expectedType)) + || (!componentType.isReferenceType() + && !ResolvedTypeVariable.class.isInstance(expectedType))) { + actualType = lastActualParamType.asArrayType().getComponentType(); + } + } if (!expectedType.isAssignableBy(actualType)) { for (ResolvedTypeParameterDeclaration tp : methodUsage.getDeclaration().getTypeParameters()) { expectedType = MethodResolutionLogic.replaceTypeParam(expectedType, tp, typeSolver); @@ -351,6 +372,24 @@ private MethodUsage resolveMethodTypeParameters(MethodUsage methodUsage, List because of the assumption +// ResolvedType actualType = new ResolvedArrayType(actualParamTypes.get(actualParamTypes.size() - 1)); + ResolvedType actualType = actualParamTypes.get(actualParamTypes.size() - 1); + if (!expectedType.isAssignableBy(actualType)) { + throw new UnsupportedOperationException( + String.format("Unable to resolve the type typeParametersValues in a MethodUsage. Expected type: %s, Actual type: %s. Method Declaration: %s. MethodUsage: %s", + expectedType, + actualType, + methodUsage.getDeclaration(), + methodUsage)); + } + matchTypeParameters(expectedType, actualType, matchedTypeParameters); + return replaceTypeParameter(methodUsage, matchedTypeParameters); } else { return methodUsage; } @@ -365,25 +404,33 @@ private MethodUsage resolveMethodTypeParameters(MethodUsage methodUsage, List matchedTypeParameters) { + for (ResolvedTypeParameterDeclaration tp : matchedTypeParameters.keySet()) { + methodUsage = methodUsage.replaceTypeParameter(tp, matchedTypeParameters.get(tp)); + } + return methodUsage; + } + private void matchTypeParameters(ResolvedType expectedType, ResolvedType actualType, Map matchedTypeParameters) { if (expectedType.isTypeVariable()) { ResolvedType type = actualType; // in case of primitive type, the expected type must be compared with the boxed type of the actual type if (type.isPrimitive()) { - type = MyObjectProvider.INSTANCE.byName(type.asPrimitive().getBoxTypeQName()); + ResolvedReferenceTypeDeclaration resolvedTypedeclaration = typeSolver.solveType(type.asPrimitive().getBoxTypeQName()); + type = new ReferenceTypeImpl(resolvedTypedeclaration); } /* * "a value of the null type (the null reference is the only such value) may be assigned to any reference type, resulting in a null reference of that type" * https://docs.oracle.com/javase/specs/jls/se15/html/jls-5.html#jls-5.2 */ if (type.isNull()) { - type = MyObjectProvider.INSTANCE.object(); + ResolvedReferenceTypeDeclaration resolvedTypedeclaration = typeSolver.getSolvedJavaLangObject(); + type = new ReferenceTypeImpl(resolvedTypedeclaration); } if (!type.isTypeVariable() && !type.isReferenceType() && !type.isArray()) { throw new UnsupportedOperationException(type.getClass().getCanonicalName()); @@ -425,8 +472,8 @@ private Optional solveMethodAsUsage(ResolvedTypeVariable tp, String // and make everything generate like instead of // https://github.com/javaparser/javaparser/issues/2044 bounds = Collections.singletonList( - ResolvedTypeParameterDeclaration.Bound.extendsBound( - JavaParserFacade.get(typeSolver).classToResolvedType(Object.class))); + ResolvedTypeParameterDeclaration.Bound.extendsBound(new ReferenceTypeImpl(typeSolver.getSolvedJavaLangObject()))); + ; } for (ResolvedTypeParameterDeclaration.Bound bound : bounds) { @@ -442,33 +489,39 @@ private Optional solveMethodAsUsage(ResolvedTypeVariable tp, String private Optional solveMethodAsUsage(ResolvedType type, String name, List argumentsTypes, Context invokationContext) { if (type instanceof ResolvedReferenceType) { return solveMethodAsUsage((ResolvedReferenceType) type, name, argumentsTypes, invokationContext); - } else if (type instanceof ResolvedTypeVariable) { + } + if (type instanceof LazyType) { + return solveMethodAsUsage(type.asReferenceType(), name, argumentsTypes, invokationContext); + } + if (type instanceof ResolvedTypeVariable) { return solveMethodAsUsage((ResolvedTypeVariable) type, name, argumentsTypes, invokationContext); - } else if (type instanceof ResolvedWildcard) { + } + if (type instanceof ResolvedWildcard) { ResolvedWildcard wildcardUsage = (ResolvedWildcard) type; if (wildcardUsage.isSuper()) { return solveMethodAsUsage(wildcardUsage.getBoundedType(), name, argumentsTypes, invokationContext); - } else if (wildcardUsage.isExtends()) { + } + if (wildcardUsage.isExtends()) { return solveMethodAsUsage(wildcardUsage.getBoundedType(), name, argumentsTypes, invokationContext); - } else { - return solveMethodAsUsage(new ReferenceTypeImpl(new ReflectionClassDeclaration(Object.class, typeSolver), typeSolver), name, argumentsTypes, invokationContext); } - } else if (type instanceof ResolvedLambdaConstraintType){ + return solveMethodAsUsage(new ReferenceTypeImpl(typeSolver.getSolvedJavaLangObject()), name, argumentsTypes, invokationContext); + } + if (type instanceof ResolvedLambdaConstraintType){ ResolvedLambdaConstraintType constraintType = (ResolvedLambdaConstraintType) type; return solveMethodAsUsage(constraintType.getBound(), name, argumentsTypes, invokationContext); - } else if (type instanceof ResolvedArrayType) { + } + if (type instanceof ResolvedArrayType) { // An array inherits methods from Object not from it's component type - return solveMethodAsUsage(new ReferenceTypeImpl(new ReflectionClassDeclaration(Object.class, typeSolver), typeSolver), name, argumentsTypes, invokationContext); - } else if (type instanceof ResolvedUnionType) { + return solveMethodAsUsage(new ReferenceTypeImpl(typeSolver.getSolvedJavaLangObject()), name, argumentsTypes, invokationContext); + } + if (type instanceof ResolvedUnionType) { Optional commonAncestor = type.asUnionType().getCommonAncestor(); if (commonAncestor.isPresent()) { return solveMethodAsUsage(commonAncestor.get(), name, argumentsTypes, invokationContext); - } else { - throw new UnsupportedOperationException("no common ancestor available for " + type.describe()); } - } else { - throw new UnsupportedOperationException("type usage: " + type.getClass().getCanonicalName()); + throw new UnsupportedOperationException("no common ancestor available for " + type.describe()); } + throw new UnsupportedOperationException("type usage: " + type.getClass().getCanonicalName()); } private ResolvedType usingParameterTypesFromScope(ResolvedType scope, ResolvedType type, Map inferredTypes) { @@ -478,10 +531,8 @@ private ResolvedType usingParameterTypesFromScope(ResolvedType scope, ResolvedTy type = type.replaceTypeVariables(entry.a, scope.asReferenceType().getGenericParameterByName(entry.a.getName()).get(), inferredTypes); } } - return type; - } else { - return type; } + return type; } private ResolvedType applyInferredTypes(ResolvedType type, Map inferredTypes) { diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/MethodContext.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/MethodContext.java similarity index 93% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/MethodContext.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/MethodContext.java index a23f131..c5294cd 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/MethodContext.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/MethodContext.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -24,7 +24,7 @@ import com.github.javaparser.ast.Node; import com.github.javaparser.ast.body.MethodDeclaration; import com.github.javaparser.ast.body.Parameter; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; +import com.github.javaparser.resolution.TypeSolver; import java.util.Collections; import java.util.List; diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/MethodReferenceExprContext.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/MethodReferenceExprContext.java similarity index 83% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/MethodReferenceExprContext.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/MethodReferenceExprContext.java index 11e1603..36c84f8 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/MethodReferenceExprContext.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/MethodReferenceExprContext.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -21,6 +21,10 @@ package com.github.javaparser.symbolsolver.javaparsermodel.contexts; +import static com.github.javaparser.resolution.Navigator.demandParentNode; + +import java.util.*; + import com.github.javaparser.ast.body.MethodDeclaration; import com.github.javaparser.ast.body.VariableDeclarator; import com.github.javaparser.ast.expr.Expression; @@ -28,23 +32,18 @@ import com.github.javaparser.ast.expr.MethodReferenceExpr; import com.github.javaparser.ast.stmt.ReturnStmt; import com.github.javaparser.resolution.MethodUsage; +import com.github.javaparser.resolution.TypeSolver; 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.resolution.logic.FunctionalInterfaceLogic; +import com.github.javaparser.resolution.logic.InferenceContext; +import com.github.javaparser.resolution.logic.MethodResolutionLogic; +import com.github.javaparser.resolution.model.SymbolReference; +import com.github.javaparser.resolution.model.typesystem.ReferenceTypeImpl; import com.github.javaparser.resolution.types.ResolvedLambdaConstraintType; import com.github.javaparser.resolution.types.ResolvedType; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade; -import com.github.javaparser.symbolsolver.logic.FunctionalInterfaceLogic; -import com.github.javaparser.symbolsolver.logic.InferenceContext; -import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; -import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl; -import com.github.javaparser.symbolsolver.reflectionmodel.MyObjectProvider; -import com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic; - -import java.util.*; - -import static com.github.javaparser.symbolsolver.javaparser.Navigator.demandParentNode; public class MethodReferenceExprContext extends AbstractJavaParserContext { @@ -82,17 +81,14 @@ public SymbolReference solveMethod(String name, List< SymbolReference firstResAttempt = MethodResolutionLogic.solveMethodInType(rrtd, name, argumentsTypes, false); if (firstResAttempt.isSolved()) { return firstResAttempt; - } else { - // If has not already been solved above then will be solved here if single argument type same as - // (or subclass of) rrtd, as call is actually performed on the argument itself with zero params - SymbolReference secondResAttempt = MethodResolutionLogic.solveMethodInType(rrtd, name, Collections.emptyList(), false); - if (secondResAttempt.isSolved()) { + } + SymbolReference secondResAttempt = MethodResolutionLogic.solveMethodInType(rrtd, name, Collections.emptyList(), false); + if (secondResAttempt.isSolved()) { return secondResAttempt; } - } } - return SymbolReference.unsolved(ResolvedMethodDeclaration.class); + return SymbolReference.unsolved(); } /// @@ -104,7 +100,13 @@ private List inferArgumentTypes() { MethodCallExpr methodCallExpr = (MethodCallExpr) demandParentNode(wrappedNode); MethodUsage methodUsage = JavaParserFacade.get(typeSolver).solveMethodAsUsage(methodCallExpr); int pos = pos(methodCallExpr, wrappedNode); - ResolvedType lambdaType = methodUsage.getParamTypes().get(pos); + ResolvedMethodDeclaration rmd = methodUsage.getDeclaration(); + // Since variable parameters are represented by an array, in case we deal with + // the variadic parameter we have to take into account the base type of the + // array. + ResolvedType lambdaType = (rmd.hasVariadicParameter() && pos >= rmd.getNumberOfParams() - 1) ? + rmd.getLastParam().getType().asArrayType().getComponentType(): + methodUsage.getParamType(pos); // Get the functional method in order for us to resolve it's type arguments properly Optional functionalMethodOpt = FunctionalInterfaceLogic.getFunctionalMethod(lambdaType); @@ -114,11 +116,11 @@ private List inferArgumentTypes() { List resolvedTypes = new ArrayList<>(); for (ResolvedType type : functionalMethod.getParamTypes()) { - InferenceContext inferenceContext = new InferenceContext(MyObjectProvider.INSTANCE); + InferenceContext inferenceContext = new InferenceContext(typeSolver); // Resolve each type variable of the lambda, and use this later to infer the type of each // implicit parameter - inferenceContext.addPair(new ReferenceTypeImpl(functionalMethod.declaringType(), typeSolver), lambdaType); + inferenceContext.addPair(new ReferenceTypeImpl(functionalMethod.declaringType()), lambdaType); // Now resolve the argument type using the inference context ResolvedType argType = inferenceContext.resolve(inferenceContext.addSingle(type)); @@ -134,12 +136,12 @@ private List inferArgumentTypes() { } return resolvedTypes; - } else { - throw new UnsupportedOperationException(); } - } else if (demandParentNode(wrappedNode) instanceof VariableDeclarator) { + throw new UnsupportedOperationException(); + } + if (demandParentNode(wrappedNode) instanceof VariableDeclarator) { VariableDeclarator variableDeclarator = (VariableDeclarator) demandParentNode(wrappedNode); - ResolvedType t = JavaParserFacade.get(typeSolver).convertToUsageVariableType(variableDeclarator); + ResolvedType t = JavaParserFacade.get(typeSolver).convertToUsage(variableDeclarator.getType()); Optional functionalMethod = FunctionalInterfaceLogic.getFunctionalMethod(t); if (functionalMethod.isPresent()) { List resolvedTypes = new ArrayList<>(); @@ -160,10 +162,10 @@ private List inferArgumentTypes() { } return resolvedTypes; - } else { - throw new UnsupportedOperationException(); } - } else if (demandParentNode(wrappedNode) instanceof ReturnStmt) { + throw new UnsupportedOperationException(); + } + if (demandParentNode(wrappedNode) instanceof ReturnStmt) { ReturnStmt returnStmt = (ReturnStmt) demandParentNode(wrappedNode); Optional optDeclaration = returnStmt.findAncestor(MethodDeclaration.class); if (optDeclaration.isPresent()) { @@ -188,14 +190,12 @@ private List inferArgumentTypes() { } return resolvedTypes; - } else { - throw new UnsupportedOperationException(); } + throw new UnsupportedOperationException(); } throw new UnsupportedOperationException(); - } else { - throw new UnsupportedOperationException(); } + throw new UnsupportedOperationException(); } private int pos(MethodCallExpr callExpr, Expression param) { diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ObjectCreationContext.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ObjectCreationContext.java similarity index 91% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ObjectCreationContext.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ObjectCreationContext.java index ccf844d..2c71f37 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ObjectCreationContext.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ObjectCreationContext.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -24,19 +24,19 @@ import com.github.javaparser.ast.Node; import com.github.javaparser.ast.expr.Expression; import com.github.javaparser.ast.expr.ObjectCreationExpr; +import com.github.javaparser.resolution.TypeSolver; 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.model.SymbolReference; import com.github.javaparser.resolution.types.ResolvedType; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory; -import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; import java.util.List; -import static com.github.javaparser.symbolsolver.javaparser.Navigator.demandParentNode; +import static com.github.javaparser.resolution.Navigator.demandParentNode; /** * @author Federico Tomassetti @@ -48,7 +48,7 @@ public ObjectCreationContext(ObjectCreationExpr wrappedNode, TypeSolver typeSolv } @Override - public SymbolReference solveType(String name) { + public SymbolReference solveType(String name, List typeArguments) { if (wrappedNode.hasScope()) { Expression scope = wrappedNode.getScope().get(); ResolvedType scopeType = JavaParserFacade.get(typeSolver).getType(scope); @@ -67,7 +67,7 @@ public SymbolReference solveType(String name) { while (parentNode instanceof ObjectCreationExpr) { parentNode = demandParentNode(parentNode); } - return JavaParserFactory.getContext(parentNode, typeSolver).solveType(name); + return JavaParserFactory.getContext(parentNode, typeSolver).solveType(name, typeArguments); } @Override diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/StatementContext.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/StatementContext.java similarity index 88% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/StatementContext.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/StatementContext.java index a7ed3d2..fbc6bc8 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/StatementContext.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/StatementContext.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -28,16 +28,16 @@ import com.github.javaparser.ast.expr.PatternExpr; import com.github.javaparser.ast.nodeTypes.NodeWithStatements; import com.github.javaparser.ast.stmt.Statement; +import com.github.javaparser.resolution.Context; +import com.github.javaparser.resolution.SymbolDeclarator; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration; import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration; +import com.github.javaparser.resolution.model.SymbolReference; +import com.github.javaparser.resolution.model.Value; import com.github.javaparser.resolution.types.ResolvedType; -import com.github.javaparser.symbolsolver.core.resolution.Context; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory; import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserSymbolDeclaration; -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.SymbolDeclarator; import java.util.Collections; import java.util.List; @@ -56,7 +56,7 @@ public StatementContext(N wrappedNode, TypeSolver typeSolver) { public static SymbolReference solveInBlock(String name, TypeSolver typeSolver, Statement stmt) { Optional optionalParentNode = stmt.getParentNode(); if(!optionalParentNode.isPresent()) { - return SymbolReference.unsolved(ResolvedValueDeclaration.class); + return SymbolReference.unsolved(); } Node parentOfWrappedNode = optionalParentNode.get(); @@ -142,12 +142,14 @@ public Optional solveSymbolAsValue(String name) { Node parentOfWrappedNode = optionalParentNode.get(); - // we should look in all the statements preceding, treating them as SymbolDeclarators + if (parentOfWrappedNode instanceof MethodDeclaration) { return parentContext.solveSymbolAsValue(name); - }else if (parentOfWrappedNode instanceof LambdaExpr) { + } + if (parentOfWrappedNode instanceof LambdaExpr) { return parentContext.solveSymbolAsValue(name); - } else if (!(parentOfWrappedNode instanceof NodeWithStatements)) { + } + if (!(parentOfWrappedNode instanceof NodeWithStatements)) { return parentContext.solveSymbolAsValue(name); } @@ -174,8 +176,8 @@ public Optional solveSymbolAsValue(String name) { } } - // If nothing is found we should ask the parent context. - return solveSymbolAsValueInParentContext(name); + // If nothing is found we should ask the grand parent context. + return parentContext.getParent().map(context -> context.solveSymbolAsValue(name)).orElse(Optional.empty()); } @Override @@ -225,19 +227,22 @@ private SymbolReference solveSymbol(String n Optional optionalParentNode = wrappedNode.getParentNode(); if(!optionalParentNode.isPresent()) { - return SymbolReference.unsolved(ResolvedValueDeclaration.class); + return SymbolReference.unsolved(); } Node parentOfWrappedNode = optionalParentNode.get(); - // we should look in all the statements preceding, treating them as SymbolDeclarators + if (parentOfWrappedNode instanceof MethodDeclaration) { return solveSymbolInParentContext(name); - } else if (parentOfWrappedNode instanceof ConstructorDeclaration) { + } + if (parentOfWrappedNode instanceof ConstructorDeclaration) { return solveSymbolInParentContext(name); - } else if (parentOfWrappedNode instanceof LambdaExpr) { + } + if (parentOfWrappedNode instanceof LambdaExpr) { return solveSymbolInParentContext(name); - } else if (parentOfWrappedNode instanceof NodeWithStatements) { + } + if (parentOfWrappedNode instanceof NodeWithStatements) { // If we choose to not solve adjacent statements abort the solution process here. // In the calling context (the context that calls this) we will attempt to // resolve all prior adjacent statements, and then the common parent as the fallback. @@ -246,7 +251,7 @@ private SymbolReference solveSymbol(String n // Further below is a more detailed explanation for why we may want to disable this visitation of adjacent statements // to prevent revisiting the same contexts over and over again. if (!iterateAdjacentStmts) { - return SymbolReference.unsolved(ResolvedValueDeclaration.class); + return SymbolReference.unsolved(); } NodeWithStatements nodeWithStmt = (NodeWithStatements) parentOfWrappedNode; @@ -261,6 +266,22 @@ private SymbolReference solveSymbol(String n ListIterator statementListIterator = nodeWithStmt.getStatements().listIterator(position); while(statementListIterator.hasPrevious()) { Context prevContext = JavaParserFactory.getContext(statementListIterator.previous(), typeSolver); + if (prevContext instanceof BlockStmtContext) { + // Issue #3631 + // We have an explicit check for "BlockStmtContext" to avoid resolving the variable x with the + // declaration defined in the block preceding the use of the variable + // For example consider the following: + // + // int x = 0; + // void method() { + // { + // var x = 1; + // System.out.println(x); // prints 1 + // } + // System.out.println(x); // prints 0 + // } + continue; + } if (prevContext instanceof StatementContext) { // We have an explicit check for "StatementContext" to prevent a factorial increase of visited statements. // diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/SwitchEntryContext.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/SwitchEntryContext.java similarity index 90% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/SwitchEntryContext.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/SwitchEntryContext.java index 0c43fb4..de46436 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/SwitchEntryContext.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/SwitchEntryContext.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -24,20 +24,20 @@ import com.github.javaparser.ast.stmt.Statement; import com.github.javaparser.ast.stmt.SwitchEntry; import com.github.javaparser.ast.stmt.SwitchStmt; +import com.github.javaparser.resolution.SymbolDeclarator; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration; import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration; import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration; +import com.github.javaparser.resolution.model.SymbolReference; +import com.github.javaparser.resolution.model.typesystem.ReferenceTypeImpl; import com.github.javaparser.resolution.types.ResolvedType; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory; -import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; -import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl; -import com.github.javaparser.symbolsolver.resolution.SymbolDeclarator; import java.util.List; -import static com.github.javaparser.symbolsolver.javaparser.Navigator.demandParentNode; +import static com.github.javaparser.resolution.Navigator.demandParentNode; /** * @author Federico Tomassetti diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/TryWithResourceContext.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/TryWithResourceContext.java similarity index 90% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/TryWithResourceContext.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/TryWithResourceContext.java index 0b34562..b4b4a18 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/TryWithResourceContext.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/TryWithResourceContext.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -28,13 +28,13 @@ import com.github.javaparser.ast.expr.VariableDeclarationExpr; import com.github.javaparser.ast.stmt.BlockStmt; import com.github.javaparser.ast.stmt.TryStmt; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration; import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration; +import com.github.javaparser.resolution.model.SymbolReference; +import com.github.javaparser.resolution.model.Value; import com.github.javaparser.resolution.types.ResolvedType; import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserSymbolDeclaration; -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 java.util.Collections; import java.util.LinkedList; @@ -42,7 +42,7 @@ import java.util.Optional; import java.util.stream.Collectors; -import static com.github.javaparser.symbolsolver.javaparser.Navigator.demandParentNode; +import static com.github.javaparser.resolution.Navigator.demandParentNode; public class TryWithResourceContext extends AbstractJavaParserContext { @@ -65,9 +65,8 @@ public Optional solveSymbolAsValue(String name) { if (demandParentNode(wrappedNode) instanceof BlockStmt) { return StatementContext.solveInBlockAsValue(name, typeSolver, wrappedNode); - } else { - return solveSymbolAsValueInParentContext(name); } + return solveSymbolAsValueInParentContext(name); } @Override @@ -84,9 +83,8 @@ public SymbolReference solveSymbol(String na if (demandParentNode(wrappedNode) instanceof BlockStmt) { return StatementContext.solveInBlock(name, typeSolver, wrappedNode); - } else { - return solveSymbolInParentContext(name); } + return solveSymbolInParentContext(name); } @Override diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/UnaryExprContext.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/UnaryExprContext.java similarity index 68% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/UnaryExprContext.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/UnaryExprContext.java index bab93c9..0b5d82a 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/UnaryExprContext.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/UnaryExprContext.java @@ -1,10 +1,30 @@ +/* + * Copyright (C) 2013-2023 The JavaParser Team. + * + * This file is part of JavaParser. + * + * JavaParser can be used either under the terms of + * a) the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * b) the terms of the Apache License + * + * You should have received a copy of both licenses in LICENCE.LGPL and + * LICENCE.APACHE. Please refer to those files for details. + * + * JavaParser is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + */ + package com.github.javaparser.symbolsolver.javaparsermodel.contexts; import com.github.javaparser.ast.expr.PatternExpr; import com.github.javaparser.ast.expr.UnaryExpr; -import com.github.javaparser.symbolsolver.core.resolution.Context; +import com.github.javaparser.resolution.Context; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; import java.util.ArrayList; import java.util.List; @@ -26,7 +46,7 @@ public List patternExprsExposedFromChildren() { // Avoid infinite loop if(!this.equals(innerContext)) { // Note that `UnaryExpr.Operator.LOGICAL_COMPLEMENT` is `!` - // Previously negated pattern expressions are now now available (double negatives) -- e.g. if(!!("a" instanceof String s)) {} + // Previously negated pattern expressions are now available (double negatives) -- e.g. if(!!("a" instanceof String s)) {} results.addAll(innerContext.negatedPatternExprsExposedFromChildren()); } } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/VariableDeclarationExprContext.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/VariableDeclarationExprContext.java similarity index 93% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/VariableDeclarationExprContext.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/VariableDeclarationExprContext.java index ba178d1..97ddef1 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/VariableDeclarationExprContext.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/VariableDeclarationExprContext.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -25,10 +25,10 @@ import com.github.javaparser.ast.body.VariableDeclarator; import com.github.javaparser.ast.expr.PatternExpr; import com.github.javaparser.ast.expr.VariableDeclarationExpr; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration; +import com.github.javaparser.resolution.model.SymbolReference; import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserSymbolDeclaration; -import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; import java.util.Collections; import java.util.List; diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/VariableDeclaratorContext.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/VariableDeclaratorContext.java similarity index 94% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/VariableDeclaratorContext.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/VariableDeclaratorContext.java index b1aa0a5..bcd4348 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/VariableDeclaratorContext.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/VariableDeclaratorContext.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -24,7 +24,7 @@ import com.github.javaparser.ast.Node; import com.github.javaparser.ast.body.VariableDeclarator; import com.github.javaparser.ast.expr.PatternExpr; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; +import com.github.javaparser.resolution.TypeSolver; import java.util.Collections; import java.util.List; diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/AstResolutionUtils.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/AstResolutionUtils.java similarity index 88% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/AstResolutionUtils.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/AstResolutionUtils.java index 098149a..ffa2759 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/AstResolutionUtils.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/AstResolutionUtils.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -26,13 +26,13 @@ import com.github.javaparser.ast.expr.AnnotationExpr; import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations; import com.github.javaparser.ast.nodeTypes.NodeWithMembers; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.UnsolvedSymbolException; import com.github.javaparser.resolution.declarations.ResolvedConstructorDeclaration; import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration; import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration; +import com.github.javaparser.resolution.model.SymbolReference; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory; -import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; import com.google.common.collect.ImmutableList; import java.util.List; @@ -71,26 +71,26 @@ static String getClassName(String base, Node container) { String cn = ((com.github.javaparser.ast.body.ClassOrInterfaceDeclaration) container).getName().getId(); if (b.isEmpty()) { return cn; - } else { - return b + "." + cn; } - } else if (container instanceof com.github.javaparser.ast.body.EnumDeclaration) { + return b + "." + cn; + } + if (container instanceof com.github.javaparser.ast.body.EnumDeclaration) { String b = getClassName(base, container.getParentNode().orElse(null)); String cn = ((com.github.javaparser.ast.body.EnumDeclaration) container).getName().getId(); if (b.isEmpty()) { return cn; - } else { - return b + "." + cn; } - } else if (container instanceof com.github.javaparser.ast.body.AnnotationDeclaration) { + return b + "." + cn; + } + if (container instanceof com.github.javaparser.ast.body.AnnotationDeclaration) { String b = getClassName(base, container.getParentNode().orElse(null)); String cn = ((com.github.javaparser.ast.body.AnnotationDeclaration) container).getName().getId(); if (b.isEmpty()) { return cn; - } else { - return b + "." + cn; } - } else if (container != null) { + return b + "." + cn; + } + if (container != null) { return getClassName(base, container.getParentNode().orElse(null)); } return base; @@ -122,8 +122,7 @@ static List(container)); - } else { - return declared; } + return declared; } } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/DefaultConstructorDeclaration.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/DefaultConstructorDeclaration.java similarity index 91% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/DefaultConstructorDeclaration.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/DefaultConstructorDeclaration.java index d90452b..6b53965 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/DefaultConstructorDeclaration.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/DefaultConstructorDeclaration.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -22,7 +22,6 @@ package com.github.javaparser.symbolsolver.javaparsermodel.declarations; import com.github.javaparser.ast.AccessSpecifier; -import com.github.javaparser.ast.body.ConstructorDeclaration; import com.github.javaparser.resolution.declarations.ResolvedConstructorDeclaration; import com.github.javaparser.resolution.declarations.ResolvedParameterDeclaration; import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration; @@ -31,7 +30,6 @@ import java.util.Collections; import java.util.List; -import java.util.Optional; /** * This represents the default constructor added by the compiler for objects not declaring one. @@ -87,8 +85,4 @@ public ResolvedType getSpecifiedException(int index) { throw new UnsupportedOperationException("The default constructor does not throw exceptions"); } - @Override - public Optional toAst() { - return Optional.empty(); - } } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnnotationDeclaration.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnnotationDeclaration.java similarity index 90% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnnotationDeclaration.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnnotationDeclaration.java index d5159e2..7df40f4 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnnotationDeclaration.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnnotationDeclaration.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -21,18 +21,19 @@ package com.github.javaparser.symbolsolver.javaparsermodel.declarations; +import java.lang.annotation.Inherited; +import java.util.*; +import java.util.stream.Collectors; + +import com.github.javaparser.ast.Node; import com.github.javaparser.ast.body.AnnotationDeclaration; import com.github.javaparser.ast.body.AnnotationMemberDeclaration; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.*; +import com.github.javaparser.resolution.model.typesystem.ReferenceTypeImpl; import com.github.javaparser.resolution.types.ResolvedReferenceType; import com.github.javaparser.resolution.types.ResolvedType; import com.github.javaparser.symbolsolver.logic.AbstractTypeDeclaration; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; -import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl; - -import java.lang.annotation.Inherited; -import java.util.*; -import java.util.stream.Collectors; /** * @author Federico Tomassetti @@ -52,7 +53,7 @@ public JavaParserAnnotationDeclaration(AnnotationDeclaration wrappedNode, TypeSo @Override public List getAncestors(boolean acceptIncompleteList) { List ancestors = new ArrayList<>(); - ancestors.add(new ReferenceTypeImpl(typeSolver.solveType("java.lang.annotation.Annotation"), typeSolver)); + ancestors.add(new ReferenceTypeImpl(typeSolver.solveType("java.lang.annotation.Annotation"))); return ancestors; } @@ -91,6 +92,14 @@ public boolean hasDirectlyAnnotation(String canonicalName) { return AstResolutionUtils.hasDirectlyAnnotation(wrappedNode, typeSolver, canonicalName); } + /* + * Returns a set of the declared annotation on this type + */ + @Override + public Set getDeclaredAnnotations() { + return javaParserTypeAdapter.getDeclaredAnnotations(); + } + @Override public String getPackageName() { return AstResolutionUtils.getPackageName(wrappedNode); @@ -106,9 +115,8 @@ public String getQualifiedName() { String containerName = AstResolutionUtils.containerName(wrappedNode.getParentNode().orElse(null)); if (containerName.isEmpty()) { return wrappedNode.getName().getId(); - } else { - return containerName + "." + wrappedNode.getName(); } + return containerName + "." + wrappedNode.getName(); } @Override @@ -146,13 +154,13 @@ public List getConstructors() { return Collections.emptyList(); } - @Override - public Optional toAst() { - return Optional.of(wrappedNode); - } - @Override public boolean isInheritable() { return wrappedNode.getAnnotationByClass(Inherited.class).isPresent(); } + + @Override + public Optional toAst() { + return Optional.of(wrappedNode); + } } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnnotationMemberDeclaration.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnnotationMemberDeclaration.java similarity index 87% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnnotationMemberDeclaration.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnnotationMemberDeclaration.java index 67451e1..61ccad3 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnnotationMemberDeclaration.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnnotationMemberDeclaration.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -21,14 +21,17 @@ package com.github.javaparser.symbolsolver.javaparsermodel.declarations; +import com.github.javaparser.ast.Node; import com.github.javaparser.ast.body.AnnotationMemberDeclaration; import com.github.javaparser.ast.expr.Expression; +import com.github.javaparser.resolution.Context; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.ResolvedAnnotationMemberDeclaration; import com.github.javaparser.resolution.types.ResolvedType; -import com.github.javaparser.symbolsolver.core.resolution.Context; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; + +import java.util.Optional; /** * @author Federico Tomassetti @@ -65,4 +68,10 @@ public String getName() { private Context getContext() { return JavaParserFactory.getContext(wrappedNode, typeSolver); } + + @Override + public Optional toAst() { + return Optional.of(wrappedNode); + } + } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnonymousClassDeclaration.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnonymousClassDeclaration.java similarity index 94% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnonymousClassDeclaration.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnonymousClassDeclaration.java index 0ec0bcd..7910da6 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnonymousClassDeclaration.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnonymousClassDeclaration.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -21,6 +21,9 @@ package com.github.javaparser.symbolsolver.javaparsermodel.declarations; +import java.util.*; +import java.util.stream.Collectors; + import com.github.javaparser.ast.AccessSpecifier; import com.github.javaparser.ast.Node; import com.github.javaparser.ast.body.FieldDeclaration; @@ -28,25 +31,22 @@ import com.github.javaparser.ast.body.TypeDeclaration; import com.github.javaparser.ast.expr.ObjectCreationExpr; import com.github.javaparser.ast.type.ClassOrInterfaceType; +import com.github.javaparser.resolution.Context; import com.github.javaparser.resolution.MethodUsage; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.*; +import com.github.javaparser.resolution.model.SymbolReference; +import com.github.javaparser.resolution.model.typesystem.ReferenceTypeImpl; import com.github.javaparser.resolution.types.ResolvedReferenceType; import com.github.javaparser.resolution.types.ResolvedType; -import com.github.javaparser.symbolsolver.core.resolution.Context; import com.github.javaparser.symbolsolver.core.resolution.MethodUsageResolutionCapability; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory; import com.github.javaparser.symbolsolver.javaparsermodel.contexts.ObjectCreationContext; import com.github.javaparser.symbolsolver.logic.AbstractClassDeclaration; -import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; -import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; -import java.util.*; -import java.util.stream.Collectors; - /** * An anonymous class declaration representation. */ @@ -86,9 +86,8 @@ public List findMembersOfKind(final Class memberClass) { .filter(node -> memberClass.isAssignableFrom(node.getClass())) .map(memberClass::cast) .collect(Collectors.toList()); - } else { - return Collections.emptyList(); } + return Collections.emptyList(); } public Context getContext() { @@ -109,7 +108,7 @@ public Optional solveMethodAsUsage(String name, List @Override protected ResolvedReferenceType object() { - return new ReferenceTypeImpl(typeSolver.getSolvedJavaLangObject(), typeSolver); + return new ReferenceTypeImpl(typeSolver.getSolvedJavaLangObject()); } @Override @@ -118,7 +117,7 @@ public Optional getSuperClass() { if (superRRTD == null) { return Optional.empty(); } - return Optional.of(new ReferenceTypeImpl(superRRTD, typeSolver)); + return Optional.of(new ReferenceTypeImpl(superRRTD)); } @Override @@ -233,9 +232,8 @@ public String getQualifiedName() { String containerName = AstResolutionUtils.containerName(wrappedNode.getParentNode().orElse(null)); if (containerName.isEmpty()) { return getName(); - } else { - return containerName + "." + getName(); } + return containerName + "." + getName(); } @Override diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserClassDeclaration.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserClassDeclaration.java similarity index 92% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserClassDeclaration.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserClassDeclaration.java index 381ba3e..f65179f 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserClassDeclaration.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserClassDeclaration.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -21,36 +21,37 @@ package com.github.javaparser.symbolsolver.javaparsermodel.declarations; +import java.util.*; +import java.util.stream.Collectors; + import com.github.javaparser.ast.AccessSpecifier; import com.github.javaparser.ast.Node; import com.github.javaparser.ast.body.BodyDeclaration; import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; -import com.github.javaparser.ast.body.FieldDeclaration; import com.github.javaparser.ast.body.MethodDeclaration; import com.github.javaparser.ast.type.ClassOrInterfaceType; +import com.github.javaparser.resolution.Context; import com.github.javaparser.resolution.MethodUsage; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.UnsolvedSymbolException; import com.github.javaparser.resolution.declarations.*; +import com.github.javaparser.resolution.model.SymbolReference; +import com.github.javaparser.resolution.model.typesystem.LazyType; +import com.github.javaparser.resolution.model.typesystem.ReferenceTypeImpl; import com.github.javaparser.resolution.types.ResolvedReferenceType; import com.github.javaparser.resolution.types.ResolvedType; -import com.github.javaparser.symbolsolver.core.resolution.Context; import com.github.javaparser.symbolsolver.core.resolution.MethodUsageResolutionCapability; +import com.github.javaparser.symbolsolver.core.resolution.SymbolResolutionCapability; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory; import com.github.javaparser.symbolsolver.logic.AbstractClassDeclaration; -import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; -import com.github.javaparser.symbolsolver.model.typesystem.LazyType; -import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl; import com.github.javaparser.symbolsolver.resolution.SymbolSolver; -import java.util.*; -import java.util.stream.Collectors; - /** * @author Federico Tomassetti */ -public class JavaParserClassDeclaration extends AbstractClassDeclaration implements MethodUsageResolutionCapability { +public class JavaParserClassDeclaration extends AbstractClassDeclaration + implements MethodUsageResolutionCapability, SymbolResolutionCapability { /// /// Fields @@ -103,7 +104,7 @@ public String toString() { /// /// Public methods: fields /// - + @Override public List getAllFields() { List fields = javaParserTypeAdapter.getFieldsForDeclaredVariables(); @@ -132,7 +133,7 @@ public ResolvedType getType() { public boolean isStatic() { return f.isStatic(); } - + @Override public boolean isVolatile() { return f.isVolatile(); @@ -142,9 +143,9 @@ public boolean isVolatile() { public ResolvedTypeDeclaration declaringType() { return f.declaringType(); } - + @Override - public Optional toAst() { + public Optional toAst() { return f.toAst(); } }); @@ -188,16 +189,15 @@ public String getName() { @Override public Optional getSuperClass() { - if(isJavaLangObject()) { + if (isJavaLangObject()) { // If this is java.lang.Object, it has no super class. return Optional.empty(); - } else if (wrappedNode.getExtendedTypes().isEmpty()) { + } + if (wrappedNode.getExtendedTypes().isEmpty()) { // All objects implicitly extend java.lang.Object -- inject it here (only when this isn't java.lang.Object) return Optional.of(object()); - } else { - // Otherwise, return the first ancestor (n.b.: we know it's not empty due to check above). - return Optional.of(toReferenceType(wrappedNode.getExtendedTypes().getFirst().get())); } + return Optional.of(toReferenceType(wrappedNode.getExtendedTypes().getFirst().get())); } @Override @@ -222,6 +222,14 @@ public boolean hasDirectlyAnnotation(String canonicalName) { return AstResolutionUtils.hasDirectlyAnnotation(wrappedNode, typeSolver, canonicalName); } + /* + * Returns a set of the declared annotation on this type + */ + @Override + public Set getDeclaredAnnotations() { + return javaParserTypeAdapter.getDeclaredAnnotations(); + } + @Override public boolean isInterface() { return wrappedNode.isInterface(); @@ -305,7 +313,7 @@ public SymbolReference solveType(String name) { return ref; } - String prefix = wrappedNode.getName() + "."; + String prefix = wrappedNode.getName().asString() + "."; if (name.startsWith(prefix) && name.length() > prefix.length()) { return new JavaParserClassDeclaration(this.wrappedNode, typeSolver).solveType(name.substring(prefix.length())); } @@ -321,6 +329,11 @@ public SymbolReference solveMethod(String name, List< return getContext().solveMethod(name, argumentsTypes, staticOnly); } + @Override + public SymbolReference solveSymbol(String name, TypeSolver typeSolver) { + return getContext().solveSymbol(name); + } + @Override public List getAncestors(boolean acceptIncompleteList) { List ancestors = new ArrayList<>(); @@ -380,7 +393,7 @@ private boolean isAncestor(ResolvedReferenceType candidateAncestor, String ownQu if (resolvedReferenceTypeDeclaration.isPresent()) { ResolvedTypeDeclaration rtd = resolvedReferenceTypeDeclaration.get().asType(); // do not consider an inner or nested class as an ancestor - return !rtd.getQualifiedName().contains(ownQualifiedName); + return !rtd.hasInternalType(ownQualifiedName); } return false; } @@ -429,7 +442,7 @@ public Optional toAst() { @Override protected ResolvedReferenceType object() { ResolvedReferenceTypeDeclaration solvedJavaLangObject = typeSolver.getSolvedJavaLangObject(); - return new ReferenceTypeImpl(solvedJavaLangObject, typeSolver); + return new ReferenceTypeImpl(solvedJavaLangObject); } @Override @@ -469,7 +482,7 @@ private ResolvedReferenceType toReferenceType(ClassOrInterfaceType classOrInterf } if (!classOrInterfaceType.getTypeArguments().isPresent()) { - return new ReferenceTypeImpl(ref.getCorrespondingDeclaration().asReferenceType(), typeSolver); + return new ReferenceTypeImpl(ref.getCorrespondingDeclaration().asReferenceType()); } List superClassTypeParameters = classOrInterfaceType.getTypeArguments().get() @@ -477,6 +490,6 @@ private ResolvedReferenceType toReferenceType(ClassOrInterfaceType classOrInterf .map(ta -> new LazyType(v -> JavaParserFacade.get(typeSolver).convert(ta, ta))) .collect(Collectors.toList()); - return new ReferenceTypeImpl(ref.getCorrespondingDeclaration().asReferenceType(), superClassTypeParameters, typeSolver); + return new ReferenceTypeImpl(ref.getCorrespondingDeclaration().asReferenceType(), superClassTypeParameters); } } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserConstructorDeclaration.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserConstructorDeclaration.java similarity index 94% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserConstructorDeclaration.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserConstructorDeclaration.java index 2ae4b76..49d3b1f 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserConstructorDeclaration.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserConstructorDeclaration.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -22,14 +22,14 @@ package com.github.javaparser.symbolsolver.javaparsermodel.declarations; import com.github.javaparser.ast.AccessSpecifier; -import com.github.javaparser.ast.body.ConstructorDeclaration; +import com.github.javaparser.ast.Node; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.ResolvedConstructorDeclaration; import com.github.javaparser.resolution.declarations.ResolvedParameterDeclaration; import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration; import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration; import com.github.javaparser.resolution.types.ResolvedType; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; import java.util.List; import java.util.Optional; @@ -109,7 +109,7 @@ public ResolvedType getSpecifiedException(int index) { } @Override - public Optional toAst() { + public Optional toAst() { return Optional.of(wrappedNode); } } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserEnumConstantDeclaration.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserEnumConstantDeclaration.java similarity index 80% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserEnumConstantDeclaration.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserEnumConstantDeclaration.java index 25ca5ca..9df774b 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserEnumConstantDeclaration.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserEnumConstantDeclaration.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -21,13 +21,16 @@ package com.github.javaparser.symbolsolver.javaparsermodel.declarations; +import com.github.javaparser.ast.Node; import com.github.javaparser.ast.body.EnumDeclaration; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.ResolvedEnumConstantDeclaration; +import com.github.javaparser.resolution.model.typesystem.ReferenceTypeImpl; import com.github.javaparser.resolution.types.ResolvedType; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; -import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl; -import static com.github.javaparser.symbolsolver.javaparser.Navigator.demandParentNode; +import java.util.Optional; + +import static com.github.javaparser.resolution.Navigator.demandParentNode; /** * @author Federico Tomassetti @@ -44,7 +47,7 @@ public JavaParserEnumConstantDeclaration(com.github.javaparser.ast.body.EnumCons @Override public ResolvedType getType() { - return new ReferenceTypeImpl(new JavaParserEnumDeclaration((EnumDeclaration) demandParentNode(wrappedNode), typeSolver), typeSolver); + return new ReferenceTypeImpl(new JavaParserEnumDeclaration((EnumDeclaration) demandParentNode(wrappedNode), typeSolver)); } @Override @@ -61,4 +64,9 @@ public com.github.javaparser.ast.body.EnumConstantDeclaration getWrappedNode() { return wrappedNode; } + @Override + public Optional toAst() { + return Optional.of(wrappedNode); + } + } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserEnumDeclaration.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserEnumDeclaration.java similarity index 92% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserEnumDeclaration.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserEnumDeclaration.java index f75281a..e5478c5 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserEnumDeclaration.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserEnumDeclaration.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -26,26 +26,26 @@ import com.github.javaparser.ast.body.BodyDeclaration; import com.github.javaparser.ast.body.EnumDeclaration; import com.github.javaparser.ast.body.FieldDeclaration; -import com.github.javaparser.ast.body.MethodDeclaration; import com.github.javaparser.ast.type.ClassOrInterfaceType; +import com.github.javaparser.resolution.Context; import com.github.javaparser.resolution.MethodUsage; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.UnsolvedSymbolException; import com.github.javaparser.resolution.declarations.*; +import com.github.javaparser.resolution.logic.MethodResolutionCapability; +import com.github.javaparser.resolution.model.SymbolReference; +import com.github.javaparser.resolution.model.typesystem.LazyType; +import com.github.javaparser.resolution.model.typesystem.ReferenceTypeImpl; import com.github.javaparser.resolution.types.ResolvedArrayType; import com.github.javaparser.resolution.types.ResolvedReferenceType; import com.github.javaparser.resolution.types.ResolvedType; import com.github.javaparser.resolution.types.parametrization.ResolvedTypeParametersMap; -import com.github.javaparser.symbolsolver.core.resolution.Context; import com.github.javaparser.symbolsolver.core.resolution.MethodUsageResolutionCapability; +import com.github.javaparser.symbolsolver.core.resolution.SymbolResolutionCapability; import com.github.javaparser.symbolsolver.core.resolution.TypeVariableResolutionCapability; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory; import com.github.javaparser.symbolsolver.logic.AbstractTypeDeclaration; -import com.github.javaparser.symbolsolver.logic.MethodResolutionCapability; -import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; -import com.github.javaparser.symbolsolver.model.typesystem.LazyType; -import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl; import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionFactory; import java.io.Serializable; @@ -57,8 +57,8 @@ */ public class JavaParserEnumDeclaration extends AbstractTypeDeclaration implements ResolvedEnumDeclaration, MethodResolutionCapability, MethodUsageResolutionCapability, - AssociableToAST { - + SymbolResolutionCapability { + private static String JAVA_LANG_ENUM = java.lang.Enum.class.getCanonicalName(); private static String JAVA_LANG_COMPARABLE = java.lang.Comparable.class.getCanonicalName(); private static String JAVA_IO_SERIALIZABLE = Serializable.class.getCanonicalName(); @@ -221,6 +221,11 @@ public SymbolReference solveMethod(String name, List< return getContext().solveMethod(name, argumentsTypes, staticOnly); } + @Override + public SymbolReference solveSymbol(String name, TypeSolver typeSolver) { + return getContext().solveSymbol(name); + } + @Override public List getAllFields() { List fields = javaParserTypeAdapter.getFieldsForDeclaredVariables(); @@ -245,7 +250,7 @@ public List getAncestors(boolean acceptIncompleteList) { .getTypeParameters() .get(0); enumClass = enumClass.deriveTypeParameters(new ResolvedTypeParametersMap.Builder() - .setValue(eTypeParameter, new ReferenceTypeImpl(this, typeSolver)) + .setValue(eTypeParameter, new ReferenceTypeImpl(this)) .build()); ancestors.add(enumClass); } else { @@ -279,12 +284,12 @@ private ResolvedReferenceType toReferenceType(ClassOrInterfaceType classOrInterf throw new UnsolvedSymbolException(classOrInterfaceType.getName().getId()); } if (!classOrInterfaceType.getTypeArguments().isPresent()) { - return new ReferenceTypeImpl(ref.getCorrespondingDeclaration().asReferenceType(), typeSolver); + return new ReferenceTypeImpl(ref.getCorrespondingDeclaration().asReferenceType()); } List superClassTypeParameters = classOrInterfaceType.getTypeArguments().get() .stream().map(ta -> new LazyType(v -> JavaParserFacade.get(typeSolver).convert(ta, ta))) .collect(Collectors.toList()); - return new ReferenceTypeImpl(ref.getCorrespondingDeclaration().asReferenceType(), superClassTypeParameters, typeSolver); + return new ReferenceTypeImpl(ref.getCorrespondingDeclaration().asReferenceType(), superClassTypeParameters); } /** @@ -331,7 +336,6 @@ public List getEnumConstants() { .collect(Collectors.toList()); } - /** * Needed by ContextHelper * @@ -359,7 +363,7 @@ public ResolvedReferenceTypeDeclaration declaringType() { @Override public ResolvedType getReturnType() { - return new ResolvedArrayType(new ReferenceTypeImpl(enumDeclaration, typeSolver)); + return new ResolvedArrayType(new ReferenceTypeImpl(enumDeclaration)); } @Override @@ -421,11 +425,15 @@ public ResolvedType getSpecifiedException(int index) { } @Override - public Optional toAst() { - return Optional.empty(); + public Optional toAst() { + return enumDeclaration.toAst(); } - } + @Override + public String toDescriptor() { + return String.format("()%s", getReturnType().toDescriptor()); + } + } /** * Needed by ContextHelper @@ -453,7 +461,7 @@ public ResolvedReferenceTypeDeclaration declaringType() { @Override public ResolvedType getReturnType() { - return new ReferenceTypeImpl(enumDeclaration, typeSolver); + return new ReferenceTypeImpl(enumDeclaration); } @Override @@ -465,6 +473,7 @@ public int getNumberOfParams() { public ResolvedParameterDeclaration getParam(int i) { if (i == 0) { return new ResolvedParameterDeclaration() { + @Override public String getName() { return "name"; @@ -472,13 +481,19 @@ public String getName() { @Override public ResolvedType getType() { - return new ReferenceTypeImpl(typeSolver.solveType("java.lang.String"), typeSolver); + return new ReferenceTypeImpl(typeSolver.solveType("java.lang.String")); } @Override public boolean isVariadic() { return false; } + + @Override + public Optional toAst() { + return enumDeclaration.toAst(); + } + }; } @@ -535,8 +550,13 @@ public ResolvedType getSpecifiedException(int index) { } @Override - public Optional toAst() { - return Optional.empty(); + public Optional toAst() { + return enumDeclaration.toAst(); + } + + @Override + public String toDescriptor() { + return String.format("(Ljava/lang/String;)%s", getReturnType().toDescriptor()); } } @@ -561,7 +581,7 @@ public List getConstructors() { } @Override - public Optional toAst() { + public Optional toAst() { return Optional.of(wrappedNode); } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserFieldDeclaration.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserFieldDeclaration.java similarity index 90% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserFieldDeclaration.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserFieldDeclaration.java index 88cd8a1..7a501b5 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserFieldDeclaration.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserFieldDeclaration.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -23,24 +23,24 @@ import com.github.javaparser.ast.AccessSpecifier; import com.github.javaparser.ast.Modifier; -import com.github.javaparser.ast.body.FieldDeclaration; +import com.github.javaparser.ast.Node; import com.github.javaparser.ast.body.TypeDeclaration; import com.github.javaparser.ast.body.VariableDeclarator; -import com.github.javaparser.resolution.declarations.AssociableToAST; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.ResolvedFieldDeclaration; import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration; import com.github.javaparser.resolution.types.ResolvedType; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; import java.util.Optional; -import static com.github.javaparser.symbolsolver.javaparser.Navigator.demandParentNode; +import static com.github.javaparser.resolution.Navigator.demandParentNode; + /** * @author Federico Tomassetti */ -public class JavaParserFieldDeclaration implements ResolvedFieldDeclaration, AssociableToAST { +public class JavaParserFieldDeclaration implements ResolvedFieldDeclaration { private VariableDeclarator variableDeclarator; private com.github.javaparser.ast.body.FieldDeclaration wrappedNode; @@ -72,7 +72,7 @@ public String getName() { public boolean isStatic() { return wrappedNode.hasModifier(Modifier.Keyword.STATIC); } - + @Override public boolean isVolatile() { return wrappedNode.hasModifier(Modifier.Keyword.VOLATILE); @@ -116,7 +116,7 @@ public ResolvedTypeDeclaration declaringType() { } @Override - public Optional toAst() { + public Optional toAst() { return Optional.ofNullable(wrappedNode); } } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserInterfaceDeclaration.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserInterfaceDeclaration.java similarity index 91% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserInterfaceDeclaration.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserInterfaceDeclaration.java index 0d8e553..2aaf917 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserInterfaceDeclaration.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserInterfaceDeclaration.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -21,37 +21,38 @@ package com.github.javaparser.symbolsolver.javaparsermodel.declarations; +import java.util.*; +import java.util.stream.Collectors; + import com.github.javaparser.ast.AccessSpecifier; import com.github.javaparser.ast.Node; import com.github.javaparser.ast.body.BodyDeclaration; import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; -import com.github.javaparser.ast.body.FieldDeclaration; import com.github.javaparser.ast.type.ClassOrInterfaceType; +import com.github.javaparser.resolution.Context; import com.github.javaparser.resolution.MethodUsage; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.UnsolvedSymbolException; import com.github.javaparser.resolution.declarations.*; +import com.github.javaparser.resolution.logic.MethodResolutionCapability; +import com.github.javaparser.resolution.model.SymbolReference; +import com.github.javaparser.resolution.model.typesystem.LazyType; +import com.github.javaparser.resolution.model.typesystem.ReferenceTypeImpl; import com.github.javaparser.resolution.types.ResolvedReferenceType; import com.github.javaparser.resolution.types.ResolvedType; -import com.github.javaparser.symbolsolver.core.resolution.Context; import com.github.javaparser.symbolsolver.core.resolution.MethodUsageResolutionCapability; +import com.github.javaparser.symbolsolver.core.resolution.SymbolResolutionCapability; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory; import com.github.javaparser.symbolsolver.logic.AbstractTypeDeclaration; -import com.github.javaparser.symbolsolver.logic.MethodResolutionCapability; -import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; -import com.github.javaparser.symbolsolver.model.typesystem.LazyType; -import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl; import com.github.javaparser.symbolsolver.resolution.SymbolSolver; -import java.util.*; -import java.util.stream.Collectors; - /** * @author Federico Tomassetti */ public class JavaParserInterfaceDeclaration extends AbstractTypeDeclaration - implements ResolvedInterfaceDeclaration, MethodResolutionCapability, MethodUsageResolutionCapability { + implements ResolvedInterfaceDeclaration, MethodResolutionCapability, MethodUsageResolutionCapability, + SymbolResolutionCapability { private TypeSolver typeSolver; private ClassOrInterfaceDeclaration wrappedNode; @@ -117,6 +118,14 @@ public boolean hasDirectlyAnnotation(String canonicalName) { return AstResolutionUtils.hasDirectlyAnnotation(wrappedNode, typeSolver, canonicalName); } + /* + * Returns a set of the declared annotation on this type + */ + @Override + public Set getDeclaredAnnotations() { + return javaParserTypeAdapter.getDeclaredAnnotations(); + } + @Override public boolean isInterface() { return true; @@ -127,7 +136,7 @@ public List getInterfacesExtended() { List interfaces = new ArrayList<>(); for (ClassOrInterfaceType t : wrappedNode.getExtendedTypes()) { interfaces.add(new ReferenceTypeImpl( - solveType(t.getName().getId()).getCorrespondingDeclaration().asInterface(), typeSolver)); + solveType(t.getName().getId()).getCorrespondingDeclaration().asInterface())); } return interfaces; } @@ -221,7 +230,7 @@ public ResolvedType getType() { public boolean isStatic() { return f.isStatic(); } - + @Override public boolean isVolatile() { return f.isVolatile(); @@ -231,15 +240,15 @@ public boolean isVolatile() { public ResolvedTypeDeclaration declaringType() { return f.declaringType(); } - + @Override - public Optional toAst() { + public Optional toAst() { return f.toAst(); } }); }) ); - + return fields; } @@ -269,7 +278,7 @@ public SymbolReference solveType(String name) { return ref; } - String prefix = wrappedNode.getName() + "."; + String prefix = wrappedNode.getName().asString() + "."; if (name.startsWith(prefix) && name.length() > prefix.length()) { return new JavaParserInterfaceDeclaration(this.wrappedNode, typeSolver).solveType(name.substring(prefix.length())); } @@ -291,6 +300,11 @@ public Optional solveMethodAsUsage(String name, List return getContext().solveMethodAsUsage(name, argumentTypes); } + @Override + public SymbolReference solveSymbol(String name, TypeSolver typeSolver) { + return getContext().solveSymbol(name); + } + @Override public List getAncestors(boolean acceptIncompleteList) { List ancestors = new ArrayList<>(); @@ -327,11 +341,10 @@ public List getAncestors(boolean acceptIncompleteList) { public List getTypeParameters() { if (this.wrappedNode.getTypeParameters() == null) { return Collections.emptyList(); - } else { - return this.wrappedNode.getTypeParameters().stream().map( + } + return this.wrappedNode.getTypeParameters().stream().map( (tp) -> new JavaParserTypeParameter(tp, typeSolver) ).collect(Collectors.toList()); - } } /** @@ -364,7 +377,7 @@ public List getConstructors() { } @Override - public Optional toAst() { + public Optional toAst() { return Optional.of(wrappedNode); } @@ -389,11 +402,11 @@ private ResolvedReferenceType toReferenceType(ClassOrInterfaceType classOrInterf throw new UnsolvedSymbolException(classOrInterfaceType.getName().getId()); } if (!classOrInterfaceType.getTypeArguments().isPresent()) { - return new ReferenceTypeImpl(ref.getCorrespondingDeclaration().asReferenceType(), typeSolver); + return new ReferenceTypeImpl(ref.getCorrespondingDeclaration().asReferenceType()); } List superClassTypeParameters = classOrInterfaceType.getTypeArguments().get() .stream().map(ta -> new LazyType(v -> JavaParserFacade.get(typeSolver).convert(ta, ta))) .collect(Collectors.toList()); - return new ReferenceTypeImpl(ref.getCorrespondingDeclaration().asReferenceType(), superClassTypeParameters, typeSolver); + return new ReferenceTypeImpl(ref.getCorrespondingDeclaration().asReferenceType(), superClassTypeParameters); } } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserMethodDeclaration.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserMethodDeclaration.java similarity index 84% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserMethodDeclaration.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserMethodDeclaration.java index ad11613..22b54da 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserMethodDeclaration.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserMethodDeclaration.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -23,26 +23,27 @@ import com.github.javaparser.ast.AccessSpecifier; import com.github.javaparser.ast.Node; -import com.github.javaparser.ast.body.MethodDeclaration; import com.github.javaparser.ast.expr.ObjectCreationExpr; +import com.github.javaparser.resolution.Context; import com.github.javaparser.resolution.MethodUsage; +import com.github.javaparser.resolution.SymbolResolver; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration; import com.github.javaparser.resolution.declarations.ResolvedParameterDeclaration; import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration; import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration; import com.github.javaparser.resolution.types.ResolvedType; -import com.github.javaparser.symbolsolver.core.resolution.Context; +import com.github.javaparser.symbolsolver.JavaSymbolSolver; import com.github.javaparser.symbolsolver.core.resolution.TypeVariableResolutionCapability; import com.github.javaparser.symbolsolver.declarations.common.MethodDeclarationCommonLogic; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; -import static com.github.javaparser.symbolsolver.javaparser.Navigator.demandParentNode; +import static com.github.javaparser.resolution.Navigator.demandParentNode; /** * @author Federico Tomassetti @@ -71,7 +72,14 @@ public ResolvedReferenceTypeDeclaration declaringType() { ObjectCreationExpr parentNode = (ObjectCreationExpr) demandParentNode(wrappedNode); return new JavaParserAnonymousClassDeclaration(parentNode, typeSolver); } - return JavaParserFactory.toTypeDeclaration(demandParentNode(wrappedNode), typeSolver); + // TODO Fix: to use getSymbolResolver() we have to fix many unit tests + // that throw IllegalStateException("Symbol resolution not configured: to configure consider setting a SymbolResolver in the ParserConfiguration" + // return wrappedNode.getSymbolResolver().toTypeDeclaration(wrappedNode); + return symbolResolver(typeSolver).toTypeDeclaration(demandParentNode(wrappedNode)); + } + + private SymbolResolver symbolResolver(TypeSolver typeSolver) { + return new JavaSymbolSolver(typeSolver); } @Override @@ -159,7 +167,12 @@ public ResolvedType getSpecifiedException(int index) { } @Override - public Optional toAst() { + public Optional toAst() { return Optional.of(wrappedNode); } + + @Override + public String toDescriptor() { + return wrappedNode.toDescriptor(); + } } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserParameterDeclaration.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserParameterDeclaration.java similarity index 89% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserParameterDeclaration.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserParameterDeclaration.java index fceabe0..b94044c 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserParameterDeclaration.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserParameterDeclaration.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -21,24 +21,24 @@ package com.github.javaparser.symbolsolver.javaparsermodel.declarations; +import com.github.javaparser.ast.Node; import com.github.javaparser.ast.body.Parameter; import com.github.javaparser.ast.type.UnknownType; -import com.github.javaparser.resolution.declarations.AssociableToAST; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.ResolvedParameterDeclaration; +import com.github.javaparser.resolution.model.Value; import com.github.javaparser.resolution.types.ResolvedArrayType; import com.github.javaparser.resolution.types.ResolvedType; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory; 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 java.util.Optional; /** * @author Federico Tomassetti */ -public class JavaParserParameterDeclaration implements ResolvedParameterDeclaration, AssociableToAST { +public class JavaParserParameterDeclaration implements ResolvedParameterDeclaration { private final Parameter wrappedNode; private final TypeSolver typeSolver; @@ -78,12 +78,13 @@ public ResolvedType getType() { * * @return A visitable JavaParser node wrapped by this object. */ + public Parameter getWrappedNode() { return wrappedNode; } @Override - public Optional toAst() { + public Optional toAst() { return Optional.of(wrappedNode); } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserPatternDeclaration.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserPatternDeclaration.java similarity index 88% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserPatternDeclaration.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserPatternDeclaration.java index 47f6c77..8691ca3 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserPatternDeclaration.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserPatternDeclaration.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -21,12 +21,12 @@ package com.github.javaparser.symbolsolver.javaparsermodel.declarations; +import com.github.javaparser.ast.Node; import com.github.javaparser.ast.expr.PatternExpr; -import com.github.javaparser.resolution.declarations.AssociableToAST; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.ResolvedPatternDeclaration; import com.github.javaparser.resolution.types.ResolvedType; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; import java.util.Optional; @@ -35,7 +35,7 @@ * * @author Roger Howell */ -public class JavaParserPatternDeclaration implements ResolvedPatternDeclaration, AssociableToAST { +public class JavaParserPatternDeclaration implements ResolvedPatternDeclaration { private final PatternExpr wrappedNode; private final TypeSolver typeSolver; @@ -65,7 +65,7 @@ public PatternExpr getWrappedNode() { } @Override - public Optional toAst() { + public Optional toAst() { return Optional.of(wrappedNode); } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserSymbolDeclaration.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserSymbolDeclaration.java similarity index 76% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserSymbolDeclaration.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserSymbolDeclaration.java index 330d7b7..c75e3b0 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserSymbolDeclaration.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserSymbolDeclaration.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -24,11 +24,10 @@ import com.github.javaparser.ast.Node; import com.github.javaparser.ast.body.Parameter; import com.github.javaparser.ast.body.VariableDeclarator; -import com.github.javaparser.ast.expr.MethodCallExpr; import com.github.javaparser.ast.expr.PatternExpr; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; +import com.github.javaparser.resolution.TypeSolver; -import static com.github.javaparser.symbolsolver.javaparser.Navigator.demandParentNode; +import static com.github.javaparser.resolution.Navigator.demandParentNode; /** * This should not be used to represent fields of parameters. @@ -60,24 +59,14 @@ public static int getParamPos(Parameter parameter) { for (Node node : demandParentNode(parameter).getChildNodes()) { if (node == parameter) { return pos; - } else if (node instanceof Parameter) { + } + if (node instanceof Parameter) { pos++; } } return pos; } - public static int getParamPos(Node node) { - if (demandParentNode(node) instanceof MethodCallExpr) { - MethodCallExpr call = (MethodCallExpr) demandParentNode(node); - for (int i = 0; i < call.getArguments().size(); i++) { - if (call.getArguments().get(i) == node) return i; - } - throw new IllegalStateException(); - } - throw new IllegalArgumentException(); - } - private JavaParserSymbolDeclaration() { // This private constructor is used to hide the public one } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeAdapter.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeAdapter.java similarity index 78% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeAdapter.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeAdapter.java index 2b57f53..4480ae1 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeAdapter.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeAdapter.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -21,31 +21,33 @@ package com.github.javaparser.symbolsolver.javaparsermodel.declarations; +import java.util.*; +import java.util.stream.Collectors; + import com.github.javaparser.ast.Node; import com.github.javaparser.ast.NodeList; import com.github.javaparser.ast.body.*; +import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations; import com.github.javaparser.ast.nodeTypes.NodeWithMembers; import com.github.javaparser.ast.nodeTypes.NodeWithSimpleName; import com.github.javaparser.ast.nodeTypes.NodeWithTypeParameters; import com.github.javaparser.ast.type.TypeParameter; +import com.github.javaparser.resolution.TypeSolver; +import com.github.javaparser.resolution.declarations.ResolvedAnnotationDeclaration; import com.github.javaparser.resolution.declarations.ResolvedFieldDeclaration; import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration; import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration; +import com.github.javaparser.resolution.model.SymbolReference; +import com.github.javaparser.resolution.model.typesystem.ReferenceTypeImpl; import com.github.javaparser.resolution.types.ResolvedReferenceType; import com.github.javaparser.resolution.types.ResolvedType; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade; -import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory; -import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; -import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl; import com.github.javaparser.symbolsolver.resolution.SymbolSolver; -import java.util.*; - /** * @author Federico Tomassetti */ -public class JavaParserTypeAdapter & NodeWithMembers> { +public class JavaParserTypeAdapter & NodeWithMembers & NodeWithAnnotations> { private T wrappedNode; private TypeSolver typeSolver; @@ -67,14 +69,13 @@ public String getQualifiedName() { String containerName = AstResolutionUtils.containerName(wrappedNode.getParentNode().orElse(null)); if (containerName.isEmpty()) { return wrappedNode.getName().getId(); - } else { - return containerName + "." + wrappedNode.getName().getId(); } + return containerName + "." + wrappedNode.getName().getId(); } public boolean isAssignableBy(ResolvedReferenceTypeDeclaration other) { List ancestorsOfOther = other.getAllAncestors(); - ancestorsOfOther.add(new ReferenceTypeImpl(other, typeSolver)); + ancestorsOfOther.add(new ReferenceTypeImpl(other)); for (ResolvedReferenceType ancestorOfOther : ancestorsOfOther) { if (ancestorOfOther.getQualifiedName().equals(this.getQualifiedName())) { return true; @@ -90,9 +91,8 @@ public boolean isAssignableBy(ResolvedType type) { if (type.isReferenceType()) { ResolvedReferenceTypeDeclaration other = typeSolver.solveType(type.describe()); return isAssignableBy(other); - } else { - throw new UnsupportedOperationException(); } + throw new UnsupportedOperationException(); } /** @@ -118,47 +118,48 @@ public SymbolReference solveType(String name) { for (BodyDeclaration member : this.wrappedNode.getMembers()) { if (member instanceof com.github.javaparser.ast.body.TypeDeclaration) { com.github.javaparser.ast.body.TypeDeclaration internalType = (com.github.javaparser.ast.body.TypeDeclaration) member; - String prefix = internalType.getName() + "."; + String prefix = internalType.getName().asString() + "."; if (internalType.getName().getId().equals(name)) { if (internalType instanceof ClassOrInterfaceDeclaration) { if (((ClassOrInterfaceDeclaration) internalType).isInterface()) { return SymbolReference.solved(new JavaParserInterfaceDeclaration((com.github.javaparser.ast.body.ClassOrInterfaceDeclaration) internalType, typeSolver)); - } else { - return SymbolReference.solved(new JavaParserClassDeclaration((com.github.javaparser.ast.body.ClassOrInterfaceDeclaration) internalType, typeSolver)); } - } else if (internalType instanceof EnumDeclaration) { + return SymbolReference.solved(new JavaParserClassDeclaration((com.github.javaparser.ast.body.ClassOrInterfaceDeclaration) internalType, typeSolver)); + } + if (internalType instanceof EnumDeclaration) { return SymbolReference.solved(new JavaParserEnumDeclaration((com.github.javaparser.ast.body.EnumDeclaration) internalType, typeSolver)); - } else if (internalType instanceof AnnotationDeclaration) { + } + if (internalType instanceof AnnotationDeclaration) { return SymbolReference.solved(new JavaParserAnnotationDeclaration((com.github.javaparser.ast.body.AnnotationDeclaration) internalType, typeSolver)); - } else { - throw new UnsupportedOperationException(); } - } else if (name.startsWith(prefix) && name.length() > prefix.length()) { + throw new UnsupportedOperationException(); + } + if (name.startsWith(prefix) && name.length() > prefix.length()) { if (internalType instanceof ClassOrInterfaceDeclaration) { if (((ClassOrInterfaceDeclaration) internalType).isInterface()) { return new JavaParserInterfaceDeclaration((com.github.javaparser.ast.body.ClassOrInterfaceDeclaration) internalType, typeSolver).solveType(name.substring(prefix.length())); - } else { - return new JavaParserClassDeclaration((com.github.javaparser.ast.body.ClassOrInterfaceDeclaration) internalType, typeSolver).solveType(name.substring(prefix.length())); } - } else if (internalType instanceof EnumDeclaration) { + return new JavaParserClassDeclaration((com.github.javaparser.ast.body.ClassOrInterfaceDeclaration) internalType, typeSolver).solveType(name.substring(prefix.length())); + } + if (internalType instanceof EnumDeclaration) { return new SymbolSolver(typeSolver).solveTypeInType(new JavaParserEnumDeclaration((com.github.javaparser.ast.body.EnumDeclaration) internalType, typeSolver), name.substring(prefix.length())); - } else if (internalType instanceof AnnotationDeclaration) { + } + if (internalType instanceof AnnotationDeclaration) { return SymbolReference.solved(new JavaParserAnnotationDeclaration((com.github.javaparser.ast.body.AnnotationDeclaration) internalType, typeSolver)); - } else { - throw new UnsupportedOperationException(); } + throw new UnsupportedOperationException(); } } } - return SymbolReference.unsolved(ResolvedTypeDeclaration.class); + return SymbolReference.unsolved(); } public Optional containerType() { return wrappedNode .getParentNode() - .map(node -> JavaParserFactory.toTypeDeclaration(node, typeSolver)); + .map(node -> node.getSymbolResolver().toTypeDeclaration(node)); } - + public List getFieldsForDeclaredVariables() { List fields = new ArrayList<>(); if (wrappedNode.getMembers() != null) { @@ -174,6 +175,15 @@ public List getFieldsForDeclaredVariables() { return fields; } + /* + * Returns a set of the declared annotation on this type + */ + public Set getDeclaredAnnotations() { + return wrappedNode.getAnnotations().stream() + .map(annotation -> annotation.resolve()) + .collect(Collectors.toSet()); + } + public Set internalTypes() { // Use a special Set implementation that avoids calculating the hashCode of the node, // since this can be very time-consuming for big node trees, and we are sure there are diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeParameter.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeParameter.java similarity index 87% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeParameter.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeParameter.java index 8927ea2..693ef20 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeParameter.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeParameter.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -24,20 +24,21 @@ import com.github.javaparser.ast.Node; import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; import com.github.javaparser.ast.type.ClassOrInterfaceType; +import com.github.javaparser.resolution.Context; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.*; +import com.github.javaparser.resolution.model.SymbolReference; +import com.github.javaparser.resolution.model.typesystem.ReferenceTypeImpl; import com.github.javaparser.resolution.types.ResolvedReferenceType; import com.github.javaparser.resolution.types.ResolvedType; -import com.github.javaparser.symbolsolver.core.resolution.Context; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade; import com.github.javaparser.symbolsolver.logic.AbstractTypeDeclaration; -import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; -import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl; import java.util.*; import java.util.stream.Collectors; -import static com.github.javaparser.symbolsolver.javaparser.Navigator.demandParentNode; +import static com.github.javaparser.resolution.Navigator.demandParentNode; + /** * @author Federico Tomassetti @@ -87,7 +88,7 @@ public String getName() { @Override public boolean isAssignableBy(ResolvedReferenceTypeDeclaration other) { - return isAssignableBy(new ReferenceTypeImpl(other, typeSolver)); + return isAssignableBy(new ReferenceTypeImpl(other)); } @Override @@ -95,11 +96,11 @@ public String getContainerQualifiedName() { ResolvedTypeParametrizable container = getContainer(); if (container instanceof ResolvedReferenceTypeDeclaration) { return ((ResolvedReferenceTypeDeclaration) container).getQualifiedName(); - } else if (container instanceof JavaParserConstructorDeclaration) { + } + if (container instanceof JavaParserConstructorDeclaration) { return ((JavaParserConstructorDeclaration) container).getQualifiedSignature(); - } else { - return ((JavaParserMethodDeclaration) container).getQualifiedSignature(); } + return ((JavaParserMethodDeclaration) container).getQualifiedSignature(); } @Override @@ -107,11 +108,11 @@ public String getContainerId() { ResolvedTypeParametrizable container = getContainer(); if (container instanceof ResolvedReferenceTypeDeclaration) { return ((ResolvedReferenceTypeDeclaration) container).getId(); - } else if (container instanceof JavaParserConstructorDeclaration) { + } + if (container instanceof JavaParserConstructorDeclaration) { return ((JavaParserConstructorDeclaration) container).getQualifiedSignature(); - } else { - return ((JavaParserMethodDeclaration) container).getQualifiedSignature(); } + return ((JavaParserMethodDeclaration) container).getQualifiedSignature(); } @Override @@ -120,7 +121,8 @@ public ResolvedTypeParametrizable getContainer() { if (parentNode instanceof com.github.javaparser.ast.body.ClassOrInterfaceDeclaration) { com.github.javaparser.ast.body.ClassOrInterfaceDeclaration jpTypeDeclaration = (com.github.javaparser.ast.body.ClassOrInterfaceDeclaration) parentNode; return JavaParserFacade.get(typeSolver).getTypeDeclaration(jpTypeDeclaration); - } else if (parentNode instanceof com.github.javaparser.ast.body.ConstructorDeclaration){ + } + if (parentNode instanceof com.github.javaparser.ast.body.ConstructorDeclaration){ com.github.javaparser.ast.body.ConstructorDeclaration jpConstructorDeclaration = (com.github.javaparser.ast.body.ConstructorDeclaration) parentNode; Optional jpTypeDeclaration = jpConstructorDeclaration.findAncestor(com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.class); if (jpTypeDeclaration.isPresent()) { @@ -147,7 +149,7 @@ public List getBounds() { } private Bound toBound(ClassOrInterfaceType classOrInterfaceType, TypeSolver typeSolver) { - ResolvedType type = JavaParserFacade.get(typeSolver).convertToUsage(classOrInterfaceType, classOrInterfaceType); + ResolvedType type = JavaParserFacade.get(typeSolver).convertToUsage(classOrInterfaceType); return Bound.extendsBound(type); } @@ -231,4 +233,15 @@ public Optional containerType() { public List getConstructors() { return Collections.emptyList(); } + + @Override + public ResolvedReferenceType object() { + return new ReferenceTypeImpl(typeSolver.getSolvedJavaLangObject()); + } + + @Override + public Optional toAst() { + return Optional.of(wrappedNode); + } + } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeVariableDeclaration.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeVariableDeclaration.java similarity index 73% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeVariableDeclaration.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeVariableDeclaration.java index 3a8cd8e..1f74833 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeVariableDeclaration.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeVariableDeclaration.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -22,22 +22,25 @@ package com.github.javaparser.symbolsolver.javaparsermodel.declarations; import com.github.javaparser.ast.Node; +import com.github.javaparser.ast.type.ClassOrInterfaceType; import com.github.javaparser.ast.type.TypeParameter; +import com.github.javaparser.resolution.Context; +import com.github.javaparser.resolution.TypeSolver; +import com.github.javaparser.resolution.UnsolvedSymbolException; import com.github.javaparser.resolution.declarations.*; +import com.github.javaparser.resolution.model.SymbolReference; +import com.github.javaparser.resolution.model.typesystem.ReferenceTypeImpl; import com.github.javaparser.resolution.types.ResolvedReferenceType; import com.github.javaparser.resolution.types.ResolvedType; -import com.github.javaparser.symbolsolver.core.resolution.Context; +import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade; import com.github.javaparser.symbolsolver.logic.AbstractTypeDeclaration; -import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; -import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl; import java.util.*; /** * @author Federico Tomassetti */ -public class JavaParserTypeVariableDeclaration extends AbstractTypeDeclaration implements AssociableToAST { +public class JavaParserTypeVariableDeclaration extends AbstractTypeDeclaration { private TypeParameter wrappedNode; private TypeSolver typeSolver; @@ -49,7 +52,7 @@ public JavaParserTypeVariableDeclaration(TypeParameter wrappedNode, TypeSolver t @Override public boolean isAssignableBy(ResolvedReferenceTypeDeclaration other) { - return isAssignableBy(new ReferenceTypeImpl(other, typeSolver)); + return isAssignableBy(new ReferenceTypeImpl(other)); } @Override @@ -90,9 +93,8 @@ public ResolvedType getUsage(Node node) { public boolean isAssignableBy(ResolvedType type) { if (type.isTypeVariable()) { throw new UnsupportedOperationException("Is this type variable declaration assignable by " + type.describe()); - } else { - throw new UnsupportedOperationException("Is this type variable declaration assignable by " + type); } + throw new UnsupportedOperationException("Is this type variable declaration assignable by " + type); } @Override @@ -117,7 +119,25 @@ public List getAllFields() { @Override public List getAncestors(boolean acceptIncompleteList) { - throw new UnsupportedOperationException(); + if (wrappedNode.getTypeBound().isEmpty()) { + // Every type variable declared as a type parameter has a bound. + // If no bound is declared for a type variable, Object is assumed. + // https://docs.oracle.com/javase/specs/jls/se8/html/jls-4.html#jls-4.4 + return Collections.singletonList(new ReferenceTypeImpl(typeSolver.getSolvedJavaLangObject())); + } + List ancestors = new ArrayList<>(); + for (ClassOrInterfaceType type : wrappedNode.getTypeBound()) { + try { + ResolvedType resolvedType = JavaParserFacade.get(typeSolver).convertToUsage(type); + ancestors.add(resolvedType.asReferenceType()); + } catch (UnsolvedSymbolException e) { + if (!acceptIncompleteList) { + // Only throw if an incomplete ancestor list is unacceptable. + throw e; + } + } + } + return ancestors; } @Override @@ -180,7 +200,7 @@ public List getConstructors() { } @Override - public Optional toAst() { + public Optional toAst() { return Optional.of(wrappedNode); } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserVariableDeclaration.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserVariableDeclaration.java similarity index 88% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserVariableDeclaration.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserVariableDeclaration.java index 6be6794..bfc6527 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserVariableDeclaration.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserVariableDeclaration.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -21,22 +21,22 @@ package com.github.javaparser.symbolsolver.javaparsermodel.declarations; +import com.github.javaparser.ast.Node; import com.github.javaparser.ast.body.VariableDeclarator; import com.github.javaparser.ast.expr.VariableDeclarationExpr; -import com.github.javaparser.resolution.declarations.AssociableToAST; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration; import com.github.javaparser.resolution.types.ResolvedType; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; import java.util.Optional; -import static com.github.javaparser.symbolsolver.javaparser.Navigator.demandParentNode; +import static com.github.javaparser.resolution.Navigator.demandParentNode; /** * @author Federico Tomassetti */ -public class JavaParserVariableDeclaration implements ResolvedValueDeclaration, AssociableToAST { +public class JavaParserVariableDeclaration implements ResolvedValueDeclaration { private VariableDeclarator variableDeclarator; private VariableDeclarationExpr wrappedNode; @@ -88,7 +88,8 @@ public String toString() { } @Override - public Optional toAst() { + public Optional toAst() { return Optional.of(wrappedNode); } + } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/AbstractSymbolDeclarator.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/AbstractSymbolDeclarator.java similarity index 86% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/AbstractSymbolDeclarator.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/AbstractSymbolDeclarator.java index 99bcb04..f7a1ff5 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/AbstractSymbolDeclarator.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/AbstractSymbolDeclarator.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -22,8 +22,8 @@ package com.github.javaparser.symbolsolver.javaparsermodel.declarators; import com.github.javaparser.ast.Node; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; -import com.github.javaparser.symbolsolver.resolution.SymbolDeclarator; +import com.github.javaparser.resolution.SymbolDeclarator; +import com.github.javaparser.resolution.TypeSolver; /** * @author Federico Tomassetti diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/FieldSymbolDeclarator.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/FieldSymbolDeclarator.java similarity index 93% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/FieldSymbolDeclarator.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/FieldSymbolDeclarator.java index 74a7201..14a47fd 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/FieldSymbolDeclarator.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/FieldSymbolDeclarator.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -23,9 +23,9 @@ import com.github.javaparser.ast.body.FieldDeclaration; import com.github.javaparser.ast.body.VariableDeclarator; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration; import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserSymbolDeclaration; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; import java.util.LinkedList; import java.util.List; diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/NoSymbolDeclarator.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/NoSymbolDeclarator.java similarity index 92% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/NoSymbolDeclarator.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/NoSymbolDeclarator.java index 0ce3daa..1eb0cf3 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/NoSymbolDeclarator.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/NoSymbolDeclarator.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -22,8 +22,8 @@ package com.github.javaparser.symbolsolver.javaparsermodel.declarators; import com.github.javaparser.ast.Node; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; import java.util.Collections; import java.util.List; diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/ParameterSymbolDeclarator.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/ParameterSymbolDeclarator.java similarity index 93% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/ParameterSymbolDeclarator.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/ParameterSymbolDeclarator.java index 7ac9ada..5be25de 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/ParameterSymbolDeclarator.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/ParameterSymbolDeclarator.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -22,9 +22,9 @@ package com.github.javaparser.symbolsolver.javaparsermodel.declarators; import com.github.javaparser.ast.body.Parameter; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration; import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserSymbolDeclaration; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; import java.util.LinkedList; import java.util.List; diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/PatternSymbolDeclarator.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/PatternSymbolDeclarator.java similarity index 93% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/PatternSymbolDeclarator.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/PatternSymbolDeclarator.java index e5b8837..f534c14 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/PatternSymbolDeclarator.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/PatternSymbolDeclarator.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -22,9 +22,9 @@ package com.github.javaparser.symbolsolver.javaparsermodel.declarators; import com.github.javaparser.ast.expr.PatternExpr; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration; import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserSymbolDeclaration; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; import java.util.LinkedList; import java.util.List; diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/VariableSymbolDeclarator.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/VariableSymbolDeclarator.java similarity index 95% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/VariableSymbolDeclarator.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/VariableSymbolDeclarator.java index 131538a..8448a74 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/VariableSymbolDeclarator.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/VariableSymbolDeclarator.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -23,9 +23,9 @@ import com.github.javaparser.ast.body.FieldDeclaration; import com.github.javaparser.ast.expr.VariableDeclarationExpr; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration; import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserSymbolDeclaration; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; import java.util.ArrayList; import java.util.List; diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/package-info.java b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/package-info.java similarity index 94% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/package-info.java rename to src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/package-info.java index df936a1..2cf2749 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/package-info.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/package-info.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistAnnotationDeclaration.java b/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistAnnotationDeclaration.java similarity index 93% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistAnnotationDeclaration.java rename to src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistAnnotationDeclaration.java index c716d10..a51bb49 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistAnnotationDeclaration.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistAnnotationDeclaration.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -21,12 +21,11 @@ package com.github.javaparser.symbolsolver.javassistmodel; -import com.github.javaparser.ast.body.AnnotationDeclaration; +import com.github.javaparser.resolution.TypeSolver; 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.logic.AbstractTypeDeclaration; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; import javassist.CtClass; import java.lang.annotation.Inherited; @@ -73,9 +72,8 @@ public String getClassName() { String qualifiedName = getQualifiedName(); if (qualifiedName.contains(".")) { return qualifiedName.substring(qualifiedName.lastIndexOf(".") + 1, qualifiedName.length()); - } else { - return qualifiedName; } + return qualifiedName; } @Override @@ -154,11 +152,6 @@ public List getAnnotationMembers() { .collect(Collectors.toList()); } - @Override - public Optional toAst() { - return Optional.empty(); - } - @Override public boolean isInheritable() { try { diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistAnnotationMemberDeclaration.java b/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistAnnotationMemberDeclaration.java similarity index 93% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistAnnotationMemberDeclaration.java rename to src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistAnnotationMemberDeclaration.java index 76f7c86..900addf 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistAnnotationMemberDeclaration.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistAnnotationMemberDeclaration.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -22,12 +22,12 @@ package com.github.javaparser.symbolsolver.javassistmodel; import com.github.javaparser.ast.expr.*; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.ResolvedAnnotationMemberDeclaration; import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration; +import com.github.javaparser.resolution.model.SymbolReference; +import com.github.javaparser.resolution.model.typesystem.ReferenceTypeImpl; import com.github.javaparser.resolution.types.ResolvedType; -import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; -import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl; import javassist.CtMethod; import javassist.bytecode.AnnotationDefaultAttribute; import javassist.bytecode.BadBytecode; @@ -78,7 +78,7 @@ public ResolvedType getType() { SignatureAttribute.MethodSignature signature = SignatureAttribute.toMethodSignature(descriptor); SymbolReference returnType = typeSolver.tryToSolveType(signature.getReturnType().jvmTypeName()); if (returnType.isSolved()) { - return new ReferenceTypeImpl(returnType.getCorrespondingDeclaration(), typeSolver); + return new ReferenceTypeImpl(returnType.getCorrespondingDeclaration()); } } catch (BadBytecode e) { // We don't expect this to happen, but we handle it anyway. diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistClassDeclaration.java b/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistClassDeclaration.java similarity index 90% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistClassDeclaration.java rename to src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistClassDeclaration.java index 443bb73..c56fd02 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistClassDeclaration.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistClassDeclaration.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -21,32 +21,35 @@ package com.github.javaparser.symbolsolver.javassistmodel; +import java.util.List; +import java.util.Optional; +import java.util.Set; + import com.github.javaparser.ast.AccessSpecifier; import com.github.javaparser.ast.Node; +import com.github.javaparser.resolution.Context; import com.github.javaparser.resolution.MethodUsage; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.UnsolvedSymbolException; import com.github.javaparser.resolution.declarations.*; +import com.github.javaparser.resolution.model.LambdaArgumentTypePlaceholder; +import com.github.javaparser.resolution.model.SymbolReference; +import com.github.javaparser.resolution.model.typesystem.ReferenceTypeImpl; import com.github.javaparser.resolution.types.ResolvedReferenceType; import com.github.javaparser.resolution.types.ResolvedType; -import com.github.javaparser.symbolsolver.core.resolution.Context; import com.github.javaparser.symbolsolver.core.resolution.MethodUsageResolutionCapability; -import com.github.javaparser.symbolsolver.javaparsermodel.LambdaArgumentTypePlaceholder; +import com.github.javaparser.symbolsolver.core.resolution.SymbolResolutionCapability; import com.github.javaparser.symbolsolver.logic.AbstractClassDeclaration; -import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; -import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl; import com.github.javaparser.symbolsolver.resolution.SymbolSolver; + import javassist.CtClass; import javassist.CtField; -import java.util.List; -import java.util.Optional; -import java.util.Set; - /** * @author Federico Tomassetti */ -public class JavassistClassDeclaration extends AbstractClassDeclaration implements MethodUsageResolutionCapability { +public class JavassistClassDeclaration extends AbstractClassDeclaration + implements MethodUsageResolutionCapability, SymbolResolutionCapability { private CtClass ctClass; private TypeSolver typeSolver; @@ -66,7 +69,7 @@ public JavassistClassDeclaration(CtClass ctClass, TypeSolver typeSolver) { @Override protected ResolvedReferenceType object() { - return new ReferenceTypeImpl(typeSolver.getSolvedJavaLangObject(), typeSolver); + return new ReferenceTypeImpl(typeSolver.getSolvedJavaLangObject()); } @Override @@ -74,6 +77,14 @@ public boolean hasDirectlyAnnotation(String canonicalName) { return ctClass.hasAnnotation(canonicalName); } + /* + * Returns a set of the declared annotation on this type + */ + @Override + public Set getDeclaredAnnotations() { + return javassistTypeDeclarationAdapter.getDeclaredAnnotations(); + } + @Override public Set getDeclaredMethods() { return javassistTypeDeclarationAdapter.getDeclaredMethods(); @@ -81,7 +92,7 @@ public Set getDeclaredMethods() { @Override public boolean isAssignableBy(ResolvedReferenceTypeDeclaration other) { - return isAssignableBy(new ReferenceTypeImpl(other, typeSolver)); + return isAssignableBy(new ReferenceTypeImpl(other)); } @Override @@ -118,13 +129,14 @@ public String getQualifiedName() { return ctClass.getName().replace('$', '.'); } - @Deprecated + @Override + @Deprecated public Optional solveMethodAsUsage(String name, List argumentsTypes, Context invokationContext, List typeParameterValues) { return JavassistUtils.solveMethodAsUsage(name, argumentsTypes, typeSolver, invokationContext, typeParameterValues, this, ctClass); } - @Deprecated + @Override public SymbolReference solveSymbol(String name, TypeSolver typeSolver) { for (CtField field : ctClass.getDeclaredFields()) { if (field.getName().equals(name)) { @@ -146,12 +158,12 @@ public SymbolReference solveSymbol(String na } } - return SymbolReference.unsolved(ResolvedValueDeclaration.class); + return SymbolReference.unsolved(); } private SymbolReference solveSymbolForFQN(String symbolName, String fqn) { if (fqn == null) { - return SymbolReference.unsolved(ResolvedValueDeclaration.class); + return SymbolReference.unsolved(); } ResolvedReferenceTypeDeclaration fqnTypeDeclaration = typeSolver.solveType(fqn); @@ -178,7 +190,7 @@ public SymbolReference solveMethod(String name, List< } public ResolvedType getUsage(Node node) { - return new ReferenceTypeImpl(this, typeSolver); + return new ReferenceTypeImpl(this); } @Override @@ -315,8 +327,4 @@ public boolean hasInternalType(String name) { return this.internalTypes().stream().anyMatch(f -> f.getName().endsWith(name)); } - @Override - public Optional toAst() { - return Optional.empty(); - } } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistConstructorDeclaration.java b/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistConstructorDeclaration.java similarity index 91% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistConstructorDeclaration.java rename to src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistConstructorDeclaration.java index 280e28d..0e8ac31 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistConstructorDeclaration.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistConstructorDeclaration.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -22,17 +22,15 @@ package com.github.javaparser.symbolsolver.javassistmodel; import com.github.javaparser.ast.AccessSpecifier; -import com.github.javaparser.ast.body.ConstructorDeclaration; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.ResolvedConstructorDeclaration; import com.github.javaparser.resolution.declarations.ResolvedParameterDeclaration; import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration; import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration; import com.github.javaparser.resolution.types.ResolvedType; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; import javassist.CtConstructor; import java.util.List; -import java.util.Optional; /** * @author Fred Lefévère-Laoide @@ -111,8 +109,4 @@ public ResolvedType getSpecifiedException(int index) { return methodLikeAdaper.getSpecifiedException(index); } - @Override - public Optional toAst() { - return Optional.empty(); - } } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistEnumConstantDeclaration.java b/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistEnumConstantDeclaration.java similarity index 89% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistEnumConstantDeclaration.java rename to src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistEnumConstantDeclaration.java index e9db25e..47c51db 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistEnumConstantDeclaration.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistEnumConstantDeclaration.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -21,10 +21,10 @@ package com.github.javaparser.symbolsolver.javassistmodel; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.ResolvedEnumConstantDeclaration; +import com.github.javaparser.resolution.model.typesystem.ReferenceTypeImpl; import com.github.javaparser.resolution.types.ResolvedType; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; -import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl; import javassist.CtField; import javassist.bytecode.AccessFlag; @@ -59,8 +59,7 @@ public String getName() { @Override public ResolvedType getType() { if (type == null) { - type = new ReferenceTypeImpl(new JavassistEnumDeclaration(ctField.getDeclaringClass(), typeSolver), - typeSolver); + type = new ReferenceTypeImpl(new JavassistEnumDeclaration(ctField.getDeclaringClass(), typeSolver)); } return type; } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistEnumDeclaration.java b/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistEnumDeclaration.java similarity index 94% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistEnumDeclaration.java rename to src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistEnumDeclaration.java index 131c310..4548b99 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistEnumDeclaration.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistEnumDeclaration.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -22,17 +22,18 @@ package com.github.javaparser.symbolsolver.javassistmodel; import com.github.javaparser.ast.AccessSpecifier; +import com.github.javaparser.resolution.Context; import com.github.javaparser.resolution.MethodUsage; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.UnsolvedSymbolException; import com.github.javaparser.resolution.declarations.*; +import com.github.javaparser.resolution.logic.MethodResolutionCapability; +import com.github.javaparser.resolution.model.SymbolReference; import com.github.javaparser.resolution.types.ResolvedReferenceType; import com.github.javaparser.resolution.types.ResolvedType; -import com.github.javaparser.symbolsolver.core.resolution.Context; import com.github.javaparser.symbolsolver.core.resolution.MethodUsageResolutionCapability; +import com.github.javaparser.symbolsolver.core.resolution.SymbolResolutionCapability; import com.github.javaparser.symbolsolver.logic.AbstractTypeDeclaration; -import com.github.javaparser.symbolsolver.logic.MethodResolutionCapability; -import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; import com.github.javaparser.symbolsolver.resolution.SymbolSolver; import javassist.CtClass; import javassist.CtField; @@ -48,7 +49,8 @@ * @author Federico Tomassetti */ public class JavassistEnumDeclaration extends AbstractTypeDeclaration - implements ResolvedEnumDeclaration, MethodResolutionCapability, MethodUsageResolutionCapability { + implements ResolvedEnumDeclaration, MethodResolutionCapability, MethodUsageResolutionCapability, + SymbolResolutionCapability { private CtClass ctClass; private TypeSolver typeSolver; @@ -184,6 +186,7 @@ public boolean hasInternalType(String name) { return this.internalTypes().stream().anyMatch(f -> f.getName().endsWith(name)); } + @Override public SymbolReference solveSymbol(String name, TypeSolver typeSolver) { for (CtField field : ctClass.getDeclaredFields()) { if (field.getName().equals(name)) { @@ -199,12 +202,12 @@ public SymbolReference solveSymbol(String na } } - return SymbolReference.unsolved(ResolvedValueDeclaration.class); + return SymbolReference.unsolved(); } private SymbolReference solveSymbolForFQN(String symbolName, String fqn) { if (fqn == null) { - return SymbolReference.unsolved(ResolvedValueDeclaration.class); + return SymbolReference.unsolved(); } ResolvedReferenceTypeDeclaration fqnTypeDeclaration = typeSolver.solveType(fqn); diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistFactory.java b/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistFactory.java similarity index 72% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistFactory.java rename to src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistFactory.java index 2f5a918..0a88c7e 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistFactory.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistFactory.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -22,13 +22,13 @@ package com.github.javaparser.symbolsolver.javassistmodel; import com.github.javaparser.ast.AccessSpecifier; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration; +import com.github.javaparser.resolution.model.typesystem.ReferenceTypeImpl; import com.github.javaparser.resolution.types.ResolvedArrayType; import com.github.javaparser.resolution.types.ResolvedPrimitiveType; import com.github.javaparser.resolution.types.ResolvedType; import com.github.javaparser.resolution.types.ResolvedVoidType; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; -import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl; import javassist.CtClass; import javassist.NotFoundException; @@ -43,24 +43,20 @@ public static ResolvedType typeUsageFor(CtClass ctClazz, TypeSolver typeSolver) try { if (ctClazz.isArray()) { return new ResolvedArrayType(typeUsageFor(ctClazz.getComponentType(), typeSolver)); - } else if (ctClazz.isPrimitive()) { + } + if (ctClazz.isPrimitive()) { if (ctClazz.getName().equals("void")) { return ResolvedVoidType.INSTANCE; - } else { - return ResolvedPrimitiveType.byName(ctClazz.getName()); - } - } else { - if (ctClazz.isInterface()) { - return new ReferenceTypeImpl(new JavassistInterfaceDeclaration(ctClazz, typeSolver), - typeSolver); - } else if (ctClazz.isEnum()) { - return new ReferenceTypeImpl(new JavassistEnumDeclaration(ctClazz, typeSolver), - typeSolver); - } else { - return new ReferenceTypeImpl(new JavassistClassDeclaration(ctClazz, typeSolver), - typeSolver); } + return ResolvedPrimitiveType.byName(ctClazz.getName()); } + if (ctClazz.isInterface()) { + return new ReferenceTypeImpl(new JavassistInterfaceDeclaration(ctClazz, typeSolver)); + } + if (ctClazz.isEnum()) { + return new ReferenceTypeImpl(new JavassistEnumDeclaration(ctClazz, typeSolver)); + } + return new ReferenceTypeImpl(new JavassistClassDeclaration(ctClazz, typeSolver)); } catch (NotFoundException e) { throw new RuntimeException(e); } @@ -69,27 +65,30 @@ public static ResolvedType typeUsageFor(CtClass ctClazz, TypeSolver typeSolver) public static ResolvedReferenceTypeDeclaration toTypeDeclaration(CtClass ctClazz, TypeSolver typeSolver) { if (ctClazz.isAnnotation()) { return new JavassistAnnotationDeclaration(ctClazz, typeSolver); - } else if (ctClazz.isInterface()) { + } + if (ctClazz.isInterface()) { return new JavassistInterfaceDeclaration(ctClazz, typeSolver); - } else if (ctClazz.isEnum()) { + } + if (ctClazz.isEnum()) { return new JavassistEnumDeclaration(ctClazz, typeSolver); - } else if (ctClazz.isArray()) { + } + if (ctClazz.isArray()) { throw new IllegalArgumentException("This method should not be called passing an array"); - } else { - return new JavassistClassDeclaration(ctClazz, typeSolver); } + return new JavassistClassDeclaration(ctClazz, typeSolver); } static AccessSpecifier modifiersToAccessLevel(final int modifiers) { if (Modifier.isPublic(modifiers)) { return AccessSpecifier.PUBLIC; - } else if (Modifier.isProtected(modifiers)) { + } + if (Modifier.isProtected(modifiers)) { return AccessSpecifier.PROTECTED; - } else if (Modifier.isPrivate(modifiers)) { + } + if (Modifier.isPrivate(modifiers)) { return AccessSpecifier.PRIVATE; - } else { - return AccessSpecifier.PACKAGE_PRIVATE; } + return AccessSpecifier.NONE; } } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistFieldDeclaration.java b/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistFieldDeclaration.java similarity index 96% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistFieldDeclaration.java rename to src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistFieldDeclaration.java index 3822cce..b30661a 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistFieldDeclaration.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistFieldDeclaration.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -22,11 +22,11 @@ package com.github.javaparser.symbolsolver.javassistmodel; import com.github.javaparser.ast.AccessSpecifier; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.ResolvedFieldDeclaration; import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration; import com.github.javaparser.resolution.declarations.ResolvedTypeParametrizable; import com.github.javaparser.resolution.types.ResolvedType; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; import javassist.CtField; import javassist.bytecode.BadBytecode; import javassist.bytecode.SignatureAttribute; diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistInterfaceDeclaration.java b/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistInterfaceDeclaration.java similarity index 90% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistInterfaceDeclaration.java rename to src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistInterfaceDeclaration.java index 100a593..76ba871 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistInterfaceDeclaration.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistInterfaceDeclaration.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -21,31 +21,33 @@ package com.github.javaparser.symbolsolver.javassistmodel; +import java.util.*; +import java.util.stream.Collectors; + import com.github.javaparser.ast.AccessSpecifier; -import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; +import com.github.javaparser.resolution.Context; import com.github.javaparser.resolution.MethodUsage; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.UnsolvedSymbolException; import com.github.javaparser.resolution.declarations.*; +import com.github.javaparser.resolution.logic.MethodResolutionCapability; +import com.github.javaparser.resolution.model.SymbolReference; import com.github.javaparser.resolution.types.ResolvedReferenceType; import com.github.javaparser.resolution.types.ResolvedType; -import com.github.javaparser.symbolsolver.core.resolution.Context; import com.github.javaparser.symbolsolver.core.resolution.MethodUsageResolutionCapability; +import com.github.javaparser.symbolsolver.core.resolution.SymbolResolutionCapability; import com.github.javaparser.symbolsolver.logic.AbstractTypeDeclaration; -import com.github.javaparser.symbolsolver.logic.MethodResolutionCapability; -import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; import com.github.javaparser.symbolsolver.resolution.SymbolSolver; + import javassist.CtClass; import javassist.CtField; -import java.util.*; -import java.util.stream.Collectors; - /** * @author Federico Tomassetti */ public class JavassistInterfaceDeclaration extends AbstractTypeDeclaration - implements ResolvedInterfaceDeclaration, MethodResolutionCapability, MethodUsageResolutionCapability { + implements ResolvedInterfaceDeclaration, MethodResolutionCapability, MethodUsageResolutionCapability, + SymbolResolutionCapability { private CtClass ctClass; private TypeSolver typeSolver; @@ -92,7 +94,8 @@ public String getQualifiedName() { return ctClass.getName().replace('$', '.'); } - @Deprecated + @Override + @Deprecated public Optional solveMethodAsUsage(String name, List argumentsTypes, Context invokationContext, List typeParameterValues) { return JavassistUtils.solveMethodAsUsage(name, argumentsTypes, typeSolver, invokationContext, typeParameterValues, this, ctClass); @@ -136,6 +139,14 @@ public boolean hasDirectlyAnnotation(String canonicalName) { return ctClass.hasAnnotation(canonicalName); } + /* + * Returns a set of the declared annotation on this type + */ + @Override + public Set getDeclaredAnnotations() { + return javassistTypeDeclarationAdapter.getDeclaredAnnotations(); + } + @Override public String getName() { String[] nameElements = ctClass.getSimpleName().replace('$', '.').split("\\."); @@ -157,8 +168,7 @@ public ResolvedInterfaceDeclaration asInterface() { return this; } - - @Deprecated + @Override public SymbolReference solveSymbol(String name, TypeSolver typeSolver) { for (CtField field : ctClass.getDeclaredFields()) { if (field.getName().equals(name)) { @@ -174,12 +184,12 @@ public SymbolReference solveSymbol(String na } } - return SymbolReference.unsolved(ResolvedValueDeclaration.class); + return SymbolReference.unsolved(); } private SymbolReference solveSymbolForFQN(String symbolName, String fqn) { if (fqn == null) { - return SymbolReference.unsolved(ResolvedValueDeclaration.class); + return SymbolReference.unsolved(); } ResolvedReferenceTypeDeclaration fqnTypeDeclaration = typeSolver.solveType(fqn); @@ -226,8 +236,4 @@ public List getConstructors() { return Collections.emptyList(); } - @Override - public Optional toAst() { - return Optional.empty(); - } } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistMethodDeclaration.java b/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistMethodDeclaration.java similarity index 92% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistMethodDeclaration.java rename to src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistMethodDeclaration.java index f45d8ce..46b34e2 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistMethodDeclaration.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistMethodDeclaration.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -23,22 +23,20 @@ import com.github.javaparser.ast.AccessSpecifier; import com.github.javaparser.ast.Node; -import com.github.javaparser.ast.body.MethodDeclaration; +import com.github.javaparser.resolution.Context; import com.github.javaparser.resolution.MethodUsage; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration; import com.github.javaparser.resolution.declarations.ResolvedParameterDeclaration; import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration; import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration; import com.github.javaparser.resolution.types.ResolvedType; -import com.github.javaparser.symbolsolver.core.resolution.Context; import com.github.javaparser.symbolsolver.core.resolution.TypeVariableResolutionCapability; import com.github.javaparser.symbolsolver.declarations.common.MethodDeclarationCommonLogic; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; import javassist.CtMethod; import java.lang.reflect.Modifier; import java.util.List; -import java.util.Optional; /** * @author Federico Tomassetti @@ -146,8 +144,7 @@ public ResolvedType getSpecifiedException(int index) { } @Override - public Optional toAst() { - return Optional.empty(); + public String toDescriptor() { + return ctMethod.getMethodInfo().getDescriptor(); } - } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistMethodLikeDeclarationAdapter.java b/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistMethodLikeDeclarationAdapter.java similarity index 95% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistMethodLikeDeclarationAdapter.java rename to src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistMethodLikeDeclarationAdapter.java index 444aaac..a6ceaf2 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistMethodLikeDeclarationAdapter.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistMethodLikeDeclarationAdapter.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -21,13 +21,13 @@ package com.github.javaparser.symbolsolver.javassistmodel; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.ResolvedMethodLikeDeclaration; import com.github.javaparser.resolution.declarations.ResolvedParameterDeclaration; import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration; import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration; +import com.github.javaparser.resolution.model.typesystem.ReferenceTypeImpl; import com.github.javaparser.resolution.types.ResolvedType; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; -import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl; import javassist.CtBehavior; import javassist.bytecode.BadBytecode; import javassist.bytecode.ExceptionsAttribute; @@ -111,7 +111,7 @@ public ResolvedType getSpecifiedException(int index) { } ResolvedReferenceTypeDeclaration typeDeclaration = typeSolver.solveType(exceptions[index]); - return new ReferenceTypeImpl(typeDeclaration, Collections.emptyList(), typeSolver); + return new ReferenceTypeImpl(typeDeclaration, Collections.emptyList()); } public ResolvedType getReturnType() { diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistParameterDeclaration.java b/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistParameterDeclaration.java similarity index 95% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistParameterDeclaration.java rename to src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistParameterDeclaration.java index a92214f..bde64a8 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistParameterDeclaration.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistParameterDeclaration.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -21,9 +21,9 @@ package com.github.javaparser.symbolsolver.javassistmodel; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.ResolvedParameterDeclaration; import com.github.javaparser.resolution.types.ResolvedType; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; import javassist.CtClass; /** diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistTypeDeclarationAdapter.java b/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistTypeDeclarationAdapter.java similarity index 80% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistTypeDeclarationAdapter.java rename to src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistTypeDeclarationAdapter.java index 6243cb2..d6e2d0c 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistTypeDeclarationAdapter.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistTypeDeclarationAdapter.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -21,13 +21,20 @@ package com.github.javaparser.symbolsolver.javassistmodel; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.UnsolvedSymbolException; import com.github.javaparser.resolution.declarations.*; +import com.github.javaparser.resolution.model.LambdaArgumentTypePlaceholder; +import com.github.javaparser.resolution.model.typesystem.ReferenceTypeImpl; import com.github.javaparser.resolution.types.ResolvedReferenceType; import com.github.javaparser.resolution.types.ResolvedType; -import com.github.javaparser.symbolsolver.javaparsermodel.LambdaArgumentTypePlaceholder; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; -import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl; + import javassist.CtClass; import javassist.CtField; import javassist.NotFoundException; @@ -35,15 +42,26 @@ import javassist.bytecode.BadBytecode; import javassist.bytecode.SignatureAttribute; -import java.util.*; -import java.util.stream.Collectors; -import java.util.stream.Stream; - /** * @author Federico Tomassetti */ public class JavassistTypeDeclarationAdapter { + // this a workaround to get the annotation type (taken from Javassist AnnotationImpl class) + private static final String JDK_ANNOTATION_CLASS_NAME = "java.lang.annotation.Annotation"; + private static Method JDK_ANNOTATION_TYPE_METHOD = null; + + static { + // Try to resolve the JDK annotation type method + try { + Class clazz = Class.forName(JDK_ANNOTATION_CLASS_NAME); + JDK_ANNOTATION_TYPE_METHOD = clazz.getMethod("annotationType", (Class[])null); + } + catch (Exception ignored) { + // Probably not JDK5+ + } + } + private CtClass ctClass; private TypeSolver typeSolver; private ResolvedReferenceTypeDeclaration typeDeclaration; @@ -64,20 +82,17 @@ public Optional getSuperClass() { // Compiled classes have generic types erased, but can be made available for reflection via getGenericSignature(). // If it is absent, then no further work is needed and we can return a reference type without generics. return Optional.of(new ReferenceTypeImpl( - typeSolver.solveType(JavassistUtils.internalNameToCanonicalName(ctClass.getClassFile().getSuperclass())), - typeSolver + typeSolver.solveType(JavassistUtils.internalNameToCanonicalName(ctClass.getClassFile().getSuperclass())) )); - } else { - // If there is a generic signature present, solve the types and return it. - SignatureAttribute.ClassSignature classSignature = SignatureAttribute.toClassSignature(ctClass.getGenericSignature()); - return Optional.ofNullable( + } + SignatureAttribute.ClassSignature classSignature = SignatureAttribute.toClassSignature(ctClass.getGenericSignature()); + return Optional.ofNullable( JavassistUtils.signatureTypeToType( classSignature.getSuperClass(), typeSolver, typeDeclaration ).asReferenceType() ); - } } catch (BadBytecode e) { throw new RuntimeException(e); } @@ -94,7 +109,7 @@ private List getInterfaces(boolean acceptIncompleteList) for (String interfaceType : ctClass.getClassFile().getInterfaces()) { try { ResolvedReferenceTypeDeclaration declaration = typeSolver.solveType(JavassistUtils.internalNameToCanonicalName(interfaceType)); - interfaces.add(new ReferenceTypeImpl(declaration, typeSolver)); + interfaces.add(new ReferenceTypeImpl(declaration)); } catch (UnsolvedSymbolException e) { if (!acceptIncompleteList) { throw e; @@ -165,11 +180,41 @@ public List getDeclaredFields() { return fields; } + /* + * Returns a set of the declared annotation on this type + */ + public Set getDeclaredAnnotations() { + try { + Object[] annotations = ctClass.getAnnotations(); + return Stream.of(annotations) + .map(annotation -> getAnnotationType(annotation)) + .filter(annotationType -> annotationType != null) + .map(annotationType -> typeSolver.solveType(annotationType)) + .map(rrtd -> rrtd.asAnnotation()) + .collect(Collectors.toSet()); + } catch (ClassNotFoundException e) { + // There is nothing to do except returns an empty set + } + return Collections.EMPTY_SET; + + } + + private String getAnnotationType(Object annotation) { + String typeName = null; + try { + Class annotationClass = (Class) Proxy.getInvocationHandler(annotation) + .invoke(annotation, JDK_ANNOTATION_TYPE_METHOD, null); + typeName = annotationClass.getTypeName(); + } catch (Throwable e) { + } + return typeName; + } + public List getTypeParameters() { if (null == ctClass.getGenericSignature()) { return Collections.emptyList(); - } else { - try { + } + try { SignatureAttribute.ClassSignature classSignature = SignatureAttribute.toClassSignature(ctClass.getGenericSignature()); return Arrays.stream(classSignature.getParameters()) @@ -178,7 +223,6 @@ public List getTypeParameters() { } catch (BadBytecode badBytecode) { throw new RuntimeException(badBytecode); } - } } public Optional containerType() { @@ -201,11 +245,11 @@ public boolean isAssignableBy(ResolvedType other) { return typeDeclaration.isFunctionalInterface(); } - return other.isAssignableBy(new ReferenceTypeImpl(typeDeclaration, typeSolver)); + return other.isAssignableBy(new ReferenceTypeImpl(typeDeclaration)); } public boolean isAssignableBy(ResolvedReferenceTypeDeclaration other) { - return isAssignableBy(new ReferenceTypeImpl(other, typeSolver)); + return isAssignableBy(new ReferenceTypeImpl(other)); } /** diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistTypeParameter.java b/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistTypeParameter.java similarity index 86% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistTypeParameter.java rename to src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistTypeParameter.java index 616d31a..22ef611 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistTypeParameter.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistTypeParameter.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -21,15 +21,18 @@ package com.github.javaparser.symbolsolver.javassistmodel; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.ResolvedMethodLikeDeclaration; import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration; import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration; import com.github.javaparser.resolution.declarations.ResolvedTypeParametrizable; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; +import com.github.javaparser.resolution.model.typesystem.ReferenceTypeImpl; +import com.github.javaparser.resolution.types.ResolvedReferenceType; import javassist.bytecode.SignatureAttribute; import java.util.ArrayList; import java.util.List; +import java.util.Objects; import java.util.Optional; /** @@ -67,6 +70,11 @@ public boolean equals(Object o) { return true; } + @Override + public int hashCode() { + return Objects.hash(getQualifiedName(), declaredOnType(), declaredOnMethod()); + } + @Override public String toString() { return "JavassistTypeParameter{" + @@ -83,7 +91,8 @@ public String getName() { public String getContainerQualifiedName() { if (this.container instanceof ResolvedReferenceTypeDeclaration) { return ((ResolvedReferenceTypeDeclaration) this.container).getQualifiedName(); - } else if (this.container instanceof ResolvedMethodLikeDeclaration) { + } + if (this.container instanceof ResolvedMethodLikeDeclaration) { return ((ResolvedMethodLikeDeclaration) this.container).getQualifiedName(); } throw new UnsupportedOperationException(); @@ -119,4 +128,9 @@ public Optional containerType() { } return Optional.empty(); } + + @Override + public ResolvedReferenceType object() { + return new ReferenceTypeImpl(typeSolver.getSolvedJavaLangObject()); + } } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistUtils.java b/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistUtils.java similarity index 84% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistUtils.java rename to src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistUtils.java index 553dc86..4c7b722 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistUtils.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistUtils.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -21,29 +21,30 @@ package com.github.javaparser.symbolsolver.javassistmodel; +import java.util.*; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +import com.github.javaparser.resolution.Context; import com.github.javaparser.resolution.MethodUsage; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.UnsolvedSymbolException; 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.resolution.declarations.ResolvedTypeParametrizable; +import com.github.javaparser.resolution.logic.MethodResolutionLogic; +import com.github.javaparser.resolution.model.SymbolReference; +import com.github.javaparser.resolution.model.typesystem.ReferenceTypeImpl; import com.github.javaparser.resolution.types.*; -import com.github.javaparser.symbolsolver.core.resolution.Context; import com.github.javaparser.symbolsolver.javaparsermodel.contexts.ContextHelper; -import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; -import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl; -import com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic; + import javassist.CtBehavior; import javassist.CtClass; import javassist.CtMethod; import javassist.Modifier; import javassist.bytecode.*; -import java.util.*; -import java.util.function.Predicate; -import java.util.stream.Collectors; - /** * @author Federico Tomassetti */ @@ -129,8 +130,9 @@ static ResolvedType signatureTypeToType(SignatureAttribute.Type signatureType, T List typeArguments = classType.getTypeArguments() == null ? Collections.emptyList() : Arrays.stream(classType.getTypeArguments()).map(ta -> typeArgumentToType(ta, typeSolver, typeParametrizable)).collect(Collectors.toList()); ResolvedReferenceTypeDeclaration typeDeclaration = typeSolver.solveType( removeTypeArguments(internalNameToCanonicalName(getTypeName(classType)))); - return new ReferenceTypeImpl(typeDeclaration, typeArguments, typeSolver); - } else if (signatureType instanceof SignatureAttribute.TypeVariable) { + return new ReferenceTypeImpl(typeDeclaration, typeArguments); + } + if (signatureType instanceof SignatureAttribute.TypeVariable) { SignatureAttribute.TypeVariable typeVariableSignature = (SignatureAttribute.TypeVariable) signatureType; Optional typeParameterDeclarationOpt = typeParametrizable.findTypeParameter(typeVariableSignature.getName()); if (!typeParameterDeclarationOpt.isPresent()) { @@ -138,19 +140,27 @@ static ResolvedType signatureTypeToType(SignatureAttribute.Type signatureType, T } ResolvedTypeParameterDeclaration typeParameterDeclaration = typeParameterDeclarationOpt.get(); return new ResolvedTypeVariable(typeParameterDeclaration); - } else if (signatureType instanceof SignatureAttribute.ArrayType) { + } + if (signatureType instanceof SignatureAttribute.ArrayType) { SignatureAttribute.ArrayType arrayType = (SignatureAttribute.ArrayType) signatureType; - return new ResolvedArrayType(signatureTypeToType(arrayType.getComponentType(), typeSolver, typeParametrizable)); - } else if (signatureType instanceof SignatureAttribute.BaseType) { + ResolvedType baseType = signatureTypeToType(arrayType.getComponentType(), typeSolver, typeParametrizable); + return getArrayType(baseType, arrayType.getDimension()); + } + if (signatureType instanceof SignatureAttribute.BaseType) { SignatureAttribute.BaseType baseType = (SignatureAttribute.BaseType) signatureType; if (baseType.toString().equals("void")) { return ResolvedVoidType.INSTANCE; - } else { - return ResolvedPrimitiveType.byName(baseType.toString()); } - } else { - throw new RuntimeException(signatureType.getClass().getCanonicalName()); + return ResolvedPrimitiveType.byName(baseType.toString()); } + throw new RuntimeException(signatureType.getClass().getCanonicalName()); + } + /* + * Manage dimension of an array + */ + private static ResolvedType getArrayType(ResolvedType resolvedType, int dimension) { + if (dimension > 0) return getArrayType(new ResolvedArrayType(resolvedType), --dimension); + return resolvedType; } private static String getTypeName(SignatureAttribute.ClassType classType) { @@ -161,9 +171,8 @@ private static String getTypeName(SignatureAttribute.ClassType classType) { private static String removeTypeArguments(String typeName) { if (typeName.contains("<")) { return typeName.substring(0, typeName.indexOf('<')); - } else { - return typeName; } + return typeName; } static String internalNameToCanonicalName(String typeName) { @@ -173,35 +182,34 @@ static String internalNameToCanonicalName(String typeName) { private static ResolvedType objectTypeArgumentToType(SignatureAttribute.ObjectType typeArgument, TypeSolver typeSolver, ResolvedTypeParametrizable typeParametrizable) { if (typeArgument instanceof SignatureAttribute.ClassType) { return signatureTypeToType(typeArgument, typeSolver, typeParametrizable); - } else if (typeArgument instanceof SignatureAttribute.ArrayType) { + } + if (typeArgument instanceof SignatureAttribute.ArrayType) { return new ResolvedArrayType(signatureTypeToType(((SignatureAttribute.ArrayType) typeArgument).getComponentType(), typeSolver, typeParametrizable)); - } else { - String typeName = typeArgument.jvmTypeName(); - return getGenericParameterByName(typeName, typeParametrizable, typeSolver); } + String typeName = typeArgument.jvmTypeName(); + return getGenericParameterByName(typeName, typeParametrizable, typeSolver); } private static ResolvedType getGenericParameterByName(String typeName, ResolvedTypeParametrizable typeParametrizable, TypeSolver typeSolver) { Optional type = typeParametrizable.findTypeParameter(typeName).map(ResolvedTypeVariable::new); return type.orElseGet(() -> new ReferenceTypeImpl( - typeSolver.solveType(removeTypeArguments(internalNameToCanonicalName(typeName))), - typeSolver)); + typeSolver.solveType(removeTypeArguments(internalNameToCanonicalName(typeName))))); } private static ResolvedType typeArgumentToType(SignatureAttribute.TypeArgument typeArgument, TypeSolver typeSolver, ResolvedTypeParametrizable typeParametrizable) { if (typeArgument.isWildcard()) { if (typeArgument.getType() == null) { return ResolvedWildcard.UNBOUNDED; - } else if (typeArgument.getKind() == '+') { + } + if (typeArgument.getKind() == '+') { return ResolvedWildcard.extendsBound(objectTypeArgumentToType(typeArgument.getType(), typeSolver, typeParametrizable)); - } else if (typeArgument.getKind() == '-') { + } + if (typeArgument.getKind() == '-') { return ResolvedWildcard.superBound(objectTypeArgumentToType(typeArgument.getType(), typeSolver, typeParametrizable)); - } else { - throw new UnsupportedOperationException(); } - } else { - return objectTypeArgumentToType(typeArgument.getType(), typeSolver, typeParametrizable); + throw new UnsupportedOperationException(); } + return objectTypeArgumentToType(typeArgument.getType(), typeSolver, typeParametrizable); } /** @@ -227,10 +235,18 @@ static Optional extractParameterName(CtBehavior method, int paramNumber) .tag); if (attr != null) { int pos = Modifier.isStatic(method.getModifiers()) ? 0 : 1; - return Optional.ofNullable(attr.variableName(paramNumber + pos)); + return getVariableName(attr, paramNumber + pos); } } return Optional.empty(); } + private static Optional getVariableName(LocalVariableAttribute attr, int pos) { + try { + return Optional.of(attr.variableNameByIndex(pos)); + } catch (ArrayIndexOutOfBoundsException e) { + return Optional.empty(); + } + } + } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/package-info.java b/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/package-info.java similarity index 94% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/package-info.java rename to src/main/java/com/github/javaparser/symbolsolver/javassistmodel/package-info.java index d2faa89..0995b7c 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/package-info.java +++ b/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/package-info.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/logic/AbstractClassDeclaration.java b/src/main/java/com/github/javaparser/symbolsolver/logic/AbstractClassDeclaration.java similarity index 95% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/logic/AbstractClassDeclaration.java rename to src/main/java/com/github/javaparser/symbolsolver/logic/AbstractClassDeclaration.java index e13a88a..468728f 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/logic/AbstractClassDeclaration.java +++ b/src/main/java/com/github/javaparser/symbolsolver/logic/AbstractClassDeclaration.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -22,6 +22,7 @@ package com.github.javaparser.symbolsolver.logic; import com.github.javaparser.resolution.declarations.ResolvedClassDeclaration; +import com.github.javaparser.resolution.logic.MethodResolutionCapability; import com.github.javaparser.resolution.types.ResolvedReferenceType; import java.util.ArrayList; diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/logic/AbstractTypeDeclaration.java b/src/main/java/com/github/javaparser/symbolsolver/logic/AbstractTypeDeclaration.java similarity index 71% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/logic/AbstractTypeDeclaration.java rename to src/main/java/com/github/javaparser/symbolsolver/logic/AbstractTypeDeclaration.java index 255db3c..866e208 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/logic/AbstractTypeDeclaration.java +++ b/src/main/java/com/github/javaparser/symbolsolver/logic/AbstractTypeDeclaration.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -21,18 +21,19 @@ package com.github.javaparser.symbolsolver.logic; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + import com.github.javaparser.resolution.MethodUsage; 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.resolution.logic.FunctionalInterfaceLogic; import com.github.javaparser.resolution.types.ResolvedReferenceType; import com.github.javaparser.resolution.types.ResolvedType; import com.github.javaparser.utils.Pair; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - /** * Common ancestor for most types. * @@ -40,6 +41,12 @@ */ public abstract class AbstractTypeDeclaration implements ResolvedReferenceTypeDeclaration { + /* + * Returns all methods which have distinct "enhanced" signature declared in this type and all members. + * An "enhanced" signature include the return type which is used sometimes to identify functional interfaces. + * This is a different implementation from the previous one which returned all methods which have a distinct + * signature (based on method name and qualified parameter types) + */ @Override public final Set getAllMethods() { Set methods = new HashSet<>(); @@ -49,7 +56,10 @@ public final Set getAllMethods() { for (ResolvedMethodDeclaration methodDeclaration : getDeclaredMethods()) { MethodUsage methodUsage = new MethodUsage(methodDeclaration); methods.add(methodUsage); - methodsSignatures.add(methodUsage.getSignature()); + String signature = methodUsage.getSignature(); + String returnType = methodUsage.getDeclaration().getReturnType().describe(); + String enhancedSignature = String.format("%s %s", returnType, signature); + methodsSignatures.add(enhancedSignature); } for (ResolvedReferenceType ancestor : getAllAncestors()) { @@ -61,8 +71,10 @@ public final Set getAllMethods() { methodUsage = methodUsage.replaceTypeParameter(p.a, p.b); } String signature = methodUsage.getSignature(); - if (!methodsSignatures.contains(signature)) { - methodsSignatures.add(signature); + String returnType = methodUsage.getDeclaration().getReturnType().describe(); + String enhancedSignature = String.format("%s %s", returnType, signature); + if (!methodsSignatures.contains(enhancedSignature)) { + methodsSignatures.add(enhancedSignature); methods.add(mu); } } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/logic/ObjectProvider.java b/src/main/java/com/github/javaparser/symbolsolver/logic/ObjectProvider.java similarity index 95% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/logic/ObjectProvider.java rename to src/main/java/com/github/javaparser/symbolsolver/logic/ObjectProvider.java index ce67f75..2f34c49 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/logic/ObjectProvider.java +++ b/src/main/java/com/github/javaparser/symbolsolver/logic/ObjectProvider.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionAnnotationDeclaration.java b/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionAnnotationDeclaration.java similarity index 90% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionAnnotationDeclaration.java rename to src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionAnnotationDeclaration.java index b1efa8e..b59281e 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionAnnotationDeclaration.java +++ b/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionAnnotationDeclaration.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -21,19 +21,18 @@ package com.github.javaparser.symbolsolver.reflectionmodel; -import com.github.javaparser.ast.body.AnnotationDeclaration; +import com.github.javaparser.resolution.Context; import com.github.javaparser.resolution.MethodUsage; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.*; +import com.github.javaparser.resolution.logic.ConflictingGenericTypesException; +import com.github.javaparser.resolution.logic.InferenceContext; +import com.github.javaparser.resolution.logic.MethodResolutionCapability; +import com.github.javaparser.resolution.model.SymbolReference; import com.github.javaparser.resolution.types.ResolvedReferenceType; import com.github.javaparser.resolution.types.ResolvedType; -import com.github.javaparser.symbolsolver.core.resolution.Context; import com.github.javaparser.symbolsolver.core.resolution.MethodUsageResolutionCapability; import com.github.javaparser.symbolsolver.logic.AbstractTypeDeclaration; -import com.github.javaparser.symbolsolver.logic.ConfilictingGenericTypesException; -import com.github.javaparser.symbolsolver.logic.InferenceContext; -import com.github.javaparser.symbolsolver.logic.MethodResolutionCapability; -import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; import java.lang.annotation.Inherited; import java.util.*; @@ -84,11 +83,10 @@ public String getPackageName() { @Override public String getClassName() { String qualifiedName = getQualifiedName(); - if(qualifiedName.contains(".")) { - return qualifiedName.substring(qualifiedName.lastIndexOf("."), qualifiedName.length()); - } else { - return qualifiedName; + if (qualifiedName.contains(".")) { + return qualifiedName.substring(qualifiedName.lastIndexOf(".") + 1); } + return qualifiedName; } @Override @@ -193,11 +191,6 @@ public List getAnnotationMembers() { .collect(Collectors.toList()); } - @Override - public Optional toAst() { - return Optional.empty(); - } - @Override public Optional solveMethodAsUsage(final String name, final List parameterTypes, @@ -207,7 +200,7 @@ public Optional solveMethodAsUsage(final String name, typeParameterValues, this, clazz); if (res.isPresent()) { // We have to replace method type typeParametersValues here - InferenceContext inferenceContext = new InferenceContext(MyObjectProvider.INSTANCE); + InferenceContext inferenceContext = new InferenceContext(typeSolver); MethodUsage methodUsage = res.get(); int i = 0; List parameters = new LinkedList<>(); @@ -225,7 +218,7 @@ public Optional solveMethodAsUsage(final String name, } methodUsage = methodUsage.replaceReturnType(inferenceContext.resolve(returnType)); return Optional.of(methodUsage); - } catch (ConfilictingGenericTypesException e) { + } catch (ConflictingGenericTypesException e) { return Optional.empty(); } } else { @@ -240,7 +233,7 @@ public SymbolReference solveMethod(final String name, return ReflectionMethodResolutionLogic.solveMethod(name, argumentsTypes, staticOnly, typeSolver,this, clazz); } - + @Override public boolean isInheritable() { return clazz.getAnnotation(Inherited.class) != null; diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionAnnotationMemberDeclaration.java b/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionAnnotationMemberDeclaration.java similarity index 92% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionAnnotationMemberDeclaration.java rename to src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionAnnotationMemberDeclaration.java index 9c86ad9..82418c2 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionAnnotationMemberDeclaration.java +++ b/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionAnnotationMemberDeclaration.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -22,13 +22,13 @@ package com.github.javaparser.symbolsolver.reflectionmodel; import com.github.javaparser.ast.expr.*; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.ResolvedAnnotationMemberDeclaration; import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration; +import com.github.javaparser.resolution.model.SymbolReference; +import com.github.javaparser.resolution.model.typesystem.ReferenceTypeImpl; import com.github.javaparser.resolution.types.ResolvedPrimitiveType; import com.github.javaparser.resolution.types.ResolvedType; -import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; -import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl; import java.lang.reflect.Method; import java.util.HashMap; @@ -74,7 +74,7 @@ public ResolvedType getType() { } SymbolReference rrtd = typeSolver.tryToSolveType(returnType.getName()); if (rrtd.isSolved()) { - return new ReferenceTypeImpl(rrtd.getCorrespondingDeclaration(), typeSolver); + return new ReferenceTypeImpl(rrtd.getCorrespondingDeclaration()); } throw new UnsupportedOperationException(String.format("Obtaining the type of the annotation member %s is not supported yet.", annotationMember.getName())); } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionClassAdapter.java b/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionClassAdapter.java similarity index 86% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionClassAdapter.java rename to src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionClassAdapter.java index d36ee07..cfb6eb0 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionClassAdapter.java +++ b/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionClassAdapter.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -21,15 +21,15 @@ package com.github.javaparser.symbolsolver.reflectionmodel; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.UnsolvedSymbolException; import com.github.javaparser.resolution.declarations.*; +import com.github.javaparser.resolution.logic.FunctionalInterfaceLogic; +import com.github.javaparser.resolution.model.LambdaArgumentTypePlaceholder; +import com.github.javaparser.resolution.model.typesystem.NullType; +import com.github.javaparser.resolution.model.typesystem.ReferenceTypeImpl; import com.github.javaparser.resolution.types.ResolvedReferenceType; import com.github.javaparser.resolution.types.ResolvedType; -import com.github.javaparser.symbolsolver.javaparsermodel.LambdaArgumentTypePlaceholder; -import com.github.javaparser.symbolsolver.logic.FunctionalInterfaceLogic; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; -import com.github.javaparser.symbolsolver.model.typesystem.NullType; -import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl; import java.lang.annotation.Annotation; import java.lang.reflect.Field; @@ -64,9 +64,9 @@ public Optional getSuperClass() { List typeParameters = Arrays.stream(parameterizedType.getActualTypeArguments()) .map((t) -> ReflectionFactory.typeUsageFor(t, typeSolver)) .collect(Collectors.toList()); - return Optional.of(new ReferenceTypeImpl(new ReflectionClassDeclaration(clazz.getSuperclass(), typeSolver), typeParameters, typeSolver)); + return Optional.of(new ReferenceTypeImpl(new ReflectionClassDeclaration(clazz.getSuperclass(), typeSolver), typeParameters)); } - return Optional.of(new ReferenceTypeImpl(new ReflectionClassDeclaration(clazz.getSuperclass(), typeSolver), typeSolver)); + return Optional.of(new ReferenceTypeImpl(new ReflectionClassDeclaration(clazz.getSuperclass(), typeSolver))); } public List getInterfaces() { @@ -77,9 +77,9 @@ public List getInterfaces() { List typeParameters = Arrays.stream(parameterizedType.getActualTypeArguments()) .map((t) -> ReflectionFactory.typeUsageFor(t, typeSolver)) .collect(Collectors.toList()); - interfaces.add(new ReferenceTypeImpl(new ReflectionInterfaceDeclaration((Class) ((ParameterizedType) superInterface).getRawType(), typeSolver), typeParameters, typeSolver)); + interfaces.add(new ReferenceTypeImpl(new ReflectionInterfaceDeclaration((Class) ((ParameterizedType) superInterface).getRawType(), typeSolver), typeParameters)); } else { - interfaces.add(new ReferenceTypeImpl(new ReflectionInterfaceDeclaration((Class) superInterface, typeSolver), typeSolver)); + interfaces.add(new ReferenceTypeImpl(new ReflectionInterfaceDeclaration((Class) superInterface, typeSolver))); } } return interfaces; @@ -87,22 +87,18 @@ public List getInterfaces() { public List getAncestors() { List ancestors = new LinkedList<>(); - if (getSuperClass().isPresent()) { - ReferenceTypeImpl superClass = getSuperClass().get(); - ancestors.add(superClass); - } else { - // Inject the implicitly added extends java.lang.Object - ReferenceTypeImpl object = new ReferenceTypeImpl(new ReflectionClassDeclaration(Object.class, typeSolver), typeSolver); - ancestors.add(object); - } + if (typeDeclaration.isClass() && !Object.class.getCanonicalName().equals(clazz.getCanonicalName())) { + if (getSuperClass().isPresent()) { + ReferenceTypeImpl superClass = getSuperClass().get(); + ancestors.add(superClass); + } else { + // Inject the implicitly added extends java.lang.Object + ReferenceTypeImpl object = new ReferenceTypeImpl( + new ReflectionClassDeclaration(Object.class, typeSolver)); + ancestors.add(object); + } + } ancestors.addAll(getInterfaces()); - for (int i = 0; i < ancestors.size(); i++) { - ResolvedReferenceType ancestor = ancestors.get(i); - if (ancestor.hasName() && ancestor.isJavaLangObject()) { - ancestors.remove(i); - i--; - } - } return ancestors; } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionClassDeclaration.java b/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionClassDeclaration.java similarity index 93% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionClassDeclaration.java rename to src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionClassDeclaration.java index 9ceea92..861b5ed 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionClassDeclaration.java +++ b/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionClassDeclaration.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -23,20 +23,21 @@ import com.github.javaparser.ast.AccessSpecifier; import com.github.javaparser.ast.Node; +import com.github.javaparser.resolution.Context; import com.github.javaparser.resolution.MethodUsage; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.*; +import com.github.javaparser.resolution.logic.MethodResolutionLogic; +import com.github.javaparser.resolution.model.LambdaArgumentTypePlaceholder; +import com.github.javaparser.resolution.model.SymbolReference; +import com.github.javaparser.resolution.model.typesystem.ReferenceTypeImpl; import com.github.javaparser.resolution.types.ResolvedReferenceType; import com.github.javaparser.resolution.types.ResolvedType; -import com.github.javaparser.symbolsolver.core.resolution.Context; import com.github.javaparser.symbolsolver.core.resolution.MethodUsageResolutionCapability; -import com.github.javaparser.symbolsolver.javaparsermodel.LambdaArgumentTypePlaceholder; +import com.github.javaparser.symbolsolver.core.resolution.SymbolResolutionCapability; import com.github.javaparser.symbolsolver.javaparsermodel.contexts.ContextHelper; import com.github.javaparser.symbolsolver.logic.AbstractClassDeclaration; -import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; -import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl; import com.github.javaparser.symbolsolver.reflectionmodel.comparators.MethodComparator; -import com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic; import java.lang.reflect.Field; import java.lang.reflect.Method; @@ -48,7 +49,8 @@ /** * @author Federico Tomassetti */ -public class ReflectionClassDeclaration extends AbstractClassDeclaration implements MethodUsageResolutionCapability { +public class ReflectionClassDeclaration extends AbstractClassDeclaration + implements MethodUsageResolutionCapability, SymbolResolutionCapability { /// /// Fields @@ -192,7 +194,7 @@ public SymbolReference solveMethod(String name, List< // MethodResolutionLogic.findMostApplicable method returns very early // when candidateSolvedMethods is empty. if (candidateSolvedMethods.isEmpty()) { - return SymbolReference.unsolved(ResolvedMethodDeclaration.class); + return SymbolReference.unsolved(); } return MethodResolutionLogic.findMostApplicable(candidateSolvedMethods, name, argumentsTypes, typeSolver); } @@ -206,7 +208,7 @@ public String toString() { public ResolvedType getUsage(Node node) { - return new ReferenceTypeImpl(this, typeSolver); + return new ReferenceTypeImpl(this); } public Optional solveMethodAsUsage(String name, List argumentsTypes, Context invokationContext, List typeParameterValues) { @@ -294,14 +296,14 @@ public List getAllFields() { return reflectionClassAdapter.getAllFields(); } - @Deprecated + @Override public SymbolReference solveSymbol(String name, TypeSolver typeSolver) { for (Field field : clazz.getFields()) { if (field.getName().equals(name)) { return SymbolReference.solved(new ReflectionFieldDeclaration(field, typeSolver)); } } - return SymbolReference.unsolved(ResolvedValueDeclaration.class); + return SymbolReference.unsolved(); } @Override @@ -316,7 +318,7 @@ public boolean hasField(String name) { @Override public boolean isAssignableBy(ResolvedReferenceTypeDeclaration other) { - return isAssignableBy(new ReferenceTypeImpl(other, typeSolver)); + return isAssignableBy(new ReferenceTypeImpl(other)); } @Override @@ -389,17 +391,12 @@ public Set internalTypes() { .collect(Collectors.toSet()); } - @Override - public Optional toAst() { - return Optional.empty(); - } - /// /// Protected methods /// @Override protected ResolvedReferenceType object() { - return new ReferenceTypeImpl(typeSolver.getSolvedJavaLangObject(), typeSolver); + return new ReferenceTypeImpl(typeSolver.getSolvedJavaLangObject()); } } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionConstructorDeclaration.java b/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionConstructorDeclaration.java similarity index 92% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionConstructorDeclaration.java rename to src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionConstructorDeclaration.java index 51e1b98..484eb82 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionConstructorDeclaration.java +++ b/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionConstructorDeclaration.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -22,18 +22,16 @@ package com.github.javaparser.symbolsolver.reflectionmodel; import com.github.javaparser.ast.AccessSpecifier; -import com.github.javaparser.ast.body.ConstructorDeclaration; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.ResolvedClassDeclaration; import com.github.javaparser.resolution.declarations.ResolvedConstructorDeclaration; import com.github.javaparser.resolution.declarations.ResolvedParameterDeclaration; import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration; import com.github.javaparser.resolution.types.ResolvedType; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; import java.lang.reflect.Constructor; import java.util.Arrays; import java.util.List; -import java.util.Optional; import java.util.stream.Collectors; /** @@ -101,8 +99,4 @@ public ResolvedType getSpecifiedException(int index) { return ReflectionFactory.typeUsageFor(this.constructor.getExceptionTypes()[index], typeSolver); } - @Override - public Optional toAst() { - return Optional.empty(); - } } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionEnumConstantDeclaration.java b/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionEnumConstantDeclaration.java similarity index 87% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionEnumConstantDeclaration.java rename to src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionEnumConstantDeclaration.java index af013d7..36ee12f 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionEnumConstantDeclaration.java +++ b/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionEnumConstantDeclaration.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -21,11 +21,11 @@ package com.github.javaparser.symbolsolver.reflectionmodel; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.ResolvedEnumConstantDeclaration; import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration; +import com.github.javaparser.resolution.model.typesystem.ReferenceTypeImpl; import com.github.javaparser.resolution.types.ResolvedType; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; -import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl; import java.lang.reflect.Field; @@ -51,6 +51,6 @@ public String getName() { public ResolvedType getType() { Class enumClass = enumConstant.getDeclaringClass(); ResolvedReferenceTypeDeclaration typeDeclaration = new ReflectionEnumDeclaration(enumClass, typeSolver); - return new ReferenceTypeImpl(typeDeclaration, typeSolver); + return new ReferenceTypeImpl(typeDeclaration); } } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionEnumDeclaration.java b/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionEnumDeclaration.java similarity index 86% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionEnumDeclaration.java rename to src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionEnumDeclaration.java index b5bea9e..fec1caa 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionEnumDeclaration.java +++ b/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionEnumDeclaration.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -22,19 +22,20 @@ package com.github.javaparser.symbolsolver.reflectionmodel; import com.github.javaparser.ast.AccessSpecifier; +import com.github.javaparser.resolution.Context; import com.github.javaparser.resolution.MethodUsage; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.*; +import com.github.javaparser.resolution.logic.ConflictingGenericTypesException; +import com.github.javaparser.resolution.logic.InferenceContext; +import com.github.javaparser.resolution.logic.MethodResolutionCapability; +import com.github.javaparser.resolution.model.SymbolReference; +import com.github.javaparser.resolution.model.typesystem.ReferenceTypeImpl; import com.github.javaparser.resolution.types.ResolvedReferenceType; import com.github.javaparser.resolution.types.ResolvedType; -import com.github.javaparser.symbolsolver.core.resolution.Context; import com.github.javaparser.symbolsolver.core.resolution.MethodUsageResolutionCapability; +import com.github.javaparser.symbolsolver.core.resolution.SymbolResolutionCapability; import com.github.javaparser.symbolsolver.logic.AbstractTypeDeclaration; -import com.github.javaparser.symbolsolver.logic.ConfilictingGenericTypesException; -import com.github.javaparser.symbolsolver.logic.InferenceContext; -import com.github.javaparser.symbolsolver.logic.MethodResolutionCapability; -import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; -import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl; import java.lang.reflect.Field; import java.util.*; @@ -44,7 +45,8 @@ * @author Federico Tomassetti */ public class ReflectionEnumDeclaration extends AbstractTypeDeclaration - implements ResolvedEnumDeclaration, MethodResolutionCapability, MethodUsageResolutionCapability { + implements ResolvedEnumDeclaration, MethodResolutionCapability, MethodUsageResolutionCapability, + SymbolResolutionCapability { /// /// Fields @@ -149,7 +151,7 @@ public boolean isAssignableBy(ResolvedType type) { @Override public boolean isAssignableBy(ResolvedReferenceTypeDeclaration other) { - return isAssignableBy(new ReferenceTypeImpl(other, typeSolver)); + return isAssignableBy(new ReferenceTypeImpl(other)); } @Override @@ -179,7 +181,7 @@ public Optional solveMethodAsUsage(String name, List typeParameterValues, this, clazz); if (res.isPresent()) { // We have to replace method type typeParametersValues here - InferenceContext inferenceContext = new InferenceContext(MyObjectProvider.INSTANCE); + InferenceContext inferenceContext = new InferenceContext(typeSolver); MethodUsage methodUsage = res.get(); int i = 0; List parameters = new LinkedList<>(); @@ -197,7 +199,7 @@ public Optional solveMethodAsUsage(String name, List } methodUsage = methodUsage.replaceReturnType(inferenceContext.resolve(returnType)); return Optional.of(methodUsage); - } catch (ConfilictingGenericTypesException e) { + } catch (ConflictingGenericTypesException e) { return Optional.empty(); } } else { @@ -205,6 +207,15 @@ public Optional solveMethodAsUsage(String name, List } } + @Override + public SymbolReference solveSymbol(String name, TypeSolver typeSolver) { + if (hasEnumConstant(name)) { + ResolvedEnumConstantDeclaration enumConstant = getEnumConstant(name); + return SymbolReference.solved(enumConstant); + } + return SymbolReference.unsolved(); + } + @Override public List getEnumConstants() { return Arrays.stream(clazz.getFields()) diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionFactory.java b/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionFactory.java similarity index 80% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionFactory.java rename to src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionFactory.java index 39205dc..51bbfd1 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionFactory.java +++ b/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionFactory.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -22,11 +22,11 @@ package com.github.javaparser.symbolsolver.reflectionmodel; import com.github.javaparser.ast.AccessSpecifier; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration; import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration; +import com.github.javaparser.resolution.model.typesystem.ReferenceTypeImpl; import com.github.javaparser.resolution.types.*; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; -import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl; import java.lang.reflect.GenericArrayType; import java.lang.reflect.Modifier; @@ -46,17 +46,20 @@ public class ReflectionFactory { public static ResolvedReferenceTypeDeclaration typeDeclarationFor(Class clazz, TypeSolver typeSolver) { if (clazz.isArray()) { throw new IllegalArgumentException("No type declaration available for an Array"); - } else if (clazz.isPrimitive()) { + } + if (clazz.isPrimitive()) { throw new IllegalArgumentException(); - } else if (clazz.isAnnotation()) { + } + if (clazz.isAnnotation()) { return new ReflectionAnnotationDeclaration(clazz, typeSolver); - } else if (clazz.isInterface()) { + } + if (clazz.isInterface()) { return new ReflectionInterfaceDeclaration(clazz, typeSolver); - } else if (clazz.isEnum()) { + } + if (clazz.isEnum()) { return new ReflectionEnumDeclaration(clazz, typeSolver); - } else { - return new ReflectionClassDeclaration(clazz, typeSolver); } + return new ReflectionClassDeclaration(clazz, typeSolver); } public static ResolvedType typeUsageFor(java.lang.reflect.Type type, TypeSolver typeSolver) { @@ -65,7 +68,8 @@ public static ResolvedType typeUsageFor(java.lang.reflect.Type type, TypeSolver boolean declaredOnClass = tv.getGenericDeclaration() instanceof java.lang.reflect.Type; ResolvedTypeParameterDeclaration typeParameter = new ReflectionTypeParameter(tv, declaredOnClass, typeSolver); return new ResolvedTypeVariable(typeParameter); - } else if (type instanceof ParameterizedType) { + } + if (type instanceof ParameterizedType) { ParameterizedType pt = (ParameterizedType) type; ResolvedReferenceType rawType = typeUsageFor(pt.getRawType(), typeSolver).asReferenceType(); List actualTypes = new ArrayList<>(); @@ -73,23 +77,25 @@ public static ResolvedType typeUsageFor(java.lang.reflect.Type type, TypeSolver // we consume the actual types rawType = rawType.transformTypeParameters(tp -> typeUsageFor(actualTypes.remove(0), typeSolver)).asReferenceType(); return rawType; - } else if (type instanceof Class) { + } + if (type instanceof Class) { Class c = (Class) type; if (c.isPrimitive()) { if (c.getName().equals(Void.TYPE.getName())) { return ResolvedVoidType.INSTANCE; - } else { - return ResolvedPrimitiveType.byName(c.getName()); } - } else if (c.isArray()) { + return ResolvedPrimitiveType.byName(c.getName()); + } + if (c.isArray()) { return new ResolvedArrayType(typeUsageFor(c.getComponentType(), typeSolver)); - } else { - return new ReferenceTypeImpl(typeDeclarationFor(c, typeSolver), typeSolver); } - } else if (type instanceof GenericArrayType) { + return new ReferenceTypeImpl(typeDeclarationFor(c, typeSolver)); + } + if (type instanceof GenericArrayType) { GenericArrayType genericArrayType = (GenericArrayType) type; return new ResolvedArrayType(typeUsageFor(genericArrayType.getGenericComponentType(), typeSolver)); - } else if (type instanceof WildcardType) { + } + if (type instanceof WildcardType) { WildcardType wildcardType = (WildcardType) type; if (wildcardType.getLowerBounds().length > 0 && wildcardType.getUpperBounds().length > 0) { if (wildcardType.getUpperBounds().length == 1 && wildcardType.getUpperBounds()[0].getTypeName().equals(JAVA_LANG_OBJECT)) { @@ -109,20 +115,20 @@ public static ResolvedType typeUsageFor(java.lang.reflect.Type type, TypeSolver return ResolvedWildcard.extendsBound(typeUsageFor(wildcardType.getUpperBounds()[0], typeSolver)); } return ResolvedWildcard.UNBOUNDED; - } else { - throw new UnsupportedOperationException(type.getClass().getCanonicalName() + " " + type); } + throw new UnsupportedOperationException(type.getClass().getCanonicalName() + " " + type); } static AccessSpecifier modifiersToAccessLevel(final int modifiers) { if (Modifier.isPublic(modifiers)) { return AccessSpecifier.PUBLIC; - } else if (Modifier.isProtected(modifiers)) { + } + if (Modifier.isProtected(modifiers)) { return AccessSpecifier.PROTECTED; - } else if (Modifier.isPrivate(modifiers)) { + } + if (Modifier.isPrivate(modifiers)) { return AccessSpecifier.PRIVATE; - } else { - return AccessSpecifier.PACKAGE_PRIVATE; } + return AccessSpecifier.NONE; } } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionFieldDeclaration.java b/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionFieldDeclaration.java similarity index 96% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionFieldDeclaration.java rename to src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionFieldDeclaration.java index 4416adc..939ab71 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionFieldDeclaration.java +++ b/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionFieldDeclaration.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -22,10 +22,10 @@ package com.github.javaparser.symbolsolver.reflectionmodel; import com.github.javaparser.ast.AccessSpecifier; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.ResolvedFieldDeclaration; import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration; import com.github.javaparser.resolution.types.ResolvedType; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; import java.lang.reflect.Field; import java.lang.reflect.Modifier; diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionInterfaceDeclaration.java b/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionInterfaceDeclaration.java similarity index 88% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionInterfaceDeclaration.java rename to src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionInterfaceDeclaration.java index f2bd21b..574637a 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionInterfaceDeclaration.java +++ b/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionInterfaceDeclaration.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -23,22 +23,22 @@ import com.github.javaparser.ast.AccessSpecifier; import com.github.javaparser.ast.Node; -import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; +import com.github.javaparser.resolution.Context; import com.github.javaparser.resolution.MethodUsage; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.*; +import com.github.javaparser.resolution.logic.ConflictingGenericTypesException; +import com.github.javaparser.resolution.logic.InferenceContext; +import com.github.javaparser.resolution.logic.MethodResolutionCapability; +import com.github.javaparser.resolution.model.LambdaArgumentTypePlaceholder; +import com.github.javaparser.resolution.model.SymbolReference; +import com.github.javaparser.resolution.model.typesystem.NullType; +import com.github.javaparser.resolution.model.typesystem.ReferenceTypeImpl; import com.github.javaparser.resolution.types.ResolvedReferenceType; import com.github.javaparser.resolution.types.ResolvedType; -import com.github.javaparser.symbolsolver.core.resolution.Context; import com.github.javaparser.symbolsolver.core.resolution.MethodUsageResolutionCapability; -import com.github.javaparser.symbolsolver.javaparsermodel.LambdaArgumentTypePlaceholder; +import com.github.javaparser.symbolsolver.core.resolution.SymbolResolutionCapability; import com.github.javaparser.symbolsolver.logic.AbstractTypeDeclaration; -import com.github.javaparser.symbolsolver.logic.ConfilictingGenericTypesException; -import com.github.javaparser.symbolsolver.logic.InferenceContext; -import com.github.javaparser.symbolsolver.logic.MethodResolutionCapability; -import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; -import com.github.javaparser.symbolsolver.model.typesystem.NullType; -import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl; import java.lang.reflect.Field; import java.util.*; @@ -48,7 +48,8 @@ * @author Federico Tomassetti */ public class ReflectionInterfaceDeclaration extends AbstractTypeDeclaration - implements ResolvedInterfaceDeclaration, MethodResolutionCapability, MethodUsageResolutionCapability { + implements ResolvedInterfaceDeclaration, MethodResolutionCapability, MethodUsageResolutionCapability, + SymbolResolutionCapability { /// /// Fields @@ -78,7 +79,7 @@ public ReflectionInterfaceDeclaration(Class clazz, TypeSolver typeSolver) { @Override public boolean isAssignableBy(ResolvedReferenceTypeDeclaration other) { - return isAssignableBy(new ReferenceTypeImpl(other, typeSolver)); + return isAssignableBy(new ReferenceTypeImpl(other)); } @Override @@ -118,7 +119,7 @@ public String toString() { } public ResolvedType getUsage(Node node) { - return new ReferenceTypeImpl(this, typeSolver); + return new ReferenceTypeImpl(this); } @Override @@ -148,7 +149,7 @@ public Optional solveMethodAsUsage(String name, List typeParameterValues, this, clazz); if (res.isPresent()) { // We have to replace method type typeParametersValues here - InferenceContext inferenceContext = new InferenceContext(MyObjectProvider.INSTANCE); + InferenceContext inferenceContext = new InferenceContext(typeSolver); MethodUsage methodUsage = res.get(); int i = 0; List parameters = new LinkedList<>(); @@ -166,7 +167,7 @@ public Optional solveMethodAsUsage(String name, List } methodUsage = methodUsage.replaceReturnType(inferenceContext.resolve(returnType)); return Optional.of(methodUsage); - } catch (ConfilictingGenericTypesException e) { + } catch (ConflictingGenericTypesException e) { return Optional.empty(); } } else { @@ -242,14 +243,14 @@ public List getAllFields() { return reflectionClassAdapter.getAllFields(); } - @Deprecated + @Override public SymbolReference solveSymbol(String name, TypeSolver typeSolver) { for (Field field : clazz.getFields()) { if (field.getName().equals(name)) { return SymbolReference.solved(new ReflectionFieldDeclaration(field, typeSolver)); } } - return SymbolReference.unsolved(ResolvedValueDeclaration.class); + return SymbolReference.unsolved(); } @Override @@ -283,7 +284,7 @@ public boolean isInterface() { public List getInterfacesExtended() { List res = new ArrayList<>(); for (Class i : clazz.getInterfaces()) { - res.add(new ReferenceTypeImpl(new ReflectionInterfaceDeclaration(i, typeSolver), typeSolver)); + res.add(new ReferenceTypeImpl(new ReflectionInterfaceDeclaration(i, typeSolver))); } return res; } @@ -325,8 +326,4 @@ public List getConstructors() { return Collections.emptyList(); } - @Override - public Optional toAst() { - return Optional.empty(); - } } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionMethodDeclaration.java b/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionMethodDeclaration.java similarity index 91% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionMethodDeclaration.java rename to src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionMethodDeclaration.java index e37b790..67e59ca 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionMethodDeclaration.java +++ b/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionMethodDeclaration.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -22,23 +22,22 @@ package com.github.javaparser.symbolsolver.reflectionmodel; import com.github.javaparser.ast.AccessSpecifier; -import com.github.javaparser.ast.body.MethodDeclaration; +import com.github.javaparser.resolution.Context; import com.github.javaparser.resolution.MethodUsage; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration; import com.github.javaparser.resolution.declarations.ResolvedParameterDeclaration; import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration; import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration; import com.github.javaparser.resolution.types.ResolvedType; -import com.github.javaparser.symbolsolver.core.resolution.Context; import com.github.javaparser.symbolsolver.core.resolution.TypeVariableResolutionCapability; import com.github.javaparser.symbolsolver.declarations.common.MethodDeclarationCommonLogic; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; +import com.github.javaparser.utils.TypeUtils; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Arrays; import java.util.List; -import java.util.Optional; import java.util.stream.Collectors; /** @@ -91,9 +90,8 @@ public ResolvedReferenceTypeDeclaration declaringType() { } if (method.getDeclaringClass().isEnum()) { return new ReflectionEnumDeclaration(method.getDeclaringClass(), typeSolver); - } else { - return new ReflectionClassDeclaration(method.getDeclaringClass(), typeSolver); } + return new ReflectionClassDeclaration(method.getDeclaringClass(), typeSolver); } @Override @@ -159,7 +157,7 @@ public ResolvedType getSpecifiedException(int index) { } @Override - public Optional toAst() { - return Optional.empty(); + public String toDescriptor() { + return TypeUtils.getMethodDescriptor(method); } } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionMethodResolutionLogic.java b/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionMethodResolutionLogic.java similarity index 91% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionMethodResolutionLogic.java rename to src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionMethodResolutionLogic.java index dbdee4f..0703088 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionMethodResolutionLogic.java +++ b/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionMethodResolutionLogic.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -21,18 +21,18 @@ package com.github.javaparser.symbolsolver.reflectionmodel; +import com.github.javaparser.resolution.Context; import com.github.javaparser.resolution.MethodUsage; +import com.github.javaparser.resolution.TypeSolver; 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.resolution.logic.MethodResolutionLogic; +import com.github.javaparser.resolution.model.SymbolReference; +import com.github.javaparser.resolution.model.typesystem.ReferenceTypeImpl; import com.github.javaparser.resolution.types.ResolvedReferenceType; import com.github.javaparser.resolution.types.ResolvedType; import com.github.javaparser.resolution.types.ResolvedTypeVariable; -import com.github.javaparser.symbolsolver.core.resolution.Context; -import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; -import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl; -import com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic; import java.lang.reflect.Method; import java.lang.reflect.Modifier; @@ -68,7 +68,7 @@ static SymbolReference solveMethod(String name, List< } if (scopeType.getAncestors().isEmpty()){ - ReferenceTypeImpl objectClass = new ReferenceTypeImpl(new ReflectionClassDeclaration(Object.class, typeSolver), typeSolver); + ReferenceTypeImpl objectClass = new ReferenceTypeImpl(new ReflectionClassDeclaration(Object.class, typeSolver)); objectClass.getTypeDeclaration().ifPresent(objectTypeDeclaration -> { SymbolReference ref = MethodResolutionLogic.solveMethodInType(objectTypeDeclaration, name, parameterTypes, staticOnly); if (ref.isSolved()) { @@ -88,7 +88,7 @@ static Optional solveMethodAsUsage(String name, List // Parameters not specified, so default to Object typeParameterValues = new ArrayList<>(); for (int i = 0; i < scopeType.getTypeParameters().size(); i++) { - typeParameterValues.add(new ReferenceTypeImpl(new ReflectionClassDeclaration(Object.class, typeSolver), typeSolver)); + typeParameterValues.add(new ReferenceTypeImpl(new ReflectionClassDeclaration(Object.class, typeSolver))); } } } @@ -102,7 +102,9 @@ static Optional solveMethodAsUsage(String name, List } - for(ResolvedReferenceType ancestor : scopeType.getAncestors()){ + List ancestors = scopeType.getAncestors(); + + for(ResolvedReferenceType ancestor : ancestors){ if(ancestor.getTypeDeclaration().isPresent()) { ResolvedReferenceTypeDeclaration ancestorTypeDeclaration = ancestor.getTypeDeclaration().get(); SymbolReference ref = MethodResolutionLogic.solveMethodInType(ancestorTypeDeclaration, name, argumentsTypes); @@ -114,8 +116,8 @@ static Optional solveMethodAsUsage(String name, List } } - if (scopeType.getAncestors().isEmpty()) { - Optional optionalObjectClass = new ReferenceTypeImpl(new ReflectionClassDeclaration(Object.class, typeSolver), typeSolver).getTypeDeclaration(); + if (ancestors.isEmpty()) { + Optional optionalObjectClass = new ReferenceTypeImpl(new ReflectionClassDeclaration(Object.class, typeSolver)).getTypeDeclaration(); if (optionalObjectClass.isPresent()) { SymbolReference ref = MethodResolutionLogic.solveMethodInType(optionalObjectClass.get(), name, argumentsTypes); if (ref.isSolved()) { diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionParameterDeclaration.java b/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionParameterDeclaration.java similarity index 96% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionParameterDeclaration.java rename to src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionParameterDeclaration.java index 729d240..a58b997 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionParameterDeclaration.java +++ b/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionParameterDeclaration.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -21,9 +21,9 @@ package com.github.javaparser.symbolsolver.reflectionmodel; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.ResolvedParameterDeclaration; import com.github.javaparser.resolution.types.ResolvedType; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; import java.util.Objects; diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionPatternDeclaration.java b/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionPatternDeclaration.java similarity index 94% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionPatternDeclaration.java rename to src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionPatternDeclaration.java index 96caa0a..b7e3527 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionPatternDeclaration.java +++ b/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionPatternDeclaration.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -21,9 +21,9 @@ package com.github.javaparser.symbolsolver.reflectionmodel; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.ResolvedPatternDeclaration; import com.github.javaparser.resolution.types.ResolvedType; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; /** * WARNING: Implemented fairly blindly. Unsure if required or even appropriate. Use with extreme caution. diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionTypeParameter.java b/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionTypeParameter.java similarity index 89% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionTypeParameter.java rename to src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionTypeParameter.java index 76b3723..a5e0806 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionTypeParameter.java +++ b/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionTypeParameter.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -21,11 +21,13 @@ package com.github.javaparser.symbolsolver.reflectionmodel; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.ResolvedMethodLikeDeclaration; import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration; import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration; import com.github.javaparser.resolution.declarations.ResolvedTypeParametrizable; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; +import com.github.javaparser.resolution.model.typesystem.ReferenceTypeImpl; +import com.github.javaparser.resolution.types.ResolvedReferenceType; import java.lang.reflect.Constructor; import java.lang.reflect.GenericDeclaration; @@ -94,18 +96,16 @@ public String getName() { public String getContainerQualifiedName() { if (container instanceof ResolvedReferenceTypeDeclaration) { return ((ResolvedReferenceTypeDeclaration) container).getQualifiedName(); - } else { - return ((ResolvedMethodLikeDeclaration) container).getQualifiedSignature(); } + return ((ResolvedMethodLikeDeclaration) container).getQualifiedSignature(); } @Override public String getContainerId() { if (container instanceof ResolvedReferenceTypeDeclaration) { return ((ResolvedReferenceTypeDeclaration) container).getId(); - } else { - return ((ResolvedMethodLikeDeclaration) container).getQualifiedSignature(); } + return ((ResolvedMethodLikeDeclaration) container).getQualifiedSignature(); } @Override @@ -132,4 +132,9 @@ public Optional containerType() { } return Optional.empty(); } + + @Override + public ResolvedReferenceType object() { + return new ReferenceTypeImpl(typeSolver.getSolvedJavaLangObject()); + } } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/comparators/ClassComparator.java b/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/comparators/ClassComparator.java similarity index 97% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/comparators/ClassComparator.java rename to src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/comparators/ClassComparator.java index fcd19ff..d10b3d3 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/comparators/ClassComparator.java +++ b/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/comparators/ClassComparator.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/comparators/MethodComparator.java b/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/comparators/MethodComparator.java similarity index 97% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/comparators/MethodComparator.java rename to src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/comparators/MethodComparator.java index 2544c9b..8491bb7 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/comparators/MethodComparator.java +++ b/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/comparators/MethodComparator.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/comparators/ParameterComparator.java b/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/comparators/ParameterComparator.java similarity index 96% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/comparators/ParameterComparator.java rename to src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/comparators/ParameterComparator.java index 16e1889..b54a3c9 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/comparators/ParameterComparator.java +++ b/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/comparators/ParameterComparator.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/package-info.java b/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/package-info.java similarity index 94% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/package-info.java rename to src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/package-info.java index fc75fbc..69577bf 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/package-info.java +++ b/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/package-info.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/SymbolSolver.java b/src/main/java/com/github/javaparser/symbolsolver/resolution/SymbolSolver.java similarity index 53% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/SymbolSolver.java rename to src/main/java/com/github/javaparser/symbolsolver/resolution/SymbolSolver.java index eae68c0..3e458f2 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/SymbolSolver.java +++ b/src/main/java/com/github/javaparser/symbolsolver/resolution/SymbolSolver.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -24,22 +24,21 @@ import com.github.javaparser.ast.Node; import com.github.javaparser.ast.type.ClassOrInterfaceType; import com.github.javaparser.ast.type.Type; -import com.github.javaparser.resolution.MethodUsage; -import com.github.javaparser.resolution.UnsolvedSymbolException; -import com.github.javaparser.resolution.declarations.*; +import com.github.javaparser.resolution.*; +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.model.SymbolReference; +import com.github.javaparser.resolution.model.Value; +import com.github.javaparser.resolution.model.typesystem.ReferenceTypeImpl; +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.core.resolution.SymbolResolutionCapability; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory; import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration; -import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserEnumDeclaration; import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserInterfaceDeclaration; -import com.github.javaparser.symbolsolver.javassistmodel.JavassistClassDeclaration; -import com.github.javaparser.symbolsolver.javassistmodel.JavassistEnumDeclaration; -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.model.resolution.Value; -import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl; +import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionAnnotationDeclaration; import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassDeclaration; import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionEnumDeclaration; import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionInterfaceDeclaration; @@ -50,7 +49,7 @@ /** * @author Federico Tomassetti */ -public class SymbolSolver { +public class SymbolSolver implements Solver { private final TypeSolver typeSolver; @@ -62,32 +61,39 @@ public SymbolSolver(TypeSolver typeSolver) { this.typeSolver = typeSolver; } - public SymbolReference solveSymbol(String name, Context context) { + @Override + public SymbolReference solveSymbol(String name, Context context) { return context.solveSymbol(name); } - public SymbolReference solveSymbol(String name, Node node) { + @Override + public SymbolReference solveSymbol(String name, Node node) { return solveSymbol(name, JavaParserFactory.getContext(node, typeSolver)); } - public Optional solveSymbolAsValue(String name, Context context) { + @Override + public Optional solveSymbolAsValue(String name, Context context) { return context.solveSymbolAsValue(name); } - public Optional solveSymbolAsValue(String name, Node node) { + @Override + public Optional solveSymbolAsValue(String name, Node node) { Context context = JavaParserFactory.getContext(node, typeSolver); return solveSymbolAsValue(name, context); } - public SymbolReference solveType(String name, Context context) { + @Override + public SymbolReference solveType(String name, Context context) { return context.solveType(name); } - public SymbolReference solveType(String name, Node node) { + @Override + public SymbolReference solveType(String name, Node node) { return solveType(name, JavaParserFactory.getContext(node, typeSolver)); } - public MethodUsage solveMethod(String methodName, List argumentsTypes, Context context) { + @Override + public MethodUsage solveMethod(String methodName, List argumentsTypes, Context context) { SymbolReference decl = context.solveMethod(methodName, argumentsTypes, false); if (!decl.isSolved()) { throw new UnsolvedSymbolException(context.toString(), methodName); @@ -95,33 +101,35 @@ public MethodUsage solveMethod(String methodName, List argumentsTy return new MethodUsage(decl.getCorrespondingDeclaration()); } - public MethodUsage solveMethod(String methodName, List argumentsTypes, Node node) { + @Override + public MethodUsage solveMethod(String methodName, List argumentsTypes, Node node) { return solveMethod(methodName, argumentsTypes, JavaParserFactory.getContext(node, typeSolver)); } - public ResolvedTypeDeclaration solveType(Type type) { + @Override + public ResolvedTypeDeclaration solveType(Type type) { if (type instanceof ClassOrInterfaceType) { // FIXME should call typesolver here! - String name = ((ClassOrInterfaceType) type).getName().getId(); + String name = ((ClassOrInterfaceType) type).getNameWithScope(); SymbolReference ref = JavaParserFactory.getContext(type, typeSolver).solveType(name); if (!ref.isSolved()) { throw new UnsolvedSymbolException(JavaParserFactory.getContext(type, typeSolver).toString(), name); } return ref.getCorrespondingDeclaration(); - } else { - throw new UnsupportedOperationException(type.getClass().getCanonicalName()); } + throw new UnsupportedOperationException(type.getClass().getCanonicalName()); } - public ResolvedType solveTypeUsage(String name, Context context) { + @Override + public ResolvedType solveTypeUsage(String name, Context context) { Optional genericType = context.solveGenericType(name); if (genericType.isPresent()) { return genericType.get(); } ResolvedReferenceTypeDeclaration typeDeclaration = typeSolver.solveType(name); - return new ReferenceTypeImpl(typeDeclaration, typeSolver); + return new ReferenceTypeImpl(typeDeclaration); } /** @@ -130,39 +138,12 @@ public ResolvedType solveTypeUsage(String name, Context context) { *

* It should contain its own private fields but not inherited private fields. */ - public SymbolReference solveSymbolInType(ResolvedTypeDeclaration typeDeclaration, String name) { - if (typeDeclaration instanceof JavaParserClassDeclaration) { - Context ctx = ((JavaParserClassDeclaration) typeDeclaration).getContext(); - return ctx.solveSymbol(name); - } - if (typeDeclaration instanceof JavaParserInterfaceDeclaration) { - Context ctx = ((JavaParserInterfaceDeclaration) typeDeclaration).getContext(); - return ctx.solveSymbol(name); - } - if (typeDeclaration instanceof JavaParserEnumDeclaration) { - Context ctx = ((JavaParserEnumDeclaration) typeDeclaration).getContext(); - return ctx.solveSymbol(name); - } - if (typeDeclaration instanceof ReflectionClassDeclaration) { - return ((ReflectionClassDeclaration) typeDeclaration).solveSymbol(name, typeSolver); - } - if (typeDeclaration instanceof ReflectionInterfaceDeclaration) { - return ((ReflectionInterfaceDeclaration) typeDeclaration).solveSymbol(name, typeSolver); - } - if (typeDeclaration instanceof ReflectionEnumDeclaration) { - ResolvedEnumConstantDeclaration red = ((ReflectionEnumDeclaration) typeDeclaration).getEnumConstant(name); - return SymbolReference.solved(red); - } - if (typeDeclaration instanceof JavassistClassDeclaration) { - return ((JavassistClassDeclaration) typeDeclaration).solveSymbol(name, typeSolver); - } - if (typeDeclaration instanceof JavassistEnumDeclaration) { - return ((JavassistEnumDeclaration) typeDeclaration).solveSymbol(name, typeSolver); + @Override + public SymbolReference solveSymbolInType(ResolvedTypeDeclaration typeDeclaration, String name) { + if (typeDeclaration instanceof SymbolResolutionCapability) { + return ((SymbolResolutionCapability) typeDeclaration).solveSymbol(name, typeSolver); } - if (typeDeclaration instanceof JavassistInterfaceDeclaration) { - return ((JavassistInterfaceDeclaration) typeDeclaration).solveSymbol(name, typeSolver); - } - return SymbolReference.unsolved(ResolvedValueDeclaration.class); + return SymbolReference.unsolved(); } /** @@ -171,7 +152,8 @@ public SymbolReference solveSymbolInType(Res * @deprecated Similarly to solveType this should eventually disappear as the symbol resolution logic should be more general * and do not be specific to JavaParser classes like in this case. */ - @Deprecated + @Override + @Deprecated public SymbolReference solveTypeInType(ResolvedTypeDeclaration typeDeclaration, String name) { if (typeDeclaration instanceof JavaParserClassDeclaration) { return ((JavaParserClassDeclaration) typeDeclaration).solveType(name); @@ -179,6 +161,31 @@ public SymbolReference solveTypeInType(ResolvedTypeDecl if (typeDeclaration instanceof JavaParserInterfaceDeclaration) { return ((JavaParserInterfaceDeclaration) typeDeclaration).solveType(name); } - return SymbolReference.unsolved(ResolvedReferenceTypeDeclaration.class); + return SymbolReference.unsolved(); + } + + /** + * Convert a {@link Class} into the corresponding {@link ResolvedType}. + * + * @param clazz The class to be converted. + * + * @return The class resolved. + */ + public ResolvedType classToResolvedType(Class clazz) { + if (clazz.isPrimitive()) { + return ResolvedPrimitiveType.byName(clazz.getName()); + } + + ResolvedReferenceTypeDeclaration declaration; + if (clazz.isAnnotation()) { + declaration = new ReflectionAnnotationDeclaration(clazz, typeSolver); + } else if (clazz.isEnum()) { + declaration = new ReflectionEnumDeclaration(clazz, typeSolver); + } else if (clazz.isInterface()) { + declaration = new ReflectionInterfaceDeclaration(clazz, typeSolver); + } else { + declaration = new ReflectionClassDeclaration(clazz, typeSolver); + } + return new ReferenceTypeImpl(declaration); } } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/naming/NameCategory.java b/src/main/java/com/github/javaparser/symbolsolver/resolution/naming/NameCategory.java similarity index 97% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/naming/NameCategory.java rename to src/main/java/com/github/javaparser/symbolsolver/resolution/naming/NameCategory.java index 33562c8..831da3f 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/naming/NameCategory.java +++ b/src/main/java/com/github/javaparser/symbolsolver/resolution/naming/NameCategory.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/naming/NameLogic.java b/src/main/java/com/github/javaparser/symbolsolver/resolution/naming/NameLogic.java similarity index 96% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/naming/NameLogic.java rename to src/main/java/com/github/javaparser/symbolsolver/resolution/naming/NameLogic.java index 7bb2b35..4ab7d50 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/naming/NameLogic.java +++ b/src/main/java/com/github/javaparser/symbolsolver/resolution/naming/NameLogic.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -32,13 +32,13 @@ import com.github.javaparser.ast.stmt.TryStmt; import com.github.javaparser.ast.type.ClassOrInterfaceType; import com.github.javaparser.ast.type.TypeParameter; +import com.github.javaparser.resolution.Context; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.UnsolvedSymbolException; import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration; import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration; -import com.github.javaparser.symbolsolver.core.resolution.Context; +import com.github.javaparser.resolution.model.SymbolReference; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory; -import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; /** * NameLogic contains a set of static methods to implement the abstraction of a "Name" as defined @@ -78,12 +78,11 @@ public static boolean isAName(Node node) { if (node instanceof FieldAccessExpr) { FieldAccessExpr fieldAccessExpr = (FieldAccessExpr) node; return isAName(fieldAccessExpr.getScope()); - } else { - return node instanceof SimpleName || + } + return node instanceof SimpleName || node instanceof Name || node instanceof ClassOrInterfaceType || node instanceof NameExpr; - } } private static Node getQualifier(Node node) { @@ -322,14 +321,13 @@ public static NameCategory classifyReference(Node name, TypeSolver typeSolver) { NameCategory first = syntacticClassificationAccordingToContext(name); // Second, a name that is initially classified by its context as an AmbiguousName or as a PackageOrTypeName is - // then reclassified to be a PackageName, TypeName, or ExpressionName. + if (first.isNeedingDisambiguation()) { NameCategory second = reclassificationOfContextuallyAmbiguousNames(name, first, typeSolver); assert !second.isNeedingDisambiguation(); return second; - } else { - return first; } + return first; } /** @@ -364,9 +362,8 @@ private static NameCategory reclassificationOfContextuallyAmbiguousPackageOrType if (isSimpleName(name)) { if (JavaParserFactory.getContext(name, typeSolver).solveType(nameAsString(name)).isSolved()) { return NameCategory.TYPE_NAME; - } else { - return NameCategory.PACKAGE_NAME; } + return NameCategory.PACKAGE_NAME; } // 6.5.4.2. Qualified PackageOrTypeNames @@ -381,9 +378,8 @@ private static NameCategory reclassificationOfContextuallyAmbiguousPackageOrType if (isQualifiedName(name)) { if (JavaParserFactory.getContext(name, typeSolver).solveType(nameAsString(name)).isSolved()) { return NameCategory.TYPE_NAME; - } else { - return NameCategory.PACKAGE_NAME; } + return NameCategory.PACKAGE_NAME; } throw new UnsupportedOperationException("This is unexpected: the name is neither simple or qualified"); @@ -410,9 +406,8 @@ private static NameCategory reclassificationOfContextuallyAmbiguousQualifiedAmbi if (leftNameCategory == NameCategory.PACKAGE_NAME) { if (typeSolver.hasType(nameAsString(nameNode))) { return NameCategory.TYPE_NAME; - } else { - return NameCategory.PACKAGE_NAME; } + return NameCategory.PACKAGE_NAME; } // * If the name to the left of the "." is reclassified as a TypeName, then: @@ -442,12 +437,10 @@ private static NameCategory reclassificationOfContextuallyAmbiguousQualifiedAmbi return NameCategory.TYPE_NAME; } return NameCategory.COMPILATION_ERROR; - } else { - throw new UnsupportedOperationException("The name is a type but it has been resolved to something that is not a reference type"); } - } else { - throw new UnsolvedSymbolException("Unable to solve context type: " + NameLogic.nameAsString(leftName)); + throw new UnsupportedOperationException("The name is a type but it has been resolved to something that is not a reference type"); } + throw new UnsolvedSymbolException("Unable to solve context type: " + NameLogic.nameAsString(leftName)); } // * If the name to the left of the "." is reclassified as an ExpressionName, then this AmbiguousName is @@ -578,7 +571,7 @@ private static boolean isSyntacticallyAAmbiguousName(Node name) { // // 4. In the default value clause of an annotation type element declaration (§9.6.2) // - // 5. To the right of an "=" in an an element-value pair (§9.7.1) + // 5. To the right of an "=" in an element-value pair (§9.7.1) if (whenParentIs(MemberValuePair.class, name, (p, c) -> p.getValue() == c)) { return true; @@ -983,23 +976,25 @@ public static String nameAsString(Node name) { } if (name instanceof Name) { return ((Name) name).asString(); - } else if (name instanceof SimpleName) { + } + if (name instanceof SimpleName) { return ((SimpleName) name).getIdentifier(); - } else if (name instanceof ClassOrInterfaceType) { + } + if (name instanceof ClassOrInterfaceType) { return ((ClassOrInterfaceType) name).asString(); - } else if (name instanceof FieldAccessExpr) { + } + if (name instanceof FieldAccessExpr) { FieldAccessExpr fieldAccessExpr = (FieldAccessExpr) name; if (isAName(fieldAccessExpr.getScope())) { return nameAsString(fieldAccessExpr.getScope()) + "." + nameAsString(fieldAccessExpr.getName()); - } else { - throw new IllegalArgumentException(); } - } else if (name instanceof NameExpr) { + throw new IllegalArgumentException(); + } + if (name instanceof NameExpr) { return ((NameExpr) name).getNameAsString(); - } else { - throw new UnsupportedOperationException("Unknown type of name found: " + name + " (" - + name.getClass().getCanonicalName() + ")"); } + throw new UnsupportedOperationException("Unknown type of name found: " + name + " (" + + name.getClass().getCanonicalName() + ")"); } private interface PredicateOnParentAndChild

{ @@ -1017,9 +1012,8 @@ private static

boolean whenParentIs( if (child.getParentNode().isPresent()) { Node parent = child.getParentNode().get(); return parentClass.isInstance(parent) && predicate.isSatisfied(parentClass.cast(parent), child); - } else { - return false; } + return false; } } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/naming/NameRole.java b/src/main/java/com/github/javaparser/symbolsolver/resolution/naming/NameRole.java similarity index 95% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/naming/NameRole.java rename to src/main/java/com/github/javaparser/symbolsolver/resolution/naming/NameRole.java index 228c230..63d4b94 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/naming/NameRole.java +++ b/src/main/java/com/github/javaparser/symbolsolver/resolution/naming/NameRole.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * diff --git a/src/main/java/com/github/javaparser/symbolsolver/resolution/promotion/BooleanConditionalExprHandler.java b/src/main/java/com/github/javaparser/symbolsolver/resolution/promotion/BooleanConditionalExprHandler.java new file mode 100644 index 0000000..14b2e21 --- /dev/null +++ b/src/main/java/com/github/javaparser/symbolsolver/resolution/promotion/BooleanConditionalExprHandler.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2013-2023 The JavaParser Team. + * + * This file is part of JavaParser. + * + * JavaParser can be used either under the terms of + * a) the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * b) the terms of the Apache License + * + * You should have received a copy of both licenses in LICENCE.LGPL and + * LICENCE.APACHE. Please refer to those files for details. + * + * JavaParser is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + */ + +package com.github.javaparser.symbolsolver.resolution.promotion; + +import com.github.javaparser.resolution.promotion.ConditionalExprHandler; +import com.github.javaparser.resolution.types.ResolvedType; + +/* + * Boolean conditional expressions are standalone expressions + * The type of a boolean conditional expression is determined as follows: + * If the second and third operands are both of type Boolean, the conditional expression has type Boolean. + * Otherwise, the conditional expression has type boolean. + */ +public class BooleanConditionalExprHandler implements ConditionalExprHandler { + ResolvedType thenExpr; + ResolvedType elseExpr; + + public BooleanConditionalExprHandler(ResolvedType thenExpr, ResolvedType elseExpr) { + this.thenExpr = thenExpr; + this.elseExpr = elseExpr; + } + + @Override + public ResolvedType resolveType() { + if (thenExpr.isReferenceType() && elseExpr.isReferenceType()) { + return thenExpr.asReferenceType(); + } + return thenExpr.isPrimitive() ? thenExpr : elseExpr; + } +} \ No newline at end of file diff --git a/src/main/java/com/github/javaparser/symbolsolver/resolution/promotion/ConditionalExprResolver.java b/src/main/java/com/github/javaparser/symbolsolver/resolution/promotion/ConditionalExprResolver.java new file mode 100644 index 0000000..a946b06 --- /dev/null +++ b/src/main/java/com/github/javaparser/symbolsolver/resolution/promotion/ConditionalExprResolver.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2013-2023 The JavaParser Team. + * + * This file is part of JavaParser. + * + * JavaParser can be used either under the terms of + * a) the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * b) the terms of the Apache License + * + * You should have received a copy of both licenses in LICENCE.LGPL and + * LICENCE.APACHE. Please refer to those files for details. + * + * JavaParser is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + */ + +package com.github.javaparser.symbolsolver.resolution.promotion; + +import com.github.javaparser.resolution.promotion.ConditionalExprHandler; +import com.github.javaparser.resolution.types.ResolvedPrimitiveType; +import com.github.javaparser.resolution.types.ResolvedType; + +/* + * The conditional operator has three operand expressions. + * ? appears between the first and second expressions, + * and : appears between the second and third expressions. + * There are three kinds of conditional expressions, classified according to the second and third operand expressions: boolean conditional expressions, numeric conditional expressions, and reference conditional expressions. + * The classification rules are as follows: + * 1/ If both the second and the third operand expressions are boolean expressions, the conditional expression is a boolean conditional expression. + * 2/ If both the second and the third operand expressions are numeric expressions, the conditional expression is a numeric conditional expression. + * 3/ Otherwise, the conditional expression is a reference conditional expression + */ +public class ConditionalExprResolver { + private static final ResolvedPrimitiveType TYPE_BOOLEAN = ResolvedPrimitiveType.BOOLEAN; + + public static ConditionalExprHandler getConditionExprHandler(ResolvedType thenExpr, ResolvedType elseExpr) { + // boolean conditional expressions + if (!thenExpr.isNull() && !elseExpr.isNull() + && thenExpr.isAssignableBy(TYPE_BOOLEAN) && elseExpr.isAssignableBy(TYPE_BOOLEAN)) { + return new BooleanConditionalExprHandler(thenExpr, elseExpr); + // numeric conditional expressions + } + if (thenExpr.isNumericType() && elseExpr.isNumericType()) { + return new NumericConditionalExprHandler(thenExpr, elseExpr); + } + // reference conditional expressions + return new ReferenceConditionalExprHandler(thenExpr, elseExpr); + } +} diff --git a/src/main/java/com/github/javaparser/symbolsolver/resolution/promotion/NumericConditionalExprHandler.java b/src/main/java/com/github/javaparser/symbolsolver/resolution/promotion/NumericConditionalExprHandler.java new file mode 100644 index 0000000..fe6f689 --- /dev/null +++ b/src/main/java/com/github/javaparser/symbolsolver/resolution/promotion/NumericConditionalExprHandler.java @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2013-2023 The JavaParser Team. + * + * This file is part of JavaParser. + * + * JavaParser can be used either under the terms of + * a) the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * b) the terms of the Apache License + * + * You should have received a copy of both licenses in LICENCE.LGPL and + * LICENCE.APACHE. Please refer to those files for details. + * + * JavaParser is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + */ + +package com.github.javaparser.symbolsolver.resolution.promotion; + +import com.github.javaparser.resolution.promotion.ConditionalExprHandler; +import com.github.javaparser.resolution.types.ResolvedPrimitiveType; +import com.github.javaparser.resolution.types.ResolvedType; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/* + * Numeric conditional expressions are standalone expressions (§15.2). + * The type of a numeric conditional expression is determined as follows: + * If the second and third operands have the same type, then that is the type of the conditional expression. + * If one of the second and third operands is of primitive type T, and the type of the other is the result of applying boxing conversion (§5.1.7) to T, then the type of the conditional expression is T. + * If one of the operands is of type byte or Byte and the other is of type short or Short, then the type of the conditional expression is short. + * If one of the operands is of type T where T is byte, short, or char, and the other operand is a constant expression (§15.28) of type int whose value is representable in type T, then the type of the conditional expression is T. + * If one of the operands is of type T, where T is Byte, Short, or Character, and the other operand is a constant expression of type int whose value is representable in the type U which is the result of applying unboxing conversion to T, then the type of the conditional expression is U. + * Otherwise, binary numeric promotion (§5.6.2) is applied to the operand types, and the type of the conditional expression is the promoted type of the second and third operands. + */ +public class NumericConditionalExprHandler implements ConditionalExprHandler { + + private static Map> NumericConverter = new HashMap(); + static { + // first type is the type of the resolution + // the list indicates the types that can be resolved in the type specified as + // key + NumericConverter.put(ResolvedPrimitiveType.SHORT, + Arrays.asList(ResolvedPrimitiveType.SHORT, ResolvedPrimitiveType.BYTE)); + } + + private static ResolvedPrimitiveType[] resolvedPrimitiveTypeSubList = new ResolvedPrimitiveType[] {ResolvedPrimitiveType.BYTE, ResolvedPrimitiveType.SHORT, ResolvedPrimitiveType.CHAR}; + + ResolvedType thenExpr; + ResolvedType elseExpr; + + public NumericConditionalExprHandler(ResolvedType thenExpr, ResolvedType elseExpr) { + this.thenExpr = thenExpr; + this.elseExpr = elseExpr; + } + + @Override + public ResolvedType resolveType() { + String qnameTypeThenExpr = thenExpr.isPrimitive() ? thenExpr.asPrimitive().describe() + : thenExpr.asReferenceType().describe(); + String qnameTypeElseExpr = elseExpr.isPrimitive() ? elseExpr.asPrimitive().describe() + : elseExpr.asReferenceType().describe(); + if (qnameTypeThenExpr.equals(qnameTypeElseExpr)) { + return thenExpr; + } + /* + * If one of the second and third operands is of primitive type T, and the type of the other is the result of + * applying boxing conversion (§5.1.7) to T, then the type of the conditional expression is T. + */ + if (thenExpr.isPrimitive() && elseExpr.isReferenceType() + && elseExpr.asReferenceType() + .isUnboxableTo((ResolvedPrimitiveType) ResolvedPrimitiveType.byName(qnameTypeThenExpr))) { + return thenExpr; + } + if (elseExpr.isPrimitive() && thenExpr.isReferenceType() + && thenExpr.asReferenceType() + .isUnboxableTo((ResolvedPrimitiveType) ResolvedPrimitiveType.byName(qnameTypeElseExpr))) { + return elseExpr; + } + /* + * If one of the operands is of type byte or Byte and the other is of type short or Short, then the type of the + * conditional expression is short. + */ + + if ((isResolvableTo(ResolvedPrimitiveType.SHORT, thenExpr) && relaxMatch(elseExpr, ResolvedPrimitiveType.BYTE)) + || (isResolvableTo(ResolvedPrimitiveType.SHORT, elseExpr) && relaxMatch(thenExpr, ResolvedPrimitiveType.BYTE))) { + return ResolvedPrimitiveType.SHORT; + } + +// if ((in(thenExpr, ResolvedPrimitiveType.SHORT) && in(elseExpr, ResolvedPrimitiveType.BYTE)) +// || (in(elseExpr, ResolvedPrimitiveType.SHORT) && in(thenExpr, ResolvedPrimitiveType.BYTE))) { +// return ResolvedPrimitiveType.SHORT; +// } + + // If one of the operands is of type T where T is byte, short, or char, and the + // other operand is a constant expression (§15.28) of type int whose value is + // representable in type T, then the type of the conditional expression is T + // How can we know if the constant expression of type int is representable in + // type T ? + + if (thenExpr.isPrimitive() && elseExpr.isPrimitive()) { + if (((ResolvedPrimitiveType)thenExpr).in(resolvedPrimitiveTypeSubList) + && ((ResolvedPrimitiveType)elseExpr).equals(ResolvedPrimitiveType.INT)) { + return thenExpr; + } + if (((ResolvedPrimitiveType)elseExpr).in(resolvedPrimitiveTypeSubList) + && ((ResolvedPrimitiveType)thenExpr).equals(ResolvedPrimitiveType.INT)) { + return elseExpr; + } + } + + // If one of the operands is of type T, where T is Byte, Short, or Character, + // and the other operand is a constant expression of type int whose value is + // representable in the type U which is the result of applying unboxing + // conversion to T, then the type of the conditional expression is U. + // How can we know it? + + if (thenExpr.isReference() && elseExpr.isPrimitive() + && thenExpr.asReferenceType().isUnboxable() + && thenExpr.asReferenceType().toUnboxedType().get().in(resolvedPrimitiveTypeSubList) + && ((ResolvedPrimitiveType)elseExpr).equals(ResolvedPrimitiveType.INT)) { + return thenExpr.asReferenceType().toUnboxedType().get(); + } + if (elseExpr.isReference() && thenExpr.isPrimitive() + && elseExpr.asReferenceType().isUnboxable() + && elseExpr.asReferenceType().toUnboxedType().get().in(resolvedPrimitiveTypeSubList) + && ((ResolvedPrimitiveType)thenExpr).equals(ResolvedPrimitiveType.INT)) { + return elseExpr.asReferenceType().toUnboxedType().get(); + } + + // Otherwise, binary numeric promotion (§5.6.2) is applied to the operand types, + // and the type of the conditional expression is the promoted type of the second + // and third operands. + ResolvedPrimitiveType PrimitiveThenExpr = thenExpr.isPrimitive() ? thenExpr.asPrimitive() + : thenExpr.asReferenceType().toUnboxedType().get(); + ResolvedPrimitiveType PrimitiveElseExpr = elseExpr.isPrimitive() ? elseExpr.asPrimitive() + : elseExpr.asReferenceType().toUnboxedType().get(); + return PrimitiveThenExpr.bnp(PrimitiveElseExpr); + } + + /* + * Verify if the {code ResolvedType} is equals to one of the specified primitive types + */ + protected boolean exactMatch(ResolvedType type, ResolvedPrimitiveType... types) { + return type.isPrimitive() && type.asPrimitive().in(types); + } + + protected boolean relaxMatch(ResolvedType type, ResolvedPrimitiveType... types) { + return exactMatch(type, types) || (type.isReferenceType() && Arrays.stream(types).anyMatch(t -> type.asReferenceType().getQualifiedName().equals(t.getBoxTypeQName()))); + } + + /* + * Verify if the {code ResolvedType} can be resolve to the specified primitive type + */ + protected boolean isResolvableTo(ResolvedPrimitiveType toType, ResolvedType resolvedType) { + // force to verify boxed type + return isResolvableTo(toType, resolvedType, true); + } + + protected boolean isResolvableTo(ResolvedPrimitiveType toType, ResolvedType resolvedType, boolean verifyBoxedType) { + return NumericConverter.entrySet().stream().filter(e -> e.getKey() == toType) + .flatMap(entry -> entry.getValue().stream()) + .anyMatch(rt -> rt == resolvedType || (verifyBoxedType && resolvedType.isReferenceType() + && resolvedType.asReferenceType().toUnboxedType().get() == toType)); + } +} diff --git a/src/main/java/com/github/javaparser/symbolsolver/resolution/promotion/ReferenceConditionalExprHandler.java b/src/main/java/com/github/javaparser/symbolsolver/resolution/promotion/ReferenceConditionalExprHandler.java new file mode 100644 index 0000000..cc708f1 --- /dev/null +++ b/src/main/java/com/github/javaparser/symbolsolver/resolution/promotion/ReferenceConditionalExprHandler.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2013-2023 The JavaParser Team. + * + * This file is part of JavaParser. + * + * JavaParser can be used either under the terms of + * a) the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * b) the terms of the Apache License + * + * You should have received a copy of both licenses in LICENCE.LGPL and + * LICENCE.APACHE. Please refer to those files for details. + * + * JavaParser is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + */ + +package com.github.javaparser.symbolsolver.resolution.promotion; + +import java.util.Arrays; +import java.util.HashSet; + +import com.github.javaparser.resolution.promotion.ConditionalExprHandler; +import com.github.javaparser.resolution.types.ResolvedType; +import com.github.javaparser.symbolsolver.resolution.typeinference.TypeHelper; + +public class ReferenceConditionalExprHandler implements ConditionalExprHandler { + ResolvedType thenExpr; + ResolvedType elseExpr; + + public ReferenceConditionalExprHandler(ResolvedType thenExpr, ResolvedType elseExpr) { + this.thenExpr = thenExpr; + this.elseExpr = elseExpr; + } + + @Override + public ResolvedType resolveType() { + // If one of the second and third operands is of the null type and the type of the other is a reference type, then the type of the conditional expression is that reference type. + if (thenExpr.isNull()) { + return elseExpr; + } + if (elseExpr.isNull()) { + return thenExpr; + } + return TypeHelper.leastUpperBound(new HashSet<>(Arrays.asList(thenExpr, elseExpr))); + } +} \ No newline at end of file diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/Bound.java b/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/Bound.java similarity index 96% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/Bound.java rename to src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/Bound.java index d39885f..2849ed7 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/Bound.java +++ b/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/Bound.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -93,18 +93,16 @@ Optional isProperLowerBoundFor(InferenceVariable inferenceVari Optional partial = isProperLowerBound(); if (partial.isPresent() && partial.get().getInferenceVariable().equals(inferenceVariable)) { return partial; - } else { - return Optional.empty(); } + return Optional.empty(); } Optional isProperUpperBoundFor(InferenceVariable inferenceVariable) { Optional partial = isProperUpperBound(); if (partial.isPresent() && partial.get().getInferenceVariable().equals(inferenceVariable)) { return partial; - } else { - return Optional.empty(); } + return Optional.empty(); } /** diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/BoundSet.java b/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/BoundSet.java similarity index 99% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/BoundSet.java rename to src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/BoundSet.java index d2701fc..02fd98e 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/BoundSet.java +++ b/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/BoundSet.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -21,11 +21,11 @@ package com.github.javaparser.symbolsolver.resolution.typeinference; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration; +import com.github.javaparser.resolution.model.typesystem.ReferenceTypeImpl; import com.github.javaparser.resolution.types.ResolvedReferenceType; 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.bounds.CapturesBound; import com.github.javaparser.symbolsolver.resolution.typeinference.bounds.FalseBound; import com.github.javaparser.symbolsolver.resolution.typeinference.bounds.SameAsBound; @@ -708,7 +708,7 @@ public Optional performResolution(List vari boolean throwsBound = bounds.stream().anyMatch(b -> b.isThrowsBoundOn(alphaI)); if (Ti == null && throwsBound && properUpperBoundsAreAtMostExceptionThrowableAndObject(alphaI)) { - Ti = new ReferenceTypeImpl(typeSolver.solveType(JAVA_LANG_RUNTIME_EXCEPTION), typeSolver); + Ti = new ReferenceTypeImpl(typeSolver.solveType(JAVA_LANG_RUNTIME_EXCEPTION)); } // - Otherwise, where αi has proper upper bounds U1, ..., Uk, Ti = glb(U1, ..., Uk) (§5.1.10). diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ConstraintFormula.java b/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ConstraintFormula.java similarity index 99% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ConstraintFormula.java rename to src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ConstraintFormula.java index f9812f9..a0f5d8c 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ConstraintFormula.java +++ b/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ConstraintFormula.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ConstraintFormulaSet.java b/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ConstraintFormulaSet.java similarity index 95% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ConstraintFormulaSet.java rename to src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ConstraintFormulaSet.java index d568f84..a9225b4 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ConstraintFormulaSet.java +++ b/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ConstraintFormulaSet.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -21,7 +21,7 @@ package com.github.javaparser.symbolsolver.resolution.typeinference; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; +import com.github.javaparser.resolution.TypeSolver; import java.util.LinkedList; import java.util.List; diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ControlFlowLogic.java b/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ControlFlowLogic.java similarity index 98% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ControlFlowLogic.java rename to src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ControlFlowLogic.java index 74da87b..1519504 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ControlFlowLogic.java +++ b/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ControlFlowLogic.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -110,9 +110,8 @@ private List containedTryStmts(Statement statement) { private

boolean parentIs(Node node, Class

parentClass) { if (node.getParentNode().isPresent()) { return parentClass.isInstance(node.getParentNode().get()); - } else { - return false; } + return false; } // See JLS 14.21 @@ -167,10 +166,8 @@ public Boolean visit(IfStmt n, Void arg) { // An if-then-else statement can complete normally iff the then-statement can // complete normally or the else-statement can complete normally. return canCompleteNormally(n.getThenStmt()) || canCompleteNormally(n.getElseStmt().get()); - } else { - // An if-then statement can complete normally iff it is reachable. - return isReachable(n); } + return isReachable(n); } @Override diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ExpressionHelper.java b/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ExpressionHelper.java similarity index 93% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ExpressionHelper.java rename to src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ExpressionHelper.java index c71c55e..b8666cc 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ExpressionHelper.java +++ b/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ExpressionHelper.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -25,9 +25,9 @@ import com.github.javaparser.ast.expr.LambdaExpr; import com.github.javaparser.ast.stmt.BlockStmt; import com.github.javaparser.ast.type.UnknownType; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.types.ResolvedType; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; import java.util.List; diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/InferenceVariable.java b/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/InferenceVariable.java similarity index 98% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/InferenceVariable.java rename to src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/InferenceVariable.java index a4527e9..12370b6 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/InferenceVariable.java +++ b/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/InferenceVariable.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/InferenceVariableSubstitution.java b/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/InferenceVariableSubstitution.java similarity index 97% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/InferenceVariableSubstitution.java rename to src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/InferenceVariableSubstitution.java index 42fc05d..6e6a051 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/InferenceVariableSubstitution.java +++ b/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/InferenceVariableSubstitution.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/Instantiation.java b/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/Instantiation.java similarity index 97% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/Instantiation.java rename to src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/Instantiation.java index e941c31..9ffdf34 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/Instantiation.java +++ b/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/Instantiation.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/InstantiationSet.java b/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/InstantiationSet.java similarity index 98% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/InstantiationSet.java rename to src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/InstantiationSet.java index 6bf4910..1677b84 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/InstantiationSet.java +++ b/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/InstantiationSet.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * diff --git a/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/LeastUpperBoundLogic.java b/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/LeastUpperBoundLogic.java new file mode 100755 index 0000000..aebf49f --- /dev/null +++ b/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/LeastUpperBoundLogic.java @@ -0,0 +1,485 @@ +package com.github.javaparser.symbolsolver.resolution.typeinference; + +import java.util.*; +import java.util.stream.Collectors; + +import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration; +import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration; +import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration.Bound; +import com.github.javaparser.resolution.model.typesystem.NullType; +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.resolution.types.ResolvedWildcard.BoundType; +import com.github.javaparser.resolution.types.parametrization.ResolvedTypeParametersMap.Builder; +import com.github.javaparser.utils.Pair; +import com.google.common.collect.Lists; +import com.google.common.collect.Multimap; +import com.google.common.collect.Multimaps; +import com.google.common.collect.Sets; + +public class LeastUpperBoundLogic { + + private Set> lubCache = new HashSet<>(); + + public static LeastUpperBoundLogic of() { + return new LeastUpperBoundLogic(); + } + + private LeastUpperBoundLogic() {} + + /** + * See JLS 4.10.4. Least Upper Bound. + */ + public ResolvedType lub(Set types) { + if (types.isEmpty()) { + throw new IllegalArgumentException(); + } + + // The direct supertypes of the null type are all reference types other than the null type itself. + // One way to handle this case is to remove the type null from the list of types. + Set resolvedTypes = types.stream().filter(type -> !(type instanceof NullType)).collect(Collectors.toSet()); + + + // The least upper bound, or "lub", of a set of reference types is a shared supertype that is more specific + // than any other shared supertype (that is, no other shared supertype is a subtype of the least upper bound). + // This type, lub(U1, ..., Uk), is determined as follows. + // + // If k = 1, then the lub is the type itself: lub(U) = U. + + if (resolvedTypes.size() == 1) { + return resolvedTypes.stream().findFirst().get(); + } + + // can we have primitive types? + + // + // Otherwise: + // + // For each Ui (1 ≤ i ≤ k): + // + // Let ST(Ui) be the set of supertypes of Ui. + + List> supertypes = supertypes(resolvedTypes); + + // + // Let EST(Ui), the set of erased supertypes of Ui, be: + // + // EST(Ui) = { |W| | W in ST(Ui) } where |W| is the erasure of W. + // + // The reason for computing the set of erased supertypes is to deal with situations where the set of types + // includes several distinct parameterizations of a generic type. + // + // For example, given List and List, simply intersecting the sets ST(List) = { + // List, Collection, Object } and ST(List) = { List, Collection, Object + // } would yield a set { Object }, and we would have lost track of the fact that the upper bound can safely be + // assumed to be a List. + // + // In contrast, intersecting EST(List) = { List, Collection, Object } and EST(List) = { List, + // Collection, Object } yields { List, Collection, Object }, which will eventually enable us to produce + // List. + // + + List> erasedSupertypes = erased(supertypes); + + // Let EC, the erased candidate set for U1 ... Uk, be the intersection of all the sets EST(Ui) (1 ≤ i ≤ k). + // + + List erasedCandidates = intersection(erasedSupertypes); + + // Let MEC, the minimal erased candidate set for U1 ... Uk, be: + // + // MEC = { V | V in EC, and for all W ≠ V in EC, it is not the case that W <: V } + // + // Because we are seeking to infer more precise types, we wish to filter out any candidates that are supertypes + // of other candidates. + // This is what computing MEC accomplishes. + // In our running example, we had EC = { List, Collection, Object }, so MEC = { List }. + + List minimalErasedCandidates = minimalCandidates(erasedCandidates); + if (minimalErasedCandidates.isEmpty()) { + return null; + } + + // The next step is to recover type arguments for the erased types in MEC. + // + // For any element G of MEC that is a generic type: + // + // Let the "relevant" parameterizations of G, Relevant(G), be: + // + // Relevant(G) = { V | 1 ≤ i ≤ k: V in ST(Ui) and V = G<...> } + // + // In our running example, the only generic element of MEC is List, and Relevant(List) = { List, + // List }. + + Multimap relevantParameterizations = relevantParameterizations( + minimalErasedCandidates, supertypes); + + // We will now seek to find a type argument for List that contains (§4.5.1) both String and Object. + // + // This is done by means of the least containing parameterization (lcp) operation defined below. + // The first line defines lcp() on a set, such as Relevant(List), as an operation on a list of the elements of + // the set. + // The next line defines the operation on such lists, as a pairwise reduction on the elements of the list. + // The third line is the definition of lcp() on pairs of parameterized types, + // which in turn relies on the notion of least containing type argument (lcta). + // lcta() is defined for all possible cases. + // + // Let the "candidate" parameterization of G, Candidate(G), be the most specific parameterization of the + // generic type G that contains all the relevant parameterizations of G: + // + // Candidate(G) = lcp(Relevant(G)) + // + // where lcp(), the least containing invocation, is: + // + // lcp(S) = lcp(e1, ..., en) where ei (1 ≤ i ≤ n) in S + // + // lcp(e1, ..., en) = lcp(lcp(e1, e2), e3, ..., en) + // + // lcp(G, G) = G + // + // lcp(G) = G + // + // and where lcta(), the least containing type argument, is: (assuming U and V are types) + // + // lcta(U, V) = U if U = V, otherwise ? extends lub(U, V) + // + // lcta(U, ? extends V) = ? extends lub(U, V) + // + // lcta(U, ? super V) = ? super glb(U, V) + // + // lcta(? extends U, ? extends V) = ? extends lub(U, V) + // + // lcta(? extends U, ? super V) = U if U = V, otherwise ? + // + // lcta(? super U, ? super V) = ? super glb(U, V) + // + // lcta(U) = ? if U's upper bound is Object, otherwise ? extends lub(U,Object) + // + // and where glb() is as defined in §5.1.10. + // + // Let lub(U1 ... Uk) be: + // + // Best(W1) & ... & Best(Wr) + // + // where Wi (1 ≤ i ≤ r) are the elements of MEC, the minimal erased candidate set of U1 ... Uk; + // + // and where, if any of these elements are generic, we use the candidate parameterization (so as to recover + // type arguments): + // + // Best(X) = Candidate(X) if X is generic; X otherwise. + // + // Strictly speaking, this lub() function only approximates a least upper bound. + // Formally, there may exist some other type T such that all of U1 ... Uk are subtypes of T and T is a subtype + // of lub(U1, ..., Uk). + // However, a compiler for the Java programming language must implement lub() as specified above. + // + + ResolvedType erasedBest = best(minimalErasedCandidates); + + // It is possible that the lub() function yields an infinite type. + // This is permissible, and a compiler for the Java programming language must recognize such situations and + // represent them appropriately using cyclic data structures. + // + // The possibility of an infinite type stems from the recursive calls to lub(). + // Readers familiar with recursive types should note that an infinite type is not the same as a recursive type. + Collection erasedTypeParameterizations = relevantParameterizations.get(erasedBest); + if (erasedTypeParameterizations != null && !erasedTypeParameterizations.contains(erasedBest)) { + Set searchedTypes = new HashSet<>(resolvedTypes); + // if we already encountered these types in LUB calculation, + // we interrupt calculation and use the erasure of the parameterized type instead + if (!lubCache.contains(searchedTypes)) { + lubCache.add(searchedTypes); + return leastContainingParameterization(new ArrayList<>(erasedTypeParameterizations)); + } + } + return erasedBest; + } + + private List> supertypes(Set types) { + return types.stream() + .map(type -> supertypes(type).stream().collect(Collectors.toCollection(LinkedHashSet::new))) + .collect(Collectors.toList()); + } + + private Set supertypes(ResolvedType type) { + // How to deal with other types like for example type variable? + return type.isReferenceType() ? supertypes(type.asReferenceType()) + : new LinkedHashSet<>(); + } + + private Set supertypes(ResolvedReferenceType type) { + Set supertypes = new LinkedHashSet<>(); + supertypes.add(type); + supertypes.addAll(type.getAllAncestors()); + return supertypes; + } + + private List> erased(List> typeSets) { + return typeSets.stream() + .map(set -> set.stream().map(ResolvedType::erasure) + .collect(Collectors.toCollection(LinkedHashSet::new))) + .collect(Collectors.toList()); + } + + private List intersection(List> supertypes) { + return new ArrayList<>(supertypes.stream().reduce(union(supertypes), Sets::intersection)); + } + + private Set union(List> supertypes) { + return supertypes.stream().flatMap(Collection::stream).collect(Collectors.toCollection(LinkedHashSet::new)); + } + + /** + * Let MEC, the minimal erased candidate set for U1 ... Uk, be: + * MEC = { V | V in EC, and for all W != V in EC, it is not the case that W <: V } + * + * @param erasedCandidates + * @return + */ + private List minimalCandidates(List erasedCandidates) { + List results = new ArrayList<>(); + for (ResolvedType v : erasedCandidates) { + if (erasedCandidates.stream().noneMatch(w -> !w.equals(v) && v.isAssignableBy(w))) { + results.add(v); + } + } + return results; + } + + /** + * For any element G of MEC that is a generic type, let the "relevant" parameterizations of G, Relevant(G), be: + * Relevant(G) = { V | 1 ≤ i ≤ k: V in ST(Ui) and V = G<...> } + * + * @param minimalErasedCandidates MEC + * @param supertypes + * @return the set of known parameterizations for each generic type G of MEC + */ + private Multimap relevantParameterizations(List minimalErasedCandidates, + List> supertypes) { + Multimap result = Multimaps.newSetMultimap(new HashMap<>(), LinkedHashSet::new); + for (Set supertypesSet : supertypes) { + for (ResolvedType supertype : supertypesSet) { + ResolvedType erasedSupertype = supertype.erasure(); + if (minimalErasedCandidates.contains(erasedSupertype)) { + result.put(erasedSupertype, supertype); + } + } + } + return result; + } + + private ResolvedType best(List minimalCandidates) { + Collections.sort(minimalCandidates, (t1, t2) -> { + // Sort minimal candidates by name with classes before interfaces, to guarantee always the same type is + // returned when approximated. + ResolvedReferenceTypeDeclaration t1Symbol = t1.asReferenceType().getTypeDeclaration().get(); + ResolvedReferenceTypeDeclaration t2Symbol = t2.asReferenceType().getTypeDeclaration().get(); + if (t1Symbol.isInterface() && t2Symbol.isInterface()) { + return t1Symbol.getQualifiedName().compareTo(t2Symbol.getQualifiedName()); + } + if (t1Symbol.isInterface()) { + return 1; + } + if (t2Symbol.isInterface()) { + return -1; + } + return t1Symbol.getQualifiedName().compareTo(t2Symbol.getQualifiedName()); + }); + return minimalCandidates.get(0); + } + + /* + * Let the "candidate" parameterization of G, Candidate(G), be the most specific parameterization of the generic + * type G that contains all * the relevant parameterizations of G: + * Candidate(G) = lcp(Relevant(G)), + * where lcp(), the least containing invocation, is: + * lcp(S) = lcp(e1, ..., en) where ei (1 ≤ i ≤ n) in S + * lcp(e1, ..., en) = lcp(lcp(e1, e2), e3, ..., en) + */ + private ResolvedType leastContainingParameterization(List types) { + if (types.size() == 1) { + return types.get(0); + } + ResolvedType type1 = types.get(0); + ResolvedType type2 = types.get(1); + ResolvedType reduction = leastContainingTypeArgument(type1, type2); + + List reducedList = Lists.newArrayList(reduction); + reducedList.addAll(types.subList(2, types.size())); + + return leastContainingParameterization(reducedList); + } + + /* + * lcp(G, G) = G + * lcp(G) = G + */ + private ResolvedType leastContainingTypeArgument(ResolvedType type1, ResolvedType type2) { + + TypeSubstitution substitution1 = substitution(type1.asReferenceType().getTypeParametersMap()); + TypeSubstitution substitution2 = substitution(type2.asReferenceType().getTypeParametersMap()); + + TypeSubstitution typeSubstitution = TypeSubstitution.empty(); + for (ResolvedTypeParameterDeclaration typeDecl : substitution1.typeParameterDeclarations()) { + ResolvedType subs1 = substitution1.substitutedType(typeDecl); + ResolvedType subs2 = substitution2.substitutedType(typeDecl); + subs1 = isSubstituable(typeDecl, subs1) && subs2.isReferenceType() ? subs2 : subs1; + subs2 = isSubstituable(typeDecl, subs2) && subs1.isReferenceType() ? subs1 : subs2; + ResolvedType newType = lcta(subs1, subs2); + typeSubstitution.withPair(typeDecl, newType); + } + + return typeSubstitution.isEmpty() ? lcta(type1, type2) : substituteType(type1, typeSubstitution); + } + + /* + * In case where the {@code ResolvedType} is an unbounded type variable, + * then the type can be can substituted by other reference type. For example + * the result of lcta(List, List) should be in List. + */ + private boolean isSubstituable(ResolvedTypeParameterDeclaration typeDecl, ResolvedType type) { + return type.isTypeVariable() && (!typeDecl.hasBound() || boundedAsObject(typeDecl)); + } + + private boolean boundedAsObject(ResolvedTypeParameterDeclaration typeDecl) { + List bounds = typeDecl.getBounds(); + return bounds.size() == 1 && bounds.get(0).getType().equals(typeDecl.object()); + } + + private ResolvedType substituteType(ResolvedType type1, TypeSubstitution typeSubstitution) { + Builder typeParametersMapBuilder = type1.asReferenceType().typeParametersMap().toBuilder(); + for (ResolvedTypeParameterDeclaration rtpd : typeSubstitution.typeParameterDeclarations) { + typeParametersMapBuilder.setValue(rtpd, typeSubstitution.substitutedType(rtpd)); + } + return type1.asReferenceType().deriveTypeParameters(typeParametersMapBuilder.build()); + } + + /* + * This is a data container that maps typeParameterDeclarations with resolvedTypes + */ + static class TypeSubstitution { + + private List typeParameterDeclarations; + private List types; + + private final static TypeSubstitution EMPTY = new TypeSubstitution(); + + public static TypeSubstitution empty() { + return new TypeSubstitution(); + } + + private TypeSubstitution() { + this.typeParameterDeclarations = new LinkedList<>(); + this.types = new LinkedList<>(); + } + + public boolean isEmpty() { + return this == EMPTY; + } + + public void withPair(ResolvedTypeParameterDeclaration typeParameterDeclaration, ResolvedType type) { + this.typeParameterDeclarations.add(typeParameterDeclaration); + this.types.add(type); + } + + public List typeParameterDeclarations() { + return typeParameterDeclarations; + } + + public ResolvedType substitutedType(ResolvedTypeParameterDeclaration typeDecl) { + int index = typeParameterDeclarations.indexOf(typeDecl); + return index > -1 ? types.get(index) : typeDecl.object(); + } + + } + + private TypeSubstitution substitution(List> pairs) { + TypeSubstitution substitution = TypeSubstitution.empty(); + pairs.stream().forEach(pair -> substitution.withPair(pair.a, pair.b)); + return substitution; + } + + /* + * the least containing type argument, is: (assuming U and V are types) + * lcta(U, V) = U if U = V, otherwise ? extends lub(U, V) + * lcta(U, ? extends V) = ? extends lub(U, V) + * lcta(U, ? super V) = ? super glb(U, V) + * lcta(? extends U, ? extends V) = ? extends lub(U, V) + * lcta(? extends U, ? super V) = U if U = V, otherwise ? + * lcta(? super U, ? super V) = ? super glb(U, V) + * lcta(U) = ? if U's upper bound is Object, otherwise ? extends lub(U,Object) + * and where glb() is as defined in §5.1.10. + */ + private ResolvedType lcta(ResolvedType type1, ResolvedType type2) { + boolean isWildcard1 = type1.isWildcard(); + boolean isWildcard2 = type2.isWildcard(); + + ResolvedType result; + if (type1.equals(type2)) { + // lcta(U, V) = U if U = V + result = type1; + } else if (isWildcard1 && isWildcard2) { + result = lctaBothWildcards(type1.asWildcard(), type2.asWildcard()); + } else if (isWildcard1 ^ isWildcard2) { + ResolvedType rawType = isWildcard1 ? type2 : type1; + ResolvedWildcard wildcardType = (ResolvedWildcard) (isWildcard1 ? type1 : type2); + result = lctaOneWildcard(rawType, wildcardType); + } else { + // otherwise lcta(U, V) = ? extends lub(U, V) + result = lctaNoWildcard(type1, type2); + } + return result; + } + + /* + * lcta(U, V) = U if U = V, otherwise ? extends lub(U, V) + */ + private ResolvedType lctaNoWildcard(ResolvedType type1, ResolvedType type2) { + ResolvedType lub = lub(toSet(type1, type2)); + return bound(lub, BoundType.EXTENDS); + } + + private ResolvedType lctaOneWildcard(ResolvedType rawType, ResolvedWildcard wildcardType) { + if (wildcardType.isUpperBounded()) { + ResolvedType glb = TypeHelper.glb(toSet(rawType, wildcardType.getBoundedType())); + return bound(glb, BoundType.SUPER); + } + ResolvedType lub = lub(toSet(rawType, wildcardType.getBoundedType())); + return bound(lub, BoundType.EXTENDS); + } + + private ResolvedType lctaBothWildcards(ResolvedWildcard type1, ResolvedWildcard type2) { + // lcta(? super U, ? super V) = ? super glb(U, V) + if (type1.isUpperBounded() && type2.isUpperBounded()) { + ResolvedType glb = TypeHelper.glb(toSet(type1.getBoundedType(), type2.getBoundedType())); + return bound(glb, BoundType.SUPER); + } + // lcta(? extends U, ? extends V) = ? extends lub(U, V) + if (type1.isLowerBounded() && type2.isLowerBounded()) { + ResolvedType lub = lub(toSet(type1.getBoundedType(), type2.getBoundedType())); + return bound(lub, BoundType.EXTENDS); + } + // lcta(? extends U, ? super V) = U if U = V, otherwise ? + if (type1.getBoundedType().equals(type2.getBoundedType())) { + return type1.getBoundedType(); + } + return ResolvedWildcard.UNBOUNDED; + } + + // Replace all type parameters in generic types with their bounds or Object if the type parameters are unbounded. + + /* + * Returns the corresponding wildcard type or Object if we want to build a wildcard type like {@code ? extends + * Object} + */ + private ResolvedType bound(ResolvedType type, BoundType boundType) { + if (type != null && type.isReferenceType() && type.asReferenceType().isJavaLangObject()) return type; + return boundType.equals(BoundType.EXTENDS) ? ResolvedWildcard.extendsBound(type) + : ResolvedWildcard.superBound(type); + } + + private Set toSet(ResolvedType... resolvedTypes) { + return new HashSet<>(Arrays.asList(resolvedTypes)); + } +} diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/MethodType.java b/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/MethodType.java similarity index 98% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/MethodType.java rename to src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/MethodType.java index 8d4b26d..6c7fd70 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/MethodType.java +++ b/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/MethodType.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ProperLowerBound.java b/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ProperLowerBound.java similarity index 97% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ProperLowerBound.java rename to src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ProperLowerBound.java index f255136..c9f4156 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ProperLowerBound.java +++ b/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ProperLowerBound.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ProperUpperBound.java b/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ProperUpperBound.java similarity index 97% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ProperUpperBound.java rename to src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ProperUpperBound.java index a229f48..0a5b446 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ProperUpperBound.java +++ b/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ProperUpperBound.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/Substitution.java b/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/Substitution.java similarity index 97% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/Substitution.java rename to src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/Substitution.java index 2f6959b..021cfd5 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/Substitution.java +++ b/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/Substitution.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/TypeHelper.java b/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/TypeHelper.java similarity index 63% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/TypeHelper.java rename to src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/TypeHelper.java index 813b841..4b7e654 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/TypeHelper.java +++ b/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/TypeHelper.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -21,21 +21,22 @@ package com.github.javaparser.symbolsolver.resolution.typeinference; +import java.util.*; + import com.github.javaparser.ast.expr.Expression; import com.github.javaparser.ast.expr.LambdaExpr; import com.github.javaparser.resolution.MethodUsage; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration; import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration; +import com.github.javaparser.resolution.logic.FunctionalInterfaceLogic; +import com.github.javaparser.resolution.model.SymbolReference; +import com.github.javaparser.resolution.model.typesystem.LazyType; +import com.github.javaparser.resolution.model.typesystem.ReferenceTypeImpl; import com.github.javaparser.resolution.types.*; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade; -import com.github.javaparser.symbolsolver.logic.FunctionalInterfaceLogic; -import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; -import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl; import com.github.javaparser.utils.Pair; -import java.util.*; - /** * The term "type" is used loosely in this chapter to include type-like syntax that contains inference variables. * @@ -58,13 +59,15 @@ public static boolean isProperType(ResolvedType type) { ResolvedReferenceType referenceType = (ResolvedReferenceType) type; return referenceType.typeParametersValues().stream().allMatch(it -> isProperType(it)); } + if (type instanceof LazyType) { + return type.asReferenceType().typeParametersValues().stream().allMatch(it -> isProperType(it)); + } if (type instanceof ResolvedWildcard) { ResolvedWildcard wildcard = (ResolvedWildcard)type; if (wildcard.isBounded()) { return isProperType(wildcard.getBoundedType()); - } else { - return true; } + return true; } if (type.isPrimitive()) { return true; @@ -159,11 +162,11 @@ public static boolean isCompatibleInALooseInvocationContext(ResolvedType s, Reso public static ResolvedType toBoxedType(ResolvedPrimitiveType primitiveType) { throw new UnsupportedOperationException(); } - + // get the resolved boxed type of the specified primitive type public static ResolvedType toBoxedType(ResolvedPrimitiveType primitiveType, TypeSolver typeSolver ) { SymbolReference typeDeclaration = typeSolver.tryToSolveType(primitiveType.getBoxTypeQName()); - return new ReferenceTypeImpl(typeDeclaration.getCorrespondingDeclaration(), typeSolver); + return new ReferenceTypeImpl(typeDeclaration.getCorrespondingDeclaration()); } public static boolean areCompatibleThroughWideningReferenceConversion(ResolvedType s, ResolvedType t) { @@ -177,9 +180,8 @@ public static boolean areCompatibleThroughWideningReferenceConversion(ResolvedTy public static boolean areCompatibleThroughWideningPrimitiveConversion(ResolvedType s, ResolvedType t) { if (s.isPrimitive() && t.isPrimitive()) { return s.isAssignableBy(t); - } else { - return false; } + return false; } public static Set usedInferenceVariables(ResolvedType type) { @@ -198,105 +200,12 @@ public static Set usedInferenceVariables(ResolvedType type) { /** * See JLS 4.10.4. Least Upper Bound. + * The least upper bound, or "lub", of a set of reference types is a shared supertype that is more specific than + * any other shared supertype (that is, no other shared supertype is a subtype of the least upper bound). */ public static ResolvedType leastUpperBound(Set types) { - if (types.isEmpty()) { - throw new IllegalArgumentException(); - } - - // The least upper bound, or "lub", of a set of reference types is a shared supertype that is more specific than - // any other shared supertype (that is, no other shared supertype is a subtype of the least upper bound). - // This type, lub(U1, ..., Uk), is determined as follows. - // - // If k = 1, then the lub is the type itself: lub(U) = U. - - if (types.size() == 1) { - return types.stream().findFirst().get(); - } - - // - //Otherwise: - // - //For each Ui (1 ≤ i ≤ k): - // - //Let ST(Ui) be the set of supertypes of Ui. - // - //Let EST(Ui), the set of erased supertypes of Ui, be: - // - //EST(Ui) = { |W| | W in ST(Ui) } where |W| is the erasure of W. - // - //The reason for computing the set of erased supertypes is to deal with situations where the set of types includes several distinct parameterizations of a generic type. - // - //For example, given List and List, simply intersecting the sets ST(List) = { List, Collection, Object } and ST(List) = { List, Collection, Object } would yield a set { Object }, and we would have lost track of the fact that the upper bound can safely be assumed to be a List. - // - //In contrast, intersecting EST(List) = { List, Collection, Object } and EST(List) = { List, Collection, Object } yields { List, Collection, Object }, which will eventually enable us to produce List. - // - //Let EC, the erased candidate set for U1 ... Uk, be the intersection of all the sets EST(Ui) (1 ≤ i ≤ k). - // - //Let MEC, the minimal erased candidate set for U1 ... Uk, be: - // - //MEC = { V | V in EC, and for all W ≠ V in EC, it is not the case that W <: V } - // - //Because we are seeking to infer more precise types, we wish to filter out any candidates that are supertypes of other candidates. This is what computing MEC accomplishes. In our running example, we had EC = { List, Collection, Object }, so MEC = { List }. The next step is to recover type arguments for the erased types in MEC. - // - //For any element G of MEC that is a generic type: - // - //Let the "relevant" parameterizations of G, Relevant(G), be: - // - //Relevant(G) = { V | 1 ≤ i ≤ k: V in ST(Ui) and V = G<...> } - // - //In our running example, the only generic element of MEC is List, and Relevant(List) = { List, List }. We will now seek to find a type argument for List that contains (§4.5.1) both String and Object. - // - //This is done by means of the least containing parameterization (lcp) operation defined below. The first line defines lcp() on a set, such as Relevant(List), as an operation on a list of the elements of the set. The next line defines the operation on such lists, as a pairwise reduction on the elements of the list. The third line is the definition of lcp() on pairs of parameterized types, which in turn relies on the notion of least containing type argument (lcta). lcta() is defined for all possible cases. - // - //Let the "candidate" parameterization of G, Candidate(G), be the most specific parameterization of the generic type G that contains all the relevant parameterizations of G: - // - //Candidate(G) = lcp(Relevant(G)) - // - //where lcp(), the least containing invocation, is: - // - //lcp(S) = lcp(e1, ..., en) where ei (1 ≤ i ≤ n) in S - // - //lcp(e1, ..., en) = lcp(lcp(e1, e2), e3, ..., en) - // - //lcp(G, G) = G - // - //lcp(G) = G - // - //and where lcta(), the least containing type argument, is: (assuming U and V are types) - // - //lcta(U, V) = U if U = V, otherwise ? extends lub(U, V) - // - //lcta(U, ? extends V) = ? extends lub(U, V) - // - //lcta(U, ? super V) = ? super glb(U, V) - // - //lcta(? extends U, ? extends V) = ? extends lub(U, V) - // - //lcta(? extends U, ? super V) = U if U = V, otherwise ? - // - //lcta(? super U, ? super V) = ? super glb(U, V) - // - //lcta(U) = ? if U's upper bound is Object, otherwise ? extends lub(U,Object) - // - //and where glb() is as defined in §5.1.10. - // - //Let lub(U1 ... Uk) be: - // - //Best(W1) & ... & Best(Wr) - // - //where Wi (1 ≤ i ≤ r) are the elements of MEC, the minimal erased candidate set of U1 ... Uk; - // - //and where, if any of these elements are generic, we use the candidate parameterization (so as to recover type arguments): - // - //Best(X) = Candidate(X) if X is generic; X otherwise. - // - //Strictly speaking, this lub() function only approximates a least upper bound. Formally, there may exist some other type T such that all of U1 ... Uk are subtypes of T and T is a subtype of lub(U1, ..., Uk). However, a compiler for the Java programming language must implement lub() as specified above. - // - //It is possible that the lub() function yields an infinite type. This is permissible, and a compiler for the Java programming language must recognize such situations and represent them appropriately using cyclic data structures. - // - //The possibility of an infinite type stems from the recursive calls to lub(). Readers familiar with recursive types should note that an infinite type is not the same as a recursive type - throw new UnsupportedOperationException(); + LeastUpperBoundLogic logic = LeastUpperBoundLogic.of(); + return logic.lub(types); } /** @@ -318,13 +227,7 @@ public static Pair groundTargetTypeOfLambda(LambdaExpr la used18_5_3 = true; throw new UnsupportedOperationException(); } - - // - If T is a wildcard-parameterized functional interface type and the lambda expression is implicitly typed, - // then the ground target type is the non-wildcard parameterization (§9.9) of T. - - else { - return new Pair<>(nonWildcardParameterizationOf(T.asReferenceType(), typeSolver), used18_5_3); - } + return new Pair<>(nonWildcardParameterizationOf(T.asReferenceType(), typeSolver), used18_5_3); } // - Otherwise, the ground target type is T. @@ -344,7 +247,7 @@ private static ResolvedReferenceType nonWildcardParameterizationOf(ResolvedRefer // Let P1...Pn be the type parameters of I with corresponding bounds B1...Bn. For all i (1 ≤ i ≤ n), // Ti is derived according to the form of Ai: - ResolvedReferenceType object = new ReferenceTypeImpl(typeSolver.getSolvedJavaLangObject(), typeSolver); + ResolvedReferenceType object = new ReferenceTypeImpl(typeSolver.getSolvedJavaLangObject()); for (int i=0;i mu = FunctionalInterfaceLogic.getFunctionalMethod(type); if (mu.isPresent()) { return MethodType.fromMethodUsage(mu.get()); - } else { - throw new IllegalArgumentException(); } + throw new IllegalArgumentException(); } /** diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/TypeInference.java b/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/TypeInference.java similarity index 98% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/TypeInference.java rename to src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/TypeInference.java index ff91661..6f6e724 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/TypeInference.java +++ b/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/TypeInference.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -21,24 +21,24 @@ package com.github.javaparser.symbolsolver.resolution.typeinference; +import java.util.LinkedList; +import java.util.List; +import java.util.Optional; + import com.github.javaparser.ast.expr.*; import com.github.javaparser.ast.type.UnknownType; import com.github.javaparser.resolution.MethodUsage; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.ResolvedInterfaceDeclaration; import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration; import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration; +import com.github.javaparser.resolution.model.typesystem.ReferenceTypeImpl; import com.github.javaparser.resolution.types.ResolvedType; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; -import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl; import com.github.javaparser.symbolsolver.resolution.typeinference.bounds.SubtypeOfBound; import com.github.javaparser.symbolsolver.resolution.typeinference.bounds.ThrowsBound; import com.github.javaparser.symbolsolver.resolution.typeinference.constraintformulas.ExpressionCompatibleWithType; -import java.util.LinkedList; -import java.util.List; -import java.util.Optional; - /** * The API exposed by the TypeInference subsystem. * @@ -54,7 +54,7 @@ public TypeInference(TypeSolver typeSolver) { throw new NullPointerException(); } this.typeSolver = typeSolver; - this.object = new ReferenceTypeImpl(typeSolver.getSolvedJavaLangObject(), typeSolver); + this.object = new ReferenceTypeImpl(typeSolver.getSolvedJavaLangObject()); } /// @@ -66,9 +66,8 @@ public static MethodUsage toMethodUsage(MethodCallExpr call, ResolvedMethodDecla Optional instantiationSetOpt = typeInference.instantiationInference(call, methodDeclaration); if (instantiationSetOpt.isPresent()) { return instantiationSetToMethodUsage(methodDeclaration, instantiationSetOpt.get()); - } else { - throw new IllegalArgumentException(); } + throw new IllegalArgumentException(); } /// @@ -567,8 +566,7 @@ private BoundSet boundSetup(List typeParameter } private boolean appearInThrowsClause(ResolvedTypeParameterDeclaration p, ResolvedMethodDeclaration methodDeclaration) { - for (int j=0;j tryToSolveType(String n // java.lang.NoClassDefFoundError: com/github/javaparser/printer/ConcreteSyntaxModel // (wrong name: com/github/javaparser/printer/concretesyntaxmodel) // note that this exception seems to be thrown only on certain platform (mac yes, linux no) - return SymbolReference.unsolved(ResolvedReferenceTypeDeclaration.class); + return SymbolReference.unsolved(); } catch (ClassNotFoundException e) { // it could be an inner class int lastDot = name.lastIndexOf('.'); if (lastDot == -1) { - return SymbolReference.unsolved(ResolvedReferenceTypeDeclaration.class); - } else { - String parentName = name.substring(0, lastDot); - String childName = name.substring(lastDot + 1); - SymbolReference parent = tryToSolveType(parentName); - if (parent.isSolved()) { + return SymbolReference.unsolved(); + } + String parentName = name.substring(0, lastDot); + String childName = name.substring(lastDot + 1); + SymbolReference parent = tryToSolveType(parentName); + if (parent.isSolved()) { Optional innerClass = parent.getCorrespondingDeclaration() .internalTypes() .stream().filter(it -> it.getName().equals(childName)).findFirst(); return innerClass.map(SymbolReference::solved) - .orElseGet(() -> SymbolReference.unsolved(ResolvedReferenceTypeDeclaration.class)); - } else { - return SymbolReference.unsolved(ResolvedReferenceTypeDeclaration.class); + .orElseGet(() -> SymbolReference.unsolved()); } - } + return SymbolReference.unsolved(); } } else { - return SymbolReference.unsolved(ResolvedReferenceTypeDeclaration.class); + return SymbolReference.unsolved(); } } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/CombinedTypeSolver.java b/src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/CombinedTypeSolver.java similarity index 95% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/CombinedTypeSolver.java rename to src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/CombinedTypeSolver.java index dc79f15..1242641 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/CombinedTypeSolver.java +++ b/src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/CombinedTypeSolver.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -21,12 +21,12 @@ package com.github.javaparser.symbolsolver.resolution.typesolvers; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.UnsolvedSymbolException; import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration; +import com.github.javaparser.resolution.model.SymbolReference; import com.github.javaparser.symbolsolver.cache.Cache; -import com.github.javaparser.symbolsolver.cache.NoCache; -import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; +import com.github.javaparser.symbolsolver.cache.InMemoryCache; import java.util.*; import java.util.function.Predicate; @@ -72,7 +72,7 @@ public CombinedTypeSolver(Iterable elements) { /** @see #exceptionHandler */ public CombinedTypeSolver(Predicate exceptionHandler, Iterable elements) { - this(exceptionHandler, elements, NoCache.create()); + this(exceptionHandler, elements, InMemoryCache.create()); } /** @@ -171,7 +171,7 @@ public SymbolReference tryToSolveType(String n } // When unable to solve, cache the value with unsolved symbol - SymbolReference unsolvedSymbol = SymbolReference.unsolved(ResolvedReferenceTypeDeclaration.class); + SymbolReference unsolvedSymbol = SymbolReference.unsolved(); typeCache.put(name, unsolvedSymbol); return unsolvedSymbol; } @@ -181,9 +181,8 @@ public ResolvedReferenceTypeDeclaration solveType(String name) throws UnsolvedSy SymbolReference res = tryToSolveType(name); if (res.isSolved()) { return res.getCorrespondingDeclaration(); - } else { - throw new UnsolvedSymbolException(name); } + throw new UnsolvedSymbolException(name); } /** diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/JarTypeSolver.java b/src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/JarTypeSolver.java similarity index 96% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/JarTypeSolver.java rename to src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/JarTypeSolver.java index 48be06a..ff4aec1 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/JarTypeSolver.java +++ b/src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/JarTypeSolver.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -21,11 +21,11 @@ package com.github.javaparser.symbolsolver.resolution.typesolvers; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.UnsolvedSymbolException; import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration; +import com.github.javaparser.resolution.model.SymbolReference; import com.github.javaparser.symbolsolver.javassistmodel.JavassistFactory; -import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; import javassist.ClassPool; import javassist.NotFoundException; @@ -258,7 +258,7 @@ public SymbolReference tryToSolveType(String n String storedKey = knownClasses.get(name); // If the name is not registered in the list we can safely say is not solvable here if (storedKey == null) { - return SymbolReference.unsolved(ResolvedReferenceTypeDeclaration.class); + return SymbolReference.unsolved(); } try { @@ -278,9 +278,8 @@ public ResolvedReferenceTypeDeclaration solveType(String name) throws UnsolvedSy SymbolReference ref = tryToSolveType(name); if (ref.isSolved()) { return ref.getCorrespondingDeclaration(); - } else { - throw new UnsolvedSymbolException(name); } + throw new UnsolvedSymbolException(name); } } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/JavaParserTypeSolver.java b/src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/JavaParserTypeSolver.java similarity index 97% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/JavaParserTypeSolver.java rename to src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/JavaParserTypeSolver.java index 78b840e..08d8813 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/JavaParserTypeSolver.java +++ b/src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/JavaParserTypeSolver.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -24,13 +24,13 @@ import com.github.javaparser.JavaParser; import com.github.javaparser.ParserConfiguration; import com.github.javaparser.ast.CompilationUnit; +import com.github.javaparser.resolution.Navigator; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration; +import com.github.javaparser.resolution.model.SymbolReference; import com.github.javaparser.symbolsolver.cache.Cache; import com.github.javaparser.symbolsolver.cache.GuavaCache; -import com.github.javaparser.symbolsolver.javaparser.Navigator; import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade; -import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; import com.github.javaparser.symbolsolver.utils.FileUtils; import com.google.common.cache.CacheBuilder; @@ -190,7 +190,7 @@ private Optional parse(Path srcFile) { // JavaParser only allow one parse at time. synchronized (javaParser) { - Optional compilationUnit = javaParser.parse(COMPILATION_UNIT, provider(srcFile)) + Optional compilationUnit = javaParser.parse(COMPILATION_UNIT, provider(srcFile, javaParser.getParserConfiguration().getCharacterEncoding())) .getResult() .map(cu -> cu.setStorage(srcFile)); parsedFiles.put(srcFile.toAbsolutePath(), compilationUnit); @@ -307,7 +307,7 @@ private SymbolReference tryToSolveTypeUncached } } - return SymbolReference.unsolved(ResolvedReferenceTypeDeclaration.class); + return SymbolReference.unsolved(); } } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/MemoryTypeSolver.java b/src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/MemoryTypeSolver.java similarity index 91% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/MemoryTypeSolver.java rename to src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/MemoryTypeSolver.java index ae996c6..28f73d8 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/MemoryTypeSolver.java +++ b/src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/MemoryTypeSolver.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -21,9 +21,9 @@ package com.github.javaparser.symbolsolver.resolution.typesolvers; +import com.github.javaparser.resolution.TypeSolver; import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration; -import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; +import com.github.javaparser.resolution.model.SymbolReference; import java.util.HashMap; import java.util.Map; @@ -91,9 +91,8 @@ public void addDeclaration(String name, ResolvedReferenceTypeDeclaration typeDec public SymbolReference tryToSolveType(String name) { if (declarationMap.containsKey(name)) { return SymbolReference.solved(declarationMap.get(name)); - } else { - return SymbolReference.unsolved(ResolvedReferenceTypeDeclaration.class); } + return SymbolReference.unsolved(); } } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/ReflectionTypeSolver.java b/src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/ReflectionTypeSolver.java similarity index 97% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/ReflectionTypeSolver.java rename to src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/ReflectionTypeSolver.java index 124e931..ab164ca 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/ReflectionTypeSolver.java +++ b/src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/ReflectionTypeSolver.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * diff --git a/src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/TypeSolverBuilder.java b/src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/TypeSolverBuilder.java new file mode 100644 index 0000000..0811098 --- /dev/null +++ b/src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/TypeSolverBuilder.java @@ -0,0 +1,327 @@ +/* + * Copyright (C) 2015-2016 Federico Tomassetti + * Copyright (C) 2017-2023 The JavaParser Team. + * + * This file is part of JavaParser. + * + * JavaParser can be used either under the terms of + * a) the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * b) the terms of the Apache License + * + * You should have received a copy of both licenses in LICENCE.LGPL and + * LICENCE.APACHE. Please refer to those files for details. + * + * JavaParser is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + */ + +package com.github.javaparser.symbolsolver.resolution.typesolvers; + +import com.github.javaparser.resolution.TypeSolver; +import org.checkerframework.checker.nullness.qual.NonNull; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * TypeSolverBuilder was created with the objective of simplifying + * the process of creating new type solved. Instead of invoking the + * constructor directly, the user can build it using the builder pattern. + * + *

+ * + * Example 1: + * Solve JRE types: + *
+ *

+ *     new TypeSolverBuilder()
+ *          .withCurrentJRE()
+ *          .build()
+ * 
+ * + *

+ * + * Example 2: + * Solve JRE and types defined in foo.jar: + *
+ *

+ *     new TypeSolverBuilder()
+ *          .withCurrentJRE()
+ *          .withJAR("foo.jar")
+ *          .build()
+ * 
+ * + * @author 4everTheOne + */ +public class TypeSolverBuilder { + + private final List typeSolvers = new ArrayList<>(); + + /** + * Append a costum type solver to the build. + * + * @param typeSolver The type solver to be added. + * + * @return the current builder. + */ + public TypeSolverBuilder with(@NonNull TypeSolver typeSolver) { + checkNotNull(typeSolver, "The typeSolver can't be null!"); + + typeSolvers.add(typeSolver); + return this; + } + + // Builders for Reflection + + /** + * Allow the type solver to resolve types that are + * defined in the current Java Runtime Environment (JRE). + *

+ * Some examples of those types are: + * + *

    + *
  • java.lang.Object
  • + *
  • java.lang.String
  • + *
  • java.lang.Math
  • + *
  • ...
  • + *
+ * + * @return the current builder. + * + * @see ReflectionTypeSolver + */ + public TypeSolverBuilder withCurrentJRE() { + TypeSolver javaRuntime = new ReflectionTypeSolver(); + return with(javaRuntime); + } + + /** + * Allow the type solver to resolve types that are + * defined in the current {@link ClassLoader}. + *

+ * Some examples of those types are: + * + *

    + *
  • java.lang.Object
  • + *
  • java.lang.String
  • + *
  • java.lang.Math
  • + *
  • com.github.javaparser.ast.Node
  • + *
  • com.github.javaparser.symbolsolver.resolution.typesolvers.TypeSolverBuilder
  • + *
  • ...
  • + *
+ * + * @return the current builder. + * + * @see ReflectionTypeSolver + */ + public TypeSolverBuilder withCurrentClassloader() { + TypeSolver classLoaderTypeSolver = new ReflectionTypeSolver(false); + return with(classLoaderTypeSolver); + } + + // Builders for JARS + + /** + * Allow the type solver to resolve types that are + * defined in a JAR file. + * + * @param pathToJar The path to the jar file. + * + * @return the current builder. + * + * @throws IOException If an I/O exception occurs while reading the Jar. + * + * @see JarTypeSolver + */ + public TypeSolverBuilder withJAR(@NonNull Path pathToJar) throws IOException { + TypeSolver jarTypeSolver = new JarTypeSolver(pathToJar); + return with(jarTypeSolver); + } + + /** + * Allow the type solver to resolve types that are + * defined in a JAR file. + * + * @param pathToJar The jar file. + * + * @return the current builder. + * + * @throws IOException If an I/O exception occurs while reading the Jar. + * + * @see JarTypeSolver + */ + public TypeSolverBuilder withJAR(@NonNull File pathToJar) throws IOException { + TypeSolver jarTypeSolver = new JarTypeSolver(pathToJar); + return with(jarTypeSolver); + } + + /** + * Allow the type solver to resolve types that are + * defined in a JAR file. + * + * @param pathToJar The path to the jar file. + * + * @return the current builder. + * + * @throws IOException If an I/O exception occurs while reading the Jar. + * + * @see JarTypeSolver + */ + public TypeSolverBuilder withJAR(@NonNull String pathToJar) throws IOException { + TypeSolver jarTypeSolver = new JarTypeSolver(pathToJar); + return with(jarTypeSolver); + } + + // Builders for AarTypeSolver + + /** + * Allow the type solver to resolve types that are + * defined in a AAR file. + * + * @param pathToAar The path to the AAR file. + * + * @return the current builder. + * + * @throws IOException If an I/O exception occurs while reading the AAR. + * + * @see AarTypeSolver + */ + public TypeSolverBuilder withAAR(@NonNull Path pathToAar) throws IOException { + TypeSolver aarTypeSolver = new AarTypeSolver(pathToAar); + return with(aarTypeSolver); + } + + /** + * Allow the type solver to resolve types that are + * defined in a AAR file. + * + * @param pathToAar The AAR file. + * + * @return the current builder. + * + * @throws IOException If an I/O exception occurs while reading the AAR. + * + * @see AarTypeSolver + */ + public TypeSolverBuilder withAAR(@NonNull File pathToAar) throws IOException { + TypeSolver aarTypeSolver = new AarTypeSolver(pathToAar); + return with(aarTypeSolver); + } + + /** + * Allow the type solver to resolve types that are + * defined in a AAR file. + * + * @param pathToAar The path to the AAR file. + * + * @return the current builder. + * + * @throws IOException If an I/O exception occurs while reading the AAR. + * + * @see AarTypeSolver + */ + public TypeSolverBuilder withAAR(@NonNull String pathToAar) throws IOException { + TypeSolver aarTypeSolver = new AarTypeSolver(pathToAar); + return with(aarTypeSolver); + } + + // Builders for JavaParserTypeSolver + + /** + * Allow the type solver to resolve types using + * external source code. + * + * @param pathToSourceCode The path to the source code. + * + * @return the current builder. + * + * @see JavaParserTypeSolver + */ + public TypeSolverBuilder withSourceCode(@NonNull Path pathToSourceCode) { + TypeSolver aarTypeSolver = new JavaParserTypeSolver(pathToSourceCode); + return with(aarTypeSolver); + } + + /** + * Allow the type solver to resolve types using + * external source code. + * + * @param pathToSourceCode The source code file. + * + * @return the current builder. + * + * @see JavaParserTypeSolver + */ + public TypeSolverBuilder withSourceCode(@NonNull File pathToSourceCode) { + TypeSolver aarTypeSolver = new JavaParserTypeSolver(pathToSourceCode); + return with(aarTypeSolver); + } + + /** + * Allow the type solver to resolve types using + * external source code. + * + * @param pathToSourceCode The path to the source code. + * + * @return the current builder. + * + * @see JavaParserTypeSolver + */ + public TypeSolverBuilder withSourceCode(@NonNull String pathToSourceCode) { + TypeSolver aarTypeSolver = new JavaParserTypeSolver(pathToSourceCode); + return with(aarTypeSolver); + } + + // Builders for ClassLoaderTypeSolver + + /** + * Allow the type solver to resolve types using + * the provided {@link ClassLoader}. + * + * @param classLoader The class loader to be registered. + * + * @return the current builder. + * + * @see ClassLoaderTypeSolver + */ + public TypeSolverBuilder withClassLoader(@NonNull ClassLoader classLoader) { + TypeSolver classLoaderTypeSolver = new ClassLoaderTypeSolver(classLoader); + return with(classLoaderTypeSolver); + } + + // build + + /** + * Convert the current build into a valid {@link TypeSolver}. + * + * @return The type solver with the requested configuration. + * + * @throws IllegalStateException if no build configuration is provided. + */ + public TypeSolver build() { + int typeSolversCount = typeSolvers.size(); + + // Check if at least one solver is present + if (typeSolversCount == 0) { + throw new IllegalStateException("At least a type solver is expected."); + } + + // Check if only one exists + if (typeSolversCount == 1) { + return typeSolvers.get(0); + } + + // Combine all type solver + return new CombinedTypeSolver(typeSolvers); + } + +} diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/logic/ConfilictingGenericTypesException.java b/src/main/java/com/github/javaparser/symbolsolver/utils/FileUtils.java similarity index 50% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/logic/ConfilictingGenericTypesException.java rename to src/main/java/com/github/javaparser/symbolsolver/utils/FileUtils.java index e159585..1dd66c7 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/logic/ConfilictingGenericTypesException.java +++ b/src/main/java/com/github/javaparser/symbolsolver/utils/FileUtils.java @@ -1,6 +1,5 @@ /* - * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2013-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -19,16 +18,29 @@ * GNU Lesser General Public License for more details. */ -package com.github.javaparser.symbolsolver.logic; +package com.github.javaparser.symbolsolver.utils; -import com.github.javaparser.resolution.types.ResolvedType; +import com.github.javaparser.utils.Utils; -/** - * @author Federico Tomassetti - */ -public class ConfilictingGenericTypesException extends RuntimeException { +import java.io.File; - public ConfilictingGenericTypesException(ResolvedType formalType, ResolvedType actualType) { - super(String.format("No matching between %s (formal) and %s (actual)", formalType, actualType)); +public class FileUtils { + + /* + * returns true if the filename exists otherwise return false + */ + public static boolean isValidPath(String filename) { + File file = new File(filename); + return file.exists(); + } + + /* + * returns the parent path from the filename as string + */ + public static String getParentPath(String filename) { + Utils.assertNotNull(filename); + int lastIndex = filename.lastIndexOf(File.separator); + return filename.substring(0, lastIndex); } + } diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/utils/SymbolSolverCollectionStrategy.java b/src/main/java/com/github/javaparser/symbolsolver/utils/SymbolSolverCollectionStrategy.java similarity index 70% rename from javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/utils/SymbolSolverCollectionStrategy.java rename to src/main/java/com/github/javaparser/symbolsolver/utils/SymbolSolverCollectionStrategy.java index b634853..4e71e61 100644 --- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/utils/SymbolSolverCollectionStrategy.java +++ b/src/main/java/com/github/javaparser/symbolsolver/utils/SymbolSolverCollectionStrategy.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Federico Tomassetti - * Copyright (C) 2017-2020 The JavaParser Team. + * Copyright (C) 2017-2023 The JavaParser Team. * * This file is part of JavaParser. * @@ -70,16 +70,33 @@ public ProjectRoot collect(Path path) { try { Files.walkFileTree(path, new SimpleFileVisitor() { private Path current_root; + private Path currentProjectDir; + private String previousSourceDirectory; private final PathMatcher javaMatcher = getPathMatcher("glob:**.java"); private final PathMatcher jarMatcher = getPathMatcher("glob:**.jar"); @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { if (javaMatcher.matches(file)) { - if (current_root == null || !file.startsWith(current_root)) { - current_root = getRoot(file).orElse(null); + String parent = file.getParent().toString(); + // This is not a very elegant or powerful solution but it works and it allows to unblock users :-( + // We are trying to verify the current_root directory for each package. + // Sometime (for exemple https://github.com/apache/logging-log4j1) we can have java packages directly under a base directory + // and source directory under the same base package. + // for exemple: + // logging-log4j1\examples\customLevel\XLevel.java <- examples is a package (the root source directory is logging-log4j1) + // logging-log4j1\src\main\java\org\apache\log4j\Appender.java <- org is a package (the root source directory is logging-log4j1\src\main\java) + if (!parent.equals(previousSourceDirectory)) { + Log.info("Trying to compute the source root from %s", () -> file.toString()); + previousSourceDirectory = parent; + currentProjectDir = getRoot(file).orElse(null); + } + if (current_root == null || (currentProjectDir != null && !currentProjectDir.equals(current_root))) { + current_root = currentProjectDir; + if (current_root != null) Log.info("New current source root is %s", () -> current_root.toString()); } } else if (jarMatcher.matches(file)) { + Log.info("Jar file is found %s", () -> file.toString()); typeSolver.add(new JarTypeSolver(file.toString())); } return CONTINUE; @@ -88,6 +105,7 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IO @Override public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { if (Files.isHidden(dir)) { + Log.info("Skipping sub-tree %s", () -> dir.toString()); return SKIP_SUBTREE; } return CONTINUE; @@ -96,6 +114,7 @@ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) th @Override public FileVisitResult postVisitDirectory(Path dir, IOException e) throws IOException { if (current_root != null && Files.isSameFile(dir, current_root)) { + Log.info("Adding source root %s", () -> dir.toString()); projectRoot.addSourceRoot(dir); typeSolver.add(new JavaParserTypeSolver(current_root.toFile(), parserConfiguration)); current_root = null;