refs = JavadocReferencesExistingSymbolsCheck.extractSeeReferences(
+ "/** @see java.util.List {@link java.util.Map} */");
+ assertThat(refs).containsExactly("java.util.List", "java.util.Map");
+ }
+
+ @Test
+ void stripMemberReference_returns_null_for_method_references() {
+ assertThat(JavadocReferencesExistingSymbolsCheck.stripMemberReference("#myMethod")).isNull();
+ }
+
+ @Test
+ void stripMemberReference_returns_fully_qualified_name_as_is() {
+ assertThat(JavadocReferencesExistingSymbolsCheck.stripMemberReference("java.util.List")).isEqualTo("java.util.List");
+ }
+
+ @Test
+ void stripMemberReference_strips_method_signature() {
+ assertThat(JavadocReferencesExistingSymbolsCheck.stripMemberReference("java.util.List#size()")).isEqualTo("java.util.List");
+ }
+
+ @Test
+ void stripMemberReference_strips_member_reference() {
+ assertThat(JavadocReferencesExistingSymbolsCheck.stripMemberReference("java.util.List#EMPTY_LIST")).isEqualTo("java.util.List");
+ }
+
+ @Test
+ void stripMemberReference_returns_simple_name() {
+ assertThat(JavadocReferencesExistingSymbolsCheck.stripMemberReference("MyClass")).isEqualTo("MyClass");
+ }
+}
diff --git a/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S9360.html b/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S9360.html
new file mode 100644
index 00000000000..049d754191b
--- /dev/null
+++ b/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S9360.html
@@ -0,0 +1,50 @@
+This rule detects @see references in Javadoc comments that point to non-existent types or members.
+Why is this an issue?
+Javadoc @see tags are used to create cross-references between documentation. When these references point to non-existent types or members, they result in broken links in the generated documentation, reducing its usefulness.
+The following patterns are detected:
+
+ - References to classes that cannot be resolved (e.g.,
@see com.example.NonExistentClass)
+ - References to methods or fields that don't exist in the referenced class
+ - Relative references to classes that don't exist in the current package
+
+This rule does not flag references to external URLs (starting with http:// or https://), as these are handled separately.
+How to fix it
+Verify that each @see reference points to an existing type or member. If the reference is intentional (e.g., documenting a planned API), consider removing it or adding a note explaining why it's referenced.
+Code examples
+Noncompliant code example
+
+import java.util.List;
+
+/**
+ * @see java.util.NonExistentClass
+ */
+public class MyClass { }
+
+Compliant solution
+
+import java.util.List;
+
+/**
+ * @see java.util.List
+ */
+public class MyClass { }
+
+Noncompliant code example
+
+/**
+ * @see com.example.NonExistentClass
+ */
+class MyClass { }
+
+Compliant solution
+
+/**
+ * @see com.example.ExistentClass
+ */
+class MyClass { }
+
+Resources
+Documentation
+
diff --git a/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S9360.json b/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S9360.json
new file mode 100644
index 00000000000..8c789ca15e6
--- /dev/null
+++ b/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S9360.json
@@ -0,0 +1,23 @@
+{
+ "title": "Javadoc references should point to existing types and members",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant/Issue",
+ "constantCost": "5min"
+ },
+ "tags": [
+ "documentation"
+ ],
+ "defaultSeverity": "Minor",
+ "ruleSpecification": "RSPEC-9360",
+ "sqKey": "S9360",
+ "scope": "All",
+ "quickfix": "covered",
+ "code": {
+ "impacts": {
+ "MAINTAINABILITY": "LOW"
+ },
+ "attribute": "CLEAR"
+ }
+}
diff --git a/sonar-java-plugin/src/main/resources/profiles/Sonar_way/S9360 b/sonar-java-plugin/src/main/resources/profiles/Sonar_way/S9360
new file mode 100644
index 00000000000..e69de29bb2d