diff --git a/.github/workflows/create_github_release.yml b/.github/workflows/create_github_release.yml index f9969d9627..a7a531948d 100644 --- a/.github/workflows/create_github_release.yml +++ b/.github/workflows/create_github_release.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v3.5.0 + uses: actions/checkout@v3.5.2 - name: Create Release id: create_release diff --git a/.github/workflows/maven_tests.yml b/.github/workflows/maven_tests.yml index eb3de6af65..66281f5504 100644 --- a/.github/workflows/maven_tests.yml +++ b/.github/workflows/maven_tests.yml @@ -46,7 +46,7 @@ jobs: steps: ## Checkout the current version of the code from the repo. - name: Checkout latest code - uses: actions/checkout@v3.5.0 + uses: actions/checkout@v3.5.2 with: fetch-depth: "0" @@ -85,7 +85,7 @@ jobs: - name: CodeCov - JavaParser Core - uses: codecov/codecov-action@v3.1.1 + uses: codecov/codecov-action@v3.1.3 timeout-minutes: 10 with: files: javaparser-core-testing/target/site/jacoco/jacoco.xml,javaparser-core-testing-bdd/target/site/jacoco/jacoco.xml @@ -95,7 +95,7 @@ jobs: env_vars: OS,JDK - name: CodeCov - JavaParser Symbol Solver - uses: codecov/codecov-action@v3.1.1 + uses: codecov/codecov-action@v3.1.3 timeout-minutes: 10 with: file: javaparser-symbol-solver-testing/target/site/jacoco/jacoco.xml @@ -110,7 +110,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout latest code - uses: actions/checkout@v3.5.0 + uses: actions/checkout@v3.5.2 with: fetch-depth: "0" - name: Set up JDK 11 diff --git a/.github/workflows/prepare_release_changelog.yml b/.github/workflows/prepare_release_changelog.yml index 2c6c175b99..03da6ca7ab 100644 --- a/.github/workflows/prepare_release_changelog.yml +++ b/.github/workflows/prepare_release_changelog.yml @@ -15,7 +15,7 @@ jobs: # Check out current repository - name: Fetch Sources - uses: actions/checkout@v3.5.0 + uses: actions/checkout@v3.5.2 # Setup Java 11 environment for the next steps - name: Setup Java diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index 08ea486aa5..d8b2495a1e 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -14,5 +14,5 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.0/apache-maven-3.9.0-bin.zip +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.1/apache-maven-3.9.1-bin.zip wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar diff --git a/changelog.md b/changelog.md index 0ceed0ca2f..701343bd05 100644 --- a/changelog.md +++ b/changelog.md @@ -1,7 +1,7 @@ -Next Release (Version 3.25.3-snapshot) +Next Release (Version 3.25.4-snapshot) -------------------------------------- -[issues resolved](https://github.com/javaparser/javaparser/milestone/199?closed=1) +[issues resolved](https://github.com/javaparser/javaparser/milestone/200?closed=1) ### Added ### Changed @@ -10,6 +10,53 @@ Next Release (Version 3.25.3-snapshot) ### Fixed ### Security + +Version 3.25.3 +-------------- +[issues resolved](https://github.com/javaparser/javaparser/milestone/199?closed=1) + +### Changed + +* Minor simplification of the Difference class (PR [#4008](https://github.com/javaparser/javaparser/pull/4008) by [@jlerbsc](https://github.com/jlerbsc)) +* Perf: Remove unnecessary methods and quickly return to the Range.cont… (PR [#3996](https://github.com/javaparser/javaparser/pull/3996) by [@jlerbsc](https://github.com/jlerbsc)) + +### Fixed + +* Fix: issue 1843 Problems with hasAnnotation() and hasDirectlyAnnotati… (PR [#4015](https://github.com/javaparser/javaparser/pull/4015) by [@jlerbsc](https://github.com/jlerbsc)) +* Fix: Issue 3995 resolving a method call with a variadic argument of p… (PR [#3998](https://github.com/javaparser/javaparser/pull/3998) by [@jlerbsc](https://github.com/jlerbsc)) +* Fix: issue 3983 why FieldDeclaration in an interface calling isStatic… (PR [#3986](https://github.com/javaparser/javaparser/pull/3986) by [@jlerbsc](https://github.com/jlerbsc)) + +### Developer Changes + +* chore(deps): bump checkstyle from 10.9.3 to 10.10.0 (PR [#4014](https://github.com/javaparser/javaparser/pull/4014) by [@dependabot[bot]](https://github.com/apps/dependabot)) +* chore(deps): update junit5 monorepo to v5.9.3 (PR [#4012](https://github.com/javaparser/javaparser/pull/4012) by [@renovate[bot]](https://github.com/apps/renovate)) +* chore(deps): bump jacoco-maven-plugin from 0.8.9 to 0.8.10 (PR [#4011](https://github.com/javaparser/javaparser/pull/4011) by [@dependabot[bot]](https://github.com/apps/dependabot)) +* chore(deps-dev): bump okhttp from 4.10.0 to 4.11.0 (PR [#4009](https://github.com/javaparser/javaparser/pull/4009) by [@dependabot[bot]](https://github.com/apps/dependabot)) +* chore(deps): bump codecov/codecov-action from 3.1.2 to 3.1.3 (PR [#4006](https://github.com/javaparser/javaparser/pull/4006) by [@dependabot[bot]](https://github.com/apps/dependabot)) +* chore(deps): bump maven-checkstyle-plugin from 3.2.1 to 3.2.2 (PR [#4005](https://github.com/javaparser/javaparser/pull/4005) by [@dependabot[bot]](https://github.com/apps/dependabot)) +* chore(deps): bump actions/checkout from 3.5.1 to 3.5.2 (PR [#3994](https://github.com/javaparser/javaparser/pull/3994) by [@dependabot[bot]](https://github.com/apps/dependabot)) +* chore(deps): bump actions/checkout from 3.5.0 to 3.5.1 (PR [#3992](https://github.com/javaparser/javaparser/pull/3992) by [@dependabot[bot]](https://github.com/apps/dependabot)) +* chore(deps): bump codecov/codecov-action from 3.1.1 to 3.1.2 (PR [#3988](https://github.com/javaparser/javaparser/pull/3988) by [@dependabot[bot]](https://github.com/apps/dependabot)) +* chore(deps): bump maven-deploy-plugin from 3.1.0 to 3.1.1 (PR [#3985](https://github.com/javaparser/javaparser/pull/3985) by [@dependabot[bot]](https://github.com/apps/dependabot)) +* chore(deps): bump jacoco-maven-plugin from 0.8.8 to 0.8.9 (PR [#3981](https://github.com/javaparser/javaparser/pull/3981) by [@dependabot[bot]](https://github.com/apps/dependabot)) +* chore(deps): bump checkstyle from 10.9.1 to 10.9.3 (PR [#3980](https://github.com/javaparser/javaparser/pull/3980) by [@dependabot[bot]](https://github.com/apps/dependabot)) +* chore(deps): bump maven-resources-plugin from 3.3.0 to 3.3.1 (PR [#3979](https://github.com/javaparser/javaparser/pull/3979) by [@dependabot[bot]](https://github.com/apps/dependabot)) +* chore(deps): bump maven-install-plugin from 3.1.0 to 3.1.1 (PR [#3975](https://github.com/javaparser/javaparser/pull/3975) by [@dependabot[bot]](https://github.com/apps/dependabot)) +* chore(deps): bump maven-release-plugin from 2.5.3 to 3.0.0 (PR [#3965](https://github.com/javaparser/javaparser/pull/3965) by [@dependabot[bot]](https://github.com/apps/dependabot)) + +### Uncategorised + +* add test for showing interface field shall be static & final (PR [#3984](https://github.com/javaparser/javaparser/pull/3984) by [@XenoAmess](https://github.com/XenoAmess)) + +### :heart: Contributors + +Thank You to all contributors who worked on this release! + +* [@kris-scheibe](https://github.com/kris-scheibe) +* [@jlerbsc](https://github.com/jlerbsc) +* [@XenoAmess](https://github.com/XenoAmess) + + Version 3.25.2 -------------- [issues resolved](https://github.com/javaparser/javaparser/milestone/198?closed=1) diff --git a/javaparser-core-generators/pom.xml b/javaparser-core-generators/pom.xml index 44363b7592..5026710358 100644 --- a/javaparser-core-generators/pom.xml +++ b/javaparser-core-generators/pom.xml @@ -3,7 +3,7 @@ javaparser-parent com.github.javaparser - 3.25.2 + 3.25.3 4.0.0 diff --git a/javaparser-core-metamodel-generator/pom.xml b/javaparser-core-metamodel-generator/pom.xml index 529079cceb..192c0d5df4 100644 --- a/javaparser-core-metamodel-generator/pom.xml +++ b/javaparser-core-metamodel-generator/pom.xml @@ -3,7 +3,7 @@ javaparser-parent com.github.javaparser - 3.25.2 + 3.25.3 4.0.0 diff --git a/javaparser-core-serialization/pom.xml b/javaparser-core-serialization/pom.xml index 95cd7fc419..b240d7489b 100644 --- a/javaparser-core-serialization/pom.xml +++ b/javaparser-core-serialization/pom.xml @@ -2,7 +2,7 @@ javaparser-parent com.github.javaparser - 3.25.2 + 3.25.3 4.0.0 diff --git a/javaparser-core-serialization/src/test/java/com/github/javaparser/serialization/JavaParserJsonSerializerTest.java b/javaparser-core-serialization/src/test/java/com/github/javaparser/serialization/JavaParserJsonSerializerTest.java index 8be2cdaa5b..dd347dc871 100644 --- a/javaparser-core-serialization/src/test/java/com/github/javaparser/serialization/JavaParserJsonSerializerTest.java +++ b/javaparser-core-serialization/src/test/java/com/github/javaparser/serialization/JavaParserJsonSerializerTest.java @@ -41,7 +41,7 @@ void test() { String serialized = serialize(cu, false); - assertEquals("{\"!\":\"com.github.javaparser.ast.CompilationUnit\",\"range\":{\"beginLine\":1,\"beginColumn\":1,\"endLine\":1,\"endColumn\":23},\"tokenRange\":{\"beginToken\":{\"kind\":19,\"text\":\"class\"},\"endToken\":{\"kind\":0,\"text\":\"\"}},\"imports\":[],\"types\":[{\"!\":\"com.github.javaparser.ast.body.ClassOrInterfaceDeclaration\",\"range\":{\"beginLine\":1,\"beginColumn\":1,\"endLine\":1,\"endColumn\":23},\"tokenRange\":{\"beginToken\":{\"kind\":19,\"text\":\"class\"},\"endToken\":{\"kind\":100,\"text\":\"}\"}},\"extendedTypes\":[],\"implementedTypes\":[],\"isInterface\":\"false\",\"typeParameters\":[],\"members\":[{\"!\":\"com.github.javaparser.ast.body.FieldDeclaration\",\"range\":{\"beginLine\":1,\"beginColumn\":9,\"endLine\":1,\"endColumn\":22},\"tokenRange\":{\"beginToken\":{\"kind\":94,\"text\":\"java\"},\"endToken\":{\"kind\":103,\"text\":\";\"}},\"modifiers\":[],\"variables\":[{\"!\":\"com.github.javaparser.ast.body.VariableDeclarator\",\"range\":{\"beginLine\":1,\"beginColumn\":21,\"endLine\":1,\"endColumn\":21},\"tokenRange\":{\"beginToken\":{\"kind\":94,\"text\":\"y\"},\"endToken\":{\"kind\":94,\"text\":\"y\"}},\"name\":{\"!\":\"com.github.javaparser.ast.expr.SimpleName\",\"range\":{\"beginLine\":1,\"beginColumn\":21,\"endLine\":1,\"endColumn\":21},\"tokenRange\":{\"beginToken\":{\"kind\":94,\"text\":\"y\"},\"endToken\":{\"kind\":94,\"text\":\"y\"}},\"identifier\":\"y\"},\"type\":{\"!\":\"com.github.javaparser.ast.type.ClassOrInterfaceType\",\"range\":{\"beginLine\":1,\"beginColumn\":9,\"endLine\":1,\"endColumn\":19},\"tokenRange\":{\"beginToken\":{\"kind\":94,\"text\":\"java\"},\"endToken\":{\"kind\":94,\"text\":\"Y\"}},\"name\":{\"!\":\"com.github.javaparser.ast.expr.SimpleName\",\"range\":{\"beginLine\":1,\"beginColumn\":19,\"endLine\":1,\"endColumn\":19},\"tokenRange\":{\"beginToken\":{\"kind\":94,\"text\":\"Y\"},\"endToken\":{\"kind\":94,\"text\":\"Y\"}},\"identifier\":\"Y\"},\"scope\":{\"!\":\"com.github.javaparser.ast.type.ClassOrInterfaceType\",\"range\":{\"beginLine\":1,\"beginColumn\":9,\"endLine\":1,\"endColumn\":17},\"tokenRange\":{\"beginToken\":{\"kind\":94,\"text\":\"java\"},\"endToken\":{\"kind\":94,\"text\":\"util\"}},\"name\":{\"!\":\"com.github.javaparser.ast.expr.SimpleName\",\"range\":{\"beginLine\":1,\"beginColumn\":14,\"endLine\":1,\"endColumn\":17},\"tokenRange\":{\"beginToken\":{\"kind\":94,\"text\":\"util\"},\"endToken\":{\"kind\":94,\"text\":\"util\"}},\"identifier\":\"util\"},\"scope\":{\"!\":\"com.github.javaparser.ast.type.ClassOrInterfaceType\",\"range\":{\"beginLine\":1,\"beginColumn\":9,\"endLine\":1,\"endColumn\":12},\"tokenRange\":{\"beginToken\":{\"kind\":94,\"text\":\"java\"},\"endToken\":{\"kind\":94,\"text\":\"java\"}},\"name\":{\"!\":\"com.github.javaparser.ast.expr.SimpleName\",\"range\":{\"beginLine\":1,\"beginColumn\":9,\"endLine\":1,\"endColumn\":12},\"tokenRange\":{\"beginToken\":{\"kind\":94,\"text\":\"java\"},\"endToken\":{\"kind\":94,\"text\":\"java\"}},\"identifier\":\"java\"},\"annotations\":[]},\"annotations\":[]},\"annotations\":[]}}],\"annotations\":[]}],\"modifiers\":[],\"name\":{\"!\":\"com.github.javaparser.ast.expr.SimpleName\",\"range\":{\"beginLine\":1,\"beginColumn\":7,\"endLine\":1,\"endColumn\":7},\"tokenRange\":{\"beginToken\":{\"kind\":94,\"text\":\"X\"},\"endToken\":{\"kind\":94,\"text\":\"X\"}},\"identifier\":\"X\"},\"annotations\":[]}]}", serialized); + assertEquals("{\"!\":\"com.github.javaparser.ast.CompilationUnit\",\"range\":{\"beginLine\":1,\"beginColumn\":1,\"endLine\":1,\"endColumn\":23},\"tokenRange\":{\"beginToken\":{\"kind\":19,\"text\":\"class\"},\"endToken\":{\"kind\":0,\"text\":\"\"}},\"imports\":[],\"types\":[{\"!\":\"com.github.javaparser.ast.body.ClassOrInterfaceDeclaration\",\"range\":{\"beginLine\":1,\"beginColumn\":1,\"endLine\":1,\"endColumn\":23},\"tokenRange\":{\"beginToken\":{\"kind\":19,\"text\":\"class\"},\"endToken\":{\"kind\":103,\"text\":\"}\"}},\"extendedTypes\":[],\"implementedTypes\":[],\"isInterface\":\"false\",\"permittedTypes\":[],\"typeParameters\":[],\"members\":[{\"!\":\"com.github.javaparser.ast.body.FieldDeclaration\",\"range\":{\"beginLine\":1,\"beginColumn\":9,\"endLine\":1,\"endColumn\":22},\"tokenRange\":{\"beginToken\":{\"kind\":97,\"text\":\"java\"},\"endToken\":{\"kind\":106,\"text\":\";\"}},\"modifiers\":[],\"variables\":[{\"!\":\"com.github.javaparser.ast.body.VariableDeclarator\",\"range\":{\"beginLine\":1,\"beginColumn\":21,\"endLine\":1,\"endColumn\":21},\"tokenRange\":{\"beginToken\":{\"kind\":97,\"text\":\"y\"},\"endToken\":{\"kind\":97,\"text\":\"y\"}},\"name\":{\"!\":\"com.github.javaparser.ast.expr.SimpleName\",\"range\":{\"beginLine\":1,\"beginColumn\":21,\"endLine\":1,\"endColumn\":21},\"tokenRange\":{\"beginToken\":{\"kind\":97,\"text\":\"y\"},\"endToken\":{\"kind\":97,\"text\":\"y\"}},\"identifier\":\"y\"},\"type\":{\"!\":\"com.github.javaparser.ast.type.ClassOrInterfaceType\",\"range\":{\"beginLine\":1,\"beginColumn\":9,\"endLine\":1,\"endColumn\":19},\"tokenRange\":{\"beginToken\":{\"kind\":97,\"text\":\"java\"},\"endToken\":{\"kind\":97,\"text\":\"Y\"}},\"name\":{\"!\":\"com.github.javaparser.ast.expr.SimpleName\",\"range\":{\"beginLine\":1,\"beginColumn\":19,\"endLine\":1,\"endColumn\":19},\"tokenRange\":{\"beginToken\":{\"kind\":97,\"text\":\"Y\"},\"endToken\":{\"kind\":97,\"text\":\"Y\"}},\"identifier\":\"Y\"},\"scope\":{\"!\":\"com.github.javaparser.ast.type.ClassOrInterfaceType\",\"range\":{\"beginLine\":1,\"beginColumn\":9,\"endLine\":1,\"endColumn\":17},\"tokenRange\":{\"beginToken\":{\"kind\":97,\"text\":\"java\"},\"endToken\":{\"kind\":97,\"text\":\"util\"}},\"name\":{\"!\":\"com.github.javaparser.ast.expr.SimpleName\",\"range\":{\"beginLine\":1,\"beginColumn\":14,\"endLine\":1,\"endColumn\":17},\"tokenRange\":{\"beginToken\":{\"kind\":97,\"text\":\"util\"},\"endToken\":{\"kind\":97,\"text\":\"util\"}},\"identifier\":\"util\"},\"scope\":{\"!\":\"com.github.javaparser.ast.type.ClassOrInterfaceType\",\"range\":{\"beginLine\":1,\"beginColumn\":9,\"endLine\":1,\"endColumn\":12},\"tokenRange\":{\"beginToken\":{\"kind\":97,\"text\":\"java\"},\"endToken\":{\"kind\":97,\"text\":\"java\"}},\"name\":{\"!\":\"com.github.javaparser.ast.expr.SimpleName\",\"range\":{\"beginLine\":1,\"beginColumn\":9,\"endLine\":1,\"endColumn\":12},\"tokenRange\":{\"beginToken\":{\"kind\":97,\"text\":\"java\"},\"endToken\":{\"kind\":97,\"text\":\"java\"}},\"identifier\":\"java\"},\"annotations\":[]},\"annotations\":[]},\"annotations\":[]}}],\"annotations\":[]}],\"modifiers\":[],\"name\":{\"!\":\"com.github.javaparser.ast.expr.SimpleName\",\"range\":{\"beginLine\":1,\"beginColumn\":7,\"endLine\":1,\"endColumn\":7},\"tokenRange\":{\"beginToken\":{\"kind\":97,\"text\":\"X\"},\"endToken\":{\"kind\":97,\"text\":\"X\"}},\"identifier\":\"X\"},\"annotations\":[]}]}", serialized); } static String serialize(Node node, boolean prettyPrint) { diff --git a/javaparser-core-testing-bdd/pom.xml b/javaparser-core-testing-bdd/pom.xml index 10ceab2ab0..beaea91e21 100644 --- a/javaparser-core-testing-bdd/pom.xml +++ b/javaparser-core-testing-bdd/pom.xml @@ -2,7 +2,7 @@ javaparser-parent com.github.javaparser - 3.25.2 + 3.25.3 4.0.0 diff --git a/javaparser-core-testing/pom.xml b/javaparser-core-testing/pom.xml index d63c10e2cf..3a053e7da7 100644 --- a/javaparser-core-testing/pom.xml +++ b/javaparser-core-testing/pom.xml @@ -2,7 +2,7 @@ javaparser-parent com.github.javaparser - 3.25.2 + 3.25.3 4.0.0 @@ -131,7 +131,7 @@ com.squareup.okhttp3 okhttp - 4.10.0 + 4.11.0 test diff --git a/javaparser-core-testing/src/test/java/com/github/javaparser/JavaParserTest.java b/javaparser-core-testing/src/test/java/com/github/javaparser/JavaParserTest.java index 284479c13f..7c43f42436 100644 --- a/javaparser-core-testing/src/test/java/com/github/javaparser/JavaParserTest.java +++ b/javaparser-core-testing/src/test/java/com/github/javaparser/JavaParserTest.java @@ -142,7 +142,7 @@ void parseErrorContainsLocation() { Problem problem = result.getProblem(0); assertEquals(range(1, 9, 1, 17), problem.getLocation().get().toRange().get()); - assertEquals("Parse error. Found , expected one of \";\" \"<\" \"@\" \"abstract\" \"boolean\" \"byte\" \"char\" \"class\" \"default\" \"double\" \"enum\" \"exports\" \"final\" \"float\" \"int\" \"interface\" \"long\" \"module\" \"native\" \"open\" \"opens\" \"private\" \"protected\" \"provides\" \"public\" \"record\" \"requires\" \"short\" \"static\" \"strictfp\" \"synchronized\" \"to\" \"transient\" \"transitive\" \"uses\" \"void\" \"volatile\" \"with\" \"yield\" \"{\" \"}\" ", problem.getMessage()); + assertEquals("Parse error. Found , expected one of \";\" \"<\" \"@\" \"abstract\" \"boolean\" \"byte\" \"char\" \"class\" \"default\" \"double\" \"enum\" \"exports\" \"final\" \"float\" \"int\" \"interface\" \"long\" \"module\" \"native\" \"non-sealed\" \"open\" \"opens\" \"private\" \"protected\" \"provides\" \"public\" \"record\" \"requires\" \"sealed\" \"short\" \"static\" \"strictfp\" \"synchronized\" \"to\" \"transient\" \"transitive\" \"uses\" \"void\" \"volatile\" \"with\" \"yield\" \"{\" \"}\" ", problem.getMessage()); assertInstanceOf(ParseException.class, problem.getCause().get()); } diff --git a/javaparser-core-testing/src/test/java/com/github/javaparser/ast/body/ClassOrInterfaceDeclarationTest.java b/javaparser-core-testing/src/test/java/com/github/javaparser/ast/body/ClassOrInterfaceDeclarationTest.java index f33557b2e6..a1bed1c52a 100644 --- a/javaparser-core-testing/src/test/java/com/github/javaparser/ast/body/ClassOrInterfaceDeclarationTest.java +++ b/javaparser-core-testing/src/test/java/com/github/javaparser/ast/body/ClassOrInterfaceDeclarationTest.java @@ -21,11 +21,15 @@ package com.github.javaparser.ast.body; +import com.github.javaparser.ParserConfiguration; import com.github.javaparser.ast.CompilationUnit; +import com.github.javaparser.ast.Modifier; +import com.github.javaparser.utils.TestParser; import org.junit.jupiter.api.Test; import static com.github.javaparser.StaticJavaParser.parse; import static com.github.javaparser.StaticJavaParser.parseBodyDeclaration; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -79,4 +83,30 @@ void localClass() { assertFalse(x.isNestedType()); assertTrue(x.isLocalClassDeclaration()); } + + @Test + void sealedClass() { + CompilationUnit cu = TestParser.parseCompilationUnit(ParserConfiguration.LanguageLevel.JAVA_17, "sealed class X permits Y, Z {}"); + ClassOrInterfaceDeclaration x = cu.getClassByName("X").get(); + + assertFalse(x.isInnerClass()); + assertFalse(x.isNestedType()); + assertFalse(x.isLocalClassDeclaration()); + assertTrue(x.hasModifier(Modifier.Keyword.SEALED)); + assertEquals(x.getPermittedTypes().size(), 2); + assertEquals(x.getPermittedTypes().get(0).getNameAsString(), "Y"); + assertEquals(x.getPermittedTypes().get(1).getNameAsString(), "Z"); + } + + @Test + void nonSealedClass() { + CompilationUnit cu = TestParser.parseCompilationUnit(ParserConfiguration.LanguageLevel.JAVA_17, "non-sealed class X{}"); + ClassOrInterfaceDeclaration x = cu.getClassByName("X").get(); + + assertFalse(x.isInnerClass()); + assertFalse(x.isNestedType()); + assertFalse(x.isLocalClassDeclaration()); + assertTrue(x.hasModifier(Modifier.Keyword.NON_SEALED)); + } + } diff --git a/javaparser-core-testing/src/test/java/com/github/javaparser/ast/body/FieldDeclarationTest.java b/javaparser-core-testing/src/test/java/com/github/javaparser/ast/body/FieldDeclarationTest.java index afbfe7f2f8..d2c2369ca8 100644 --- a/javaparser-core-testing/src/test/java/com/github/javaparser/ast/body/FieldDeclarationTest.java +++ b/javaparser-core-testing/src/test/java/com/github/javaparser/ast/body/FieldDeclarationTest.java @@ -25,6 +25,7 @@ import com.github.javaparser.ast.Modifier; import com.github.javaparser.ast.Modifier.Keyword; import com.github.javaparser.ast.NodeList; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import static com.github.javaparser.StaticJavaParser.parse; @@ -77,4 +78,26 @@ private void testChangingModifiers(FieldDeclaration field) { assertTrue(modifiers.contains(Modifier.synchronizedModifier())); assertEquals(2, modifiers.size()); } + + @Test + void interfaceFieldTest() { + CompilationUnit compilationUnit = parse("" + + "interface A {\n" + + " int a = 1;\n" + + " static int a_s = 1;\n" + + " final int a_f = 1;\n" + + " static final int a_s_f = 1;\n" + + " String b = \"b\";\n" + + " static String b_s = \"b\";\n" + + " final String b_f = \"b\";\n" + + " static final String b_s_f = \"b\";\n" + + "}\n"); + for (int i = 0; i < 8; ++i) { + BodyDeclaration declaration = compilationUnit.getType(0).getMembers().get(i); + FieldDeclaration fieldDeclaration = declaration.asFieldDeclaration(); + Assertions.assertTrue(fieldDeclaration.isStatic()); + Assertions.assertTrue(fieldDeclaration.isFinal()); + } + } + } diff --git a/javaparser-core-testing/src/test/java/com/github/javaparser/ast/validator/Java17ValidatorTest.java b/javaparser-core-testing/src/test/java/com/github/javaparser/ast/validator/Java17ValidatorTest.java new file mode 100644 index 0000000000..78355b9366 --- /dev/null +++ b/javaparser-core-testing/src/test/java/com/github/javaparser/ast/validator/Java17ValidatorTest.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2007-2010 Júlio Vilmar Gesser. + * Copyright (C) 2011, 2013-2023 The JavaParser Team. + * + * This file is part of JavaParser. + * + * JavaParser can be used either under the terms of + * a) the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * b) the terms of the Apache License + * + * You should have received a copy of both licenses in LICENCE.LGPL and + * LICENCE.APACHE. Please refer to those files for details. + * + * JavaParser is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + */ + +package com.github.javaparser.ast.validator; + +import com.github.javaparser.JavaParser; +import com.github.javaparser.ParseResult; +import com.github.javaparser.ParserConfiguration; +import com.github.javaparser.ast.CompilationUnit; +import com.github.javaparser.utils.TestUtils; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import static com.github.javaparser.ParseStart.COMPILATION_UNIT; +import static com.github.javaparser.ParserConfiguration.LanguageLevel.JAVA_17; +import static com.github.javaparser.Providers.provider; + +class Java17ValidatorTest { + + private final JavaParser javaParser = new JavaParser(new ParserConfiguration().setLanguageLevel(JAVA_17)); + + @Nested + class Sealed { + + @Test + void sealedAllowed() { + ParseResult result = javaParser.parse(COMPILATION_UNIT, provider("sealed class X permits Y, Z {}")); + TestUtils.assertNoProblems(result); + } + + @Test + void nonSealedAllowed() { + ParseResult result = javaParser.parse(COMPILATION_UNIT, provider("non-sealed class X {}")); + TestUtils.assertNoProblems(result); + } + + } + +} diff --git a/javaparser-core/pom.xml b/javaparser-core/pom.xml index 754c667b46..ef836fb6ef 100644 --- a/javaparser-core/pom.xml +++ b/javaparser-core/pom.xml @@ -2,7 +2,7 @@ javaparser-parent com.github.javaparser - 3.25.2 + 3.25.3 4.0.0 @@ -30,7 +30,7 @@ - stubparser-3.25.2 + stubparser-3.25.3 com.helger.maven diff --git a/javaparser-core/src/main/java/com/github/javaparser/JavaToken.java b/javaparser-core/src/main/java/com/github/javaparser/JavaToken.java index 8530232cea..ce7b9e8e91 100644 --- a/javaparser-core/src/main/java/com/github/javaparser/JavaToken.java +++ b/javaparser-core/src/main/java/com/github/javaparser/JavaToken.java @@ -300,111 +300,114 @@ public enum Kind { LONG(40), NATIVE(41), NEW(42), - NULL(43), - PACKAGE(44), - PRIVATE(45), - PROTECTED(46), - PUBLIC(47), - RECORD(48), - RETURN(49), - SHORT(50), - STATIC(51), - STRICTFP(52), - SUPER(53), - SWITCH(54), - SYNCHRONIZED(55), - THIS(56), - THROW(57), - THROWS(58), - TRANSIENT(59), - TRUE(60), - TRY(61), - VOID(62), - VOLATILE(63), - WHILE(64), - YIELD(65), - REQUIRES(66), - TO(67), - WITH(68), - OPEN(69), - OPENS(70), - USES(71), - MODULE(72), - EXPORTS(73), - PROVIDES(74), - TRANSITIVE(75), - LONG_LITERAL(76), - INTEGER_LITERAL(77), - DECIMAL_LITERAL(78), - HEX_LITERAL(79), - OCTAL_LITERAL(80), - BINARY_LITERAL(81), - FLOATING_POINT_LITERAL(82), - DECIMAL_FLOATING_POINT_LITERAL(83), - DECIMAL_EXPONENT(84), - HEXADECIMAL_FLOATING_POINT_LITERAL(85), - HEXADECIMAL_EXPONENT(86), - HEX_DIGITS(87), - UNICODE_ESCAPE(88), - CHARACTER_LITERAL(89), - STRING_LITERAL(90), - ENTER_TEXT_BLOCK(91), - TEXT_BLOCK_LITERAL(92), - TEXT_BLOCK_CONTENT(93), - IDENTIFIER(94), - LETTER(95), - PART_LETTER(96), - LPAREN(97), - RPAREN(98), - LBRACE(99), - RBRACE(100), - LBRACKET(101), - RBRACKET(102), - SEMICOLON(103), - COMMA(104), - DOT(105), - ELLIPSIS(106), - AT(107), - DOUBLECOLON(108), - ASSIGN(109), - LT(110), - BANG(111), - TILDE(112), - HOOK(113), - COLON(114), - ARROW(115), - EQ(116), - GE(117), - LE(118), - NE(119), - SC_AND(120), - SC_OR(121), - INCR(122), - DECR(123), - PLUS(124), - MINUS(125), - STAR(126), - SLASH(127), - BIT_AND(128), - BIT_OR(129), - XOR(130), - REM(131), - LSHIFT(132), - PLUSASSIGN(133), - MINUSASSIGN(134), - STARASSIGN(135), - SLASHASSIGN(136), - ANDASSIGN(137), - ORASSIGN(138), - XORASSIGN(139), - REMASSIGN(140), - LSHIFTASSIGN(141), - RSIGNEDSHIFTASSIGN(142), - RUNSIGNEDSHIFTASSIGN(143), - RUNSIGNEDSHIFT(144), - RSIGNEDSHIFT(145), - GT(146), - CTRL_Z(147); + NON_SEALED(43), + NULL(44), + PACKAGE(45), + PERMITS(46), + PRIVATE(47), + PROTECTED(48), + PUBLIC(49), + RECORD(50), + RETURN(51), + SEALED(52), + SHORT(53), + STATIC(54), + STRICTFP(55), + SUPER(56), + SWITCH(57), + SYNCHRONIZED(58), + THIS(59), + THROW(60), + THROWS(61), + TRANSIENT(62), + TRUE(63), + TRY(64), + VOID(65), + VOLATILE(66), + WHILE(67), + YIELD(68), + REQUIRES(69), + TO(70), + WITH(71), + OPEN(72), + OPENS(73), + USES(74), + MODULE(75), + EXPORTS(76), + PROVIDES(77), + TRANSITIVE(78), + LONG_LITERAL(79), + INTEGER_LITERAL(80), + DECIMAL_LITERAL(81), + HEX_LITERAL(82), + OCTAL_LITERAL(83), + BINARY_LITERAL(84), + FLOATING_POINT_LITERAL(85), + DECIMAL_FLOATING_POINT_LITERAL(86), + DECIMAL_EXPONENT(87), + HEXADECIMAL_FLOATING_POINT_LITERAL(88), + HEXADECIMAL_EXPONENT(89), + HEX_DIGITS(90), + UNICODE_ESCAPE(91), + CHARACTER_LITERAL(92), + STRING_LITERAL(93), + ENTER_TEXT_BLOCK(94), + TEXT_BLOCK_LITERAL(95), + TEXT_BLOCK_CONTENT(96), + IDENTIFIER(97), + LETTER(98), + PART_LETTER(99), + LPAREN(100), + RPAREN(101), + LBRACE(102), + RBRACE(103), + LBRACKET(104), + RBRACKET(105), + SEMICOLON(106), + COMMA(107), + DOT(108), + ELLIPSIS(109), + AT(110), + DOUBLECOLON(111), + ASSIGN(112), + LT(113), + BANG(114), + TILDE(115), + HOOK(116), + COLON(117), + ARROW(118), + EQ(119), + GE(120), + LE(121), + NE(122), + SC_AND(123), + SC_OR(124), + INCR(125), + DECR(126), + PLUS(127), + MINUS(128), + STAR(129), + SLASH(130), + BIT_AND(131), + BIT_OR(132), + XOR(133), + REM(134), + LSHIFT(135), + PLUSASSIGN(136), + MINUSASSIGN(137), + STARASSIGN(138), + SLASHASSIGN(139), + ANDASSIGN(140), + ORASSIGN(141), + XORASSIGN(142), + REMASSIGN(143), + LSHIFTASSIGN(144), + RSIGNEDSHIFTASSIGN(145), + RUNSIGNEDSHIFTASSIGN(146), + RUNSIGNEDSHIFT(147), + RSIGNEDSHIFT(148), + GT(149), + CTRL_Z(150); private final int kind; @@ -414,216 +417,222 @@ public enum Kind { public static Kind valueOf(int kind) { switch(kind) { - case 147: + case 150: return CTRL_Z; - case 146: + case 149: return GT; - case 145: + case 148: return RSIGNEDSHIFT; - case 144: + case 147: return RUNSIGNEDSHIFT; - case 143: + case 146: return RUNSIGNEDSHIFTASSIGN; - case 142: + case 145: return RSIGNEDSHIFTASSIGN; - case 141: + case 144: return LSHIFTASSIGN; - case 140: + case 143: return REMASSIGN; - case 139: + case 142: return XORASSIGN; - case 138: + case 141: return ORASSIGN; - case 137: + case 140: return ANDASSIGN; - case 136: + case 139: return SLASHASSIGN; - case 135: + case 138: return STARASSIGN; - case 134: + case 137: return MINUSASSIGN; - case 133: + case 136: return PLUSASSIGN; - case 132: + case 135: return LSHIFT; - case 131: + case 134: return REM; - case 130: + case 133: return XOR; - case 129: + case 132: return BIT_OR; - case 128: + case 131: return BIT_AND; - case 127: + case 130: return SLASH; - case 126: + case 129: return STAR; - case 125: + case 128: return MINUS; - case 124: + case 127: return PLUS; - case 123: + case 126: return DECR; - case 122: + case 125: return INCR; - case 121: + case 124: return SC_OR; - case 120: + case 123: return SC_AND; - case 119: + case 122: return NE; - case 118: + case 121: return LE; - case 117: + case 120: return GE; - case 116: + case 119: return EQ; - case 115: + case 118: return ARROW; - case 114: + case 117: return COLON; - case 113: + case 116: return HOOK; - case 112: + case 115: return TILDE; - case 111: + case 114: return BANG; - case 110: + case 113: return LT; - case 109: + case 112: return ASSIGN; - case 108: + case 111: return DOUBLECOLON; - case 107: + case 110: return AT; - case 106: + case 109: return ELLIPSIS; - case 105: + case 108: return DOT; - case 104: + case 107: return COMMA; - case 103: + case 106: return SEMICOLON; - case 102: + case 105: return RBRACKET; - case 101: + case 104: return LBRACKET; - case 100: + case 103: return RBRACE; - case 99: + case 102: return LBRACE; - case 98: + case 101: return RPAREN; - case 97: + case 100: return LPAREN; - case 96: + case 99: return PART_LETTER; - case 95: + case 98: return LETTER; - case 94: + case 97: return IDENTIFIER; - case 93: + case 96: return TEXT_BLOCK_CONTENT; - case 92: + case 95: return TEXT_BLOCK_LITERAL; - case 91: + case 94: return ENTER_TEXT_BLOCK; - case 90: + case 93: return STRING_LITERAL; - case 89: + case 92: return CHARACTER_LITERAL; - case 88: + case 91: return UNICODE_ESCAPE; - case 87: + case 90: return HEX_DIGITS; - case 86: + case 89: return HEXADECIMAL_EXPONENT; - case 85: + case 88: return HEXADECIMAL_FLOATING_POINT_LITERAL; - case 84: + case 87: return DECIMAL_EXPONENT; - case 83: + case 86: return DECIMAL_FLOATING_POINT_LITERAL; - case 82: + case 85: return FLOATING_POINT_LITERAL; - case 81: + case 84: return BINARY_LITERAL; - case 80: + case 83: return OCTAL_LITERAL; - case 79: + case 82: return HEX_LITERAL; - case 78: + case 81: return DECIMAL_LITERAL; - case 77: + case 80: return INTEGER_LITERAL; - case 76: + case 79: return LONG_LITERAL; - case 75: + case 78: return TRANSITIVE; - case 74: + case 77: return PROVIDES; - case 73: + case 76: return EXPORTS; - case 72: + case 75: return MODULE; - case 71: + case 74: return USES; - case 70: + case 73: return OPENS; - case 69: + case 72: return OPEN; - case 68: + case 71: return WITH; - case 67: + case 70: return TO; - case 66: + case 69: return REQUIRES; - case 65: + case 68: return YIELD; - case 64: + case 67: return WHILE; - case 63: + case 66: return VOLATILE; - case 62: + case 65: return VOID; - case 61: + case 64: return TRY; - case 60: + case 63: return TRUE; - case 59: + case 62: return TRANSIENT; - case 58: + case 61: return THROWS; - case 57: + case 60: return THROW; - case 56: + case 59: return THIS; - case 55: + case 58: return SYNCHRONIZED; - case 54: + case 57: return SWITCH; - case 53: + case 56: return SUPER; - case 52: + case 55: return STRICTFP; - case 51: + case 54: return STATIC; - case 50: + case 53: return SHORT; - case 49: + case 52: + return SEALED; + case 51: return RETURN; - case 48: + case 50: return RECORD; - case 47: + case 49: return PUBLIC; - case 46: + case 48: return PROTECTED; - case 45: + case 47: return PRIVATE; - case 44: + case 46: + return PERMITS; + case 45: return PACKAGE; - case 43: + case 44: return NULL; + case 43: + return NON_SEALED; case 42: return NEW; case 41: diff --git a/javaparser-core/src/main/java/com/github/javaparser/Position.java b/javaparser-core/src/main/java/com/github/javaparser/Position.java index 4888d58aba..e3a1756dcb 100644 --- a/javaparser-core/src/main/java/com/github/javaparser/Position.java +++ b/javaparser-core/src/main/java/com/github/javaparser/Position.java @@ -20,10 +20,10 @@ */ package com.github.javaparser; -import java.util.Objects; - import static com.github.javaparser.utils.Utils.assertNotNull; +import java.util.Objects; + /** * A position in a source file. Lines and columns start counting at 1. */ @@ -156,7 +156,6 @@ public boolean isAfter(Position otherPosition) { } public boolean isAfterOrEqual(Position otherPosition) { - assertNotNull(otherPosition); return isAfter(otherPosition) || equals(otherPosition); } @@ -173,7 +172,6 @@ public boolean isBefore(Position otherPosition) { } public boolean isBeforeOrEqual(Position otherPosition) { - assertNotNull(otherPosition); return isBefore(otherPosition) || equals(otherPosition); } diff --git a/javaparser-core/src/main/java/com/github/javaparser/Range.java b/javaparser-core/src/main/java/com/github/javaparser/Range.java index b0647d6cb9..964e9effe5 100644 --- a/javaparser-core/src/main/java/com/github/javaparser/Range.java +++ b/javaparser-core/src/main/java/com/github/javaparser/Range.java @@ -140,8 +140,8 @@ public Range withEnd(Position end) { */ public boolean contains(Range other) { boolean beginResult = (begin.isBeforeOrEqual(other.begin)); - boolean endResult = (end.isAfterOrEqual(other.end)); - return beginResult && endResult; + if (!beginResult) return false; + return end.isAfterOrEqual(other.end); } /** diff --git a/javaparser-core/src/main/java/com/github/javaparser/TokenTypes.java b/javaparser-core/src/main/java/com/github/javaparser/TokenTypes.java index 49e8190b94..f7c329c7d1 100644 --- a/javaparser-core/src/main/java/com/github/javaparser/TokenTypes.java +++ b/javaparser-core/src/main/java/com/github/javaparser/TokenTypes.java @@ -170,6 +170,9 @@ public static JavaToken.Category getCategory(int kind) { case EXPORTS: case PROVIDES: case TRANSITIVE: + case PERMITS: + case SEALED: + case NON_SEALED: return JavaToken.Category.KEYWORD; case LONG_LITERAL: case INTEGER_LITERAL: diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/Modifier.java b/javaparser-core/src/main/java/com/github/javaparser/ast/Modifier.java index 84ea3c561b..fc788cd916 100644 --- a/javaparser-core/src/main/java/com/github/javaparser/ast/Modifier.java +++ b/javaparser-core/src/main/java/com/github/javaparser/ast/Modifier.java @@ -103,7 +103,9 @@ public enum Keyword { SYNCHRONIZED("synchronized"), NATIVE("native"), STRICTFP("strictfp"), - TRANSITIVE("transitive"); + TRANSITIVE("transitive"), + SEALED("sealed"), + NON_SEALED("non-sealed"); private final String codeRepresentation; 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 b071107ea2..d13fbc7fcc 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 @@ -20,6 +20,20 @@ */ package com.github.javaparser.ast; +import static com.github.javaparser.ast.Node.Parsedness.PARSED; +import static com.github.javaparser.ast.Node.TreeTraversal.PREORDER; +import static java.util.Collections.emptySet; +import static java.util.Collections.unmodifiableList; +import static java.util.Spliterator.DISTINCT; +import static java.util.Spliterator.NONNULL; + +import java.util.*; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; + import com.github.javaparser.HasParentNode; import com.github.javaparser.Position; import com.github.javaparser.Range; @@ -48,20 +62,6 @@ import com.github.javaparser.resolution.SymbolResolver; import com.github.javaparser.utils.LineSeparator; -import java.util.*; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.function.Predicate; -import java.util.stream.Stream; -import java.util.stream.StreamSupport; - -import static com.github.javaparser.ast.Node.Parsedness.PARSED; -import static com.github.javaparser.ast.Node.TreeTraversal.PREORDER; -import static java.util.Collections.emptySet; -import static java.util.Collections.unmodifiableList; -import static java.util.Spliterator.DISTINCT; -import static java.util.Spliterator.NONNULL; - /** * Base class for all nodes of the abstract syntax tree. *

Construction

@@ -237,18 +237,21 @@ public Optional getComment() { /** * @return the range of characters in the source code that this node covers. */ - public Optional getRange() { + @Override + public Optional getRange() { return Optional.ofNullable(range); } /** * @return the range of tokens that this node covers. */ - public Optional getTokenRange() { + @Override + public Optional getTokenRange() { return Optional.ofNullable(tokenRange); } - public Node setTokenRange(TokenRange tokenRange) { + @Override + public Node setTokenRange(TokenRange tokenRange) { this.tokenRange = tokenRange; if (tokenRange == null || !(tokenRange.getBegin().hasRange() && tokenRange.getEnd().hasRange())) { range = null; @@ -262,7 +265,8 @@ public Node setTokenRange(TokenRange tokenRange) { * @param range the range of characters in the source code that this node covers. null can be used to indicate that * no range information is known, or that it is not of interest. */ - public Node setRange(Range range) { + @Override + public Node setRange(Range range) { if (this.range == range) { return this; } @@ -1132,7 +1136,7 @@ private Node nextFromLevel() { } /* - * returns true if the node defines a scope + * Returns true if the node has an (optional) scope expression eg. method calls (object.method()) */ public boolean hasScope() { return (NodeWithOptionalScope.class.isAssignableFrom(this.getClass()) && ((NodeWithOptionalScope) this).getScope().isPresent()) diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/body/ClassOrInterfaceDeclaration.java b/javaparser-core/src/main/java/com/github/javaparser/ast/body/ClassOrInterfaceDeclaration.java index 3545031c61..71de8a9454 100644 --- a/javaparser-core/src/main/java/com/github/javaparser/ast/body/ClassOrInterfaceDeclaration.java +++ b/javaparser-core/src/main/java/com/github/javaparser/ast/body/ClassOrInterfaceDeclaration.java @@ -62,29 +62,32 @@ public class ClassOrInterfaceDeclaration extends TypeDeclaration implementedTypes; + private NodeList permittedTypes; + public ClassOrInterfaceDeclaration() { - this(null, new NodeList<>(), new NodeList<>(), false, new SimpleName(), new NodeList<>(), new NodeList<>(), new NodeList<>(), new NodeList<>()); + this(null, new NodeList<>(), new NodeList<>(), false, new SimpleName(), new NodeList<>(), new NodeList<>(), new NodeList<>(), new NodeList<>(), new NodeList<>()); } public ClassOrInterfaceDeclaration(final NodeList modifiers, final boolean isInterface, final String name) { - this(null, modifiers, new NodeList<>(), isInterface, new SimpleName(name), new NodeList<>(), new NodeList<>(), new NodeList<>(), new NodeList<>()); + this(null, modifiers, new NodeList<>(), isInterface, new SimpleName(name), new NodeList<>(), new NodeList<>(), new NodeList<>(), new NodeList<>(), new NodeList<>()); } @AllFieldsConstructor - public ClassOrInterfaceDeclaration(final NodeList modifiers, final NodeList annotations, final boolean isInterface, final SimpleName name, final NodeList typeParameters, final NodeList extendedTypes, final NodeList implementedTypes, final NodeList> members) { - this(null, modifiers, annotations, isInterface, name, typeParameters, extendedTypes, implementedTypes, members); + public ClassOrInterfaceDeclaration(final NodeList modifiers, final NodeList annotations, final boolean isInterface, final SimpleName name, final NodeList typeParameters, final NodeList extendedTypes, final NodeList implementedTypes, final NodeList permittedTypes, final NodeList> members) { + this(null, modifiers, annotations, isInterface, name, typeParameters, extendedTypes, implementedTypes, permittedTypes, members); } /** * This constructor is used by the parser and is considered private. */ @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator") - public ClassOrInterfaceDeclaration(TokenRange tokenRange, NodeList modifiers, NodeList annotations, boolean isInterface, SimpleName name, NodeList typeParameters, NodeList extendedTypes, NodeList implementedTypes, NodeList> members) { + public ClassOrInterfaceDeclaration(TokenRange tokenRange, NodeList modifiers, NodeList annotations, boolean isInterface, SimpleName name, NodeList typeParameters, NodeList extendedTypes, NodeList implementedTypes, NodeList permittedTypes, NodeList> members) { super(tokenRange, modifiers, annotations, name, members); setInterface(isInterface); setTypeParameters(typeParameters); setExtendedTypes(extendedTypes); setImplementedTypes(implementedTypes); + setPermittedTypes(permittedTypes); customInitialization(); } @@ -110,6 +113,11 @@ public NodeList getImplementedTypes() { return implementedTypes; } + @Generated("com.github.javaparser.generator.core.node.PropertyGenerator") + public NodeList getPermittedTypes() { + return permittedTypes; + } + @Generated("com.github.javaparser.generator.core.node.PropertyGenerator") public NodeList getTypeParameters() { return typeParameters; @@ -148,6 +156,20 @@ public ClassOrInterfaceDeclaration setImplementedTypes(final NodeList permittedTypes) { + assertNotNull(permittedTypes); + if (permittedTypes == this.permittedTypes) { + return this; + } + notifyPropertyChange(ObservableProperty.PERMITTED_TYPES, this.permittedTypes, permittedTypes); + if (this.permittedTypes != null) + this.permittedTypes.setParentNode(null); + this.permittedTypes = permittedTypes; + setAsParentNodeOf(permittedTypes); + return this; + } + @Generated("com.github.javaparser.generator.core.node.PropertyGenerator") public ClassOrInterfaceDeclaration setInterface(final boolean isInterface) { if (isInterface == this.isInterface) { @@ -190,6 +212,12 @@ public boolean remove(Node node) { return true; } } + for (int i = 0; i < permittedTypes.size(); i++) { + if (permittedTypes.get(i) == node) { + permittedTypes.remove(i); + return true; + } + } for (int i = 0; i < typeParameters.size(); i++) { if (typeParameters.get(i) == node) { typeParameters.remove(i); @@ -252,6 +280,12 @@ public boolean replace(Node node, Node replacementNode) { return true; } } + for (int i = 0; i < permittedTypes.size(); i++) { + if (permittedTypes.get(i) == node) { + permittedTypes.set(i, (ClassOrInterfaceType) replacementNode); + return true; + } + } for (int i = 0; i < typeParameters.size(); i++) { if (typeParameters.get(i) == node) { typeParameters.set(i, (TypeParameter) replacementNode); diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/body/FieldDeclaration.java b/javaparser-core/src/main/java/com/github/javaparser/ast/body/FieldDeclaration.java index 90e2edef7f..3c7cf1c49c 100644 --- a/javaparser-core/src/main/java/com/github/javaparser/ast/body/FieldDeclaration.java +++ b/javaparser-core/src/main/java/com/github/javaparser/ast/body/FieldDeclaration.java @@ -20,8 +20,16 @@ */ package com.github.javaparser.ast.body; +import static com.github.javaparser.ast.Modifier.Keyword.STATIC; +import static com.github.javaparser.ast.NodeList.nodeList; +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.AssignExpr; import com.github.javaparser.ast.expr.AssignExpr.Operator; @@ -45,12 +53,6 @@ import com.github.javaparser.resolution.Resolvable; import com.github.javaparser.resolution.declarations.ResolvedFieldDeclaration; -import java.util.Optional; -import java.util.function.Consumer; - -import static com.github.javaparser.ast.NodeList.nodeList; -import static com.github.javaparser.utils.Utils.assertNotNull; - /** * The declaration of a field in a class. "private static int a=15*15;" in this example: {@code class X { private static * int a=15*15; }} @@ -124,17 +126,20 @@ public void accept(final VoidVisitor v, final A arg) { * @return modifiers * @see Modifier */ - @Generated("com.github.javaparser.generator.core.node.PropertyGenerator") + @Override + @Generated("com.github.javaparser.generator.core.node.PropertyGenerator") public NodeList getModifiers() { return modifiers; } - @Generated("com.github.javaparser.generator.core.node.PropertyGenerator") + @Override + @Generated("com.github.javaparser.generator.core.node.PropertyGenerator") public NodeList getVariables() { return variables; } - @Generated("com.github.javaparser.generator.core.node.PropertyGenerator") + @Override + @Generated("com.github.javaparser.generator.core.node.PropertyGenerator") public FieldDeclaration setModifiers(final NodeList modifiers) { assertNotNull(modifiers); if (modifiers == this.modifiers) { @@ -148,7 +153,8 @@ public FieldDeclaration setModifiers(final NodeList modifiers) { return this; } - @Generated("com.github.javaparser.generator.core.node.PropertyGenerator") + @Override + @Generated("com.github.javaparser.generator.core.node.PropertyGenerator") public FieldDeclaration setVariables(final NodeList variables) { assertNotNull(variables); if (variables == this.variables) { @@ -233,6 +239,38 @@ public FieldDeclaration setVolatile(boolean set) { return setModifier(Modifier.Keyword.VOLATILE, set); } + /* + * Every field declaration in the body of an interface is implicitly public, static, and final. + */ + @Override + public boolean isStatic() { + return hasModifier(STATIC) || isDeclaredInInterface(); + } + + /* + * Every field declaration in the body of an interface is implicitly public, static, and final. + */ + @Override + public boolean isFinal() { + return hasModifier(Keyword.FINAL) || isDeclaredInInterface(); + } + + /* + * Every field declaration in the body of an interface is implicitly public, static, and final. + */ + @Override + public boolean isPublic() { + return hasModifier(Keyword.PUBLIC) || isDeclaredInInterface(); + } + + /* + * Returns true if the field is declared in an interface + */ + private boolean isDeclaredInInterface() { + Optional parentClass = findAncestor(ClassOrInterfaceDeclaration.class); + return parentClass.map(parent -> parent.isInterface()).orElse(false); + } + @Override @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator") public boolean remove(Node node) { diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/observer/ObservableProperty.java b/javaparser-core/src/main/java/com/github/javaparser/ast/observer/ObservableProperty.java index 0c56c46117..2f888cee1d 100644 --- a/javaparser-core/src/main/java/com/github/javaparser/ast/observer/ObservableProperty.java +++ b/javaparser-core/src/main/java/com/github/javaparser/ast/observer/ObservableProperty.java @@ -92,6 +92,7 @@ public enum ObservableProperty { PARAMETER(Type.SINGLE_REFERENCE), PARAMETERS(Type.MULTIPLE_REFERENCE), PATTERN(Type.SINGLE_REFERENCE), + PERMITTED_TYPES(Type.MULTIPLE_REFERENCE), QUALIFIER(Type.SINGLE_REFERENCE), RECEIVER_PARAMETER(Type.SINGLE_REFERENCE), RECORD_DECLARATION(Type.SINGLE_REFERENCE), diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/validator/language_level_validations/Java17Validator.java b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/language_level_validations/Java17Validator.java index 8a904261e2..256d49c1dc 100644 --- a/javaparser-core/src/main/java/com/github/javaparser/ast/validator/language_level_validations/Java17Validator.java +++ b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/language_level_validations/Java17Validator.java @@ -30,6 +30,8 @@ public class Java17Validator extends Java16Validator { public Java17Validator() { super(); // Released Language Features - // No new released language features added in Java 17 + // Sealed Classes - https://openjdk.java.net/jeps/409 + remove(noSealedClasses); + remove(noPermitsListInClasses); } } diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/validator/language_level_validations/Java1_0Validator.java b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/language_level_validations/Java1_0Validator.java index cc5551a9d6..a4da2f79fe 100644 --- a/javaparser-core/src/main/java/com/github/javaparser/ast/validator/language_level_validations/Java1_0Validator.java +++ b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/language_level_validations/Java1_0Validator.java @@ -21,6 +21,7 @@ package com.github.javaparser.ast.validator.language_level_validations; import com.github.javaparser.ast.ImportDeclaration; +import com.github.javaparser.ast.Modifier; import com.github.javaparser.ast.Node; import com.github.javaparser.ast.body.*; import com.github.javaparser.ast.expr.*; @@ -106,6 +107,10 @@ public class Java1_0Validator extends Validators { final Validator noRecordDeclaration = new SimpleValidator<>(RecordDeclaration.class, n -> true, (n, reporter) -> reporter.report(n, "Record Declarations are not supported.")); + final Validator noSealedClasses = new SimpleValidator<>(ClassOrInterfaceDeclaration.class, n -> n.hasModifier(Modifier.Keyword.SEALED) || n.hasModifier(Modifier.Keyword.NON_SEALED), (n, reporter) -> reporter.report(n, "Sealed classes are not supported.")); + + final Validator noPermitsListInClasses = new SimpleValidator<>(ClassOrInterfaceDeclaration.class, n -> n.getPermittedTypes().isNonEmpty(), (n, reporter) -> reporter.report(n, "Permitted sub-classes are not supported.")); + public Java1_0Validator() { super(new CommonValidators()); add(modifiersWithoutStrictfpAndDefaultAndStaticInterfaceMethodsAndPrivateInterfaceMethods); @@ -130,5 +135,7 @@ public Java1_0Validator() { add(noPatternMatchingInstanceOf); add(noTextBlockLiteral); add(noRecordDeclaration); + add(noSealedClasses); + add(noPermitsListInClasses); } } diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/validator/language_level_validations/chunks/ModifierValidator.java b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/language_level_validations/chunks/ModifierValidator.java index c8607823f6..ab5f61ed29 100644 --- a/javaparser-core/src/main/java/com/github/javaparser/ast/validator/language_level_validations/chunks/ModifierValidator.java +++ b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/language_level_validations/chunks/ModifierValidator.java @@ -73,19 +73,19 @@ public void visit(ClassOrInterfaceDeclaration n, ProblemReporter reporter) { private void validateClassModifiers(ClassOrInterfaceDeclaration n, ProblemReporter reporter) { if (n.isTopLevelType()) { - validateModifiers(n, reporter, PUBLIC, ABSTRACT, FINAL, STRICTFP); + validateModifiers(n, reporter, PUBLIC, ABSTRACT, FINAL, STRICTFP, SEALED, NON_SEALED); } else if (n.isNestedType()) { - validateModifiers(n, reporter, PUBLIC, PROTECTED, PRIVATE, ABSTRACT, STATIC, FINAL, STRICTFP); + validateModifiers(n, reporter, PUBLIC, PROTECTED, PRIVATE, ABSTRACT, STATIC, FINAL, STRICTFP, SEALED, NON_SEALED); } else if (n.isLocalClassDeclaration()) { - validateModifiers(n, reporter, ABSTRACT, FINAL, STRICTFP); + validateModifiers(n, reporter, ABSTRACT, FINAL, STRICTFP, SEALED, NON_SEALED); } } private void validateInterfaceModifiers(TypeDeclaration n, ProblemReporter reporter) { if (n.isTopLevelType()) { - validateModifiers(n, reporter, PUBLIC, ABSTRACT, STRICTFP); + validateModifiers(n, reporter, PUBLIC, ABSTRACT, STRICTFP, SEALED, NON_SEALED); } else if (n.isNestedType()) { - validateModifiers(n, reporter, PUBLIC, PROTECTED, PRIVATE, ABSTRACT, STATIC, STRICTFP); + validateModifiers(n, reporter, PUBLIC, PROTECTED, PRIVATE, ABSTRACT, STATIC, STRICTFP, SEALED, NON_SEALED); } } 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 075e3a84f1..5a6a20fef5 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 @@ -113,13 +113,14 @@ public Visitable visit(final BlockComment n, final Object arg) { public Visitable visit(final ClassOrInterfaceDeclaration n, final Object arg) { NodeList extendedTypes = cloneList(n.getExtendedTypes(), arg); NodeList implementedTypes = cloneList(n.getImplementedTypes(), arg); + NodeList permittedTypes = cloneList(n.getPermittedTypes(), arg); NodeList typeParameters = cloneList(n.getTypeParameters(), arg); NodeList> members = cloneList(n.getMembers(), arg); NodeList modifiers = cloneList(n.getModifiers(), arg); SimpleName name = cloneNode(n.getName(), arg); NodeList annotations = cloneList(n.getAnnotations(), arg); Comment comment = cloneNode(n.getComment(), arg); - ClassOrInterfaceDeclaration r = new ClassOrInterfaceDeclaration(n.getTokenRange().orElse(null), modifiers, annotations, n.isInterface(), name, typeParameters, extendedTypes, implementedTypes, members); + ClassOrInterfaceDeclaration r = new ClassOrInterfaceDeclaration(n.getTokenRange().orElse(null), modifiers, annotations, n.isInterface(), name, typeParameters, extendedTypes, implementedTypes, permittedTypes, members); r.setComment(comment); n.getOrphanComments().stream().map(Comment::clone).forEach(r::addOrphanComment); copyData(n, r); diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/EqualsVisitor.java b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/EqualsVisitor.java index 9d591a056c..f80297d23e 100644 --- a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/EqualsVisitor.java +++ b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/EqualsVisitor.java @@ -207,6 +207,8 @@ public Boolean visit(final ClassOrInterfaceDeclaration n, final Visitable arg) { return false; if (!objEquals(n.isInterface(), n2.isInterface())) return false; + if (!nodesEquals(n.getPermittedTypes(), n2.getPermittedTypes())) + return false; if (!nodesEquals(n.getTypeParameters(), n2.getTypeParameters())) return false; if (!nodesEquals(n.getMembers(), n2.getMembers())) diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/GenericListVisitorAdapter.java b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/GenericListVisitorAdapter.java index e2d1670b0e..040917486d 100644 --- a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/GenericListVisitorAdapter.java +++ b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/GenericListVisitorAdapter.java @@ -415,6 +415,11 @@ public List visit(final ClassOrInterfaceDeclaration n, final A arg) { if (tmp != null) result.addAll(tmp); } + { + tmp = n.getPermittedTypes().accept(this, arg); + if (tmp != null) + result.addAll(tmp); + } { tmp = n.getTypeParameters().accept(this, arg); if (tmp != null) diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/GenericVisitorAdapter.java b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/GenericVisitorAdapter.java index 41fb90dd9e..a30a31a331 100644 --- a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/GenericVisitorAdapter.java +++ b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/GenericVisitorAdapter.java @@ -357,6 +357,11 @@ public R visit(final ClassOrInterfaceDeclaration n, final A arg) { if (result != null) return result; } + { + result = n.getPermittedTypes().accept(this, arg); + if (result != null) + return result; + } { result = n.getTypeParameters().accept(this, arg); if (result != null) diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/HashCodeVisitor.java b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/HashCodeVisitor.java index 48dd7be317..83b4725be0 100644 --- a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/HashCodeVisitor.java +++ b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/HashCodeVisitor.java @@ -119,7 +119,7 @@ public Integer visit(final ClassExpr n, final Void arg) { } public Integer visit(final ClassOrInterfaceDeclaration n, final Void arg) { - return (n.getExtendedTypes().accept(this, arg)) * 31 + (n.getImplementedTypes().accept(this, arg)) * 31 + (n.isInterface() ? 1 : 0) * 31 + (n.getTypeParameters().accept(this, arg)) * 31 + (n.getMembers().accept(this, arg)) * 31 + (n.getModifiers().accept(this, arg)) * 31 + (n.getName().accept(this, arg)) * 31 + (n.getAnnotations().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0); + return (n.getExtendedTypes().accept(this, arg)) * 31 + (n.getImplementedTypes().accept(this, arg)) * 31 + (n.isInterface() ? 1 : 0) * 31 + (n.getPermittedTypes().accept(this, arg)) * 31 + (n.getTypeParameters().accept(this, arg)) * 31 + (n.getMembers().accept(this, arg)) * 31 + (n.getModifiers().accept(this, arg)) * 31 + (n.getName().accept(this, arg)) * 31 + (n.getAnnotations().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0); } public Integer visit(final ClassOrInterfaceType n, final Void arg) { diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/ModifierVisitor.java b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/ModifierVisitor.java index ab30956b90..a2499971a2 100644 --- a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/ModifierVisitor.java +++ b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/ModifierVisitor.java @@ -241,6 +241,7 @@ public Visitable visit(final ClassOrInterfaceDeclaration n, final A arg) { NodeList modifiers = modifyList(n.getModifiers(), arg); NodeList extendedTypes = modifyList(n.getExtendedTypes(), arg); NodeList implementedTypes = modifyList(n.getImplementedTypes(), arg); + NodeList permittedTypes = modifyList(n.getPermittedTypes(), arg); NodeList typeParameters = modifyList(n.getTypeParameters(), arg); NodeList> members = modifyList(n.getMembers(), arg); SimpleName name = (SimpleName) n.getName().accept(this, arg); @@ -251,6 +252,7 @@ public Visitable visit(final ClassOrInterfaceDeclaration n, final A arg) { n.setModifiers(modifiers); n.setExtendedTypes(extendedTypes); n.setImplementedTypes(implementedTypes); + n.setPermittedTypes(permittedTypes); n.setTypeParameters(typeParameters); n.setMembers(members); n.setName(name); diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/NoCommentEqualsVisitor.java b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/NoCommentEqualsVisitor.java index 28e3e6229e..ba882abf73 100644 --- a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/NoCommentEqualsVisitor.java +++ b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/NoCommentEqualsVisitor.java @@ -150,6 +150,8 @@ public Boolean visit(final ClassOrInterfaceDeclaration n, final Visitable arg) { return false; if (!objEquals(n.isInterface(), n2.isInterface())) return false; + if (!nodesEquals(n.getPermittedTypes(), n2.getPermittedTypes())) + return false; if (!nodesEquals(n.getTypeParameters(), n2.getTypeParameters())) return false; if (!nodesEquals(n.getMembers(), n2.getMembers())) diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/NoCommentHashCodeVisitor.java b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/NoCommentHashCodeVisitor.java index 0a16c3fe73..3200b1b47f 100644 --- a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/NoCommentHashCodeVisitor.java +++ b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/NoCommentHashCodeVisitor.java @@ -111,7 +111,7 @@ public Integer visit(final ClassExpr n, final Void arg) { } public Integer visit(final ClassOrInterfaceDeclaration n, final Void arg) { - return (n.getExtendedTypes().accept(this, arg)) * 31 + (n.getImplementedTypes().accept(this, arg)) * 31 + (n.isInterface() ? 1 : 0) * 31 + (n.getTypeParameters().accept(this, arg)) * 31 + (n.getMembers().accept(this, arg)) * 31 + (n.getModifiers().accept(this, arg)) * 31 + (n.getName().accept(this, arg)) * 31 + (n.getAnnotations().accept(this, arg)); + return (n.getExtendedTypes().accept(this, arg)) * 31 + (n.getImplementedTypes().accept(this, arg)) * 31 + (n.isInterface() ? 1 : 0) * 31 + (n.getPermittedTypes().accept(this, arg)) * 31 + (n.getTypeParameters().accept(this, arg)) * 31 + (n.getMembers().accept(this, arg)) * 31 + (n.getModifiers().accept(this, arg)) * 31 + (n.getName().accept(this, arg)) * 31 + (n.getAnnotations().accept(this, arg)); } public Integer visit(final ClassOrInterfaceType n, final Void arg) { diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/VoidVisitorAdapter.java b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/VoidVisitorAdapter.java index dc14a5dd24..aa0807d9a5 100644 --- a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/VoidVisitorAdapter.java +++ b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/VoidVisitorAdapter.java @@ -150,6 +150,7 @@ public void visit(final ClassExpr n, final A arg) { public void visit(final ClassOrInterfaceDeclaration n, final A arg) { n.getExtendedTypes().forEach(p -> p.accept(this, arg)); n.getImplementedTypes().forEach(p -> p.accept(this, arg)); + n.getPermittedTypes().forEach(p -> p.accept(this, arg)); n.getTypeParameters().forEach(p -> p.accept(this, arg)); n.getMembers().forEach(p -> p.accept(this, arg)); n.getModifiers().forEach(p -> p.accept(this, arg)); diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/ClassOrInterfaceDeclarationMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ClassOrInterfaceDeclarationMetaModel.java index 6bb35f7437..d617844a9e 100644 --- a/javaparser-core/src/main/java/com/github/javaparser/metamodel/ClassOrInterfaceDeclarationMetaModel.java +++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ClassOrInterfaceDeclarationMetaModel.java @@ -48,5 +48,7 @@ public class ClassOrInterfaceDeclarationMetaModel extends TypeDeclarationMetaMod public PropertyMetaModel isInterfacePropertyMetaModel; + public PropertyMetaModel permittedTypesPropertyMetaModel; + public PropertyMetaModel typeParametersPropertyMetaModel; } diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/JavaParserMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/JavaParserMetaModel.java index 21f2c39b56..ccb83a4893 100644 --- a/javaparser-core/src/main/java/com/github/javaparser/metamodel/JavaParserMetaModel.java +++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/JavaParserMetaModel.java @@ -87,6 +87,7 @@ private static void initializeConstructorParameters() { classOrInterfaceDeclarationMetaModel.getConstructorParameters().add(classOrInterfaceDeclarationMetaModel.typeParametersPropertyMetaModel); classOrInterfaceDeclarationMetaModel.getConstructorParameters().add(classOrInterfaceDeclarationMetaModel.extendedTypesPropertyMetaModel); classOrInterfaceDeclarationMetaModel.getConstructorParameters().add(classOrInterfaceDeclarationMetaModel.implementedTypesPropertyMetaModel); + classOrInterfaceDeclarationMetaModel.getConstructorParameters().add(classOrInterfaceDeclarationMetaModel.permittedTypesPropertyMetaModel); classOrInterfaceDeclarationMetaModel.getConstructorParameters().add(typeDeclarationMetaModel.membersPropertyMetaModel); constructorDeclarationMetaModel.getConstructorParameters().add(callableDeclarationMetaModel.modifiersPropertyMetaModel); constructorDeclarationMetaModel.getConstructorParameters().add(bodyDeclarationMetaModel.annotationsPropertyMetaModel); @@ -488,6 +489,8 @@ private static void initializePropertyMetaModels() { classOrInterfaceDeclarationMetaModel.getDeclaredPropertyMetaModels().add(classOrInterfaceDeclarationMetaModel.implementedTypesPropertyMetaModel); classOrInterfaceDeclarationMetaModel.isInterfacePropertyMetaModel = new PropertyMetaModel(classOrInterfaceDeclarationMetaModel, "isInterface", boolean.class, Optional.empty(), false, false, false, false); classOrInterfaceDeclarationMetaModel.getDeclaredPropertyMetaModels().add(classOrInterfaceDeclarationMetaModel.isInterfacePropertyMetaModel); + classOrInterfaceDeclarationMetaModel.permittedTypesPropertyMetaModel = new PropertyMetaModel(classOrInterfaceDeclarationMetaModel, "permittedTypes", com.github.javaparser.ast.type.ClassOrInterfaceType.class, Optional.of(classOrInterfaceTypeMetaModel), false, false, true, false); + classOrInterfaceDeclarationMetaModel.getDeclaredPropertyMetaModels().add(classOrInterfaceDeclarationMetaModel.permittedTypesPropertyMetaModel); classOrInterfaceDeclarationMetaModel.typeParametersPropertyMetaModel = new PropertyMetaModel(classOrInterfaceDeclarationMetaModel, "typeParameters", com.github.javaparser.ast.type.TypeParameter.class, Optional.of(typeParameterMetaModel), false, false, true, false); classOrInterfaceDeclarationMetaModel.getDeclaredPropertyMetaModels().add(classOrInterfaceDeclarationMetaModel.typeParametersPropertyMetaModel); constructorDeclarationMetaModel.bodyPropertyMetaModel = new PropertyMetaModel(constructorDeclarationMetaModel, "body", com.github.javaparser.ast.stmt.BlockStmt.class, Optional.of(blockStmtMetaModel), false, false, false, false); 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 f73a1bf4d7..045d43d85e 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,6 +20,12 @@ */ package com.github.javaparser.printer.lexicalpreservation; +import static com.github.javaparser.GeneratedJavaParserConstants.*; + +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; @@ -34,12 +40,6 @@ import com.github.javaparser.printer.concretesyntaxmodel.*; import com.github.javaparser.printer.lexicalpreservation.LexicalDifferenceCalculator.CsmChild; -import java.util.*; -import java.util.function.Predicate; -import java.util.stream.IntStream; - -import static com.github.javaparser.GeneratedJavaParserConstants.*; - /** * 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. @@ -89,11 +89,11 @@ private List processIndentation(List indentation, List indentation = takeWhile(prevElements.subList(eolIndex + 1, prevElements.size()), element -> element.isWhiteSpace()); return indentation; } - + /* * returns only the elements that match the given predicate. * takeWhile takes elements from the initial stream while the predicate holds true. - * Meaning that when an element is encountered that does not match the predicate, the rest of the list is discarded. + * Meaning that when an element is encountered that does not match the predicate, the rest of the list is discarded. */ List takeWhile(List prevElements, Predicate predicate) { List spaces = new ArrayList<>(); @@ -106,8 +106,8 @@ List takeWhile(List prevElements, Predicate source) { return IntStream.range(0, source.size()) .map(i -> source.size() - i - 1) @@ -137,14 +137,14 @@ private int posOfNextComment(int fromIndex, List elements) { } return -1; } - + /* * Returns true if the next element in the list (starting from @{code fromIndex}) is a comment */ private boolean isFollowedByComment(int fromIndex, List elements) { return posOfNextComment(fromIndex, elements) != -1; } - + /* * Removes all elements in the list starting from @{code fromIndex}) ending to @{code toIndex}) */ @@ -160,13 +160,13 @@ private void removeElements(int fromIndex, int toIndex, List elemen count++; } } - + private boolean isValidIndex(int index, List elements) { return index >= 0 && index <= elements.size(); } /* - * Returns the position of the last new line character or -1 if there is no eol in the specified list of TextElement + * Returns the position of the last new line character or -1 if there is no eol in the specified list of TextElement */ int lastIndexOfEolWithoutGPT(List source) { ListIterator listIterator = source.listIterator(source.size()); @@ -204,25 +204,25 @@ private boolean isAfterLBrace(NodeText nodeText, int nodeTextIndex) { * If we are at the beginning of a line, with just spaces or tabs before/after the position of the deleted element * we should force the space to be the same as the current indentation. * This method handles the following case if we remove the modifier {@code public} ([ ] is an indent character) - * {@code + * {@code * [ ][ ]public[ ][ ][ ]void[ ]m{} * <-1--> <---2---> * 1/ current indentation * 2/ these whitespaces must be removed * } * should produce - * {@code - * [ ][ ]void[ ]m{} + * {@code + * [ ][ ]void[ ]m{} * } */ private int considerEnforcingIndentation(NodeText nodeText, int nodeTextIndex) { return considerIndentation(nodeText, nodeTextIndex, indentation.size()); } - + private int considerRemovingIndentation(NodeText nodeText, int nodeTextIndex) { return considerIndentation(nodeText, nodeTextIndex, 0); } - + private int considerIndentation(NodeText nodeText, int nodeTextIndex, int numberOfCharactersToPreserve) { EnforcingIndentationContext enforcingIndentationContext = defineEnforcingIndentationContext(nodeText, nodeTextIndex); // the next position in the list (by default the current position) @@ -238,29 +238,40 @@ private int considerIndentation(NodeText nodeText, int nodeTextIndex, int number } return res; } - + private boolean isEnforcingIndentationActivable(RemovedGroup removedGroup) { - return (diffIndex + 1 >= diffElements.size() || !(diffElements.get(diffIndex + 1).isAdded())) + return (isLastElement(diffElements, diffIndex) || !(nextDiffElement(diffElements,diffIndex).isAdded())) && originalIndex < originalElements.size() && !removedGroup.isACompleteLine(); } private boolean isRemovingIndentationActivable(RemovedGroup removedGroup) { - return (diffIndex + 1 >= diffElements.size() || !(diffElements.get(diffIndex + 1).isAdded())) + return (isLastElement(diffElements, diffIndex) || !(nextDiffElement(diffElements,diffIndex).isAdded())) && originalIndex < originalElements.size() && removedGroup.isACompleteLine(); } - + + private boolean isLastElement(List list, int index) { + return index + 1 >= list.size(); + } + + private DifferenceElement nextDiffElement(List list, int index) { + return list.get(index + 1); + } + /* - * This data structure class hold the starting position of the first whitespace char + * This data structure class hold the starting position of the first whitespace char * and the number of consecutive whitespace (or tab) characters */ private class EnforcingIndentationContext { int start; int extraCharacters; public EnforcingIndentationContext(int start) { + this(start,0); + } + public EnforcingIndentationContext(int start, int extraCharacters) { this.start=start; - this.extraCharacters=0; + this.extraCharacters=extraCharacters; } } @@ -280,7 +291,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 + * 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 nodeTextIndex Starting position in the input list @@ -296,7 +307,7 @@ private EnforcingIndentationContext defineEnforcingIndentationContext(NodeText n if (nodeText.getTextElement(i).isNewline()) { break; } - if (!nodeText.getTextElement(i).isSpaceOrTab()) { + if (!isSpaceOrTabElement(nodeText, i)) { ctx = new EnforcingIndentationContext(startIndex); break; } @@ -305,21 +316,29 @@ private EnforcingIndentationContext defineEnforcingIndentationContext(NodeText n } } // compute space after the deleted element - if (nodeText.getTextElement(startIndex).isSpaceOrTab()) { + if (isSpaceOrTabElement(nodeText, startIndex)) { +// int startingFromIndex = startIndex == 0 ? startIndex : startIndex + 1; for (int i = startIndex; i >= 0 && i < nodeText.numberOfElements(); i++) { if (nodeText.getTextElement(i).isNewline()) { break; } - if (!nodeText.getTextElement(i).isSpaceOrTab()) { + if (!isSpaceOrTabElement(nodeText, i)) { break; } ctx.extraCharacters++; } } - + return ctx; } + /* + * Returns true if the indexed element is a space or a tab + */ + private boolean isSpaceOrTabElement(NodeText nodeText, int i) { + return nodeText.getTextElement(i).isSpaceOrTab(); + } + /** * Node that we have calculate the Difference we can apply to a concrete NodeText, modifying it according * to the difference (adding and removing the elements provided). @@ -528,7 +547,7 @@ private void applyRemovedDiffElement(RemovedGroup removedGroup, Removed removed, } } else { nodeText.removeElement(originalIndex); - // When we don't try to remove a complete line + // 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) // (in the latter case we keep the indentation) // then we want to enforce the indentation. @@ -578,7 +597,7 @@ private void applyRemovedDiffElement(RemovedGroup removedGroup, Removed removed, }else if (originalElementIsToken && originalElement.isWhiteSpaceOrComment()) { originalIndex++; // skip the newline token which may be generated unnecessarily by the concrete syntax pattern - if (removed.isNewLine()) { + if (removed.isNewLine()) { diffIndex++; } } else if (originalElement.isLiteral()) { @@ -615,8 +634,8 @@ 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) + if (!removedGroup.isProcessed() + && removedGroup.isLastElement(removed) && removedGroup.isACompleteLine() && !removed.isNewLine()) { Integer lastElementIndex = removedGroup.getLastElementIndex(); @@ -777,7 +796,7 @@ private boolean isNodeWithTypeArguments(DifferenceElement element) { } /* - * Try to resolve the number of token to skip in the original list to match + * Try to resolve the number of token to skip in the original list to match * a ClassOrInterfaceType with a list of tokens like "java", ".", "lang", ".", "Object" */ private int getIndexToNextTokenElement(TokenTextElement element, DifferenceElement kept) { @@ -1058,12 +1077,12 @@ private String tokenDescription(int kind) { * Considering that the lists of elements are ordered, We can find the common * elements by starting with the list before the modifications and, for each * element, by going through the list of elements containing the modifications. - * + * * We can find the common elements by starting with the list before the * modifications (L1) and, for each element, by going through the list of elements * containing the modifications (L2). - * - * If element A in list L1 is not found in list L2, it is a deleted element. + * + * If element A in list L1 is not found in list L2, it is a deleted element. * If element A of list L1 is found in list L2, it is a kept element. In this * case the search for the next element of the list L1 must start from the * position of the last element kept {@code syncNextIndex}. @@ -1085,24 +1104,24 @@ private Map getCorrespondanceBetweenNextOrderAndPreviousOrder( correspondanceBetweenNextOrderAndPreviousOrder.put(nextOrderElementsIterator.index(), previousOrderElementsIterator.index()); // set the position to start on the next {@code nextOrderElementsIterator} iteration - syncNextIndex = nextOrderElementsIterator.index(); + syncNextIndex = nextOrderElementsIterator.index(); break; } } } return correspondanceBetweenNextOrderAndPreviousOrder; } - + /* - * A list iterator which does not allow to modify the list - * and which provides a method to know the current positioning + * A list iterator which does not allow to modify the list + * and which provides a method to know the current positioning */ private class ReadOnlyListIterator implements ListIterator { ListIterator elements; public ReadOnlyListIterator(List elements) { this(elements, 0); } - + public ReadOnlyListIterator(List elements, int index) { this.elements = elements.listIterator(index); } @@ -1136,14 +1155,14 @@ public int nextIndex() { public int previousIndex() { return elements.previousIndex(); } - + /* * Returns the current index in the underlying list */ public int index() { return elements.nextIndex() - 1; } - + @Override public void remove() { throw new UnsupportedOperationException(); @@ -1158,7 +1177,7 @@ public void set(T e) { public void add(T e) { throw new UnsupportedOperationException(); } - + } /* 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 5ee6f62e09..4e397f9f55 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 @@ -20,16 +20,16 @@ */ package com.github.javaparser.resolution.declarations; +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; import com.github.javaparser.resolution.types.ResolvedReferenceType; import com.github.javaparser.resolution.types.ResolvedType; -import java.util.*; -import java.util.function.Function; -import java.util.stream.Collectors; - /** * @author Federico Tomassetti */ @@ -286,14 +286,46 @@ default boolean canBeAssignedTo(ResolvedReferenceTypeDeclaration other) { /** * Has the type at least one annotation declared or inherited having the specified qualified name? + * By default, the subclasses do not inherit the annotation declared on the parent class. + * However, there is a way to propagate particular annotations throughout the class hierarchy using the @Inherited annotation. */ default boolean hasAnnotation(String qualifiedName) { if (hasDirectlyAnnotation(qualifiedName)) { return true; } - return getAllAncestors().stream().filter(it -> it.asReferenceType().getTypeDeclaration().isPresent()).anyMatch(it -> it.asReferenceType().getTypeDeclaration().get().hasDirectlyAnnotation(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)); } + /** + * Returns true if the specified annotation is inheritable. + */ + default boolean isInheritedAnnotation(String name) { + Optional declaration = getDeclaredAnnotation(name); + return declaration.isPresent() && declaration.get().isInheritable(); + } + + /** + * 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 a collection of all annotations declared in this type declaration. + */ + 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. diff --git a/javaparser-core/src/main/javacc/java.jj b/javaparser-core/src/main/javacc/java.jj index a6bc686706..876f724183 100644 --- a/javaparser-core/src/main/javacc/java.jj +++ b/javaparser-core/src/main/javacc/java.jj @@ -330,13 +330,16 @@ TOKEN : | < LONG: "long" > | < NATIVE: "native" > | < NEW: "new" > +| < NON_SEALED: "non-sealed" > | < NULL: "null" > | < PACKAGE: "package"> +| < PERMITS: "permits"> | < PRIVATE: "private" > | < PROTECTED: "protected" > | < PUBLIC: "public" > | < RECORD: "record" > | < RETURN: "return" > +| < SEALED: "sealed" > | < SHORT: "short" > | < STATIC: "static" > | < STRICTFP: "strictfp" > @@ -1366,6 +1369,10 @@ ModifierHolder Modifiers(): "transitive" { add(modifiers, new Modifier(tokenRange(), Modifier.Keyword.TRANSITIVE)); begin = orIfInvalid(begin, token()); } | "default" { add(modifiers, new Modifier(tokenRange(), Modifier.Keyword.DEFAULT)); begin = orIfInvalid(begin, token()); } + | + "sealed" { add(modifiers, new Modifier(tokenRange(), Modifier.Keyword.SEALED)); begin = orIfInvalid(begin, token()); } + | + "non-sealed" { add(modifiers, new Modifier(tokenRange(), Modifier.Keyword.NON_SEALED)); begin = orIfInvalid(begin, token()); } | ann = Annotation() { annotations = add(annotations, ann); begin = orIfInvalid(begin, ann); } ) @@ -1415,6 +1422,7 @@ ClassOrInterfaceDeclaration ClassOrInterfaceDeclaration(ModifierHolder modifier) RangedList typePar = new RangedList(emptyNodeList()); NodeList extList = emptyNodeList(); NodeList impList = emptyNodeList(); + NodeList permitsList = emptyNodeList(); NodeList> members = emptyNodeList(); JavaToken begin = modifier.begin; } @@ -1429,10 +1437,11 @@ ClassOrInterfaceDeclaration ClassOrInterfaceDeclaration(ModifierHolder modifier) [ typePar = TypeParameters() ] [ extList = ExtendsList() ] [ impList = ImplementsList() ] + [ permitsList = PermitsList() ] members = ClassOrInterfaceBody() - { return new ClassOrInterfaceDeclaration(range(begin, token()), modifier.modifiers, modifier.annotations, isInterface, name, typePar.list, extList, impList, members); } + { return new ClassOrInterfaceDeclaration(range(begin, token()), modifier.modifiers, modifier.annotations, isInterface, name, typePar.list, extList, impList, permitsList, members); } } /** @@ -1557,6 +1566,37 @@ NodeList ImplementsList(): { return ret; } } +/** + * https://docs.oracle.com/javase/specs/jls/se15/html/jls-8.html#jls-8.1.5 + *
{@code
+ *     ClassPermits:
+ *         permits TypeName {, TypeName}
+ * }
+ * For convenience: + * https://docs.oracle.com/javase/specs/jls/se15/html/jls-4.html#jls-4.3 + *
{@code
+ *     ClassOrInterfaceType:
+ *         ClassType
+ *         InterfaceType
+ *     ClassType:
+ *         {Annotation} TypeIdentifier [TypeArguments]
+ *         PackageName . {Annotation} TypeIdentifier [TypeArguments]
+ *         ClassOrInterfaceType . {Annotation} TypeIdentifier [TypeArguments]
+ *     InterfaceType:
+ *         ClassType
+ * }
+ */ +NodeList PermitsList(): +{ + NodeList ret = new NodeList(); + ClassOrInterfaceType cit; +} +{ + "permits" cit = AnnotatedClassOrInterfaceType() { ret.add(cit); } + ( "," cit = AnnotatedClassOrInterfaceType() { ret.add(cit); } )* + { return ret; } +} + /** * https://docs.oracle.com/javase/specs/jls/se15/html/jls-8.html#jls-8.9 *
{@code
diff --git a/javaparser-symbol-solver-core/pom.xml b/javaparser-symbol-solver-core/pom.xml
index 8f4f63d3c3..115bbe127d 100644
--- a/javaparser-symbol-solver-core/pom.xml
+++ b/javaparser-symbol-solver-core/pom.xml
@@ -3,8 +3,8 @@
   
       javaparser-parent
       com.github.javaparser
-      3.25.2
-  
+      3.25.3
+      
   4.0.0
 
     javaparser-symbol-solver-core
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/MethodCallExprContext.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/MethodCallExprContext.java
index 213ae36cd7..4909fbee3b 100644
--- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/MethodCallExprContext.java
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/MethodCallExprContext.java
@@ -340,13 +340,24 @@ private MethodUsage resolveMethodTypeParameters(MethodUsage methodUsage, List
                 // but Arrays.aslist(String[]{""}) must returns List
-                // May be the result depends on the component type of the array
+                // Arrays.asList() accept generic type T. Since Java generics work only on
+				// reference types (object types), not on primitives, and int[] is an object
+                // then Arrays.aslist(int[]{1}) returns List
                 ResolvedType lastActualParamType =
                         actualParamTypes.get(actualParamTypes.size() - 1);
-                ResolvedType actualType =
-                		lastActualParamType.isArray() && lastActualParamType.asArrayType().getComponentType().isReferenceType() ?
-                				lastActualParamType.asArrayType().getComponentType() :
-                					lastActualParamType;
+                ResolvedType actualType = lastActualParamType;
+                if (lastActualParamType.isArray()) {
+                	ResolvedType componentType = lastActualParamType.asArrayType().getComponentType();
+                	// in cases where, the expected type is a generic type (Arrays.asList(T... a)) and the component type of the array type is a reference type
+                	// or the expected type is not a generic (IntStream.of(int... values)) and the component type is not a reference type
+                	// then the actual type is the component type (in the example above 'int')
+                	if ((componentType.isReferenceType()
+                			&& ResolvedTypeVariable.class.isInstance(expectedType))
+                			|| (!componentType.isReferenceType()
+                        			&& !ResolvedTypeVariable.class.isInstance(expectedType))) {
+                		actualType = lastActualParamType.asArrayType().getComponentType();
+                	}
+                }
                 if (!expectedType.isAssignableBy(actualType)) {
                     for (ResolvedTypeParameterDeclaration tp : methodUsage.getDeclaration().getTypeParameters()) {
                         expectedType = MethodResolutionLogic.replaceTypeParam(expectedType, tp, typeSolver);
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnnotationDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnnotationDeclaration.java
index f99376a54d..405bac13ff 100644
--- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnnotationDeclaration.java
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnnotationDeclaration.java
@@ -21,6 +21,10 @@
 
 package com.github.javaparser.symbolsolver.javaparsermodel.declarations;
 
+import java.lang.annotation.Inherited;
+import java.util.*;
+import java.util.stream.Collectors;
+
 import com.github.javaparser.ast.Node;
 import com.github.javaparser.ast.body.AnnotationDeclaration;
 import com.github.javaparser.ast.body.AnnotationMemberDeclaration;
@@ -31,10 +35,6 @@
 import com.github.javaparser.resolution.types.ResolvedType;
 import com.github.javaparser.symbolsolver.logic.AbstractTypeDeclaration;
 
-import java.lang.annotation.Inherited;
-import java.util.*;
-import java.util.stream.Collectors;
-
 /**
  * @author Federico Tomassetti
  */
@@ -92,6 +92,14 @@ public boolean hasDirectlyAnnotation(String canonicalName) {
         return AstResolutionUtils.hasDirectlyAnnotation(wrappedNode, typeSolver, canonicalName);
     }
 
+    /*
+     * Returns a set of the declared annotation on this type
+     */
+    @Override
+    public Set getDeclaredAnnotations() {
+        return javaParserTypeAdapter.getDeclaredAnnotations();
+    }
+
     @Override
     public String getPackageName() {
         return AstResolutionUtils.getPackageName(wrappedNode);
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnonymousClassDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnonymousClassDeclaration.java
index 5e95bf1131..18b497aee1 100644
--- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnonymousClassDeclaration.java
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnonymousClassDeclaration.java
@@ -21,6 +21,9 @@
 
 package com.github.javaparser.symbolsolver.javaparsermodel.declarations;
 
+import java.util.*;
+import java.util.stream.Collectors;
+
 import com.github.javaparser.ast.AccessSpecifier;
 import com.github.javaparser.ast.Node;
 import com.github.javaparser.ast.body.FieldDeclaration;
@@ -44,9 +47,6 @@
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Lists;
 
-import java.util.*;
-import java.util.stream.Collectors;
-
 /**
  * An anonymous class declaration representation.
  */
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserClassDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserClassDeclaration.java
index 6778fb2c95..c73ab84457 100644
--- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserClassDeclaration.java
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserClassDeclaration.java
@@ -21,6 +21,9 @@
 
 package com.github.javaparser.symbolsolver.javaparsermodel.declarations;
 
+import java.util.*;
+import java.util.stream.Collectors;
+
 import com.github.javaparser.ast.AccessSpecifier;
 import com.github.javaparser.ast.Node;
 import com.github.javaparser.ast.body.BodyDeclaration;
@@ -44,9 +47,6 @@
 import com.github.javaparser.symbolsolver.logic.AbstractClassDeclaration;
 import com.github.javaparser.symbolsolver.resolution.SymbolSolver;
 
-import java.util.*;
-import java.util.stream.Collectors;
-
 /**
  * @author Federico Tomassetti
  */
@@ -104,7 +104,7 @@ public String toString() {
     ///
     /// Public methods: fields
     ///
-    
+
     @Override
     public List getAllFields() {
         List fields = javaParserTypeAdapter.getFieldsForDeclaredVariables();
@@ -143,7 +143,7 @@ public boolean isVolatile() {
                                 public ResolvedTypeDeclaration declaringType() {
                                     return f.declaringType();
                                 }
-                                
+
                                 @Override
                                 public Optional toAst() {
                                     return f.toAst();
@@ -223,6 +223,14 @@ public boolean hasDirectlyAnnotation(String canonicalName) {
         return AstResolutionUtils.hasDirectlyAnnotation(wrappedNode, typeSolver, canonicalName);
     }
 
+    /*
+     * Returns a set of the declared annotation on this type
+     */
+    @Override
+    public Set getDeclaredAnnotations() {
+        return javaParserTypeAdapter.getDeclaredAnnotations();
+    }
+
     @Override
     public boolean isInterface() {
         return wrappedNode.isInterface();
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserInterfaceDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserInterfaceDeclaration.java
index 4bae624d24..5264281b72 100644
--- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserInterfaceDeclaration.java
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserInterfaceDeclaration.java
@@ -21,6 +21,9 @@
 
 package com.github.javaparser.symbolsolver.javaparsermodel.declarations;
 
+import java.util.*;
+import java.util.stream.Collectors;
+
 import com.github.javaparser.ast.AccessSpecifier;
 import com.github.javaparser.ast.Node;
 import com.github.javaparser.ast.body.BodyDeclaration;
@@ -44,9 +47,6 @@
 import com.github.javaparser.symbolsolver.logic.AbstractTypeDeclaration;
 import com.github.javaparser.symbolsolver.resolution.SymbolSolver;
 
-import java.util.*;
-import java.util.stream.Collectors;
-
 /**
  * @author Federico Tomassetti
  */
@@ -118,6 +118,14 @@ public boolean hasDirectlyAnnotation(String canonicalName) {
         return AstResolutionUtils.hasDirectlyAnnotation(wrappedNode, typeSolver, canonicalName);
     }
 
+    /*
+     * Returns a set of the declared annotation on this type
+     */
+    @Override
+    public Set getDeclaredAnnotations() {
+        return javaParserTypeAdapter.getDeclaredAnnotations();
+    }
+
     @Override
     public boolean isInterface() {
         return true;
@@ -232,7 +240,7 @@ public boolean isVolatile() {
                                 public ResolvedTypeDeclaration declaringType() {
                                     return f.declaringType();
                                 }
-                                
+
                                 @Override
                                 public Optional toAst() {
                                     return f.toAst();
@@ -240,7 +248,7 @@ public Optional toAst() {
                             });
                         })
                 );
-        
+
         return fields;
     }
 
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeAdapter.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeAdapter.java
index 893e783b53..5733080a7d 100644
--- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeAdapter.java
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeAdapter.java
@@ -21,14 +21,19 @@
 
 package com.github.javaparser.symbolsolver.javaparsermodel.declarations;
 
+import java.util.*;
+import java.util.stream.Collectors;
+
 import com.github.javaparser.ast.Node;
 import com.github.javaparser.ast.NodeList;
 import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations;
 import com.github.javaparser.ast.nodeTypes.NodeWithMembers;
 import com.github.javaparser.ast.nodeTypes.NodeWithSimpleName;
 import com.github.javaparser.ast.nodeTypes.NodeWithTypeParameters;
 import com.github.javaparser.ast.type.TypeParameter;
 import com.github.javaparser.resolution.TypeSolver;
+import com.github.javaparser.resolution.declarations.ResolvedAnnotationDeclaration;
 import com.github.javaparser.resolution.declarations.ResolvedFieldDeclaration;
 import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
 import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration;
@@ -39,12 +44,10 @@
 import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
 import com.github.javaparser.symbolsolver.resolution.SymbolSolver;
 
-import java.util.*;
-
 /**
  * @author Federico Tomassetti
  */
-public class JavaParserTypeAdapter & NodeWithMembers> {
+public class JavaParserTypeAdapter & NodeWithMembers & NodeWithAnnotations> {
 
     private T wrappedNode;
     private TypeSolver typeSolver;
@@ -157,7 +160,7 @@ public Optional containerType() {
                 .getParentNode()
                 .map(node -> node.getSymbolResolver().toTypeDeclaration(node));
     }
-    
+
     public List getFieldsForDeclaredVariables() {
         List fields = new ArrayList<>();
         if (wrappedNode.getMembers() != null) {
@@ -173,6 +176,15 @@ public List getFieldsForDeclaredVariables() {
         return fields;
     }
 
+    /*
+     * Returns a set of the declared annotation on this type
+     */
+    public Set getDeclaredAnnotations() {
+    	return wrappedNode.getAnnotations().stream()
+    		.map(annotation -> annotation.resolve())
+    		.collect(Collectors.toSet());
+    }
+
     public Set internalTypes() {
         // Use a special Set implementation that avoids calculating the hashCode of the node,
         // since this can be very time-consuming for big node trees, and we are sure there are
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistClassDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistClassDeclaration.java
index 8e83c3e013..c56fd027c6 100644
--- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistClassDeclaration.java
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistClassDeclaration.java
@@ -21,6 +21,10 @@
 
 package com.github.javaparser.symbolsolver.javassistmodel;
 
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+
 import com.github.javaparser.ast.AccessSpecifier;
 import com.github.javaparser.ast.Node;
 import com.github.javaparser.resolution.Context;
@@ -37,13 +41,10 @@
 import com.github.javaparser.symbolsolver.core.resolution.SymbolResolutionCapability;
 import com.github.javaparser.symbolsolver.logic.AbstractClassDeclaration;
 import com.github.javaparser.symbolsolver.resolution.SymbolSolver;
+
 import javassist.CtClass;
 import javassist.CtField;
 
-import java.util.List;
-import java.util.Optional;
-import java.util.Set;
-
 /**
  * @author Federico Tomassetti
  */
@@ -76,6 +77,14 @@ public boolean hasDirectlyAnnotation(String canonicalName) {
         return ctClass.hasAnnotation(canonicalName);
     }
 
+    /*
+     * Returns a set of the declared annotation on this type
+     */
+    @Override
+    public Set getDeclaredAnnotations() {
+        return javassistTypeDeclarationAdapter.getDeclaredAnnotations();
+    }
+
     @Override
     public Set getDeclaredMethods() {
         return javassistTypeDeclarationAdapter.getDeclaredMethods();
@@ -120,7 +129,8 @@ public String getQualifiedName() {
         return ctClass.getName().replace('$', '.');
     }
 
-    @Deprecated
+    @Override
+	@Deprecated
     public Optional solveMethodAsUsage(String name, List argumentsTypes,
                                                     Context invokationContext, List typeParameterValues) {
         return JavassistUtils.solveMethodAsUsage(name, argumentsTypes, typeSolver, invokationContext, typeParameterValues, this, ctClass);
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistInterfaceDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistInterfaceDeclaration.java
index bc183d78bf..76ba87101d 100644
--- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistInterfaceDeclaration.java
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistInterfaceDeclaration.java
@@ -21,6 +21,9 @@
 
 package com.github.javaparser.symbolsolver.javassistmodel;
 
+import java.util.*;
+import java.util.stream.Collectors;
+
 import com.github.javaparser.ast.AccessSpecifier;
 import com.github.javaparser.resolution.Context;
 import com.github.javaparser.resolution.MethodUsage;
@@ -35,12 +38,10 @@
 import com.github.javaparser.symbolsolver.core.resolution.SymbolResolutionCapability;
 import com.github.javaparser.symbolsolver.logic.AbstractTypeDeclaration;
 import com.github.javaparser.symbolsolver.resolution.SymbolSolver;
+
 import javassist.CtClass;
 import javassist.CtField;
 
-import java.util.*;
-import java.util.stream.Collectors;
-
 /**
  * @author Federico Tomassetti
  */
@@ -93,7 +94,8 @@ public String getQualifiedName() {
         return ctClass.getName().replace('$', '.');
     }
 
-    @Deprecated
+    @Override
+	@Deprecated
     public Optional solveMethodAsUsage(String name, List argumentsTypes,
                                                     Context invokationContext, List typeParameterValues) {
         return JavassistUtils.solveMethodAsUsage(name, argumentsTypes, typeSolver, invokationContext, typeParameterValues, this, ctClass);
@@ -137,6 +139,14 @@ public boolean hasDirectlyAnnotation(String canonicalName) {
         return ctClass.hasAnnotation(canonicalName);
     }
 
+    /*
+     * Returns a set of the declared annotation on this type
+     */
+    @Override
+    public Set getDeclaredAnnotations() {
+        return javassistTypeDeclarationAdapter.getDeclaredAnnotations();
+    }
+
     @Override
     public String getName() {
         String[] nameElements = ctClass.getSimpleName().replace('$', '.').split("\\.");
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistTypeDeclarationAdapter.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistTypeDeclarationAdapter.java
index fe1cf9d74b..ebbd8e82ec 100644
--- a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistTypeDeclarationAdapter.java
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistTypeDeclarationAdapter.java
@@ -21,6 +21,12 @@
 
 package com.github.javaparser.symbolsolver.javassistmodel;
 
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.*;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
 import com.github.javaparser.resolution.TypeSolver;
 import com.github.javaparser.resolution.UnsolvedSymbolException;
 import com.github.javaparser.resolution.declarations.*;
@@ -28,6 +34,7 @@
 import com.github.javaparser.resolution.model.typesystem.ReferenceTypeImpl;
 import com.github.javaparser.resolution.types.ResolvedReferenceType;
 import com.github.javaparser.resolution.types.ResolvedType;
+
 import javassist.CtClass;
 import javassist.CtField;
 import javassist.NotFoundException;
@@ -35,15 +42,26 @@
 import javassist.bytecode.BadBytecode;
 import javassist.bytecode.SignatureAttribute;
 
-import java.util.*;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
 /**
  * @author Federico Tomassetti
  */
 public class JavassistTypeDeclarationAdapter {
 
+	// this a workaround to get the annotation type (taken from Javassist AnnotationImpl class)
+	private static final String JDK_ANNOTATION_CLASS_NAME = "java.lang.annotation.Annotation";
+    private static Method JDK_ANNOTATION_TYPE_METHOD = null;
+
+    static {
+        // Try to resolve the JDK annotation type method
+        try {
+            Class clazz = Class.forName(JDK_ANNOTATION_CLASS_NAME);
+            JDK_ANNOTATION_TYPE_METHOD = clazz.getMethod("annotationType", (Class[])null);
+        }
+        catch (Exception ignored) {
+            // Probably not JDK5+
+        }
+    }
+
     private CtClass ctClass;
     private TypeSolver typeSolver;
     private ResolvedReferenceTypeDeclaration typeDeclaration;
@@ -164,6 +182,36 @@ public List getDeclaredFields() {
         return fields;
     }
 
+    /*
+     * Returns a set of the declared annotation on this type
+     */
+    public Set getDeclaredAnnotations() {
+    	try {
+			Object[] annotations = ctClass.getAnnotations();
+			return Stream.of(annotations)
+	    			.map(annotation -> getAnnotationType(annotation))
+	    			.filter(annotationType -> annotationType != null)
+	    			.map(annotationType -> typeSolver.solveType(annotationType))
+	    			.map(rrtd -> rrtd.asAnnotation())
+	    			.collect(Collectors.toSet());
+		} catch (ClassNotFoundException e) {
+			// There is nothing to do except returns an empty set
+		}
+    	return Collections.EMPTY_SET;
+
+    }
+
+    private String getAnnotationType(Object annotation) {
+    	String typeName = null;
+    	try {
+    		Class annotationClass = (Class) Proxy.getInvocationHandler(annotation)
+					.invoke(annotation, JDK_ANNOTATION_TYPE_METHOD, null);
+    		typeName = annotationClass.getTypeName();
+		} catch (Throwable e) {
+		}
+    	return typeName;
+    }
+
     public List getTypeParameters() {
         if (null == ctClass.getGenericSignature()) {
             return Collections.emptyList();
diff --git a/javaparser-symbol-solver-testing/pom.xml b/javaparser-symbol-solver-testing/pom.xml
index 5ba6e1fbdf..6f6d327605 100644
--- a/javaparser-symbol-solver-testing/pom.xml
+++ b/javaparser-symbol-solver-testing/pom.xml
@@ -3,7 +3,7 @@
     
         javaparser-parent
         com.github.javaparser
-        3.25.2
+        3.25.3
     
     4.0.0
 
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserClassDeclarationTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserClassDeclarationTest.java
index fc6ad17cb1..08fb1d0235 100644
--- a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserClassDeclarationTest.java
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserClassDeclarationTest.java
@@ -927,12 +927,22 @@ void testHasAnnotation() throws IOException {
         assertFalse(ca.hasAnnotation("foo.bar.MyUnexistingAnnotation"));
 
         JavaParserClassDeclaration cb = new JavaParserClassDeclaration(Navigator.demandClass(cu, "CB"), typeSolver);
-        assertTrue(cb.hasAnnotation("foo.bar.MyAnnotation"));
+        assertFalse(cb.hasAnnotation("foo.bar.MyAnnotation"));
         assertTrue(cb.hasAnnotation("foo.bar.MyAnnotation2"));
         assertFalse(cb.hasAnnotation("MyAnnotation"));
         assertFalse(cb.hasAnnotation("foo.bar.MyUnexistingAnnotation"));
     }
 
+    @Test
+    void testHasInheritedAnnotation() throws IOException {
+        TypeSolver typeSolver = new ReflectionTypeSolver();
+
+        CompilationUnit cu = parse(adaptPath("src/test/resources/Annotations.java.txt"));
+
+        JavaParserClassDeclaration child = new JavaParserClassDeclaration(Navigator.demandClass(cu, "Child"), typeSolver);
+        assertTrue(child.hasAnnotation("foo.bar.InheritedAnnotation"));
+    }
+
     ///
     ///
     ///
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistClassDeclarationTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistClassDeclarationTest.java
index 6474cca1c5..cb0eee4079 100644
--- a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistClassDeclarationTest.java
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistClassDeclarationTest.java
@@ -21,6 +21,17 @@
 
 package com.github.javaparser.symbolsolver.javassistmodel;
 
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.*;
+import java.util.stream.Collectors;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+
 import com.github.javaparser.ast.Node;
 import com.github.javaparser.resolution.MethodUsage;
 import com.github.javaparser.resolution.TypeSolver;
@@ -39,19 +50,10 @@
 import com.github.javaparser.symbolsolver.resolution.typesolvers.JarTypeSolver;
 import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
 import com.google.common.collect.ImmutableSet;
+
 import javassist.ClassPool;
 import javassist.CtClass;
 import javassist.NotFoundException;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Nested;
-import org.junit.jupiter.api.Test;
-
-import java.io.IOException;
-import java.nio.file.Path;
-import java.util.*;
-import java.util.stream.Collectors;
-
-import static org.junit.jupiter.api.Assertions.*;
 
 class JavassistClassDeclarationTest extends AbstractClassDeclarationTest {
 
@@ -162,7 +164,8 @@ void testHasDirectlyAnnotation() {
     @Test
     void testHasAnnotation() {
         JavassistClassDeclaration compilationUnit = (JavassistClassDeclaration) anotherTypeSolver.solveType("com.github.javaparser.test.TestChildClass");
-        assertTrue(compilationUnit.hasAnnotation("com.github.javaparser.test.TestAnnotation"));
+        //TestChildClass has no TestAnnotation annotation declared even though parent class is annotated with this annotation because TestAnnotation annotation is not inheritable
+        assertFalse(compilationUnit.hasAnnotation("com.github.javaparser.test.TestAnnotation"));
     }
 
     @Test
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistEnumDeclarationTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistEnumDeclarationTest.java
index a65731f99c..35cfd540db 100644
--- a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistEnumDeclarationTest.java
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistEnumDeclarationTest.java
@@ -21,19 +21,20 @@
 
 package com.github.javaparser.symbolsolver.javassistmodel;
 
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.IOException;
+import java.nio.file.Path;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
 import com.github.javaparser.resolution.TypeSolver;
 import com.github.javaparser.resolution.declarations.ResolvedEnumDeclaration;
 import com.github.javaparser.symbolsolver.AbstractSymbolResolutionTest;
 import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
 import com.github.javaparser.symbolsolver.resolution.typesolvers.JarTypeSolver;
 import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-import java.io.IOException;
-import java.nio.file.Path;
-
-import static org.junit.jupiter.api.Assertions.*;
 
 class JavassistEnumDeclarationTest extends AbstractSymbolResolutionTest {
 
@@ -139,7 +140,7 @@ void testHasDirectlyAnnotation(){
     @Test
     void testHasAnnotation(){
         ResolvedEnumDeclaration compilationUnit = (ResolvedEnumDeclaration) anotherTypeSolver.solveType("com.github.javaparser.test.TestParentEnum");
-        assertTrue(compilationUnit.hasAnnotation("com.github.javaparser.test.TestAnnotation"));
+        assertFalse(compilationUnit.hasAnnotation("com.github.javaparser.test.TestAnnotation"));
     }
 
     ///
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistInterfaceDeclarationTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistInterfaceDeclarationTest.java
index 740e7a4980..6cffe3c671 100644
--- a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistInterfaceDeclarationTest.java
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistInterfaceDeclarationTest.java
@@ -21,6 +21,19 @@
 
 package com.github.javaparser.symbolsolver.javassistmodel;
 
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.function.Consumer;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+
 import com.github.javaparser.resolution.TypeSolver;
 import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
 import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
@@ -36,20 +49,9 @@
 import com.github.javaparser.symbolsolver.resolution.typesolvers.MemoryTypeSolver;
 import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
 import com.github.javaparser.utils.Pair;
+
 import javassist.ClassPool;
 import javassist.CtClass;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Nested;
-import org.junit.jupiter.api.Test;
-
-import java.io.IOException;
-import java.nio.file.Path;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-import java.util.function.Consumer;
-
-import static org.junit.jupiter.api.Assertions.*;
 
 class JavassistInterfaceDeclarationTest extends AbstractSymbolResolutionTest {
 
@@ -155,7 +157,7 @@ void testHasDirectlyAnnotation(){
     @Test
     void testHasAnnotation(){
         JavassistInterfaceDeclaration compilationUnit = (JavassistInterfaceDeclaration) anotherTypeSolver.solveType("com.github.javaparser.test.TestChildInterface");
-        assertTrue(compilationUnit.hasAnnotation("com.github.javaparser.test.TestAnnotation"));
+        assertFalse(compilationUnit.hasAnnotation("com.github.javaparser.test.TestAnnotation"));
     }
 
     @Nested
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/model/typesystem/WildcardUsageTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/model/typesystem/WildcardUsageTest.java
index 501518cf07..10bde6cf71 100644
--- a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/model/typesystem/WildcardUsageTest.java
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/model/typesystem/WildcardUsageTest.java
@@ -21,19 +21,25 @@
 
 package com.github.javaparser.symbolsolver.model.typesystem;
 
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
 import com.github.javaparser.resolution.TypeSolver;
 import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
 import com.github.javaparser.resolution.model.typesystem.ReferenceTypeImpl;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.resolution.types.ResolvedType;
 import com.github.javaparser.resolution.types.ResolvedTypeVariable;
 import com.github.javaparser.resolution.types.ResolvedWildcard;
 import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassDeclaration;
 import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-import java.util.Collections;
-
-import static org.junit.jupiter.api.Assertions.*;
 
 class WildcardUsageTest {
 
@@ -424,4 +430,57 @@ class Foo {
         assertEquals(false, ref.getFieldType("bar").isPresent());
     }*/
 
+//    @Test
+//	void testIsAssignableByGenerics() {
+//		ResolvedType listOfSomethingExtendingNumbers = genericType(List.class.getCanonicalName(),
+//				extendsBound(Number.class.getCanonicalName()));
+//		ResolvedType listOfNumbers = genericType(List.class.getCanonicalName(), Number.class.getCanonicalName());
+//		ResolvedType listOfSomethingExtendingIntegers = genericType(List.class.getCanonicalName(),
+//				extendsBound(Integer.class.getCanonicalName()));
+//
+//		ResolvedType list1 = genericType(List.class.getCanonicalName(), Integer.class.getCanonicalName());
+//
+//		print(listOfSomethingExtendingIntegers.asReferenceType().getAllAncestors());
+//
+//		Collection c1;
+//		Collection c2 = new ArrayList<>();;
+//		List lnum = new ArrayList<>();
+//		List lint = new ArrayList<>();
+//		c1 = lint;
+//		c1 = lnum;
+//		lnum = lint;
+//		c1 = c2;
+//	}
+
+
+    // Utility methods
+
+	private void print(List ancestors) {
+		for (ResolvedReferenceType ancestor : ancestors) {
+			System.out.println(ancestor.describe());
+		}
+	}
+
+	private List types(String... types) {
+		return Arrays.stream(types).map(type -> type(type)).collect(Collectors.toList());
+	}
+
+	private ResolvedType type(String type) {
+		return new ReferenceTypeImpl(typeSolver.solveType(type));
+	}
+
+	private ResolvedType genericType(String type, String... parameterTypes) {
+		return new ReferenceTypeImpl(typeSolver.solveType(type), types(parameterTypes));
+	}
+
+	private ResolvedType genericType(String type, ResolvedType... parameterTypes) {
+		return new ReferenceTypeImpl(typeSolver.solveType(type), Arrays.asList(parameterTypes));
+	}
+
+	private ResolvedType extendsBound(String type) {
+		return ResolvedWildcard.extendsBound(type(type));
+	}
+
+
+
 }
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/DefaultPackageTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/DefaultPackageTest.java
index a389ec1627..cb977ce19e 100644
--- a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/DefaultPackageTest.java
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/DefaultPackageTest.java
@@ -21,6 +21,14 @@
 
 package com.github.javaparser.symbolsolver.resolution;
 
+import static com.github.javaparser.StaticJavaParser.parse;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import java.util.*;
+
+import org.junit.jupiter.api.Test;
+
 import com.github.javaparser.ast.AccessSpecifier;
 import com.github.javaparser.ast.type.ClassOrInterfaceType;
 import com.github.javaparser.resolution.UnsolvedSymbolException;
@@ -31,13 +39,6 @@
 import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
 import com.github.javaparser.symbolsolver.logic.AbstractClassDeclaration;
 import com.github.javaparser.symbolsolver.resolution.typesolvers.MemoryTypeSolver;
-import org.junit.jupiter.api.Test;
-
-import java.util.*;
-
-import static com.github.javaparser.StaticJavaParser.parse;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
 
 /**
  * See issue #16
@@ -146,6 +147,11 @@ public Optional containerType() {
         public SymbolReference solveMethod(String name, List argumentsTypes, boolean staticOnly) {
             throw new UnsupportedOperationException();
         }
+
+		@Override
+		public Set getDeclaredAnnotations() {
+			return new HashSet<>();
+		}
     }
 
     @Test
@@ -169,7 +175,7 @@ void aClassInDefaultPackageCanBeAccessedFromOutsideTheDefaultPackageImportingIt(
         ResolvedType resolvedType = JavaParserFacade.get(memoryTypeSolver).convertToUsage(jpType);
         assertEquals("B", resolvedType.asReferenceType().getQualifiedName());
     });
-                
+
                 }
 
     @Test
@@ -181,6 +187,6 @@ void aClassInDefaultPackageCanBeAccessedFromOutsideTheDefaultPackageWithoutImpor
         ResolvedType resolvedType = JavaParserFacade.get(memoryTypeSolver).convertToUsage(parse(code).getClassByName("A").get().getExtendedTypes(0));
         assertEquals("B", resolvedType.asReferenceType().getQualifiedName());
     });
-                
+
         }
 }
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/JavaParserFacadeResolutionTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/JavaParserFacadeResolutionTest.java
index 76cb94970d..8cac015477 100644
--- a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/JavaParserFacadeResolutionTest.java
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/JavaParserFacadeResolutionTest.java
@@ -250,6 +250,49 @@ void resolveTypeParameterFromPrimitiveArrayArgument() {
         assertEquals("java.util.List", resolvedType.describe());
     }
 
+    @Test
+    void resolveTypeParameterFromReferenceArrayArgument() {
+        String sourceCode = "" +
+                "import java.util.Arrays;\n" +
+                "\n" +
+                "public class Main {\n" +
+                "    public void main(String[] args) {\n" +
+                "        Arrays.asList(args);\n" +
+                "    }\n" +
+                "}";
+
+        JavaParser parser = createParserWithResolver(defaultTypeSolver());
+        CompilationUnit cu = parser.parse(sourceCode).getResult().get();
+
+        MethodCallExpr mce = cu.findFirst(MethodCallExpr.class).get();
+
+        ResolvedType resolvedType = mce.calculateResolvedType();
+
+        assertEquals("java.util.List", resolvedType.describe());
+    }
+
+    @Test
+    void resolveTypeParameterFromPrimitiveArrayArgumentOnNonGenericExpectedParameter() {
+        String sourceCode = "" +
+        		"import java.util.OptionalDouble;\n" +
+				"import java.util.stream.IntStream;\n" +
+                "\n" +
+                "public class Main {\n" +
+                "	OptionalDouble pre(int[] values) {\n" +
+				"		return IntStream.of(values).map(s -> s).average();\n" +
+				"	}\n" +
+                "}";
+
+        JavaParser parser = createParserWithResolver(defaultTypeSolver());
+        CompilationUnit cu = parser.parse(sourceCode).getResult().get();
+
+        MethodCallExpr mce = cu.findFirst(MethodCallExpr.class).get();
+
+        ResolvedType resolvedType = mce.calculateResolvedType();
+
+        assertEquals("java.util.OptionalDouble", resolvedType.describe());
+    }
+
     // See issue 3725
     @Test
     void resolveVarTypeInForEachLoopFromIterableExpression2() {
diff --git a/javaparser-symbol-solver-testing/src/test/resources/Annotations.java.txt b/javaparser-symbol-solver-testing/src/test/resources/Annotations.java.txt
index 1ddea7a35b..0f8e7d5bae 100644
--- a/javaparser-symbol-solver-testing/src/test/resources/Annotations.java.txt
+++ b/javaparser-symbol-solver-testing/src/test/resources/Annotations.java.txt
@@ -80,3 +80,7 @@ class CH {
 public @interface InheritedAnnotation {
 }
 
+@InheritedAnnotation
+class Parent {}
+class Child extends Parent {}
+
diff --git a/pom.xml b/pom.xml
index c2513c4588..b0d3f8720f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -14,7 +14,7 @@
     com.github.javaparser
     javaparser-parent
     pom
-    3.25.2
+    3.25.3
 
     javaparser-parent
     https://github.com/javaparser
@@ -215,7 +215,7 @@
                 
                     org.apache.maven.plugins
                     maven-install-plugin
-                    3.1.0
+                    3.1.1
                 
                 
                     org.apache.maven.plugins
@@ -231,7 +231,7 @@
                     
                     org.apache.maven.plugins
                     maven-release-plugin
-                    2.5.3
+                    3.0.0
                     
                         
                         true
@@ -246,7 +246,7 @@
                 
                     org.apache.maven.plugins
                     maven-resources-plugin
-                    3.3.0
+                    3.3.1
                 
                 
                     org.apache.maven.plugins
@@ -273,7 +273,7 @@
                 
                     org.jacoco
                     jacoco-maven-plugin
-                    0.8.8
+                    0.8.10
                 
                 
                     org.apache.maven.plugins
@@ -317,7 +317,7 @@
                 
                     org.apache.maven.plugins
                     maven-deploy-plugin
-                    3.1.0
+                    3.1.1
                 
                 
                     org.codehaus.mojo
@@ -345,7 +345,7 @@
                 
                     org.apache.maven.plugins
                     maven-checkstyle-plugin
-                    3.2.1
+                    3.2.2
                     
                         dev-files/JavaParser-CheckStyle.xml
                         true
@@ -355,7 +355,7 @@
                         
                             com.puppycrawl.tools
                             checkstyle
-                            10.9.1
+                            10.10.0
                         
                     
                 
@@ -391,19 +391,19 @@
             
                 org.junit.jupiter
                 junit-jupiter-engine
-                5.9.2
+                5.9.3
                 test
             
             
                 org.junit.jupiter
                 junit-jupiter-params
-                5.9.2
+                5.9.3
                 test
             
             
                 org.junit.vintage
                 junit-vintage-engine
-                5.9.2
+                5.9.3
                 test
             
             
diff --git a/readme.md b/readme.md
index 774abeda92..e9e5a47840 100644
--- a/readme.md
+++ b/readme.md
@@ -138,14 +138,14 @@ Just add the following to your maven configuration or tailor to your own depende
 
     com.github.javaparser
     javaparser-symbol-solver-core
-    3.25.2
+    3.25.3
 
 ```
 
 **Gradle**:
 
 ```
-implementation 'com.github.javaparser:javaparser-symbol-solver-core:3.25.2'
+implementation 'com.github.javaparser:javaparser-symbol-solver-core:3.25.3'
 ```
 
 Since Version 3.5.10, the JavaParser project includes the JavaSymbolSolver.
@@ -160,14 +160,14 @@ Using the dependency above will add both JavaParser and JavaSymbolSolver to your
 
     com.github.javaparser
     javaparser-core
-    3.25.2
+    3.25.3
 
 ```
 
 **Gradle**:
 
 ```
-implementation 'com.github.javaparser:javaparser-core:3.25.2'
+implementation 'com.github.javaparser:javaparser-core:3.25.3'
 ```
 
 Since version 3.6.17 the AST can be serialized to JSON.
@@ -179,14 +179,14 @@ There is a separate module for this:
 
     com.github.javaparser
     javaparser-core-serialization
-    3.25.2
+    3.25.3
 
 ```
 
 **Gradle**:
 
 ```
-implementation 'com.github.javaparser:javaparser-core-serialization:3.25.2'
+implementation 'com.github.javaparser:javaparser-core-serialization:3.25.3'
 ```
 
 ## How To Compile Sources