diff --git a/.all-contributorsrc b/.all-contributorsrc index 924c39021e..cb5a734560 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -7071,7 +7071,8 @@ "avatar_url": "https://avatars.githubusercontent.com/u/26581168?v=4", "profile": "https://github.com/mluckam", "contributions": [ - "code" + "code", + "bug" ] }, { @@ -7534,6 +7535,52 @@ "contributions": [ "bug" ] + }, + { + "login": "cowwoc", + "name": "Gili Tzabari", + "avatar_url": "https://avatars.githubusercontent.com/u/633348?v=4", + "profile": "https://github.com/cowwoc", + "contributions": [ + "bug" + ] + }, + { + "login": "bobalicious", + "name": "Rob Baillie", + "avatar_url": "https://avatars.githubusercontent.com/u/6523911?v=4", + "profile": "http://robertbaillie.blogspot.co.uk/", + "contributions": [ + "bug" + ] + }, + { + "login": "mdagcilar", + "name": "Metin Dagcilar", + "avatar_url": "https://avatars.githubusercontent.com/u/6627550?v=4", + "profile": "https://github.com/mdagcilar", + "contributions": [ + "bug" + ] + }, + { + "login": "kesslerj", + "name": "Jonas Keßler", + "avatar_url": "https://avatars.githubusercontent.com/u/25590499?v=4", + "profile": "https://github.com/kesslerj", + "contributions": [ + "bug" + ] + }, + { + "login": "Gold856", + "name": "Gold856", + "avatar_url": "https://avatars.githubusercontent.com/u/117957790?v=4", + "profile": "https://github.com/Gold856", + "contributions": [ + "bug", + "code" + ] } ], "contributorsPerLine": 7, diff --git a/Gemfile.lock b/Gemfile.lock index 10d7e8eadd..858d9626a0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -4,7 +4,7 @@ GEM addressable (2.8.6) public_suffix (>= 2.0.2, < 6.0) base64 (0.2.0) - bigdecimal (3.1.6) + bigdecimal (3.1.8) claide (1.1.0) claide-plugins (0.9.2) cork @@ -28,7 +28,7 @@ GEM octokit (>= 4.0) terminal-table (>= 1, < 4) differ (0.1.2) - et-orbi (1.2.8) + et-orbi (1.2.11) tzinfo faraday (2.9.0) faraday-net_http (>= 2.0, < 3.2) @@ -36,8 +36,8 @@ GEM faraday (>= 0.8) faraday-net_http (3.1.0) net-http - fugit (1.10.1) - et-orbi (~> 1, >= 1.2.7) + fugit (1.11.0) + et-orbi (~> 1, >= 1.2.11) raabro (~> 1.4) git (1.19.1) addressable (~> 2.8) @@ -46,13 +46,13 @@ GEM rexml kramdown-parser-gfm (1.1.0) kramdown (~> 2.0) - liquid (5.4.0) + liquid (5.5.0) logger-colors (1.0.0) nap (1.1.0) net-http (0.4.1) uri no_proxy_fix (0.1.2) - nokogiri (1.16.2-x86_64-linux) + nokogiri (1.16.5-x86_64-linux) racc (~> 1.4) octokit (8.1.0) base64 @@ -66,12 +66,13 @@ GEM nokogiri (~> 1.13) rufus-scheduler (~> 3.8) slop (~> 4.9) - public_suffix (5.0.4) + public_suffix (5.0.5) raabro (1.4.0) - racc (1.7.3) + racc (1.8.0) rchardet (1.8.0) - rexml (3.2.6) - rouge (4.2.0) + rexml (3.2.8) + strscan (>= 3.0.9) + rouge (4.2.1) rufus-scheduler (3.9.1) fugit (~> 1.1, >= 1.1.6) safe_yaml (1.0.5) @@ -79,6 +80,7 @@ GEM addressable (>= 2.3.5) faraday (>= 0.17.3, < 3) slop (4.10.1) + strscan (3.1.0) terminal-table (3.0.2) unicode-display_width (>= 1.1.1, < 3) tzinfo (2.0.6) diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock index 8f8b94acac..bd44b12521 100644 --- a/docs/Gemfile.lock +++ b/docs/Gemfile.lock @@ -1,7 +1,7 @@ GEM remote: https://rubygems.org/ specs: - activesupport (7.1.3.2) + activesupport (7.1.3.3) base64 bigdecimal concurrent-ruby (~> 1.0, >= 1.0.2) @@ -14,7 +14,7 @@ GEM addressable (2.8.6) public_suffix (>= 2.0.2, < 6.0) base64 (0.2.0) - bigdecimal (3.1.6) + bigdecimal (3.1.8) coffee-script (2.4.1) coffee-script-source execjs @@ -23,8 +23,8 @@ GEM commonmarker (0.23.10) concurrent-ruby (1.2.3) connection_pool (2.4.1) - csv (3.2.8) - dnsruby (1.71.0) + csv (3.3.0) + dnsruby (1.72.1) simpleidn (~> 0.2.1) drb (2.2.1) em-websocket (0.5.3) @@ -96,7 +96,7 @@ GEM activesupport (>= 2) nokogiri (>= 1.4) http_parser.rb (0.8.0) - i18n (1.14.4) + i18n (1.14.5) concurrent-ruby (~> 1.0) jekyll (3.9.5) addressable (~> 2.4) @@ -219,23 +219,24 @@ GEM jekyll (>= 3.5, < 5.0) jekyll-feed (~> 0.9) jekyll-seo-tag (~> 2.1) - minitest (5.22.2) + minitest (5.23.1) mutex_m (0.2.0) net-http (0.4.1) uri - nokogiri (1.16.2-x86_64-linux) + nokogiri (1.16.5-x86_64-linux) racc (~> 1.4) octokit (4.25.1) faraday (>= 1, < 3) sawyer (~> 0.9) pathutil (0.16.2) forwardable-extended (~> 2.6) - public_suffix (5.0.4) - racc (1.7.3) + public_suffix (5.0.5) + racc (1.8.0) rb-fsevent (0.11.2) - rb-inotify (0.10.1) + rb-inotify (0.11.1) ffi (~> 1.0) - rexml (3.2.6) + rexml (3.2.8) + strscan (>= 3.0.9) rouge (3.30.0) rubyzip (2.3.2) safe_yaml (1.0.5) @@ -247,17 +248,14 @@ GEM sawyer (0.9.2) addressable (>= 2.3.5) faraday (>= 0.17.3, < 3) - simpleidn (0.2.1) - unf (~> 0.1.4) + simpleidn (0.2.3) + strscan (3.1.0) terminal-table (1.8.0) unicode-display_width (~> 1.1, >= 1.1.1) typhoeus (1.4.1) ethon (>= 0.9.0) tzinfo (2.0.6) concurrent-ruby (~> 1.0) - unf (0.1.4) - unf_ext - unf_ext (0.0.9.1) unicode-display_width (1.8.0) uri (0.13.0) webrick (1.8.1) diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 9855a0bacd..bf7ccbd23f 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -294,780 +294,785 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
If a nested type is package-qualified, this method + * will only return a non-null result for the leftmost (=innermost) + * ASTClassType node. For instance in {@code java.util.Map.Entry}, + * the node {@code java.util.Map} has package qualifier + * {@code "java.util"}, while the node for {@code Entry} + * has package qualifier {@code null}. Note that the + * {@linkplain JClassSymbol#getPackageName() package name} + * of the symbol and type mirror will reflect that package + * name anyway, on both nodes. + */ + public @Nullable String getPackageQualifier() { + if (isFullyQualified()) { + assert symbol != null : "Symbol should be non-null if isFullyQualified returns true"; + return symbol.getPackageName(); + } + return null; + } + @Override protected
R acceptVisitor(JavaVisitor super P, ? extends R> visitor, P data) {
return visitor.visit(this, data);
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCompilationUnit.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCompilationUnit.java
index f6861c8bb7..f9afd45f6e 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCompilationUnit.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCompilationUnit.java
@@ -13,7 +13,6 @@ import net.sourceforge.pmd.annotation.Experimental;
import net.sourceforge.pmd.lang.ast.AstInfo;
import net.sourceforge.pmd.lang.ast.NodeStream;
import net.sourceforge.pmd.lang.ast.RootNode;
-import net.sourceforge.pmd.lang.ast.impl.GenericNode;
import net.sourceforge.pmd.lang.java.symbols.table.JSymbolTable;
import net.sourceforge.pmd.lang.java.types.TypeSystem;
import net.sourceforge.pmd.lang.java.types.ast.internal.LazyTypeResolver;
@@ -49,7 +48,7 @@ import net.sourceforge.pmd.lang.rule.xpath.NoAttribute;
* @see JEP 445: Unnamed Classes and Instance Main Methods (Preview) (Java 21)
* @see #isUnnamedClass()
*/
-public final class ASTCompilationUnit extends AbstractJavaNode implements JavaNode, GenericNode Invalid literals or overflows result in {@code 0L}.
*/
static long parseIntegralValue(Chars image) {
- final int base = getBase(image);
+ final int base = getBase(image, true);
if (base == 8) {
image = image.subSequence(1); // 0
} else if (base != 10) {
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTRecordComponentList.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTRecordComponentList.java
index 082a3e55e7..0ed93007be 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTRecordComponentList.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTRecordComponentList.java
@@ -6,7 +6,6 @@
package net.sourceforge.pmd.lang.java.ast;
import net.sourceforge.pmd.lang.java.ast.ASTList.ASTMaybeEmptyListOf;
-import net.sourceforge.pmd.lang.java.ast.InternalInterfaces.AllChildrenAreOfType;
import net.sourceforge.pmd.lang.java.symbols.JConstructorSymbol;
/**
@@ -18,8 +17,7 @@ import net.sourceforge.pmd.lang.java.symbols.JConstructorSymbol;
*
*
*/
-public final class ASTRecordComponentList extends ASTMaybeEmptyListOf Their syntax is identical though, and described on {@link ASTSwitchLike}.
*/
-public final class ASTSwitchExpression extends AbstractJavaExpr
- implements ASTExpression,
- ASTSwitchLike {
+public final class ASTSwitchExpression extends AbstractJavaExpr implements ASTSwitchLike {
ASTSwitchExpression(int id) {
super(id);
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTVariableId.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTVariableId.java
index 88f97fecfe..c9085fb226 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTVariableId.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTVariableId.java
@@ -43,7 +43,7 @@ import net.sourceforge.pmd.lang.java.types.JTypeMirror;
* Note: This node has been called ASTVariableDeclaratorId in PMD 6.
*/
// @formatter:on
-public final class ASTVariableId extends AbstractTypedSymbolDeclarator
* Type variables do not, in general, use reference identity. Use
* equals to compare them.
*/
-public interface JTypeVar extends JTypeMirror, SubstVar {
+public interface JTypeVar extends SubstVar {
/**
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/Lub.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/Lub.java
index 80e6ac5575..9a589aa79d 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/Lub.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/Lub.java
@@ -340,10 +340,21 @@ final class Lub {
JTypeMirror componentGlb = glb(ts, setOf(((JArrayType) ci).getComponentType(),
((JArrayType) primaryBound).getComponentType()));
primaryBound = ts.arrayType(componentGlb);
+
} else {
- throw new IllegalArgumentException(
- "Bad intersection, unrelated class types " + ci + " and " + primaryBound + " in " + types
- );
+ // We have two primary bounds. This may happen during capture
+ // of recursive F-bounded types. Here we do a last resort check
+ // to see if one of the bounds is a subtype (unchecked) of the other.
+ // In that case we pick this as primary bound as it is more specific.
+
+ int cmp = compareRelatedness(ci.getErasure(), primaryBound.getErasure());
+ if (cmp == 0) {
+ throw new IllegalArgumentException(
+ "Bad intersection, unrelated class types " + ci + " and " + primaryBound + " in " + types
+ );
+ } else if (cmp < 0) {
+ primaryBound = ci;
+ }
}
} else {
bounds.add(ci);
@@ -366,6 +377,15 @@ final class Lub {
return new JIntersectionType(ts, primaryBound, bounds);
}
+ private static int compareRelatedness(JTypeMirror t, JTypeMirror s) {
+ if (TypeOps.isConvertiblePure(t, s.getErasure()).withoutWarnings()) {
+ return -1;
+ } else if (TypeOps.isConvertiblePure(s, t.getErasure()).withoutWarnings()) {
+ return 1;
+ }
+ return 0;
+ }
+
private static void checkGlbComponent(Collection extends JTypeMirror> types, JTypeMirror ci) {
if (ci.isPrimitive() || ci instanceof JWildcardType || ci instanceof JIntersectionType) {
throw new IllegalArgumentException("Bad intersection type component: " + ci + " in " + types);
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java
index 5104bbedfa..66f237ae61 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java
@@ -1091,14 +1091,10 @@ public final class TypeOps {
Hello, world Hello, world Hello, world Hello, world Hello, world Hello, world
* str.trim().length()==0
*
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JAccessibleElementSymbol.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JAccessibleElementSymbol.java
index 956c2fd1ef..37be4bd6d6 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JAccessibleElementSymbol.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JAccessibleElementSymbol.java
@@ -16,7 +16,7 @@ import org.checkerframework.checker.nullness.qual.Nullable;
*
* @since 7.0.0
*/
-public interface JAccessibleElementSymbol extends JElementSymbol, AnnotableSymbol {
+public interface JAccessibleElementSymbol extends AnnotableSymbol {
/**
* Conventional return value of {@link #getPackageName()} for
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JExecutableSymbol.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JExecutableSymbol.java
index 076db24b92..c8bbac2c0f 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JExecutableSymbol.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JExecutableSymbol.java
@@ -19,7 +19,7 @@ import net.sourceforge.pmd.lang.java.types.Substitution;
* Common supertype for {@linkplain JMethodSymbol method}
* and {@linkplain JConstructorSymbol constructor symbols}.
*/
-public interface JExecutableSymbol extends JAccessibleElementSymbol, JTypeParameterOwnerSymbol {
+public interface JExecutableSymbol extends JTypeParameterOwnerSymbol {
/**
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JTypeDeclSymbol.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JTypeDeclSymbol.java
index fbe2aee615..638bcbee7d 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JTypeDeclSymbol.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JTypeDeclSymbol.java
@@ -21,7 +21,7 @@ import net.sourceforge.pmd.lang.java.types.JTypeMirror;
*
* @since 7.0.0
*/
-public interface JTypeDeclSymbol extends JElementSymbol, JAccessibleElementSymbol {
+public interface JTypeDeclSymbol extends JAccessibleElementSymbol {
/**
* Returns true if this class is a symbolic reference to an unresolved
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/AstUnnamedClassSym.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/AstUnnamedClassSym.java
index 1d575cd9d5..c8b8c6da48 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/AstUnnamedClassSym.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/AstUnnamedClassSym.java
@@ -16,12 +16,11 @@ import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTVariableId;
import net.sourceforge.pmd.lang.java.ast.JModifier;
-import net.sourceforge.pmd.lang.java.symbols.JClassSymbol;
import net.sourceforge.pmd.lang.java.symbols.JFieldSymbol;
import net.sourceforge.pmd.lang.java.symbols.JMethodSymbol;
import net.sourceforge.pmd.lang.java.symbols.internal.EmptyClassSymbol;
-class AstUnnamedClassSym extends EmptyClassSymbol implements JClassSymbol {
+class AstUnnamedClassSym extends EmptyClassSymbol {
private final List {
// convenience to build name resolvers
- public