... types) {
* Walks the parents of this node and returns the first node of type {@code type} that matches {@code predicate}, or
* {@code empty()} if none is found. The given type may also be an interface type, such as one of the
* {@code NodeWith...} interface types.
- *
- * @deprecated This method is no longer acceptable to find ancestor.
+ * @deprecated
+ * This method is no longer acceptable to find ancestor.
* Use {@link findAncestor(Predicate, Class)} instead.
*/
@Deprecated
@@ -85,16 +85,16 @@ default Optional findAncestor(Class type, Predicate predicate) {
* Walks the parents of this node and returns the first node that matches one of types {@code types}, or
* {@code empty()} if none is found. The given type may also be an interface type, such as one of the
* {@code NodeWith...} interface types.
- *
* @param
*/
default Optional findAncestor(Predicate predicate, Class... types) {
if (!hasParentNode())
return Optional.empty();
Node parent = getParentNode().get();
- Optional> oType = Arrays.stream(types).filter(type -> type.isAssignableFrom(parent.getClass()) && predicate.test(type.cast(parent))).findFirst();
- if (oType.isPresent()) {
- return Optional.of(oType.get().cast(parent));
+ for (Class type : types) {
+ if (type.isAssignableFrom(parent.getClass()) && predicate.test(type.cast(parent))) {
+ return Optional.of(type.cast(parent));
+ }
}
return parent.findAncestor(predicate, types);
}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/Node.java b/javaparser-core/src/main/java/com/github/javaparser/ast/Node.java
index 62cf54ba94..2b6acaa2c4 100644
--- a/javaparser-core/src/main/java/com/github/javaparser/ast/Node.java
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/Node.java
@@ -539,6 +539,22 @@ public M getData(final DataKey key) {
return value;
}
+ /**
+ * Gets data for this node using the given key or returns an {@code Optional.empty()}.
+ *
+ * @param The type of the data.
+ * @param key The key for the data
+ * @return The data.
+ * @see DataKey
+ */
+ @SuppressWarnings("unchecked")
+ public Optional findData(final DataKey key) {
+ if (containsData(key)) {
+ return Optional.of(getData(key));
+ }
+ return Optional.empty();
+ }
+
/**
* This method was added to support the clone method.
*
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/body/MethodDeclaration.java b/javaparser-core/src/main/java/com/github/javaparser/ast/body/MethodDeclaration.java
index 2e0962fb41..1ac76db62a 100644
--- a/javaparser-core/src/main/java/com/github/javaparser/ast/body/MethodDeclaration.java
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/body/MethodDeclaration.java
@@ -20,11 +20,9 @@
*/
package com.github.javaparser.ast.body;
-import static com.github.javaparser.utils.Utils.assertNotNull;
-import java.util.Optional;
-import java.util.function.Consumer;
import com.github.javaparser.TokenRange;
import com.github.javaparser.ast.*;
+import com.github.javaparser.ast.Modifier.Keyword;
import com.github.javaparser.ast.expr.AnnotationExpr;
import com.github.javaparser.ast.expr.SimpleName;
import com.github.javaparser.ast.jml.clauses.JmlContract;
@@ -45,6 +43,13 @@
import com.github.javaparser.resolution.Resolvable;
import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import java.util.Arrays;
+import java.util.Optional;
+import java.util.function.Consumer;
+
+import static com.github.javaparser.ast.Modifier.DefaultKeyword.*;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+
/**
* A method declaration. "public int abc() {return 1;}" in this example: {@code class X { public int abc() {return 1;}
* }}
@@ -250,6 +255,40 @@ public String toDescriptor() {
return sb.toString();
}
+ /*
+ * A method in the body of an interface may be declared public or private
+ * (§6.6). If no access modifier is given, the method is implicitly public.
+ * https://docs.oracle.com/javase/specs/jls/se9/html/jls-9.html#jls-9.4
+ */
+ @Override
+ public boolean isPublic() {
+ return hasModifier(PUBLIC) || isImplicitlyPublic();
+ }
+
+ private boolean isImplicitlyPublic() {
+ return getAccessSpecifier() == AccessSpecifier.NONE
+ && hasParentNode()
+ && getParentNode().get() instanceof ClassOrInterfaceDeclaration
+ && ((ClassOrInterfaceDeclaration) getParentNode().get()).isInterface();
+ }
+
+ /*
+ * An interface method lacking a private, default, or static modifier is implicitly abstract.
+ * https://docs.oracle.com/javase/specs/jls/se9/html/jls-9.html#jls-9.4
+ */
+ @Override
+ public boolean isAbstract() {
+ return super.isAbstract() || isImplicitlyAbstract();
+ }
+
+ private boolean isImplicitlyAbstract() {
+ return hasParentNode() && getParentNode().get() instanceof ClassOrInterfaceDeclaration
+ && ((ClassOrInterfaceDeclaration) getParentNode().get()).isInterface()
+ && Arrays.asList(STATIC, DEFAULT, PRIVATE).stream()
+ .noneMatch(modifier -> hasModifier(modifier));
+ }
+
+
public boolean isNative() {
return hasModifier(Modifier.DefaultKeyword.NATIVE);
}
@@ -259,7 +298,7 @@ public boolean isSynchronized() {
}
public boolean isDefault() {
- return hasModifier(Modifier.DefaultKeyword.DEFAULT);
+ return hasModifier(DEFAULT);
}
public MethodDeclaration setNative(boolean set) {
@@ -271,7 +310,7 @@ public MethodDeclaration setSynchronized(boolean set) {
}
public MethodDeclaration setDefault(boolean set) {
- return setModifier(Modifier.DefaultKeyword.DEFAULT, set);
+ return setModifier(DEFAULT, set);
}
@Override
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/expr/LambdaExpr.java b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/LambdaExpr.java
index 5cef6df01d..2f83755c74 100644
--- a/javaparser-core/src/main/java/com/github/javaparser/ast/expr/LambdaExpr.java
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/LambdaExpr.java
@@ -20,6 +20,11 @@
*/
package com.github.javaparser.ast.expr;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+
+import java.util.Optional;
+import java.util.function.Consumer;
+
import com.github.javaparser.TokenRange;
import com.github.javaparser.ast.AllFieldsConstructor;
import com.github.javaparser.ast.Generated;
@@ -38,9 +43,6 @@
import com.github.javaparser.metamodel.DerivedProperty;
import com.github.javaparser.metamodel.JavaParserMetaModel;
import com.github.javaparser.metamodel.LambdaExprMetaModel;
-import java.util.Optional;
-import java.util.function.Consumer;
-import static com.github.javaparser.utils.Utils.assertNotNull;
/**
* A lambda expression
@@ -115,11 +117,13 @@ public LambdaExpr(TokenRange tokenRange, NodeList parameters, Stateme
customInitialization();
}
+ @Override
@Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
public NodeList getParameters() {
return parameters;
}
+ @Override
@Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
public LambdaExpr setParameters(final NodeList parameters) {
assertNotNull(parameters);
@@ -272,4 +276,11 @@ public Optional toLambdaExpr() {
public boolean isPolyExpression() {
return true;
}
+
+ /*
+ * Returns true if no type parameter has been defined
+ */
+ public boolean isExplicitlyTyped() {
+ return getParameters().stream().allMatch(p -> !(p.getType().isUnknownType()));
+ }
}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/validator/RecordAsTypeIdentifierNotAllowed.java b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/RecordAsTypeIdentifierNotAllowed.java
index 5a7f0b5272..4fe7bd7736 100644
--- a/javaparser-core/src/main/java/com/github/javaparser/ast/validator/RecordAsTypeIdentifierNotAllowed.java
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/RecordAsTypeIdentifierNotAllowed.java
@@ -39,7 +39,7 @@ public RecordAsTypeIdentifierNotAllowed() {
@Override
public void visit(Name n, ProblemReporter arg) {
- if (n.getIdentifier().equals("record") && !validUsage(n)) {
+ if ("record".equals(n.getIdentifier()) && !validUsage(n)) {
arg.report(n, error);
}
super.visit(n, arg);
@@ -47,7 +47,7 @@ public void visit(Name n, ProblemReporter arg) {
@Override
public void visit(SimpleName n, ProblemReporter arg) {
- if (n.getIdentifier().equals("record") && !validUsage(n)) {
+ if ("record".equals(n.getIdentifier()) && !validUsage(n)) {
arg.report(n, error);
}
super.visit(n, arg);
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/validator/language_level_validations/chunks/UnderscoreKeywordValidator.java b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/language_level_validations/chunks/UnderscoreKeywordValidator.java
index 873eba395f..6613ef83aa 100644
--- a/javaparser-core/src/main/java/com/github/javaparser/ast/validator/language_level_validations/chunks/UnderscoreKeywordValidator.java
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/language_level_validations/chunks/UnderscoreKeywordValidator.java
@@ -41,7 +41,7 @@ public void visit(SimpleName n, ProblemReporter arg) {
}
private static void validateIdentifier(Node n, String id, ProblemReporter arg) {
- if (id.equals("_")) {
+ if ("_".equals(id)) {
arg.report(n, "'_' is a reserved keyword.");
}
}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/validator/postprocessors/Java10PostProcessor.java b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/postprocessors/Java10PostProcessor.java
index 7baee89145..c33a109eae 100644
--- a/javaparser-core/src/main/java/com/github/javaparser/ast/validator/postprocessors/Java10PostProcessor.java
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/postprocessors/Java10PostProcessor.java
@@ -27,6 +27,7 @@
import com.github.javaparser.ast.expr.ClassExpr;
import com.github.javaparser.ast.type.ClassOrInterfaceType;
import com.github.javaparser.ast.type.VarType;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -39,7 +40,6 @@ public class Java10PostProcessor extends PostProcessors {
// List of parent contexts in which a var type must not be detected.
// for example: in this statement var.class.getCanonicalName(), var must not be considered as a VarType
private static List FORBIDEN_PARENT_CONTEXT_TO_DETECT_POTENTIAL_VAR_TYPE = new ArrayList<>();
-
static {
FORBIDEN_PARENT_CONTEXT_TO_DETECT_POTENTIAL_VAR_TYPE.addAll(Arrays.asList(ClassExpr.class));
}
@@ -49,19 +49,23 @@ public class Java10PostProcessor extends PostProcessors {
@Override
public void postProcess(ParseResult extends Node> result, ParserConfiguration configuration) {
result.getResult().ifPresent(node -> {
- node.findAll(ClassOrInterfaceType.class).forEach(n -> {
- if (n.getNameAsString().equals("var") && !matchForbiddenContext(n)) {
- n.replace(new VarType(n.getTokenRange().orElse(null)));
- }
+ node.findAll(ClassOrInterfaceType.class)
+ .forEach(n -> {
+ if ("var".equals(n.getNameAsString())
+ && !matchForbiddenContext(n)) {
+ n.replace(new VarType(n.getTokenRange().orElse(null)));
+ }
});
});
}
private boolean matchForbiddenContext(ClassOrInterfaceType cit) {
- return cit.getParentNode().isPresent() && FORBIDEN_PARENT_CONTEXT_TO_DETECT_POTENTIAL_VAR_TYPE.stream().anyMatch(cl -> cl.isInstance(cit.getParentNode().get()));
+ return cit.getParentNode().isPresent()
+ && FORBIDEN_PARENT_CONTEXT_TO_DETECT_POTENTIAL_VAR_TYPE.stream().anyMatch(cl -> cl.isInstance(cit.getParentNode().get()));
}
};
+
public Java10PostProcessor() {
add(varNodeCreator);
}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/CloneVisitor.java b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/CloneVisitor.java
index 3512de80b9..05fdb31c50 100644
--- a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/CloneVisitor.java
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/CloneVisitor.java
@@ -20,6 +20,8 @@
*/
package com.github.javaparser.ast.visitor;
+import java.util.Optional;
+
import com.github.javaparser.ast.*;
import com.github.javaparser.ast.body.*;
import com.github.javaparser.ast.comments.BlockComment;
@@ -39,8 +41,6 @@
import com.github.javaparser.ast.modules.*;
import com.github.javaparser.ast.stmt.*;
import com.github.javaparser.ast.type.*;
-import java.util.Optional;
-
/**
* A visitor that clones (copies) a node and all its children.
*/
@@ -268,7 +268,6 @@ public Visitable visit(final Parameter n, final Object arg) {
@Override
public Visitable visit(final InitializerDeclaration n, final Object arg) {
BlockStmt body = cloneNode(n.getBody(), arg);
- NodeList annotations = cloneList(n.getAnnotations(), arg);
Comment comment = cloneNode(n.getComment(), arg);
InitializerDeclaration r = new InitializerDeclaration(n.getTokenRange().orElse(null), n.isStatic(), body);
r.setComment(comment);
@@ -339,7 +338,6 @@ public Visitable visit(final ArrayCreationLevel n, final Object arg) {
@Override
public Visitable visit(final IntersectionType n, final Object arg) {
NodeList elements = cloneList(n.getElements(), arg);
- NodeList annotations = cloneList(n.getAnnotations(), arg);
Comment comment = cloneNode(n.getComment(), arg);
IntersectionType r = new IntersectionType(n.getTokenRange().orElse(null), elements);
r.setComment(comment);
@@ -351,7 +349,6 @@ public Visitable visit(final IntersectionType n, final Object arg) {
@Override
public Visitable visit(final UnionType n, final Object arg) {
NodeList elements = cloneList(n.getElements(), arg);
- NodeList annotations = cloneList(n.getAnnotations(), arg);
Comment comment = cloneNode(n.getComment(), arg);
UnionType r = new UnionType(n.getTokenRange().orElse(null), elements);
r.setComment(comment);
@@ -362,7 +359,6 @@ public Visitable visit(final UnionType n, final Object arg) {
@Override
public Visitable visit(final VoidType n, final Object arg) {
- NodeList annotations = cloneList(n.getAnnotations(), arg);
Comment comment = cloneNode(n.getComment(), arg);
VoidType r = new VoidType(n.getTokenRange().orElse(null));
r.setComment(comment);
@@ -386,7 +382,6 @@ public Visitable visit(final WildcardType n, final Object arg) {
@Override
public Visitable visit(final UnknownType n, final Object arg) {
- NodeList annotations = cloneList(n.getAnnotations(), arg);
Comment comment = cloneNode(n.getComment(), arg);
UnknownType r = new UnknownType(n.getTokenRange().orElse(null));
r.setComment(comment);
@@ -1204,7 +1199,6 @@ public Visitable visit(final ReceiverParameter n, final Object arg) {
@Override
public Visitable visit(final VarType n, final Object arg) {
- NodeList annotations = cloneList(n.getAnnotations(), arg);
Comment comment = cloneNode(n.getComment(), arg);
VarType r = new VarType(n.getTokenRange().orElse(null));
r.setComment(comment);
diff --git a/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/Difference.java b/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/Difference.java
index d0198bc45f..bdb92b5fb5 100644
--- a/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/Difference.java
+++ b/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/Difference.java
@@ -20,10 +20,14 @@
*/
package com.github.javaparser.printer.lexicalpreservation;
-import static com.github.javaparser.GeneratedJavaParserConstants.*;
+import static com.github.javaparser.GeneratedJavaParserConstants.LBRACE;
+import static com.github.javaparser.GeneratedJavaParserConstants.RBRACE;
+import static com.github.javaparser.GeneratedJavaParserConstants.SPACE;
+
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.IntStream;
+
import com.github.javaparser.GeneratedJavaParserConstants;
import com.github.javaparser.JavaToken;
import com.github.javaparser.JavaToken.Kind;
@@ -43,7 +47,7 @@
/**
* A Difference should give me a sequence of elements I should find (to indicate the context) followed by a list of elements
* to remove or to add and follow by another sequence of elements.
- *
+ *
* I should later be able to apply such difference to a nodeText.
*/
public class Difference {
@@ -107,8 +111,13 @@ List takeWhile(List prevElements, Predicate source) {
- return IntStream.range(0, source.size()).map(i -> source.size() - i - 1).filter(i -> source.get(i).isNewline()).findFirst().orElse(-1);
+ return IntStream.range(0, source.size())
+ .map(i -> source.size() - i - 1)
+ .filter(i -> source.get(i).isNewline())
+ .findFirst()
+ .orElse(-1);
}
/*
@@ -235,11 +244,15 @@ private int considerIndentation(NodeText nodeText, int nodeTextIndex, int number
}
private boolean isEnforcingIndentationActivable(RemovedGroup removedGroup) {
- return (isLastElement(diffElements, diffIndex) || !(nextDiffElement(diffElements, diffIndex).isAdded())) && originalIndex < originalElements.size() && !removedGroup.isACompleteLine();
+ return (isLastElement(diffElements, diffIndex) || !(nextDiffElement(diffElements, diffIndex).isAdded()))
+ && originalIndex < originalElements.size()
+ && !removedGroup.isACompleteLine();
}
private boolean isRemovingIndentationActivable(RemovedGroup removedGroup) {
- return (isLastElement(diffElements, diffIndex) || !(nextDiffElement(diffElements, diffIndex).isAdded())) && originalIndex < originalElements.size() && removedGroup.isACompleteLine();
+ return (isLastElement(diffElements, diffIndex) || !(nextDiffElement(diffElements, diffIndex).isAdded()))
+ && originalIndex < originalElements.size()
+ && removedGroup.isACompleteLine();
}
private boolean isLastElement(List> list, int index) {
@@ -255,9 +268,7 @@ private DifferenceElement nextDiffElement(List list, int inde
* and the number of consecutive whitespace (or tab) characters
*/
private class EnforcingIndentationContext {
-
int start;
-
int extraCharacters;
public EnforcingIndentationContext(int start) {
@@ -272,8 +283,7 @@ public EnforcingIndentationContext(int start, int extraCharacters) {
/**
* Remove excess white space after deleting element.
- *
- * @param nodeText Contains a list of elements to analyze
+ * @param nodeText Contains a list of elements to analyze
* @param nodeTextIndex Starting position in the input list
* @return The current position in the list of the elements
*/
@@ -289,8 +299,7 @@ private int removeExtraCharacters(NodeText nodeText, int nodeTextIndex, int extr
/**
* Starting at {@code nodeTextIndex} this method tries to determine how many contiguous spaces there are between
* the previous end of line and the next non whitespace (or tab) character
- *
- * @param nodeText List of elements to analyze
+ * @param nodeText List of elements to analyze
* @param nodeTextIndex Starting position in the input list
* @return EnforcingIndentationContext Data structure that hold the starting position of the first whitespace char and
* The number of consecutive whitespace (or tab) characters
@@ -314,7 +323,7 @@ private EnforcingIndentationContext defineEnforcingIndentationContext(NodeText n
}
// compute space after the deleted element
if (startIndex < nodeText.numberOfElements() && isSpaceOrTabElement(nodeText, startIndex)) {
- // int startingFromIndex = startIndex == 0 ? startIndex : startIndex + 1;
+// int startingFromIndex = startIndex == 0 ? startIndex : startIndex + 1;
for (int i = startIndex; i >= 0 && i < nodeText.numberOfElements(); i++) {
if (nodeText.getTextElement(i).isNewline()) {
break;
@@ -325,9 +334,30 @@ private EnforcingIndentationContext defineEnforcingIndentationContext(NodeText n
ctx.extraCharacters++;
}
}
+
return ctx;
}
+ /*
+ * An element is considered inlined if, before the line break, there are nodes in the list of elements
+ */
+ private boolean isInlined(NodeText nodeText, int startIndex) {
+ boolean inlined = false;
+ if (startIndex < nodeText.numberOfElements() && startIndex >= 0) {
+ // at this stage startIndex points to the first element before the deleted one
+ for (int i = startIndex; i < nodeText.numberOfElements(); i++) {
+ if (nodeText.getTextElement(i).isNewline()) {
+ break;
+ }
+ if (nodeText.getTextElement(i).isChild()) {
+ inlined = true;
+ break;
+ }
+ }
+ }
+ return inlined;
+ }
+
/*
* Returns true if the indexed element is a space or a tab
*/
@@ -458,6 +488,26 @@ private void applyRemovedDiffElement(RemovedGroup removedGroup, Removed removed,
originalIndex++;
}
} else {
+ // If we delete the first element, it is possible that there is an indentation to be deleted which is stored in the parent node.
+ NodeText parentNodeText = new NodeText();
+ List indentationTokens = new ArrayList<>();
+ if (originalIndex == 0 && removed.getChild().getParentNode().isPresent()) {
+ Node startingNodeForFindingIndentation = removed.getChild();
+ Node parentNode = removed.getChild().getParentNode().get();
+ parentNodeText = LexicalPreservingPrinter.getOrCreateNodeText(parentNode);
+ // If we are trying to delete the first element of a node and that node is also the first element of the parent node, we need to look for the grandfather node which logically contains the indentation characters.
+ // This is the case, for example, when trying to delete an annotation positioned on a method declaration.
+ // The token corresponding to the annotation is the first element of the annotation node
+ // and it is also the first element of the parent node (MethodDeclaration),
+ // so the previous indentation is defined in the parent node of the method declaration.
+ if (!parentNodeText.getElements().isEmpty()
+ && parentNode.getParentNode().isPresent()
+ && parentNodeText.getTextElement(0).equals(nodeText.getTextElement(originalIndex))) {
+ startingNodeForFindingIndentation = parentNode;
+ parentNodeText = LexicalPreservingPrinter.getOrCreateNodeText(parentNode.getParentNode().get());
+ }
+ indentationTokens = LexicalPreservingPrinter.findIndentation(startingNodeForFindingIndentation);
+ }
nodeText.removeElement(originalIndex);
// When we don't try to remove a complete line
// and removing the element is not the first action of a replacement (removal followed by addition)
@@ -488,6 +538,19 @@ private void applyRemovedDiffElement(RemovedGroup removedGroup, Removed removed,
if (isRemovingIndentationActivable(removedGroup)) {
// Since the element has been deleted we try to start the analysis from the previous element
originalIndex = considerRemovingIndentation(nodeText, originalIndex);
+ // If we delete the first element, it is possible that there is an indentation
+ // to be deleted which is stored in the parent node.
+ // We don't want to remove indentation when the node to remove is not the only
+ // node in the line (if there are other nodes before the next character
+ // indicating the end of line).
+ // This is for example the case when we want to delete an annotation declared on
+ // the same line as a method declaration.
+ if (originalIndex == 0 && !indentationTokens.isEmpty() && !isInlined(nodeText, originalIndex)) {
+ for (TextElement indentationToken : indentationTokens) {
+ parentNodeText.removeElement(
+ parentNodeText.findElement(indentationToken.and(indentationToken.matchByRange())));
+ }
+ }
}
diffIndex++;
}
@@ -497,12 +560,13 @@ private void applyRemovedDiffElement(RemovedGroup removedGroup, Removed removed,
if (isRemovingIndentationActivable(removedGroup)) {
originalIndex = considerRemovingIndentation(nodeText, originalIndex);
}
- } else if (removed.isToken() && originalElementIsToken && (// handle EOLs separately as their token kind might not be equal. This is because the 'removed'
+ } else if (removed.isToken() && originalElementIsToken && (removed.getTokenType() == ((TokenTextElement) originalElement).getTokenKind() || // handle EOLs separately as their token kind might not be equal. This is because the 'removed'
// element always has the current operating system's EOL as type
- removed.getTokenType() == ((TokenTextElement) originalElement).getTokenKind() || (((TokenTextElement) originalElement).getToken().getCategory().isEndOfLine() && removed.isNewLine()))) {
+ (((TokenTextElement) originalElement).getToken().getCategory().isEndOfLine() && removed.isNewLine()))) {
nodeText.removeElement(originalIndex);
diffIndex++;
- } else if ((removed.isWhiteSpaceNotEol() || removed.getElement() instanceof CsmIndent || removed.getElement() instanceof CsmUnindent) && originalElement.isSpaceOrTab()) {
+ } else if ((removed.isWhiteSpaceNotEol() || removed.getElement() instanceof CsmIndent || removed.getElement() instanceof CsmUnindent)
+ && originalElement.isSpaceOrTab()) {
// remove the current space
nodeText.removeElement(originalIndex);
} else if (originalElementIsToken && originalElement.isWhiteSpaceOrComment()) {
@@ -545,7 +609,10 @@ private void cleanTheLineOfLeftOverSpace(RemovedGroup removedGroup, Removed remo
}
// we dont want to remove the indentation if the last removed element is a newline
// because in this case we are trying to remove the indentation of the next child element
- if (!removedGroup.isProcessed() && removedGroup.isLastElement(removed) && removedGroup.isACompleteLine() && !removed.isNewLine()) {
+ if (!removedGroup.isProcessed()
+ && removedGroup.isLastElement(removed)
+ && removedGroup.isACompleteLine()
+ && !removed.isNewLine()) {
Integer lastElementIndex = removedGroup.getLastElementIndex();
Optional indentation = removedGroup.getIndentation();
if (indentation.isPresent() && !isReplaced(lastElementIndex)) {
@@ -721,7 +788,7 @@ private int getIndexToNextTokenElement(TokenTextElement element, DifferenceEleme
if (part.equals(token.asString())) {
// get 'dot' token
token = token.getNextToken().get();
- if (!token.asString().equals("."))
+ if (!".".equals(token.asString()))
break;
// get the next part
token = token.getNextToken().get();
@@ -889,7 +956,9 @@ private void applyAddedDiffElement(Added added) {
boolean currentIsNewline = nodeText.getTextElement(originalIndex).isNewline();
boolean isFirstElement = originalIndex == 0;
boolean previousIsWhiteSpace = originalIndex > 0 && nodeText.getTextElement(originalIndex - 1).isWhiteSpace();
- boolean commentIsBeforeAddedElement = currentIsAComment && addedTextElement.getRange().isPresent() && nodeText.getTextElement(originalIndex).getRange().map(range -> range.isBefore(addedTextElement.getRange().get())).orElse(false);
+ boolean commentIsBeforeAddedElement = currentIsAComment && addedTextElement.getRange().isPresent()
+ && nodeText.getTextElement(originalIndex).getRange()
+ .map(range -> range.isBefore(addedTextElement.getRange().get())).orElse(false);
if (sufficientTokensRemainToSkip && currentIsAComment && commentIsBeforeAddedElement) {
// Need to get behind the comment:
// FIXME: Why 2? This comment and the next newline?
@@ -951,7 +1020,6 @@ private void applyAddedDiffElement(Added added) {
* A list iterator which provides a method to know the current positioning
*/
public static class ArrayIterator implements ListIterator {
-
ListIterator iterator;
public ArrayIterator(List elements) {
@@ -1015,6 +1083,7 @@ public void add(T e) {
iterator.add(e);
;
}
+
}
/*
diff --git a/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/LexicalPreservingPrinter.java b/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/LexicalPreservingPrinter.java
index 123f186921..d6c5a5b82e 100644
--- a/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/LexicalPreservingPrinter.java
+++ b/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/LexicalPreservingPrinter.java
@@ -26,10 +26,12 @@
import static com.github.javaparser.utils.Utils.decapitalize;
import static java.util.Comparator.comparing;
import static java.util.stream.Collectors.toList;
+
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.util.*;
+
import com.github.javaparser.JavaToken;
import com.github.javaparser.Range;
import com.github.javaparser.ast.DataKey;
@@ -132,11 +134,10 @@ public void concretePropertyChange(Node observedNode, ObservableProperty propert
if (property == ObservableProperty.COMMENT) {
Optional parentNode = observedNode.getParentNode();
NodeText nodeText = parentNode.map(parent -> getOrCreateNodeText(parentNode.get())).orElseGet(() -> getOrCreateNodeText(observedNode));
- if (oldValue == null) {
- // this case corresponds to the addition of a comment
- int index = // Find the position of the comment node and put in front of it the [...]
- parentNode.isPresent() ? //
- nodeText.findChild(observedNode) : 0;
+ if (oldValue == null) { // this case corresponds to the addition of a comment
+ int index = parentNode.isPresent() ? // Find the position of the comment node and put in front of it the [...]
+ nodeText.findChild(observedNode) : //
+ 0;
/* Add the same indentation to the comment as the previous node
* for example if we want to add a comment on the body of the method declaration :
* Actual code
@@ -162,8 +163,7 @@ public void concretePropertyChange(Node observedNode, ObservableProperty propert
nodeText.addElement(index++, makeCommentToken((Comment) newValue));
nodeText.addToken(index, eolTokenKind(lineSeparator), lineSeparator.asRawString());
// code indentation after inserting an eol token may be wrong
- } else if (newValue == null) {
- // this case corresponds to a deletion of a comment
+ } else if (newValue == null) { // this case corresponds to a deletion of a comment
if (oldValue instanceof Comment) {
if (((Comment) oldValue).isOrphan()) {
nodeText = getOrCreateNodeText(observedNode);
@@ -175,9 +175,6 @@ public void concretePropertyChange(Node observedNode, ObservableProperty propert
} else {
removeAllExtraCharactersStartingFrom(nodeText.getElements().listIterator(index));
}
- // if (nodeText.getElements().get(index).isNewline()) {
- // nodeText.removeElement(index);
- // }
} else {
throw new UnsupportedOperationException("Trying to remove something that is not a comment!");
}
@@ -200,17 +197,14 @@ public void concretePropertyChange(Node observedNode, ObservableProperty propert
}
private boolean isCompleteLine(List elements, int index) {
- if (index <= 0 || index >= elements.size())
- return false;
+ if (index <= 0 || index >= elements.size()) return false;
boolean isCompleteLine = true;
ListIterator iterator = elements.listIterator(index);
// verify if elements after the index are only spaces or tabs
while (iterator.hasNext()) {
TextElement textElement = iterator.next();
- if (textElement.isNewline())
- break;
- if (textElement.isSpaceOrTab())
- continue;
+ if (textElement.isNewline()) break;
+ if (textElement.isSpaceOrTab()) continue;
isCompleteLine = false;
break;
}
@@ -218,18 +212,16 @@ private boolean isCompleteLine(List elements, int index) {
iterator = elements.listIterator(index);
while (iterator.hasPrevious() && isCompleteLine) {
TextElement textElement = iterator.previous();
- if (textElement.isNewline())
- break;
- if (textElement.isSpaceOrTab())
- continue;
+ if (textElement.isNewline()) break;
+ if (textElement.isSpaceOrTab()) continue;
isCompleteLine = false;
}
+
return isCompleteLine;
}
private void removeAllExtraCharacters(List elements, int index) {
- if (index < 0 || index >= elements.size())
- return;
+ if (index < 0 || index >= elements.size()) return;
removeAllExtraCharactersStartingFrom(elements.listIterator(index));
removeAllExtraCharactersBeforePosition(elements.listIterator(index));
}
@@ -290,12 +282,21 @@ private int getIndexOfComment(Comment oldValue, NodeText nodeText) {
return nodeText.findElement(matchingChild.and(matchingChild.matchByRange()));
}
+ /*
+ * Comment
+ */
private List findChildTextElementForComment(Comment oldValue, NodeText nodeText) {
List matchingChildElements;
matchingChildElements = selectMatchingChildElements(oldValue, nodeText);
if (matchingChildElements.size() > 1) {
// Duplicate child nodes found, refine the result
- matchingChildElements = matchingChildElements.stream().filter(t -> isEqualRange(t.getChild().getRange(), oldValue.getRange())).collect(toList());
+ matchingChildElements = matchingChildElements.stream()
+ .filter(t -> t.getChild().hasRange() && oldValue.hasRange())
+ .filter(t -> t.getChild().getRange().get().equals(oldValue.getRange().get())
+ || (t.getChild().getComment().isPresent()
+ && t.getChild().getComment().get().hasRange()
+ && t.getChild().getComment().get().getRange().get().equals(oldValue.getRange().get())))
+ .collect(toList());
}
if (matchingChildElements.size() != 1) {
throw new IllegalStateException("The matching child text element for the comment to be removed could not be found.");
@@ -305,7 +306,8 @@ private List findChildTextElementForComment(Comment oldValue,
private List selectMatchingChildElements(Comment oldValue, NodeText nodeText) {
List result = new ArrayList<>();
- List childTextElements = nodeText.getElements().stream().filter(e -> e.isChild()).map(c -> (ChildTextElement) c).collect(toList());
+ List childTextElements = nodeText.getElements().stream().filter(e -> e.isChild())
+ .map(c -> (ChildTextElement) c).collect(toList());
ListIterator iterator = childTextElements.listIterator();
while (iterator.hasNext()) {
ChildTextElement textElement = iterator.next();
@@ -329,24 +331,31 @@ private boolean isSameComment(Comment childValue, Comment oldValue) {
private List findTokenTextElementForComment(Comment oldValue, NodeText nodeText) {
List matchingTokens;
if (oldValue instanceof JavadocComment) {
- matchingTokens = nodeText.getElements().stream().filter(e -> e.isToken(JAVADOC_COMMENT)).map(e -> (TokenTextElement) e).filter(t -> t.getText().equals(oldValue.getHeader() + oldValue.getContent() + oldValue.getFooter())).collect(toList());
+ matchingTokens = nodeText.getElements().stream()
+ .filter(e -> e.isToken(JAVADOC_COMMENT))
+ .map(e -> (TokenTextElement) e)
+ .filter(t -> t.getText().equals(oldValue.asString()))
+ .collect(toList());
} else if (oldValue instanceof BlockComment) {
- matchingTokens = nodeText.getElements().stream().filter(e -> e.isToken(MULTI_LINE_COMMENT)).map(e -> (TokenTextElement) e).filter(t -> t.getText().equals(oldValue.getHeader() + oldValue.getContent() + oldValue.getFooter())).collect(toList());
+ matchingTokens = nodeText.getElements().stream()
+ .filter(e -> e.isToken(MULTI_LINE_COMMENT))
+ .map(e -> (TokenTextElement) e)
+ .filter(t -> t.getText().equals(oldValue.asString()))
+ .collect(toList());
} else {
- matchingTokens = nodeText.getElements().stream().filter(e -> e.isToken(SINGLE_LINE_COMMENT)).map(e -> (TokenTextElement) e).filter(t -> t.getText().trim().equals((oldValue.getHeader() + oldValue.getContent()).trim())).collect(toList());
- }
- if (matchingTokens.size() > 1) {
- // Duplicate comments found, refine the result
- matchingTokens = matchingTokens.stream().filter(t -> isEqualRange(t.getToken().getRange(), oldValue.getRange())).collect(toList());
- }
- return matchingTokens;
- }
-
- private boolean isEqualRange(Optional range1, Optional range2) {
- if (range1.isPresent() && range2.isPresent()) {
- return range1.get().equals(range2.get());
+ matchingTokens = nodeText.getElements().stream()
+ .filter(e -> e.isToken(SINGLE_LINE_COMMENT))
+ .map(e -> (TokenTextElement) e)
+ .filter(t -> t.getText().trim().equals((oldValue.asString()).trim()))
+ .collect(toList());
}
- return false;
+ // To check that a comment matches in the list of tokens, if exists the range must be always checked,
+ // as comments with the same content may exist on different lines.
+ return matchingTokens.stream()
+ .filter(t -> (!t.getToken().hasRange() && !oldValue.hasRange())
+ || (t.getToken().hasRange() && oldValue.hasRange()
+ && t.getToken().getRange().get().equals(oldValue.getRange().get())))
+ .collect(toList());
}
/**
@@ -507,6 +516,7 @@ public static String print(Node node) {
final NodeText nodeText = getOrCreateNodeText(node);
nodeText.getElements().forEach(element -> element.accept(visitor));
return visitor.toString();
+
}
//
@@ -581,8 +591,8 @@ private static NodeText interpret(Node node, CsmElement csm, NodeText nodeText)
if (!comment.hasRange()) {
LineSeparator lineSeparator = node.getLineEndingStyleOrDefault(LineSeparator.SYSTEM);
calculatedSyntaxModel.elements.add(0, new CsmToken(eolTokenKind(lineSeparator), lineSeparator.asRawString()));
- calculatedSyntaxModel.elements.add(0, new CsmChild(comment));
- }
+ calculatedSyntaxModel.elements.add(0,new CsmChild(comment));
+ }
});
for (CsmElement element : calculatedSyntaxModel.elements) {
if (element instanceof CsmIndent) {
diff --git a/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/changes/ListRemovalChange.java b/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/changes/ListRemovalChange.java
index ba9a723f02..5e19065d8c 100644
--- a/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/changes/ListRemovalChange.java
+++ b/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/changes/ListRemovalChange.java
@@ -21,6 +21,8 @@
package com.github.javaparser.printer.lexicalpreservation.changes;
import java.util.Optional;
+
+import com.github.javaparser.Range;
import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.NodeList;
import com.github.javaparser.ast.observer.ObservableProperty;
@@ -55,14 +57,33 @@ public Object getValue(ObservableProperty property, Node node) {
NodeList newNodeList = new NodeList<>();
// fix #2187 set the parent node in the new list
newNodeList.setParentNode(currentNodeList.getParentNodeForChildren());
- newNodeList.addAll(currentNodeList);
- // Perform modification -- remove an item from the list
- newNodeList.remove(index);
+ // Here we want to obtain a sub-list that does not contain an element.
+ // It is important not to implement this by first adding all the elements in the
+ // list and then deleting the element to be removed, as this involves event
+ // propagation mechanisms, particularly for lexical preservation,
+ // which deletes the relationship between a node and its parent node.
+ // This relationship is necessary to reinforce indentation, for example when
+ // deleting a node, as indentation can be carried by the parent node.
+ currentNodeList.stream().filter(n -> !isSameNode(currentNodeList.get(index), n))
+ .forEach(selectedNode -> newNodeList.add(selectedNode));
return newNodeList;
}
return new NoChange().getValue(property, node);
}
+ private boolean isSameNode(Node n1, Node n2) {
+ return n1.equals(n2) && isSameRange(n1, n2);
+ }
+
+ private boolean isSameRange(Node n1, Node n2) {
+ return (!n1.hasRange() && !n2.hasRange())
+ || (n1.hasRange() && n2.hasRange() && isSameRange(n1.getRange().get(), n2.getRange().get()));
+ }
+
+ private boolean isSameRange(Range r1, Range r2) {
+ return r1.equals(r2);
+ }
+
@Override
public ObservableProperty getProperty() {
return observableProperty;
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedReferenceTypeDeclaration.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedReferenceTypeDeclaration.java
index be966d5661..112414bc6e 100644
--- a/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedReferenceTypeDeclaration.java
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedReferenceTypeDeclaration.java
@@ -24,6 +24,7 @@
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
+
import com.github.javaparser.ast.AccessSpecifier;
import com.github.javaparser.resolution.MethodUsage;
import com.github.javaparser.resolution.UnsolvedSymbolException;
@@ -36,11 +37,8 @@
public interface ResolvedReferenceTypeDeclaration extends ResolvedTypeDeclaration, ResolvedTypeParametrizable {
String JAVA_LANG_ENUM = java.lang.Enum.class.getCanonicalName();
-
String JAVA_LANG_COMPARABLE = java.lang.Comparable.class.getCanonicalName();
-
String JAVA_IO_SERIALIZABLE = Serializable.class.getCanonicalName();
-
String JAVA_LANG_OBJECT = java.lang.Object.class.getCanonicalName();
@Override
@@ -295,7 +293,12 @@ default boolean hasAnnotation(String qualifiedName) {
if (hasDirectlyAnnotation(qualifiedName)) {
return true;
}
- return isClass() && getAllAncestors().stream().filter(it -> it.asReferenceType().getTypeDeclaration().isPresent()).filter(it -> it.asReferenceType().getTypeDeclaration().get().isClass()).map(it -> it.asReferenceType().getTypeDeclaration().get()).anyMatch(rrtd -> rrtd.hasDirectlyAnnotation(qualifiedName) && rrtd.isInheritedAnnotation(qualifiedName));
+ return isClass() && getAllAncestors().stream()
+ .filter(it -> it.asReferenceType().getTypeDeclaration().isPresent())
+ .filter(it -> it.asReferenceType().getTypeDeclaration().get().isClass())
+ .map(it -> it.asReferenceType().getTypeDeclaration().get())
+ .anyMatch(rrtd -> rrtd.hasDirectlyAnnotation(qualifiedName)
+ && rrtd.isInheritedAnnotation(qualifiedName));
}
/**
@@ -310,7 +313,9 @@ default boolean isInheritedAnnotation(String name) {
* Returns the resolved annotation corresponding to the specified name and declared in this type declaration.
*/
default Optional getDeclaredAnnotation(String name) {
- return getDeclaredAnnotations().stream().filter(annotation -> annotation.getQualifiedName().endsWith(name)).findFirst();
+ return getDeclaredAnnotations().stream()
+ .filter(annotation -> annotation.getQualifiedName().endsWith(name))
+ .findFirst();
}
/**
@@ -320,6 +325,7 @@ default Set getDeclaredAnnotations() {
throw new UnsupportedOperationException("Getting declared annotation is not supproted on this type " + this.getName());
}
+
/**
* This means that the type has a functional method. Conceptually, a functional interface has exactly one abstract method.
* Typically these classes has the FunctionInterface annotation but this is not mandatory.
@@ -353,8 +359,8 @@ default Optional findTypeParameter(String name
* @see https://github.com/javaparser/javaparser/issues/2044
*/
default boolean isJavaLangObject() {
- return // Consider anonymous classes
- this.isClass() && !isAnonymousClass() && hasName() && getQualifiedName().equals(JAVA_LANG_OBJECT);
+ return this.isClass() && !isAnonymousClass() && // Consider anonymous classes
+ hasName() && JAVA_LANG_OBJECT.equals(getQualifiedName());
}
/**
@@ -362,6 +368,6 @@ default boolean isJavaLangObject() {
* @see ResolvedReferenceType#isJavaLangEnum()
*/
default boolean isJavaLangEnum() {
- return this.isEnum() && getQualifiedName().equals(JAVA_LANG_ENUM);
+ return this.isEnum() && JAVA_LANG_ENUM.equals(getQualifiedName());
}
}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/logic/MethodResolutionLogic.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/logic/MethodResolutionLogic.java
index 8720330235..e7d9431388 100644
--- a/javaparser-core/src/main/java/com/github/javaparser/resolution/logic/MethodResolutionLogic.java
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/logic/MethodResolutionLogic.java
@@ -116,7 +116,6 @@ private static boolean isApplicable(ResolvedMethodDeclaration methodDeclaration,
}
// The index of the final argument passed (on the method usage).
int countOfNeedleArgumentsPassedAfterGrouping = needleArgumentTypes.size();
- int lastNeedleArgumentIndexAfterGrouping = getLastParameterIndex(countOfNeedleArgumentsPassed);
// 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) {
@@ -383,7 +382,6 @@ public static boolean isApplicable(MethodUsage methodUsage, String needleName, L
int lastMethodUsageArgumentIndex = getLastParameterIndex(countOfMethodUsageArgumentsPassed);
// The index of the final argument passed (on the method usage).
int needleParameterCount = needleParameterTypes.size();
- int lastNeedleParameterIndex = getLastParameterIndex(needleParameterCount);
// 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.
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedReferenceType.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedReferenceType.java
index 0316ece22d..ceb44a564a 100644
--- a/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedReferenceType.java
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedReferenceType.java
@@ -23,6 +23,7 @@
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
+
import com.github.javaparser.ast.AccessSpecifier;
import com.github.javaparser.resolution.MethodUsage;
import com.github.javaparser.resolution.declarations.ResolvedFieldDeclaration;
@@ -87,9 +88,20 @@ public ResolvedReferenceType(ResolvedReferenceTypeDeclaration typeDeclaration, L
public boolean equals(Object o) {
if (this == o)
return true;
- if (o == null || (!isLazyType(o) && getClass() != o.getClass()) || (isLazyType(o) && !this.equals(asResolvedReferenceType(o))))
+ if (o == null)
+ return false;
+
+ if (o instanceof LazyType) {
+ final LazyType lazyType = (LazyType) o;
+ if (!lazyType.isReferenceType())
+ return false;
+ return this.equals(lazyType.asReferenceType());
+ }
+
+ if (getClass() != o.getClass())
return false;
- ResolvedReferenceType that = asResolvedReferenceType(o);
+
+ ResolvedReferenceType that = (ResolvedReferenceType) o;
if (!typeDeclaration.equals(that.typeDeclaration))
return false;
if (!typeParametersMap.equals(that.typeParametersMap))
@@ -97,17 +109,6 @@ public boolean equals(Object o) {
return true;
}
- private boolean isLazyType(Object type) {
- return type != null && type instanceof LazyType;
- }
-
- private ResolvedReferenceType asResolvedReferenceType(Object o) {
- if (isLazyType(o)) {
- return ((LazyType) o).asReferenceType();
- }
- return ResolvedReferenceType.class.cast(o);
- }
-
@Override
public int hashCode() {
int result = typeDeclaration.hashCode();
@@ -523,8 +524,8 @@ private static List deriveParams(ResolvedReferenceTypeDeclaration
* @see https://github.com/javaparser/javaparser/issues/2044
*/
public boolean isJavaLangObject() {
- return // Consider anonymous classes
- this.isReferenceType() && hasName() && getQualifiedName().equals(JAVA_LANG_OBJECT);
+ return this.isReferenceType() && // Consider anonymous classes
+ hasName() && getQualifiedName().equals(JAVA_LANG_OBJECT);
}
/**
@@ -532,8 +533,8 @@ public boolean isJavaLangObject() {
* @see ResolvedReferenceTypeDeclaration#isJavaLangEnum()
*/
public boolean isJavaLangEnum() {
- return // Consider anonymous classes
- this.isReferenceType() && hasName() && getQualifiedName().equals(JAVA_LANG_ENUM);
+ return this.isReferenceType() && // Consider anonymous classes
+ hasName() && getQualifiedName().equals(JAVA_LANG_ENUM);
}
// /
@@ -574,13 +575,7 @@ public ResolvedType erasure() {
}
private List erasureOfParamaters(ResolvedTypeParametersMap typeParametersMap) {
- List erasedParameters = new ArrayList();
- if (!typeParametersMap.isEmpty()) {
- // add erased type except java.lang.object
- List parameters = typeParametersMap.getTypes().stream().filter(type -> !type.isReferenceType()).map(type -> type.erasure()).filter(erasedType -> !(isJavaObject(erasedType))).filter(erasedType -> erasedType != null).collect(Collectors.toList());
- erasedParameters.addAll(parameters);
- }
- return erasedParameters;
+ return new ArrayList();
}
private boolean isJavaObject(ResolvedType rt) {
diff --git a/javaparser-core/src/main/java/com/github/javaparser/utils/CollectionStrategy.java b/javaparser-core/src/main/java/com/github/javaparser/utils/CollectionStrategy.java
index 86259ae4db..df2ab58df8 100644
--- a/javaparser-core/src/main/java/com/github/javaparser/utils/CollectionStrategy.java
+++ b/javaparser-core/src/main/java/com/github/javaparser/utils/CollectionStrategy.java
@@ -49,7 +49,7 @@ default Optional getRoot(Path file) {
if (parseResult.getResult().isPresent()) {
final Optional storage = parseResult.getResult().flatMap(CompilationUnit::getStorage);
if (storage.isPresent()) {
- if (storage.get().getFileName().equals("module-info.java")) {
+ if ("module-info.java".equals(storage.get().getFileName())) {
// module-info.java is useless for finding the source root, since it can be placed in any directory.
return Optional.empty();
}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/utils/ParserCollectionStrategy.java b/javaparser-core/src/main/java/com/github/javaparser/utils/ParserCollectionStrategy.java
index 9dbf7c5546..8f059e8b10 100644
--- a/javaparser-core/src/main/java/com/github/javaparser/utils/ParserCollectionStrategy.java
+++ b/javaparser-core/src/main/java/com/github/javaparser/utils/ParserCollectionStrategy.java
@@ -64,7 +64,7 @@ public ProjectRoot collect(Path path) {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
- if (file.getFileName().toString().equals("module-info.java")) {
+ if ("module-info.java".equals(file.getFileName().toString())) {
// module-info.java is useless for finding the source root, since it can be placed within any directory.
return CONTINUE;
}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/utils/Utils.java b/javaparser-core/src/main/java/com/github/javaparser/utils/Utils.java
index 085f010705..24fa37ae15 100644
--- a/javaparser-core/src/main/java/com/github/javaparser/utils/Utils.java
+++ b/javaparser-core/src/main/java/com/github/javaparser/utils/Utils.java
@@ -20,13 +20,14 @@
*/
package com.github.javaparser.utils;
-import com.github.javaparser.ast.Node;
-import com.github.javaparser.ast.expr.UnaryExpr;
+import static java.util.Arrays.asList;
import java.io.IOException;
import java.io.Reader;
import java.util.*;
import java.util.function.Function;
-import static java.util.Arrays.asList;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.expr.UnaryExpr;
/**
* Any kind of utility.
@@ -219,17 +220,20 @@ public static boolean valueIsNullOrEmpty(Object value) {
}
public static boolean valueIsNullOrEmptyStringOrOptional(Object value) {
+ // is null?
if (value == null) {
return true;
}
- if (value instanceof Optional) {
- if (((Optional) value).isPresent()) {
- value = ((Optional) value).get();
- } else {
- return true;
- }
- }
- return false;
+// // is not Optional?
+// if (!(value instanceof Optional)) {
+// return false;
+// }
+// // is an empty Optional?
+// if (!((Optional) value).isPresent()) {
+// return true;
+// }
+// return false;
+ return value instanceof Optional ? !((Optional) value).isPresent() : false;
}
/**
diff --git a/javaparser-symbol-solver-core/pom.xml b/javaparser-symbol-solver-core/pom.xml
index 24e69b843f..85d1d50447 100644
--- a/javaparser-symbol-solver-core/pom.xml
+++ b/javaparser-symbol-solver-core/pom.xml
@@ -4,7 +4,7 @@
jmlparser-parent
io.github.jmltoolkit
- 3.25.8-SNAPSHOT
+ 3.25.10-SNAPSHOT
4.0.0
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/JavaSymbolSolver.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/JavaSymbolSolver.java
index f541fade87..1c14edffb1 100644
--- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/JavaSymbolSolver.java
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/JavaSymbolSolver.java
@@ -247,7 +247,7 @@ public T resolveDeclarationImpl(Node node, Class resultClass) {
return resultClass.cast(result.getCorrespondingDeclaration());
}
} else {
- if (((FieldAccessExpr) node).getName().getId().equals("length")) {
+ if ("length".equals(((FieldAccessExpr) node).getName().getId())) {
ResolvedType scopeType = ((FieldAccessExpr) node).getScope().calculateResolvedType();
if (scopeType.isArray()) {
if (resultClass.isInstance(ArrayLengthValueDeclaration.INSTANCE)) {
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/JavaParserFacade.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/JavaParserFacade.java
index 435c1b2d04..d7f0e98af3 100644
--- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/JavaParserFacade.java
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/JavaParserFacade.java
@@ -343,53 +343,45 @@ public ResolvedType getType(Node node) {
}
}
+ /*
+ * Returns the resolved Type of the {@code Node}. If the node is a method call
+ * expression and and the flag activates lambda expression resolution, the type
+ * of the arguments to the expression are looked up beforehand so that the type
+ * resolution is as relevant as possible.
+ */
public ResolvedType getType(Node node, boolean solveLambdas) {
if (solveLambdas) {
if (!node.containsData(TYPE_WITH_LAMBDAS_RESOLVED)) {
- ResolvedType res = getTypeConcrete(node, solveLambdas);
-
- node.setData(TYPE_WITH_LAMBDAS_RESOLVED, res);
- boolean secondPassNecessary = false;
if (node instanceof MethodCallExpr) {
MethodCallExpr methodCallExpr = (MethodCallExpr) node;
for (Node arg : methodCallExpr.getArguments()) {
if (!arg.containsData(TYPE_WITH_LAMBDAS_RESOLVED)) {
getType(arg, true);
- secondPassNecessary = true;
}
}
}
- if (secondPassNecessary) {
- node.removeData(TYPE_WITH_LAMBDAS_RESOLVED);
- ResolvedType type = getType(node, true);
- node.setData(TYPE_WITH_LAMBDAS_RESOLVED, type);
-
- }
+ ResolvedType res = getTypeConcrete(node, solveLambdas);
+ node.setData(TYPE_WITH_LAMBDAS_RESOLVED, res);
Log.trace("getType on %s -> %s", () -> node, () -> res);
}
return node.getData(TYPE_WITH_LAMBDAS_RESOLVED);
}
- Optional res = find(TYPE_WITH_LAMBDAS_RESOLVED, node);
+
+ // Try to return a value from the cache of resolved types using lambda expressions
+ Optional res = node.findData(TYPE_WITH_LAMBDAS_RESOLVED);
if (res.isPresent()) {
return res.get();
- }
- 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();
- }
-
- private Optional find(DataKey dataKey, Node node) {
- if (node.containsData(dataKey)) {
- return Optional.of(node.getData(dataKey));
}
- return Optional.empty();
+
+ // else try to return a value from the cache of resolved types without lambda expressions
+ // Or resolves the node type without resolving the lambda expressions
+ return node.findData(TYPE_WITHOUT_LAMBDAS_RESOLVED).orElseGet(() -> {
+ ResolvedType resType = getTypeConcrete(node, solveLambdas);
+ node.setData(TYPE_WITHOUT_LAMBDAS_RESOLVED, resType);
+ Log.trace("getType on %s (no solveLambdas) -> %s", () -> node, () -> res);
+ return resType;
+ });
}
protected MethodUsage toMethodUsage(MethodReferenceExpr methodReferenceExpr, List paramTypes) {
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/FieldAccessContext.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/FieldAccessContext.java
index e814810546..baf8dff6d6 100644
--- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/FieldAccessContext.java
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/FieldAccessContext.java
@@ -83,7 +83,7 @@ public Optional solveSymbolAsValue(String name) {
Expression scope = wrappedNode.getScope();
if (wrappedNode.getName().toString().equals(name)) {
ResolvedType typeOfScope = JavaParserFacade.get(typeSolver).getType(scope);
- if (typeOfScope.isArray() && name.equals(ARRAY_LENGTH_FIELD_NAME)) {
+ if (typeOfScope.isArray() && ARRAY_LENGTH_FIELD_NAME.equals(name)) {
return Optional.of(new Value(ResolvedPrimitiveType.INT, ARRAY_LENGTH_FIELD_NAME));
}
if (typeOfScope.isReferenceType()) {
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/JavaParserTypeDeclarationAdapter.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/JavaParserTypeDeclarationAdapter.java
index 9a68102dfe..c171ae2668 100644
--- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/JavaParserTypeDeclarationAdapter.java
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/JavaParserTypeDeclarationAdapter.java
@@ -96,7 +96,9 @@ public SymbolReference solveType(String name, List symbolRef = context.getParent()
.orElseThrow(() -> new RuntimeException("Parent context unexpectedly empty."))
.solveType(name, typeArguments);
@@ -140,17 +142,7 @@ public SymbolReference solveType(String name, List solveMethod(String name, List<
// If we haven't located any candidates that are declared on this type or its ancestors, consider the parent context.
// This is relevant e.g. with nested classes.
// Note that we want to avoid infinite recursion when a class is using its own method - see issue #75
- if (candidateMethods.isEmpty()) {
+ // We also want to avoid infinite recursion when handling static imports - see issue #4358
+ if (candidateMethods.isEmpty() && !staticOnly) {
SymbolReference parentSolution = context.getParent()
.orElseThrow(() -> new RuntimeException("Parent context unexpectedly empty."))
.solveMethod(name, argumentsTypes, staticOnly);
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/MethodReferenceExprContext.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/MethodReferenceExprContext.java
index 7b4374a4a3..f86aa9ca8a 100644
--- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/MethodReferenceExprContext.java
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/MethodReferenceExprContext.java
@@ -27,12 +27,13 @@
import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.body.VariableDeclarator;
-import com.github.javaparser.ast.expr.Expression;
import com.github.javaparser.ast.expr.MethodCallExpr;
import com.github.javaparser.ast.expr.MethodReferenceExpr;
+import com.github.javaparser.ast.expr.ObjectCreationExpr;
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.ResolvedConstructorDeclaration;
import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
@@ -99,7 +100,7 @@ private List inferArgumentTypes() {
if (demandParentNode(wrappedNode) instanceof MethodCallExpr) {
MethodCallExpr methodCallExpr = (MethodCallExpr) demandParentNode(wrappedNode);
MethodUsage methodUsage = JavaParserFacade.get(typeSolver).solveMethodAsUsage(methodCallExpr);
- int pos = pos(methodCallExpr, wrappedNode);
+ int pos = methodCallExpr.getArgumentPosition(wrappedNode);
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
@@ -108,37 +109,24 @@ private List inferArgumentTypes() {
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);
- if (functionalMethodOpt.isPresent()) {
- MethodUsage functionalMethod = functionalMethodOpt.get();
-
- List resolvedTypes = new ArrayList<>();
-
- for (ResolvedType type : functionalMethod.getParamTypes()) {
- 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()), lambdaType);
-
- // Now resolve the argument type using the inference context
- ResolvedType argType = inferenceContext.resolve(inferenceContext.addSingle(type));
-
- ResolvedLambdaConstraintType conType;
- if (argType.isWildcard()) {
- conType = ResolvedLambdaConstraintType.bound(argType.asWildcard().getBoundedType());
- } else {
- conType = ResolvedLambdaConstraintType.bound(argType);
- }
+ return resolveLambdaTypes(lambdaType);
+ }
- resolvedTypes.add(conType);
- }
+ if (demandParentNode(wrappedNode) instanceof ObjectCreationExpr) {
+ ObjectCreationExpr objectCreationExpr = (ObjectCreationExpr) demandParentNode(wrappedNode);
+ ResolvedConstructorDeclaration rcd = JavaParserFacade.get(typeSolver).solve(objectCreationExpr)
+ .getCorrespondingDeclaration();
+ int pos = objectCreationExpr.getArgumentPosition(wrappedNode);
+ // 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 = (rcd.hasVariadicParameter() && pos >= rcd.getNumberOfParams() - 1) ?
+ rcd.getLastParam().getType().asArrayType().getComponentType() :
+ rcd.getParam(pos).getType();
- return resolvedTypes;
- }
- throw new UnsupportedOperationException();
+ return resolveLambdaTypes(lambdaType);
}
+
if (demandParentNode(wrappedNode) instanceof VariableDeclarator) {
VariableDeclarator variableDeclarator = (VariableDeclarator) demandParentNode(wrappedNode);
ResolvedType t = JavaParserFacade.get(typeSolver).convertToUsage(variableDeclarator.getType());
@@ -165,6 +153,7 @@ private List inferArgumentTypes() {
}
throw new UnsupportedOperationException();
}
+
if (demandParentNode(wrappedNode) instanceof ReturnStmt) {
ReturnStmt returnStmt = (ReturnStmt) demandParentNode(wrappedNode);
Optional optDeclaration = returnStmt.findAncestor(MethodDeclaration.class);
@@ -198,15 +187,37 @@ private List inferArgumentTypes() {
throw new UnsupportedOperationException();
}
- private int pos(MethodCallExpr callExpr, Expression param) {
- int i = 0;
- for (Expression p : callExpr.getArguments()) {
- if (p == param) {
- return i;
+ private List resolveLambdaTypes(ResolvedType lambdaType) {
+ // Get the functional method in order for us to resolve it's type arguments properly
+ Optional functionalMethodOpt = FunctionalInterfaceLogic.getFunctionalMethod(lambdaType);
+ if (functionalMethodOpt.isPresent()) {
+ MethodUsage functionalMethod = functionalMethodOpt.get();
+
+ List resolvedTypes = new ArrayList<>();
+
+ for (ResolvedType type : functionalMethod.getParamTypes()) {
+ 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()), lambdaType);
+
+ // Now resolve the argument type using the inference context
+ ResolvedType argType = inferenceContext.resolve(inferenceContext.addSingle(type));
+
+ ResolvedLambdaConstraintType conType;
+ if (argType.isWildcard()) {
+ conType = ResolvedLambdaConstraintType.bound(argType.asWildcard().getBoundedType());
+ } else {
+ conType = ResolvedLambdaConstraintType.bound(argType);
+ }
+
+ resolvedTypes.add(conType);
}
- i++;
+
+ return resolvedTypes;
}
- throw new IllegalArgumentException();
+ throw new UnsupportedOperationException();
}
}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/SwitchEntryContext.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/SwitchEntryContext.java
index d5dbbd808a..fdc78cced8 100644
--- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/SwitchEntryContext.java
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/SwitchEntryContext.java
@@ -21,9 +21,9 @@
package com.github.javaparser.symbolsolver.javaparsermodel.contexts;
+import com.github.javaparser.ast.nodeTypes.SwitchNode;
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;
@@ -50,8 +50,8 @@ public SwitchEntryContext(SwitchEntry wrappedNode, TypeSolver typeSolver) {
@Override
public SymbolReference extends ResolvedValueDeclaration> solveSymbol(String name) {
- SwitchStmt switchStmt = (SwitchStmt) demandParentNode(wrappedNode);
- ResolvedType type = JavaParserFacade.get(typeSolver).getType(switchStmt.getSelector());
+ SwitchNode switchNode = (SwitchNode) demandParentNode(wrappedNode);
+ ResolvedType type = JavaParserFacade.get(typeSolver).getType(switchNode.getSelector());
if (type.isReferenceType() && type.asReferenceType().getTypeDeclaration().isPresent()) {
ResolvedReferenceTypeDeclaration typeDeclaration = type.asReferenceType().getTypeDeclaration().get();
if (typeDeclaration.isEnum()) {
@@ -75,7 +75,7 @@ public SymbolReference extends ResolvedValueDeclaration> solveSymbol(String na
}
// look for declaration in this and previous switch entry statements
- for (SwitchEntry seStmt : switchStmt.getEntries()) {
+ for (SwitchEntry seStmt : switchNode.getEntries()) {
for (Statement stmt : seStmt.getStatements()) {
SymbolDeclarator symbolDeclarator = JavaParserFactory.getSymbolDeclarator(stmt, typeSolver);
SymbolReference extends ResolvedValueDeclaration> symbolReference = solveWith(symbolDeclarator, name);
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserEnumDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserEnumDeclaration.java
index e2459891eb..008903c915 100644
--- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserEnumDeclaration.java
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserEnumDeclaration.java
@@ -122,7 +122,7 @@ public boolean canBeAssignedTo(ResolvedReferenceTypeDeclaration other) {
if (otherName.equals(this.getQualifiedName())) {
return true;
}
- if (otherName.equals(JAVA_LANG_ENUM)) {
+ if (JAVA_LANG_ENUM.equals(otherName)) {
return true;
}
// Enum implements Comparable and Serializable
@@ -132,10 +132,7 @@ public boolean canBeAssignedTo(ResolvedReferenceTypeDeclaration other) {
if (otherName.equals(JAVA_IO_SERIALIZABLE)) {
return true;
}
- if (other.isJavaLangObject()) {
- return true;
- }
- return false;
+ return other.isJavaLangObject();
}
@Override
@@ -185,9 +182,7 @@ public boolean equals(Object o) {
JavaParserEnumDeclaration that = (JavaParserEnumDeclaration) o;
- if (!wrappedNode.equals(that.wrappedNode)) return false;
-
- return true;
+ return wrappedNode.equals(that.wrappedNode);
}
@Override
@@ -204,10 +199,10 @@ public Optional solveMethodAsUsage(String name, List
@Override
public SymbolReference solveMethod(String name, List argumentsTypes,
boolean staticOnly) {
- if (name.equals("values") && argumentsTypes.isEmpty()) {
+ if ("values".equals(name) && argumentsTypes.isEmpty()) {
return SymbolReference.solved(new JavaParserEnumDeclaration.ValuesMethod(this, typeSolver));
}
- if (name.equals("valueOf") && argumentsTypes.size() == 1) {
+ if ("valueOf".equals(name) && argumentsTypes.size() == 1) {
ResolvedType argument = argumentsTypes.get(0);
if (argument.isReferenceType() && "java.lang.String".equals(argument.asReferenceType().getQualifiedName())) {
return SymbolReference.solved(new JavaParserEnumDeclaration.ValueOfMethod(this, typeSolver));
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeParameter.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeParameter.java
index aa86a53013..a175ad7cf6 100644
--- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeParameter.java
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeParameter.java
@@ -21,6 +21,11 @@
package com.github.javaparser.symbolsolver.javaparsermodel.declarations;
+import static com.github.javaparser.resolution.Navigator.demandParentNode;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.ast.type.ClassOrInterfaceType;
@@ -34,11 +39,6 @@
import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
import com.github.javaparser.symbolsolver.logic.AbstractTypeDeclaration;
-import java.util.*;
-import java.util.stream.Collectors;
-
-import static com.github.javaparser.resolution.Navigator.demandParentNode;
-
/**
* @author Federico Tomassetti
@@ -69,9 +69,7 @@ public boolean equals(Object o) {
JavaParserTypeParameter that = (JavaParserTypeParameter) o;
- if (wrappedNode != null ? !wrappedNode.equals(that.wrappedNode) : that.wrappedNode != null) return false;
-
- return true;
+ return wrappedNode != null && wrappedNode.equals(that.wrappedNode);
}
@Override
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistEnumDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistEnumDeclaration.java
index e241de948f..f2688e61fc 100644
--- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistEnumDeclaration.java
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistEnumDeclaration.java
@@ -127,7 +127,7 @@ public boolean canBeAssignedTo(ResolvedReferenceTypeDeclaration other) {
if (otherName.equals(this.getQualifiedName())) {
return true;
}
- if (otherName.equals(JAVA_LANG_ENUM)) {
+ if (JAVA_LANG_ENUM.equals(otherName)) {
return true;
}
// Enum implements Comparable and Serializable
@@ -137,10 +137,7 @@ public boolean canBeAssignedTo(ResolvedReferenceTypeDeclaration other) {
if (otherName.equals(JAVA_IO_SERIALIZABLE)) {
return true;
}
- if (other.isJavaLangObject()) {
- return true;
- }
- return false;
+ return other.isJavaLangObject();
}
@Override
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistTypeParameter.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistTypeParameter.java
index b3f6929733..02f325ba15 100644
--- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistTypeParameter.java
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistTypeParameter.java
@@ -21,6 +21,11 @@
package com.github.javaparser.symbolsolver.javassistmodel;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+
import com.github.javaparser.resolution.TypeSolver;
import com.github.javaparser.resolution.declarations.ResolvedMethodLikeDeclaration;
import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
@@ -28,12 +33,8 @@
import com.github.javaparser.resolution.declarations.ResolvedTypeParametrizable;
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;
+import javassist.bytecode.SignatureAttribute;
/**
* @author Federico Tomassetti
@@ -60,14 +61,11 @@ public boolean equals(Object o) {
if (!getQualifiedName().equals(that.getQualifiedName())) {
return false;
}
- if (declaredOnType() != that.declaredOnType()) {
- return false;
- }
- if (declaredOnMethod() != that.declaredOnMethod()) {
- return false;
+ if (declaredOnType() == that.declaredOnType()) {
+ return true;
}
// TODO check bounds
- return true;
+ return declaredOnMethod() == that.declaredOnMethod();
}
@Override
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionClassDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionClassDeclaration.java
index 48ce4ddf0f..5cec199887 100644
--- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionClassDeclaration.java
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionClassDeclaration.java
@@ -21,6 +21,13 @@
package com.github.javaparser.symbolsolver.reflectionmodel;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.*;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
import com.github.javaparser.ast.AccessSpecifier;
import com.github.javaparser.ast.Node;
import com.github.javaparser.resolution.Context;
@@ -39,13 +46,6 @@
import com.github.javaparser.symbolsolver.logic.AbstractClassDeclaration;
import com.github.javaparser.symbolsolver.reflectionmodel.comparators.MethodComparator;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.*;
-import java.util.function.Predicate;
-import java.util.stream.Collectors;
-
/**
* @author Federico Tomassetti
*/
@@ -108,9 +108,7 @@ public boolean equals(Object o) {
ReflectionClassDeclaration that = (ReflectionClassDeclaration) o;
- if (!clazz.getCanonicalName().equals(that.clazz.getCanonicalName())) return false;
-
- return true;
+ return clazz.getCanonicalName().equals(that.clazz.getCanonicalName());
}
@Override
@@ -190,8 +188,8 @@ public SymbolReference solveMethod(String name, List<
}
// When empty there is no sense in trying to find the most applicable.
- // This is useful for debugging. Performance is not affected as
- // MethodResolutionLogic.findMostApplicable method returns very early
+ // This is useful for debugging. Performance is not affected as
+ // MethodResolutionLogic.findMostApplicable method returns very early
// when candidateSolvedMethods is empty.
if (candidateSolvedMethods.isEmpty()) {
return SymbolReference.unsolved();
@@ -211,6 +209,7 @@ public ResolvedType getUsage(Node node) {
return new ReferenceTypeImpl(this);
}
+ @Override
public Optional solveMethodAsUsage(String name, List argumentsTypes, Context invokationContext, List typeParameterValues) {
List methodUsages = new ArrayList<>();
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionEnumDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionEnumDeclaration.java
index 9a56bc3be3..12546310b3 100644
--- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionEnumDeclaration.java
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionEnumDeclaration.java
@@ -151,7 +151,7 @@ public boolean canBeAssignedTo(ResolvedReferenceTypeDeclaration other) {
if (otherName.equals(this.getQualifiedName())) {
return true;
}
- if (otherName.equals(JAVA_LANG_ENUM)) {
+ if (JAVA_LANG_ENUM.equals(otherName)) {
return true;
}
// Enum implements Comparable and Serializable
@@ -161,10 +161,7 @@ public boolean canBeAssignedTo(ResolvedReferenceTypeDeclaration other) {
if (otherName.equals(JAVA_IO_SERIALIZABLE)) {
return true;
}
- if (other.isJavaLangObject()) {
- return true;
- }
- return false;
+ return other.isJavaLangObject();
}
@Override
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionInterfaceDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionInterfaceDeclaration.java
index 7ef1af6731..369c19c18a 100644
--- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionInterfaceDeclaration.java
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionInterfaceDeclaration.java
@@ -21,6 +21,10 @@
package com.github.javaparser.symbolsolver.reflectionmodel;
+import java.lang.reflect.Field;
+import java.util.*;
+import java.util.stream.Collectors;
+
import com.github.javaparser.ast.AccessSpecifier;
import com.github.javaparser.ast.Node;
import com.github.javaparser.resolution.Context;
@@ -40,10 +44,6 @@
import com.github.javaparser.symbolsolver.core.resolution.SymbolResolutionCapability;
import com.github.javaparser.symbolsolver.logic.AbstractTypeDeclaration;
-import java.lang.reflect.Field;
-import java.util.*;
-import java.util.stream.Collectors;
-
/**
* @author Federico Tomassetti
*/
@@ -131,11 +131,7 @@ public boolean equals(Object o) {
if (!clazz.getCanonicalName().equals(that.clazz.getCanonicalName())) return false;
- if (!getTypeParameters().equals(that.getTypeParameters())) {
- return false;
- }
-
- return true;
+ return getTypeParameters().equals(that.getTypeParameters());
}
@Override
@@ -143,6 +139,7 @@ public int hashCode() {
return clazz.hashCode();
}
+ @Override
public Optional solveMethodAsUsage(String name, List parameterTypes,
Context invokationContext, List typeParameterValues) {
Optional res = ReflectionMethodResolutionLogic.solveMethodAsUsage(name, parameterTypes, typeSolver, invokationContext,
@@ -193,12 +190,8 @@ && new ReflectionInterfaceDeclaration(clazz.getSuperclass(), typeSolver).canBeAs
}
}
- if (other.isJavaLangObject()) {
- // Everything can be assigned to {@code java.lang.Object}
- return true;
- }
-
- return false;
+ // Everything can be assigned to {@code java.lang.Object}
+ return other.isJavaLangObject();
}
@Override
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionTypeParameter.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionTypeParameter.java
index 29d9d26896..016a02a2af 100644
--- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionTypeParameter.java
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionTypeParameter.java
@@ -21,14 +21,6 @@
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.resolution.model.typesystem.ReferenceTypeImpl;
-import com.github.javaparser.resolution.types.ResolvedReferenceType;
-
import java.lang.reflect.Constructor;
import java.lang.reflect.GenericDeclaration;
import java.lang.reflect.Method;
@@ -38,6 +30,14 @@
import java.util.Optional;
import java.util.stream.Collectors;
+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.resolution.model.typesystem.ReferenceTypeImpl;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+
/**
* @author Federico Tomassetti
*/
@@ -70,14 +70,11 @@ public boolean equals(Object o) {
if (!getQualifiedName().equals(that.getQualifiedName())) {
return false;
}
- if (declaredOnType() != that.declaredOnType()) {
- return false;
- }
- if (declaredOnMethod() != that.declaredOnMethod()) {
- return false;
+ if (declaredOnType() == that.declaredOnType()) {
+ return true;
}
// TODO check bounds
- return true;
+ return declaredOnMethod() == that.declaredOnMethod();
}
@Override
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/naming/NameLogic.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/naming/NameLogic.java
index 3ed190549c..3c3b4c9360 100644
--- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/naming/NameLogic.java
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/naming/NameLogic.java
@@ -592,12 +592,8 @@ private static boolean isSyntacticallyAPackageOrTypeName(Node name) {
// 2. In a type-import-on-demand declaration (§7.5.2)
- if (whenParentIs(ImportDeclaration.class, name, (p, c) ->
- !p.isStatic() && p.isAsterisk() && p.getName() == name)) {
- return true;
- }
-
- return false;
+ return whenParentIs(ImportDeclaration.class, name, (p, c) ->
+ !p.isStatic() && p.isAsterisk() && p.getName() == name);
}
private static boolean isSyntacticallyAMethodName(Node name) {
@@ -605,11 +601,7 @@ private static boolean isSyntacticallyAMethodName(Node name) {
//
// 1. Before the "(" in a method invocation expression (§15.12)
- if (whenParentIs(MethodCallExpr.class, name, (p, c) -> p.getName() == c)) {
- return true;
- }
-
- return false;
+ return whenParentIs(MethodCallExpr.class, name, (p, c) -> p.getName() == c);
}
private static boolean isSyntacticallyAModuleName(Node name) {
@@ -626,11 +618,8 @@ private static boolean isSyntacticallyAModuleName(Node name) {
if (whenParentIs(ModuleExportsDirective.class, name, (p, c) -> p.getModuleNames().contains(name))) {
return true;
}
- if (whenParentIs(ModuleOpensDirective.class, name, (p, c) -> p.getModuleNames().contains(name))) {
- return true;
- }
- return false;
+ return whenParentIs(ModuleOpensDirective.class, name, (p, c) -> p.getModuleNames().contains(name));
}
private static boolean isSyntacticallyAPackageName(Node name) {
@@ -644,12 +633,9 @@ private static boolean isSyntacticallyAPackageName(Node name) {
return true;
}
// 2. To the left of the "." in a qualified PackageName
- if (whenParentIs(Name.class, name, (p, c) -> p.getQualifier().isPresent()
+ return whenParentIs(Name.class, name, (p, c) -> p.getQualifier().isPresent()
&& p.getQualifier().get() == name
- && isSyntacticallyAPackageName(p))) {
- return true;
- }
- return false;
+ && isSyntacticallyAPackageName(p));
}
private static boolean isSyntacticallyATypeName(Node name) {
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ExpressionHelper.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ExpressionHelper.java
deleted file mode 100644
index 011fc80577..0000000000
--- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ExpressionHelper.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2015-2016 Federico Tomassetti
- * Copyright (C) 2017-2024 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.typeinference;
-
-import com.github.javaparser.ast.expr.Expression;
-import com.github.javaparser.ast.expr.LambdaExpr;
-import com.github.javaparser.ast.stmt.BlockStmt;
-import com.github.javaparser.resolution.TypeSolver;
-import com.github.javaparser.resolution.types.ResolvedType;
-import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
-
-import java.util.List;
-
-/**
- * @author Federico Tomassetti
- */
-public class ExpressionHelper {
-
- public static boolean isExplicitlyTyped(LambdaExpr lambdaExpr) {
- return lambdaExpr.getParameters().stream().allMatch(p -> !(p.getType().isUnknownType()));
- }
-
- public static List getResultExpressions(BlockStmt blockStmt) {
- throw new UnsupportedOperationException();
- }
-
- public static boolean isCompatibleInAssignmentContext(Expression expression, ResolvedType type, TypeSolver typeSolver) {
- return type.isAssignableBy(JavaParserFacade.get(typeSolver).getType(expression, false));
- }
-}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/TypeHelper.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/TypeHelper.java
index 8c08c5dfc9..bdaadaba6c 100644
--- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/TypeHelper.java
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/TypeHelper.java
@@ -227,7 +227,7 @@ public static Pair groundTargetTypeOfLambda(LambdaExpr la
// - If T is a wildcard-parameterized functional interface type and the lambda expression is explicitly typed,
// then the ground target type is inferred as described in §18.5.3.
- if (ExpressionHelper.isExplicitlyTyped(lambdaExpr)) {
+ if (lambdaExpr.isExplicitlyTyped()) {
used18_5_3 = true;
throw new UnsupportedOperationException();
}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/constraintformulas/ExpressionCompatibleWithType.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/constraintformulas/ExpressionCompatibleWithType.java
index c0b541c84d..5c2b763ec3 100644
--- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/constraintformulas/ExpressionCompatibleWithType.java
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/constraintformulas/ExpressionCompatibleWithType.java
@@ -21,9 +21,20 @@
package com.github.javaparser.symbolsolver.resolution.typeinference.constraintformulas;
-import com.github.javaparser.ast.expr.*;
+import static com.github.javaparser.symbolsolver.resolution.typeinference.TypeHelper.isCompatibleInALooseInvocationContext;
+import static com.github.javaparser.symbolsolver.resolution.typeinference.TypeHelper.isProperType;
+import static java.util.stream.Collectors.toList;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import com.github.javaparser.ast.expr.ConditionalExpr;
+import com.github.javaparser.ast.expr.EnclosedExpr;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.LambdaExpr;
import com.github.javaparser.ast.stmt.BlockStmt;
-import com.github.javaparser.ast.stmt.ExpressionStmt;
import com.github.javaparser.ast.stmt.ReturnStmt;
import com.github.javaparser.ast.stmt.Statement;
import com.github.javaparser.resolution.TypeSolver;
@@ -34,15 +45,6 @@
import com.github.javaparser.symbolsolver.resolution.typeinference.*;
import com.github.javaparser.utils.Pair;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
-import static com.github.javaparser.symbolsolver.resolution.typeinference.TypeHelper.isCompatibleInALooseInvocationContext;
-import static com.github.javaparser.symbolsolver.resolution.typeinference.TypeHelper.isProperType;
-import static java.util.stream.Collectors.toList;
-
/**
* An expression is compatible in a loose invocation context with type T
*
@@ -86,8 +88,8 @@ public ReductionResult reduce(BoundSet currentBoundSet) {
// - If the expression is a parenthesized expression of the form ( Expression' ), the constraint reduces
// to ‹Expression' → T›.
- if (expression instanceof EnclosedExpr) {
- EnclosedExpr enclosedExpr = (EnclosedExpr) expression;
+ if (expression.isEnclosedExpr()) {
+ EnclosedExpr enclosedExpr = expression.asEnclosedExpr();
return ReductionResult.oneConstraint(new ExpressionCompatibleWithType(typeSolver, enclosedExpr.getInner(), T));
}
@@ -99,20 +101,20 @@ public ReductionResult reduce(BoundSet currentBoundSet) {
// This bound set may contain new inference variables, as well as dependencies between these new
// variables and the inference variables in T.
- if (expression instanceof ObjectCreationExpr) {
+ if (expression.isObjectCreationExpr()) {
BoundSet B3 = new TypeInference(typeSolver).invocationTypeInferenceBoundsSetB3();
return ReductionResult.bounds(B3);
}
- if (expression instanceof MethodCallExpr) {
+ if (expression.isMethodCallExpr()) {
throw new UnsupportedOperationException();
}
// - If the expression is a conditional expression of the form e1 ? e2 : e3, the constraint reduces to two
// constraint formulas, ‹e2 → T› and ‹e3 → T›.
- if (expression instanceof ConditionalExpr) {
- ConditionalExpr conditionalExpr = (ConditionalExpr) expression;
+ if (expression.isConditionalExpr()) {
+ ConditionalExpr conditionalExpr = expression.asConditionalExpr();
return ReductionResult.withConstraints(
new ExpressionCompatibleWithType(typeSolver, conditionalExpr.getThenExpr(), T),
new ExpressionCompatibleWithType(typeSolver, conditionalExpr.getElseExpr(), T));
@@ -123,8 +125,8 @@ public ReductionResult reduce(BoundSet currentBoundSet) {
// A constraint formula of the form ‹LambdaExpression → T›, where T mentions at least one inference variable, is reduced as follows:
- if (expression instanceof LambdaExpr) {
- LambdaExpr lambdaExpr = (LambdaExpr) expression;
+ if (expression.isLambdaExpr()) {
+ LambdaExpr lambdaExpr = expression.asLambdaExpr();
// - If T is not a functional interface type (§9.8), the constraint reduces to false.
@@ -150,7 +152,7 @@ public ReductionResult reduce(BoundSet currentBoundSet) {
//
// Federico: THIS SHOULD NOT HAPPEN, IN CASE WE WILL THROW AN EXCEPTION
//
- // - Otherwise, the congruence of LambdaExpression with the target function type is asserted as
+ // - Otherwise,) the congruence of LambdaExpression with the target function type is asserted as
// follows:
//
// - If the number of lambda parameters differs from the number of parameter types of the function
@@ -176,7 +178,7 @@ public ReductionResult reduce(BoundSet currentBoundSet) {
// - If the function type's result is not void and the lambda body is a block that is not
// value-compatible, the constraint reduces to false.
- if (!targetFunctionType.getReturnType().isVoid() && lambdaExpr.getBody() instanceof BlockStmt
+ if (!targetFunctionType.getReturnType().isVoid() && lambdaExpr.getBody().isBlockStmt()
&& !isValueCompatibleBlock(lambdaExpr.getBody())) {
return ReductionResult.falseResult();
}
@@ -204,16 +206,16 @@ public ReductionResult reduce(BoundSet currentBoundSet) {
// - If R is a proper type, and if the lambda body or some result expression in the lambda body
// is not compatible in an assignment context with R, then false.
- if (lambdaExpr.getBody() instanceof BlockStmt) {
- List resultExpressions = ExpressionHelper.getResultExpressions((BlockStmt) lambdaExpr.getBody());
+ if (lambdaExpr.getBody().isBlockStmt()) {
+ List resultExpressions = getResultExpressions(lambdaExpr.getBody().asBlockStmt());
for (Expression e : resultExpressions) {
- if (!ExpressionHelper.isCompatibleInAssignmentContext(e, R, typeSolver)) {
+ if (!isCompatibleInAssignmentContext(e, R, typeSolver)) {
return ReductionResult.falseResult();
}
}
} else {
- Expression e = ((ExpressionStmt) lambdaExpr.getBody()).getExpression();
- if (!ExpressionHelper.isCompatibleInAssignmentContext(e, R, typeSolver)) {
+ Expression e = lambdaExpr.getBody().asExpressionStmt().getExpression();
+ if (!isCompatibleInAssignmentContext(e, R, typeSolver)) {
return ReductionResult.falseResult();
}
}
@@ -222,8 +224,8 @@ public ReductionResult reduce(BoundSet currentBoundSet) {
// the constraint ‹Expression → R›; or where the lambda body is a block with result
// expressions e1, ..., em, for all i (1 ≤ i ≤ m), ‹ei → R›.
- if (lambdaExpr.getBody() instanceof BlockStmt) {
- getAllReturnExpressions((BlockStmt) lambdaExpr.getBody()).forEach(e -> constraints.add(new ExpressionCompatibleWithType(typeSolver, e, R)));
+ if (lambdaExpr.getBody().isBlockStmt()) {
+ getAllReturnExpressions(lambdaExpr.getBody().asBlockStmt()).forEach(e -> constraints.add(new ExpressionCompatibleWithType(typeSolver, e, R)));
} else {
// FEDERICO: Added - Start
for (int i = 0; i < lambdaExpr.getParameters().size(); i++) {
@@ -231,7 +233,7 @@ public ReductionResult reduce(BoundSet currentBoundSet) {
TypeInferenceCache.addRecord(typeSolver, lambdaExpr, lambdaExpr.getParameter(i).getNameAsString(), paramType);
}
// FEDERICO: Added - End
- Expression e = ((ExpressionStmt) lambdaExpr.getBody()).getExpression();
+ Expression e = lambdaExpr.getBody().asExpressionStmt().getExpression();
constraints.add(new ExpressionCompatibleWithType(typeSolver, e, R));
}
}
@@ -242,7 +244,7 @@ public ReductionResult reduce(BoundSet currentBoundSet) {
// A constraint formula of the form ‹MethodReference → T›, where T mentions at least one inference variable, is reduced as follows:
- if (expression instanceof MethodReferenceExpr) {
+ if (expression.isMethodReferenceExpr()) {
// - If T is not a functional interface type, or if T is a functional interface type that does not have a function type (§9.9), the constraint reduces to false.
//
@@ -279,6 +281,14 @@ public ReductionResult reduce(BoundSet currentBoundSet) {
throw new RuntimeException("This should not happen");
}
+ private List getResultExpressions(BlockStmt blockStmt) {
+ throw new UnsupportedOperationException();
+ }
+
+ private boolean isCompatibleInAssignmentContext(Expression expression, ResolvedType type, TypeSolver typeSolver) {
+ return type.isAssignableBy(JavaParserFacade.get(typeSolver).getType(expression, false));
+ }
+
private List getAllReturnExpressions(BlockStmt blockStmt) {
return blockStmt.findAll(ReturnStmt.class).stream()
.filter(r -> r.getExpression().isPresent())
@@ -290,7 +300,7 @@ private boolean isValueCompatibleBlock(Statement statement) {
// A block lambda body is value-compatible if it cannot complete normally (§14.21) and every return statement
// in the block has the form return Expression;.
- if (statement instanceof BlockStmt) {
+ if (statement.isBlockStmt()) {
if (!ControlFlowLogic.getInstance().canCompleteNormally(statement)) {
return true;
}
diff --git a/javaparser-symbol-solver-testing/pom.xml b/javaparser-symbol-solver-testing/pom.xml
index 54e199ddff..6d5136aea3 100644
--- a/javaparser-symbol-solver-testing/pom.xml
+++ b/javaparser-symbol-solver-testing/pom.xml
@@ -4,7 +4,7 @@
jmlparser-parent
io.github.jmltoolkit
- 3.25.8-SNAPSHOT
+ 3.25.10-SNAPSHOT
4.0.0
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue3878Test.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue3878Test.java
new file mode 100644
index 0000000000..6a5e269bd9
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue3878Test.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2013-2024 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;
+
+import com.github.javaparser.StaticJavaParser;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.expr.MethodReferenceExpr;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class Issue3878Test {
+
+ @BeforeEach
+ void setup() {
+ JavaSymbolSolver symbolSolver = new JavaSymbolSolver(new ReflectionTypeSolver());
+ StaticJavaParser.getParserConfiguration().setSymbolResolver(symbolSolver);
+ }
+
+ @Test
+ void resolve_method_reference_in_ObjectCreationExpr() {
+ String code = "package test;\n" +
+ "import java.util.function.Consumer;\n" +
+ "\n" +
+ "class A {\n" +
+ "A(Consumer f) {}\n" +
+ "void bar(int i) {}\n" +
+ "void foo() { new A(this::bar); }\n" +
+ "}";
+ CompilationUnit cu = StaticJavaParser.parse(code);
+ MethodReferenceExpr expr = cu.findFirst(MethodReferenceExpr.class).get();
+
+ ResolvedMethodDeclaration decl = expr.resolve();
+
+ assertEquals("test.A.bar(int)", decl.getQualifiedSignature());
+ }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue4284Test.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue4284Test.java
new file mode 100755
index 0000000000..f243d36cb3
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue4284Test.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2013-2024 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;
+
+import org.junit.jupiter.api.Test;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.JavaParserAdapter;
+import com.github.javaparser.ParserConfiguration;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.symbolsolver.resolution.AbstractResolutionTest;
+
+public class Issue4284Test extends AbstractResolutionTest {
+
+ @Test
+ void test() {
+
+ String code =
+ "public class SampleCode {\n"
+ + " public static void main(String... args) {\n"
+ + " char ch = args[0].charAt(0);\n"
+ + " int result = switch (ch) {\n"
+ + " default -> System.out.println(ch);\n"
+ + " };\n"
+ + " }\n"
+ + "}";
+
+ ParserConfiguration parserConfiguration = new ParserConfiguration()
+ .setLanguageLevel(ParserConfiguration.LanguageLevel.JAVA_17)
+ .setSymbolResolver(symbolResolver(defaultTypeSolver()));
+
+ CompilationUnit cu = JavaParserAdapter.of(new JavaParser(parserConfiguration)).parse(code);
+
+ cu.findAll(MethodCallExpr.class).forEach(MethodCallExpr::resolve);
+
+ }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue4358Test.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue4358Test.java
new file mode 100644
index 0000000000..6779e229f7
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue4358Test.java
@@ -0,0 +1,40 @@
+package com.github.javaparser.symbolsolver;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import com.github.javaparser.ParserConfiguration;
+import com.github.javaparser.StaticJavaParser;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.JavaParserTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+
+import java.io.IOException;
+import java.nio.file.Path;
+
+import org.junit.jupiter.api.Test;
+
+public class Issue4358Test extends AbstractSymbolResolutionTest {
+ @Test
+ public void testIssue4358() throws IOException {
+ Path issueResourcesPath = adaptPath("src/test/resources/issue4358");
+ ReflectionTypeSolver rts = new ReflectionTypeSolver();
+ JavaParserTypeSolver jpts = new JavaParserTypeSolver(issueResourcesPath);
+ CombinedTypeSolver cts = new CombinedTypeSolver();
+ cts.add(rts);
+ cts.add(jpts);
+ ParserConfiguration pc = new ParserConfiguration()
+ .setSymbolResolver(new JavaSymbolSolver(cts));
+ StaticJavaParser.setConfiguration(pc);
+ CompilationUnit cu = StaticJavaParser.parse(issueResourcesPath.resolve("foo/A.java"));
+
+ // There's only one method call in this compilation unit
+ ResolvedMethodDeclaration actual = cu.findAll(MethodCallExpr.class).stream()
+ .map(MethodCallExpr::resolve)
+ .findAny().get();
+
+ assertEquals("foo.B.d()", actual.getQualifiedSignature());
+ }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javaparsermodel/JavaParserFacadeTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javaparsermodel/JavaParserFacadeTest.java
index 31a3d416c2..ae387a108c 100644
--- a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javaparsermodel/JavaParserFacadeTest.java
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javaparsermodel/JavaParserFacadeTest.java
@@ -21,15 +21,22 @@
package com.github.javaparser.symbolsolver.javaparsermodel;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.junit.jupiter.api.Test;
+
+import com.github.javaparser.JavaParserAdapter;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.expr.MethodCallExpr;
import com.github.javaparser.resolution.Solver;
+import com.github.javaparser.resolution.UnsolvedSymbolException;
import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.resolution.AbstractResolutionTest;
import com.github.javaparser.symbolsolver.resolution.SymbolSolver;
import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
-import org.junit.jupiter.api.Test;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-
-class JavaParserFacadeTest {
+class JavaParserFacadeTest extends AbstractResolutionTest {
private final Solver symbolSolver = new SymbolSolver(new ReflectionTypeSolver());
@@ -70,4 +77,25 @@ private enum TestEnum {
A, B;
}
+ // issue 3939
+ @Test
+ public void checksThatTheBehaviourIsConsistentInTheEventOfAnUnsolvedSymbol() {
+ String code =
+ "import java.util.List;\n"
+ + "import java.util.stream.Collectors;\n"
+ + "\n"
+ + "public class Foo {\n"
+ + "\n"
+ + " void m(List> classNames) {\n"
+ + " classNames.stream().map(c -> c.asSubclass(IMutator.class));\n"
+ + " }\n"
+ + "}";
+ CompilationUnit cu = JavaParserAdapter.of(createParserWithResolver(defaultTypeSolver())).parse(code);
+ MethodCallExpr expr = cu.findFirst(MethodCallExpr.class).get();
+ // First pass, there must be an UnsolvedSymbolException because the type of the method parameter cannot be resolved
+ assertThrows(UnsolvedSymbolException.class, () -> expr.getSymbolResolver().calculateType(expr));
+ // Second pass, we always want an exception to ensure consistent behaviour
+ assertThrows(UnsolvedSymbolException.class, () -> expr.getSymbolResolver().calculateType(expr));
+ }
+
}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/JavaParserTypeDeclarationAdapterTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/JavaParserTypeDeclarationAdapterTest.java
index 3e2369d9fb..e4573821a3 100644
--- a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/JavaParserTypeDeclarationAdapterTest.java
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/JavaParserTypeDeclarationAdapterTest.java
@@ -18,59 +18,95 @@
* GNU Lesser General Public License for more details.
*/
-package com.github.javaparser.symbolsolver.javaparsermodel.contexts;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-
-import org.junit.jupiter.api.*;
-
-import com.github.javaparser.JavaParserAdapter;
-import com.github.javaparser.ast.CompilationUnit;
-import com.github.javaparser.ast.expr.MethodCallExpr;
-import com.github.javaparser.symbolsolver.resolution.AbstractResolutionTest;
-
-class JavaParserTypeDeclarationAdapterTest extends AbstractResolutionTest {
-
- @BeforeAll
- static void setUpBeforeClass() throws Exception {
- }
-
- @AfterAll
- static void tearDownAfterClass() throws Exception {
- }
-
- @BeforeEach
- void setUp() throws Exception {
- }
-
- @AfterEach
- void tearDownAfterEach() throws Exception {
- }
-
- @Test
- void issue3214() {
- String code =
- "public interface Foo {\n"
- + " interface Bar {}\n"
- + " }\n"
- + "\n"
- + " public interface Bar {\n"
- + " void show();\n"
- + " }\n"
- + "\n"
- + " public class Test implements Foo.Bar {\n"
- + " private Bar bar;\n"
- + " private void m() {\n"
- + " bar.show();\n"
- + " }\n"
- + " }";
-
- JavaParserAdapter parser = JavaParserAdapter.of(createParserWithResolver(defaultTypeSolver()));
- CompilationUnit cu = parser.parse(code);
-
- MethodCallExpr mce = cu.findAll(MethodCallExpr.class).get(0);
-
- assertEquals("Bar.show()", mce.resolve().getQualifiedSignature());
- }
-
-}
+package com.github.javaparser.symbolsolver.javaparsermodel.contexts;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.junit.jupiter.api.*;
+
+import com.github.javaparser.JavaParserAdapter;
+import com.github.javaparser.StaticJavaParser;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.symbolsolver.JavaSymbolSolver;
+import com.github.javaparser.symbolsolver.resolution.AbstractResolutionTest;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+
+class JavaParserTypeDeclarationAdapterTest extends AbstractResolutionTest {
+
+ @BeforeAll
+ static void setUpBeforeClass() throws Exception {
+ }
+
+ @AfterAll
+ static void tearDownAfterClass() throws Exception {
+ }
+
+ @BeforeEach
+ void setUp() throws Exception {
+ }
+
+ @AfterEach
+ void tearDownAfterEach() throws Exception {
+ }
+
+ @Test
+ void issue3214() {
+ String code =
+ "public interface Foo {\n"
+ + " interface Bar {}\n"
+ + " }\n"
+ + "\n"
+ + " public interface Bar {\n"
+ + " void show();\n"
+ + " }\n"
+ + "\n"
+ + " public class Test implements Foo.Bar {\n"
+ + " private Bar bar;\n"
+ + " private void m() {\n"
+ + " bar.show();\n"
+ + " }\n"
+ + " }";
+
+ JavaParserAdapter parser = JavaParserAdapter.of(createParserWithResolver(defaultTypeSolver()));
+ CompilationUnit cu = parser.parse(code);
+
+ MethodCallExpr mce = cu.findAll(MethodCallExpr.class).get(0);
+
+ assertEquals("Bar.show()", mce.resolve().getQualifiedSignature());
+ }
+
+ @Test
+ void issue3946() {
+
+ String code =
+ "interface Activity {\n"
+ + "class Timestamps {}\n"
+ + " Timestamps getTimestamps();\n"
+ + "}\n"
+ + "interface RichPresence extends Activity {}\n"
+ + " class ActivityImpl implements Activity {\n"
+ + " RichPresence.Timestamps timestamps;\n"
+ + " @Override\n"
+ + " public RichPresence.Timestamps getTimestamps() { return timestamps; }\n"
+ + " }\n"
+ + "class RichPresenceImpl extends ActivityImpl implements RichPresence { }";
+
+ final JavaSymbolSolver solver = new JavaSymbolSolver(new ReflectionTypeSolver(false));
+ StaticJavaParser.getParserConfiguration().setSymbolResolver(solver);
+ final CompilationUnit compilationUnit = StaticJavaParser.parse(code);
+
+ final List returnTypes = compilationUnit.findAll(MethodDeclaration.class)
+ .stream()
+ .map(md -> md.resolve())
+ .map(rmd -> rmd.getReturnType().describe())
+ .collect(Collectors.toList());
+
+ returnTypes.forEach(type -> assertEquals("Activity.Timestamps", type));
+ }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/model/typesystem/ReferenceTypeTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/model/typesystem/ReferenceTypeTest.java
index 0edd9128ec..3493f4dbc3 100644
--- a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/model/typesystem/ReferenceTypeTest.java
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/model/typesystem/ReferenceTypeTest.java
@@ -21,10 +21,15 @@
package com.github.javaparser.symbolsolver.model.typesystem;
-import static org.hamcrest.CoreMatchers.*;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.hasItem;
+import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder;
-import static org.junit.jupiter.api.Assertions.*;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.IOException;
import java.io.Serializable;
@@ -39,7 +44,9 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-import com.github.javaparser.*;
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ParserConfiguration;
+import com.github.javaparser.StaticJavaParser;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.resolution.TypeSolver;
@@ -811,7 +818,7 @@ void testDeclaredFields() {
parserConfiguration.setSymbolResolver(new JavaSymbolSolver(typeSolver));
CompilationUnit cu = new JavaParser(parserConfiguration)
- .parse(ParseStart.COMPILATION_UNIT, new StringProvider(code)).getResult().get();
+ .parse(code).getResult().get();
ClassOrInterfaceDeclaration classA = cu.getClassByName("A").get();
ClassOrInterfaceDeclaration classB = cu.getClassByName("B").get();
@@ -837,7 +844,7 @@ void testGetAllFieldsVisibleToInheritors() {
parserConfiguration.setSymbolResolver(new JavaSymbolSolver(typeSolver));
CompilationUnit cu = new JavaParser(parserConfiguration)
- .parse(ParseStart.COMPILATION_UNIT, new StringProvider(code)).getResult().get();
+ .parse(code).getResult().get();
ClassOrInterfaceDeclaration classA = cu.getClassByName("A").get();
ClassOrInterfaceDeclaration classB = cu.getClassByName("B").get();
@@ -876,10 +883,28 @@ void erasure_rawtype() {
assertEquals(expected, erasedType.describe());
}
+ @Test
+ // The erasure of a parameterized type with bound.
+ void erasure_type_variable() {
+ List types = declaredTypes(
+ "class A {}");
+ ResolvedType rt = types.get(0);
+ String expected = "A";
+ assertEquals(expected, rt.erasure().describe());
+ }
+
+ @Test
+ // The erasure of a parameterized type
+ void erasure_parametrizedType() {
+ ResolvedType parametrizedType = genericType(Map.class.getCanonicalName(), Integer.class.getCanonicalName(), Integer.class.getCanonicalName());
+ String expected = "java.util.Map";
+ assertEquals(expected, parametrizedType.erasure().describe());
+ }
+
@Test
// The erasure of an array type T[] is |T|[].
void erasure_arraytype() {
- // create a type : List
+ // create a type : List []
ResolvedType genericList = array(genericType(List.class.getCanonicalName(), String.class.getCanonicalName()));
String expected = "java.util.List[]";
assertEquals(expected, genericList.erasure().describe());
@@ -888,21 +913,20 @@ void erasure_arraytype() {
@Test
// The erasure of an array type T[] is |T|[].
void erasure_arraytype_with_bound() {
- // create a type : List
+ // create a type : List []
ResolvedTypeVariable typeArguments = parametrizedType("T", Serializable.class.getCanonicalName());
ResolvedType genericList = array(genericType(List.class.getCanonicalName(), typeArguments));
- String expected = "java.util.List[]";
+ String expected = "java.util.List[]";
assertEquals(expected, genericList.erasure().describe());
}
@Test
- // The erasure of a type variable (§4.4) is the erasure of its leftmost bound.
- void erasure_type_variable() {
- List types = declaredTypes(
- "class A {}");
- ResolvedType rt = types.get(0);
- String expected = "A";
- assertEquals(expected, rt.erasure().describe());
+ // The erasure of T extends Serializable is the erasure of its leftmost bound.
+ void erasure_bounded_type_parameter() {
+ // create a type : T extends Serializable
+ ResolvedTypeVariable typeArguments = parametrizedType("T", Serializable.class.getCanonicalName());
+ String expected = "java.io.Serializable";
+ assertEquals(expected, typeArguments.erasure().describe());
}
@Test
diff --git a/javaparser-symbol-solver-testing/src/test/resources/issue4358/foo/A.java b/javaparser-symbol-solver-testing/src/test/resources/issue4358/foo/A.java
new file mode 100644
index 0000000000..dfeaf5ceff
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/issue4358/foo/A.java
@@ -0,0 +1,9 @@
+package foo;
+
+import static foo.B.d;
+
+class A {
+ void c() {
+ d();
+ }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/resources/issue4358/foo/B.java b/javaparser-symbol-solver-testing/src/test/resources/issue4358/foo/B.java
new file mode 100644
index 0000000000..dbafa5726a
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/issue4358/foo/B.java
@@ -0,0 +1,6 @@
+package foo;
+
+class B extends A {
+ static void d() {
+ }
+}
diff --git a/jmlparser-jml-tests/pom.xml b/jmlparser-jml-tests/pom.xml
index a1da4d3771..6f243cb50f 100644
--- a/jmlparser-jml-tests/pom.xml
+++ b/jmlparser-jml-tests/pom.xml
@@ -2,7 +2,7 @@
jmlparser-parent
io.github.jmltoolkit
- 3.25.8-SNAPSHOT
+ 3.25.10-SNAPSHOT
4.0.0
diff --git a/pom.xml b/pom.xml
index 5f2472af37..6cc599f999 100644
--- a/pom.xml
+++ b/pom.xml
@@ -16,7 +16,7 @@
io.github.jmltoolkit
jmlparser-parent
pom
- 3.25.8-SNAPSHOT
+ 3.25.10-SNAPSHOT
jmlparser-parent
https://github.com/wadoon/jmlparser
@@ -153,9 +153,9 @@
${project.basedir}/jmlparser-jml-tests/target/site/jacoco/jacoco.xml,
${project.basedir}/javaparser-core-testing-bdd/target/site/jacoco/jacoco.xml,
- 1.14.11
+ 1.14.13
-javaagent:${settings.localRepository}/net/bytebuddy/byte-buddy-agent/${byte-buddy.version}/byte-buddy-agent-${byte-buddy.version}.jar
- 2024-01-01T00:00:00Z
+ 2024-04-04T00:00:00Z
@@ -208,12 +208,12 @@
org.apache.maven.plugins
maven-compiler-plugin
- 3.12.1
+ 3.13.0
org.apache.maven.plugins
maven-gpg-plugin
- 3.1.1
+ 3.2.2
org.apache.maven.plugins
@@ -272,7 +272,7 @@
org.jacoco
jacoco-maven-plugin
- 0.8.11
+ 0.8.12
org.apache.maven.plugins
@@ -300,12 +300,12 @@
org.apache.maven.plugins
maven-surefire-plugin
- 3.2.3
+ 3.2.5
org.codehaus.mojo
exec-maven-plugin
- 3.1.1
+ 3.2.0
org.apache.maven.plugins
@@ -348,7 +348,7 @@
com.puppycrawl.tools
checkstyle
- 10.12.7
+ 10.15.0
@@ -367,7 +367,7 @@
com.google.guava
guava
- 33.0.0-jre
+ 33.1.0-jre
junit
@@ -390,19 +390,19 @@
org.junit.jupiter
junit-jupiter-engine
- 5.10.1
+ 5.10.2
test
org.junit.jupiter
junit-jupiter-params
- 5.10.1
+ 5.10.2
test
org.junit.vintage
junit-vintage-engine
- 5.10.1
+ 5.10.2
test
@@ -518,7 +518,7 @@
org.apache.maven.plugins
maven-gpg-plugin
- 3.1.0
+ 3.2.2
sign-artifacts