diff options
author | Kalyan Prasad Tatavarthi | 2020-08-14 11:33:53 +0000 |
---|---|---|
committer | Kalyan Prasad Tatavarthi | 2020-08-17 09:08:36 +0000 |
commit | f283097bad85669ee08dfa2a363f9ad7772a773b (patch) | |
tree | 375cd95877887020b1beb964d8a29e36c93d45a7 | |
parent | 0d3a39e6b9eb5cda3a498cd5d8329042abbd25f7 (diff) | |
download | eclipse.jdt.core-f283097bad85669ee08dfa2a363f9ad7772a773b.tar.gz eclipse.jdt.core-f283097bad85669ee08dfa2a363f9ad7772a773b.tar.xz eclipse.jdt.core-f283097bad85669ee08dfa2a363f9ad7772a773b.zip |
and @linkplain javadoc tags.
Change-Id: I05c4a42e63d7b10cad1bae0a9d9a47376a5ae8fb
Signed-off-by: Kalyan Prasad Tatavarthi <kalyan_prasad@in.ibm.com>
13 files changed, 569 insertions, 9 deletions
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java index 973ae05589..ccb08f8c7d 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java @@ -725,6 +725,7 @@ public void test011_problem_categories() { expectedProblemAttributes.put("JavadocInheritedNameHidesEnclosingTypeName", new ProblemAttributes(CategorizedProblem.CAT_JAVADOC)); expectedProblemAttributes.put("JavadocInternalTypeNameProvided", new ProblemAttributes(CategorizedProblem.CAT_JAVADOC)); expectedProblemAttributes.put("JavadocInvalidMemberTypeQualification", new ProblemAttributes(CategorizedProblem.CAT_JAVADOC)); + expectedProblemAttributes.put("JavadocInvalidModuleQualification", new ProblemAttributes(CategorizedProblem.CAT_JAVADOC)); expectedProblemAttributes.put("JavadocInvalidParamName", new ProblemAttributes(CategorizedProblem.CAT_JAVADOC)); expectedProblemAttributes.put("JavadocInvalidParamTagName", new ProblemAttributes(CategorizedProblem.CAT_JAVADOC)); expectedProblemAttributes.put("JavadocInvalidParamTagTypeParameter", new ProblemAttributes(CategorizedProblem.CAT_JAVADOC)); @@ -1770,6 +1771,7 @@ public void test012_compiler_problems_tuning() { expectedProblemAttributes.put("JavadocInheritedNameHidesEnclosingTypeName", new ProblemAttributes(JavaCore.COMPILER_PB_INVALID_JAVADOC)); expectedProblemAttributes.put("JavadocInternalTypeNameProvided", new ProblemAttributes(JavaCore.COMPILER_PB_INVALID_JAVADOC)); expectedProblemAttributes.put("JavadocInvalidMemberTypeQualification", new ProblemAttributes(JavaCore.COMPILER_PB_INVALID_JAVADOC)); + expectedProblemAttributes.put("JavadocInvalidModuleQualification", new ProblemAttributes(JavaCore.COMPILER_PB_INVALID_JAVADOC)); expectedProblemAttributes.put("JavadocInvalidParamName", new ProblemAttributes(JavaCore.COMPILER_PB_INVALID_JAVADOC)); expectedProblemAttributes.put("JavadocInvalidParamTagName", new ProblemAttributes(JavaCore.COMPILER_PB_INVALID_JAVADOC)); expectedProblemAttributes.put("JavadocInvalidParamTagTypeParameter", new ProblemAttributes(JavaCore.COMPILER_PB_INVALID_JAVADOC)); diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JavadocTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JavadocTest.java index 66e672d6cb..7098b9205b 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JavadocTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JavadocTest.java @@ -5,9 +5,13 @@ * are made available under the terms of the Eclipse Public License 2.0 * which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-2.0/ - * + * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation * Stephan Herrmann <stephan@cs.tu-berlin.de> - Contribution for bug 185682 - Increment/decrement operators mark local variables as read @@ -89,6 +93,9 @@ public abstract class JavadocTest extends AbstractRegressionTest { if ((complianceLevels & AbstractCompilerTest.F_14) != 0) { testSuite.addTest(buildUniqueComplianceTestSuite(JavadocTestForRecord.class, ClassFileConstants.JDK14)); } + if ((complianceLevels & AbstractCompilerTest.F_15) != 0) { + testSuite.addTest(buildUniqueComplianceTestSuite(JavadocTest_15.class, ClassFileConstants.JDK15)); + } return testSuite; } diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JavadocTest_15.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JavadocTest_15.java new file mode 100644 index 0000000000..518420bfaf --- /dev/null +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JavadocTest_15.java @@ -0,0 +1,234 @@ +/*******************************************************************************
+ * Copyright (c) 2020 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.tests.compiler.regression;
+
+import java.io.File;
+import java.util.Map;
+
+import junit.framework.Test;
+
+import org.eclipse.jdt.core.tests.util.Util;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+
+
+@SuppressWarnings({ "unchecked", "rawtypes" })
+public class JavadocTest_15 extends JavadocTest {
+
+ String docCommentSupport = CompilerOptions.ENABLED;
+ String reportInvalidJavadoc = CompilerOptions.ERROR;
+ String reportMissingJavadocDescription = CompilerOptions.RETURN_TAG;
+ String reportInvalidJavadocVisibility = CompilerOptions.PRIVATE;
+ String reportMissingJavadocTags = CompilerOptions.ERROR;
+ String reportMissingJavadocComments = null;
+ String reportMissingJavadocCommentsVisibility = null;
+ String reportDeprecation = CompilerOptions.ERROR;
+ String reportJavadocDeprecation = null;
+ String processAnnotations = null;
+
+public JavadocTest_15(String name) {
+ super(name);
+}
+
+public static Class javadocTestClass() {
+ return JavadocTest_15.class;
+}
+
+// Use this static initializer to specify subset for tests
+// All specified tests which does not belong to the class are skipped...
+static {
+
+}
+
+public static Test suite() {
+ return buildMinimalComplianceTestSuite(javadocTestClass(), F_15);
+}
+
+@Override
+protected Map getCompilerOptions() {
+ Map options = super.getCompilerOptions();
+ options.put(CompilerOptions.OPTION_DocCommentSupport, this.docCommentSupport);
+ options.put(CompilerOptions.OPTION_ReportInvalidJavadoc, this.reportInvalidJavadoc);
+ if (!CompilerOptions.IGNORE.equals(this.reportInvalidJavadoc)) {
+ options.put(CompilerOptions.OPTION_ReportInvalidJavadocTagsVisibility, this.reportInvalidJavadocVisibility);
+ }
+ if (this.reportJavadocDeprecation != null) {
+ options.put(CompilerOptions.OPTION_ReportInvalidJavadocTagsDeprecatedRef, this.reportJavadocDeprecation);
+ }
+ if (this.reportMissingJavadocComments != null) {
+ options.put(CompilerOptions.OPTION_ReportMissingJavadocComments, this.reportMissingJavadocComments);
+ options.put(CompilerOptions.OPTION_ReportMissingJavadocCommentsOverriding, CompilerOptions.ENABLED);
+ if (this.reportMissingJavadocCommentsVisibility != null) {
+ options.put(CompilerOptions.OPTION_ReportMissingJavadocCommentsVisibility, this.reportMissingJavadocCommentsVisibility);
+ }
+ } else {
+ options.put(CompilerOptions.OPTION_ReportMissingJavadocComments, this.reportInvalidJavadoc);
+ }
+ if (this.reportMissingJavadocTags != null) {
+ options.put(CompilerOptions.OPTION_ReportMissingJavadocTags, this.reportMissingJavadocTags);
+ options.put(CompilerOptions.OPTION_ReportMissingJavadocTagsOverriding, CompilerOptions.ENABLED);
+ } else {
+ options.put(CompilerOptions.OPTION_ReportMissingJavadocTags, this.reportInvalidJavadoc);
+ }
+ if (this.reportMissingJavadocDescription != null) {
+ options.put(CompilerOptions.OPTION_ReportMissingJavadocTagDescription, this.reportMissingJavadocDescription);
+ }
+ if (this.processAnnotations != null) {
+ options.put(CompilerOptions.OPTION_Process_Annotations, this.processAnnotations);
+ }
+ options.put(CompilerOptions.OPTION_ReportFieldHiding, CompilerOptions.IGNORE);
+ options.put(CompilerOptions.OPTION_ReportSyntheticAccessEmulation, CompilerOptions.IGNORE);
+ options.put(CompilerOptions.OPTION_ReportDeprecation, this.reportDeprecation);
+ options.put(CompilerOptions.OPTION_ReportUnusedImport, CompilerOptions.ERROR);
+ options.put(CompilerOptions.OPTION_ReportRawTypeReference, CompilerOptions.IGNORE);
+ options.put(CompilerOptions.OPTION_ReportUnusedPrivateMember, CompilerOptions.IGNORE);
+ return options;
+}
+/* (non-Javadoc)
+ * @see junit.framework.TestCase#setUp()
+ */
+@Override
+protected void setUp() throws Exception {
+ super.setUp();
+ this.docCommentSupport = CompilerOptions.ENABLED;
+ this.reportInvalidJavadoc = CompilerOptions.ERROR;
+ this.reportInvalidJavadocVisibility = CompilerOptions.PRIVATE;
+ this.reportMissingJavadocTags = CompilerOptions.IGNORE;
+ this.reportMissingJavadocComments = CompilerOptions.IGNORE;
+ this.reportMissingJavadocCommentsVisibility = CompilerOptions.PUBLIC;
+ this.reportDeprecation = CompilerOptions.ERROR;
+}
+
+public void test001() {
+ File outputDirectory = new File(OUTPUT_DIR);
+ Util.flushDirectoryContent(outputDirectory);
+
+ String moduleInfo = "" +
+ "/**\n" +
+ " */\n" +
+ "module mod.one { \n" +
+ " exports p;\n" +
+ "}";
+ String I1 = "" +
+ "package p;\n" +
+ "/**\n" +
+ " * interface I1\n" +
+ " * @see mod.one/\n" +
+ " */\n" +
+ "interface I1 {\n" +
+ " /**\n" +
+ " * Method foo\n" +
+ " * @return int\n" +
+ " */\n" +
+ " public int foo();\n" +
+ "}";
+
+ String P1 = "" +
+ "package p;\n" +
+ "/**\n" +
+ " * class P1\n" +
+ " * @see mod.one/p.I1\n" +
+ " */\n" +
+ "public class P1 implements I1 {\n" +
+ " @Override\n" +
+ " public int foo() { return 0; }\n" +
+ "}";
+
+ this.runConformTest(new String[] {"p/I1.java", I1 ,"p/P1.java" , P1 } ,
+ new String[] {"module-info.java", moduleInfo }, "" );
+}
+
+public void test002() {
+ File outputDirectory = new File(OUTPUT_DIR);
+ Util.flushDirectoryContent(outputDirectory);
+
+ String moduleInfo = "" +
+ "/**\n" +
+ " */\n" +
+ "module mod.one { \n" +
+ " exports p;\n" +
+ "}";
+ String I1 = "" +
+ "package p;\n" +
+ "/**\n" +
+ " * interface I1\n" +
+ " * {@link mod.one/}\n" +
+ " */\n" +
+ "interface I1 {\n" +
+ " /**\n" +
+ " * Method foo\n" +
+ " * @return int\n" +
+ " */\n" +
+ " public int foo();\n" +
+ "}";
+
+ String P1 = "" +
+ "package p;\n" +
+ "/**\n" +
+ " * class P1\n" +
+ " * {@link mod.one/p.I1}\n" +
+ " */\n" +
+ "public class P1 implements I1 {\n" +
+ " @Override\n" +
+ " public int foo() { return 0; }\n" +
+ "}";
+
+ this.runConformTest(new String[] {"p/I1.java", I1 ,"p/P1.java" , P1 } ,
+ new String[] {"module-info.java", moduleInfo }, "" );
+}
+
+public void test003() {
+ File outputDirectory = new File(OUTPUT_DIR);
+ Util.flushDirectoryContent(outputDirectory);
+
+ String moduleInfo = "" +
+ "/**\n" +
+ " */\n" +
+ "module mod.one { \n" +
+ " exports p;\n" +
+ "}";
+ String I1 = "" +
+ "package p;\n" +
+ "/**\n" +
+ " * interface I1\n" +
+ " * {@linkplain mod.one/}\n" +
+ " */\n" +
+ "interface I1 {\n" +
+ " /**\n" +
+ " * Method foo\n" +
+ " * @return int\n" +
+ " */\n" +
+ " public int foo();\n" +
+ "}";
+
+ String P1 = "" +
+ "package p;\n" +
+ "/**\n" +
+ " * class P1\n" +
+ " * {@linkplain mod.one/p.I1}\n" +
+ " */\n" +
+ "public class P1 implements I1 {\n" +
+ " @Override\n" +
+ " public int foo() { return 0; }\n" +
+ "}";
+
+ this.runConformTest(new String[] {"p/I1.java", I1 ,"p/P1.java" , P1 } ,
+ new String[] {"module-info.java", moduleInfo }, "" );
+}
+
+}
+
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java index db369ea437..a1840683b0 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java @@ -204,6 +204,7 @@ public static Test suite() { ArrayList since_15 = new ArrayList(); since_15.add(SealedTypes15Tests.class); since_15.add(ClassFileReaderTest_15.class); + since_15.add(JavadocTest_15.class); // Build final test suite TestSuite all = new TestSuite(TestAll.class.getName()); all.addTest(new TestSuite(StandAloneASTParserTest.class)); diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java index 677ee71272..64921074c8 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java @@ -1225,6 +1225,8 @@ void setSourceStart(int sourceStart); int JavadocInvalidProvidesClassName = Javadoc + Internal + 1808; /** @since 3.20 */ int JavadocInvalidProvidesClass = Javadoc + Internal + 1809; + /** @since 3.23 */ + int JavadocInvalidModuleQualification = Javadoc + Internal + 1810; /** * Generics diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ASTVisitor.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ASTVisitor.java index abc6f8a15a..08a82852c1 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ASTVisitor.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ASTVisitor.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2019 IBM Corporation and others. + * Copyright (c) 2000, 2020 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ @@ -244,6 +248,12 @@ public abstract class ASTVisitor { public void endVisit(JavadocQualifiedTypeReference typeRef, ClassScope scope) { // do nothing by default } + public void endVisit(JavadocModuleReference moduleRef, BlockScope scope) { + // do nothing by default + } + public void endVisit(JavadocModuleReference moduleRef, ClassScope scope) { + // do nothing by default + } public void endVisit(JavadocReturnStatement statement, BlockScope scope) { // do nothing by default } @@ -740,6 +750,12 @@ public abstract class ASTVisitor { public boolean visit(JavadocQualifiedTypeReference typeRef, ClassScope scope) { return true; // do nothing by default, keep traversing } + public boolean visit(JavadocModuleReference moduleRef, BlockScope scope) { + return true; // do nothing by default, keep traversing + } + public boolean visit(JavadocModuleReference moduleRef, ClassScope scope) { + return true; // do nothing by default, keep traversing + } public boolean visit(JavadocReturnStatement statement, BlockScope scope) { return true; // do nothing by default, keep traversing } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java index ceb1307c0f..5fea8a60ff 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2019 IBM Corporation and others. + * Copyright (c) 2000, 2020 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation * Stephan Herrmann - Contribution for @@ -478,6 +482,22 @@ public class Javadoc extends ASTNode { verifyTypeReference(reference, reference, scope, source15, resolvedType, resolvedType.modifiers); } + if (!hasProblems && (reference instanceof JavadocModuleReference)) { + JavadocModuleReference ref= (JavadocModuleReference)reference; + ref.resolve(scope); + ModuleReference mRef = ref.getModuleReference(); + if (mRef != null) { + ModuleBinding mType = mRef.binding; + if (verifyModuleReference(reference, reference, scope, source15, mType, mType.modifiers)) { + TypeReference tRef= ref.getTypeReference(); + if ((tRef instanceof JavadocSingleTypeReference || tRef instanceof JavadocQualifiedTypeReference) && tRef.resolvedType instanceof ReferenceBinding) { + ReferenceBinding resolvedType = (ReferenceBinding) tRef.resolvedType; + verifyTypeReference(reference, reference, scope, source15, resolvedType, resolvedType.modifiers); + } + } + } + } + // Verify that message reference are not used for @value tags if (reference instanceof JavadocMessageSend) { JavadocMessageSend msgSend = (JavadocMessageSend) reference; @@ -1143,6 +1163,40 @@ public class Javadoc extends ASTNode { } } + private boolean verifyModuleReference(Expression reference, Expression typeReference, Scope scope, boolean source15, ModuleBinding moduleType, int modifiers) { + boolean bindingFound = false; + if (moduleType!= null && moduleType.isValidBinding()) { + int scopeModifiers = -1; + + ModuleBinding mBinding = scope.module(); + + if (mBinding == null) { + scope.problemReporter().javadocInvalidModuleQualification(typeReference.sourceStart, typeReference.sourceEnd, scopeModifiers); + return bindingFound; + } + + if (mBinding.equals(moduleType)) { + bindingFound = true; + } else { + ModuleBinding[] bindings = mBinding.getAllRequiredModules(); + for (ModuleBinding binding : bindings) { + if (moduleType.equals(binding)) { + bindingFound = true; + break; + } + } + } + + if (!bindingFound) { + if (!canBeSeen(scope.problemReporter().options.reportInvalidJavadocTagsVisibility, moduleType.modifiers)) { + scope.problemReporter().javadocHiddenReference(typeReference.sourceStart, typeReference.sourceEnd, scope, moduleType.modifiers); + return bindingFound; + } + } + } + return bindingFound; + } + @Override public void traverse(ASTVisitor visitor, BlockScope scope) { if (visitor.visit(this, scope)) { diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocModuleReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocModuleReference.java new file mode 100644 index 0000000000..4650b1f8ca --- /dev/null +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocModuleReference.java @@ -0,0 +1,115 @@ +/*******************************************************************************
+ * Copyright (c) 2020 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+import org.eclipse.jdt.internal.compiler.lookup.ModuleBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Scope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+
+public class JavadocModuleReference extends Expression implements IJavadocTypeReference {
+
+ public int tagSourceStart, tagSourceEnd;
+ public TypeReference typeReference;
+ public ModuleReference moduleReference;
+
+ public JavadocModuleReference(char[][] sources, long[] pos, int tagStart, int tagEnd) {
+ super();
+ this.moduleReference = new ModuleReference(sources, pos);
+ this.tagSourceStart = tagStart;
+ this.tagSourceEnd = tagEnd;
+ this.bits |= ASTNode.InsideJavadoc;
+ }
+
+ /* (non-Javadoc)
+ * Redefine to capture javadoc specific signatures
+ * @see org.eclipse.jdt.internal.compiler.ast.ASTNode#traverse(org.eclipse.jdt.internal.compiler.ASTVisitor, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+ */
+ @Override
+ public void traverse(ASTVisitor visitor, BlockScope scope) {
+ visitor.visit(this, scope);
+ visitor.endVisit(this, scope);
+ }
+
+ @Override
+ public int getTagSourceStart() {
+ return this.tagSourceStart;
+ }
+
+ @Override
+ public int getTagSourceEnd() {
+ return this.tagSourceEnd;
+ }
+
+ public TypeReference getTypeReference() {
+ return this.typeReference;
+ }
+
+ public void setTypeReference(TypeReference typeReference) {
+ this.typeReference = typeReference;
+ }
+
+ public ModuleReference getModuleReference() {
+ return this.moduleReference;
+ }
+
+ public void setModuleReference(ModuleReference moduleReference) {
+ this.moduleReference = moduleReference;
+ }
+
+ @Override
+ public StringBuffer printExpression(int indent, StringBuffer output) {
+ if (this.moduleReference != null) {
+ output.append(this.moduleReference.moduleName);
+ }
+ if (this.typeReference != null) {
+ output.append('/');
+ this.typeReference.printExpression(indent, output);
+ }
+ return output;
+ }
+
+ public ModuleBinding resolve(Scope scope) {
+ return this.moduleReference.resolve(scope);
+ }
+
+ public ModuleBinding resolveModule(BlockScope scope) {
+ return this.moduleReference.resolve(scope);
+ }
+
+ @Override
+ public TypeBinding resolveType(BlockScope blockScope) {
+ this.resolveModule(blockScope);
+ assert(this.moduleReference.binding != null);
+ if (this.typeReference != null) {
+ return this.typeReference.resolveType(blockScope);
+ }
+ return null;
+ }
+
+ @Override
+ public TypeBinding resolveType(ClassScope classScope) {
+ if (this.typeReference != null) {
+ return this.typeReference.resolveType(classScope, -1);
+ }
+ return null;
+ }
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java index 36934e1bea..dc9dded36d 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java @@ -6,12 +6,12 @@ * which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-2.0/ * + * SPDX-License-Identifier: EPL-2.0 + * * This is an implementation of an early-draft specification developed under the Java * Community Process (JCP) and is made available for testing and evaluation purposes * only. The code is not compatible with any specification of the JCP. * - * SPDX-License-Identifier: EPL-2.0 - * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ @@ -489,6 +489,7 @@ public abstract class AbstractCommentParser implements JavadocTagConstants { protected Object createReturnStatement() { return null; } protected abstract void createTag(); protected abstract Object createTypeReference(int primitiveToken); + protected abstract Object createModuleTypeReference(int primitiveToken, int moduleRefTokenCount); private int getIndexPosition() { if (this.index > this.lineEnd) { @@ -1070,6 +1071,11 @@ public abstract class AbstractCommentParser implements JavadocTagConstants { } } + private boolean isTokenModule(int token, int moduleRefTokenCount) { + return ((token == TerminalTokens.TokenNameDIVIDE) + && (moduleRefTokenCount > 0)); + } + /* * Parse a qualified name and built a type reference if the syntax is valid. */ @@ -1084,8 +1090,20 @@ public abstract class AbstractCommentParser implements JavadocTagConstants { // Scan tokens int primitiveToken = -1; int parserKind = this.kind & PARSER_KIND; + int prevToken = TerminalTokens.TokenNameNotAToken; + int curToken = TerminalTokens.TokenNameNotAToken; + int moduleRefTokenCount = 0; + boolean lookForModule = false; + boolean parsingJava15Plus = this.scanner != null ? this.scanner.sourceLevel >= ClassFileConstants.JDK15 : false; nextToken : for (int iToken = 0; ; iToken++) { + if (iToken == 0) { + lookForModule = false; + prevToken = TerminalTokens.TokenNameNotAToken; + } else { + prevToken = curToken; + } int token = readTokenSafely(); + curToken= token; switch (token) { case TerminalTokens.TokenNameIdentifier : if (((iToken & 1) != 0)) { // identifiers must be odd tokens @@ -1093,6 +1111,9 @@ public abstract class AbstractCommentParser implements JavadocTagConstants { } pushIdentifier(iToken == 0, false); consumeToken(); + if (parsingJava15Plus && getChar() == '/' ) { + lookForModule = true; + } break; case TerminalTokens.TokenNameRestrictedIdentifierYield: @@ -1164,6 +1185,18 @@ public abstract class AbstractCommentParser implements JavadocTagConstants { } // Fall through default case to verify that we do not leave on a dot //$FALL-THROUGH$ + case TerminalTokens.TokenNameDIVIDE: + if (parsingJava15Plus && lookForModule) { + if (((iToken & 1) == 0) && (moduleRefTokenCount > 0)) { // '/' must be even token + throw new InvalidInputException(); + } + moduleRefTokenCount = (iToken+1) / 2; + consumeToken(); + lookForModule = false; + break; + } // else fall through + // Note: Add other cases before this case. + //$FALL-THROUGH$ default : if (iToken == 0) { if (this.identifierPtr>=0) { @@ -1171,12 +1204,15 @@ public abstract class AbstractCommentParser implements JavadocTagConstants { } return null; } - if ((iToken & 1) == 0) { // cannot leave on a dot + if ((iToken & 1) == 0 && !isTokenModule(prevToken, moduleRefTokenCount)) { // cannot leave on a dot switch (parserKind) { case COMPLETION_PARSER: if (this.identifierPtr>=0) { this.lastIdentifierEndPosition = (int) this.identifierPositionStack[this.identifierPtr]; } + if (moduleRefTokenCount > 0) { + return syntaxRecoverModuleQualifiedName(primitiveToken, moduleRefTokenCount); + } return syntaxRecoverQualifiedName(primitiveToken); case DOM_PARSER: if (this.currentTokenType != -1) { @@ -1202,6 +1238,9 @@ public abstract class AbstractCommentParser implements JavadocTagConstants { if (this.identifierPtr>=0) { this.lastIdentifierEndPosition = (int) this.identifierPositionStack[this.identifierPtr]; } + if (moduleRefTokenCount > 0) { + return createModuleTypeReference(primitiveToken, moduleRefTokenCount); + } return createTypeReference(primitiveToken); } @@ -1553,6 +1592,32 @@ public abstract class AbstractCommentParser implements JavadocTagConstants { } /* + * get current character. + * Warning: scanner position is unchanged using this method! + */ + private char getChar() { + int indexVal = this.index; + char c = this.source[indexVal++]; + if (c == '\\' && this.source[indexVal] == 'u') { + int c1, c2, c3, c4; + int pos = indexVal; + indexVal++; + while (this.source[indexVal] == 'u') + indexVal++; + if (!(((c1 = ScannerHelper.getHexadecimalValue(this.source[indexVal++])) > 15 || c1 < 0) + || ((c2 = ScannerHelper.getHexadecimalValue(this.source[indexVal++])) > 15 || c2 < 0) + || ((c3 = ScannerHelper.getHexadecimalValue(this.source[indexVal++])) > 15 || c3 < 0) + || ((c4 = ScannerHelper.getHexadecimalValue(this.source[indexVal++])) > 15 || c4 < 0))) { + c = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4); + } else { + // TODO (frederic) currently reset to previous position, perhaps signal a syntax error would be more appropriate + indexVal = pos; + } + } + return c; + } + + /* * Read token only if previous was consumed */ protected int readToken() throws InvalidInputException { @@ -1636,6 +1701,14 @@ public abstract class AbstractCommentParser implements JavadocTagConstants { return null; } + /* + * Entry point for recovery on invalid syntax + */ + protected Object syntaxRecoverModuleQualifiedName(int primitiveToken, int moduleTokenCount) throws InvalidInputException { + // do nothing, just an entry point for recovery + return null; + } + @Override public String toString() { StringBuffer buffer = new StringBuffer(); diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java index 388eb092c6..880b2e021e 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2019 IBM Corporation and others. + * Copyright (c) 2000, 2020 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ @@ -28,6 +32,7 @@ import org.eclipse.jdt.internal.compiler.ast.JavadocArraySingleTypeReference; import org.eclipse.jdt.internal.compiler.ast.JavadocFieldReference; import org.eclipse.jdt.internal.compiler.ast.JavadocImplicitTypeReference; import org.eclipse.jdt.internal.compiler.ast.JavadocMessageSend; +import org.eclipse.jdt.internal.compiler.ast.JavadocModuleReference; import org.eclipse.jdt.internal.compiler.ast.JavadocQualifiedTypeReference; import org.eclipse.jdt.internal.compiler.ast.JavadocReturnStatement; import org.eclipse.jdt.internal.compiler.ast.JavadocSingleNameReference; @@ -347,6 +352,43 @@ public class JavadocParser extends AbstractCommentParser { return typeRef; } + protected JavadocModuleReference createModuleReference(int moduleRefTokenCount) { + JavadocModuleReference moduleRef = null; + char[][] tokens = new char[moduleRefTokenCount][]; + System.arraycopy(this.identifierStack, 0, tokens, 0, moduleRefTokenCount); + long[] positions = new long[moduleRefTokenCount]; + System.arraycopy(this.identifierPositionStack, 0, positions, 0, moduleRefTokenCount); + moduleRef = new JavadocModuleReference(tokens, positions, this.tagSourceStart, this.tagSourceEnd); + return moduleRef; + } + + @Override + protected Object createModuleTypeReference(int primitiveToken, int moduleRefTokenCount) { + JavadocModuleReference moduleRef= createModuleReference(moduleRefTokenCount); + + TypeReference typeRef = null; + int size = this.identifierLengthStack[this.identifierLengthPtr]; + int newSize= size-moduleRefTokenCount; + if (newSize == 1) { // Single Type ref + typeRef = new JavadocSingleTypeReference( + this.identifierStack[this.identifierPtr], + this.identifierPositionStack[this.identifierPtr], + this.tagSourceStart, + this.tagSourceEnd); + } else if (newSize > 1) { // Qualified Type ref + char[][] tokens = new char[newSize][]; + System.arraycopy(this.identifierStack, this.identifierPtr - newSize + 1, tokens, 0, newSize); + long[] positions = new long[newSize]; + System.arraycopy(this.identifierPositionStack, this.identifierPtr - newSize + 1, positions, 0, newSize); + typeRef = new JavadocQualifiedTypeReference(tokens, positions, this.tagSourceStart, this.tagSourceEnd); + } else { + this.lastIdentifierEndPosition++; + } + + moduleRef.setTypeReference(typeRef); + return moduleRef; + } + /* * Get current parsed type declaration. */ diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java index b472255352..179a2e895d 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java @@ -614,6 +614,7 @@ public static int getIrritant(int problemID) { case IProblem.JavadocHiddenReference: case IProblem.JavadocMissingTagDescription: case IProblem.JavadocInvalidSeeUrlReference: + case IProblem.JavadocInvalidModuleQualification: return CompilerOptions.InvalidJavadoc; case IProblem.JavadocMissingParamTag: @@ -5549,6 +5550,11 @@ public void javadocInvalidMemberTypeQualification(int sourceStart, int sourceEnd this.handle(IProblem.JavadocInvalidMemberTypeQualification, NoArgument, NoArgument, sourceStart, sourceEnd); } } +public void javadocInvalidModuleQualification(int sourceStart, int sourceEnd, int modifiers){ + if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) { + this.handle(IProblem.JavadocInvalidModuleQualification, NoArgument, NoArgument, sourceStart, sourceEnd); + } +} /* * Similar implementation than invalidMethod(MessageSend...) * Note that following problem id cannot occur for Javadoc: diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties index d0a0e3da7c..35324f715c 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties @@ -1077,6 +1077,7 @@ 1807 = Missing provides class name 1808 = Invalid provides class name 1809 = Invalid provides class +1810 = Invalid module qualification # Java 15 Preview - cont @@ -1097,8 +1098,6 @@ 1864 = A local class {1} cannot have a sealed direct superclass or a sealed direct superinterface {0} 1865 = An anonymous class cannot subclass a sealed type {0} -# Java 15 Preview - end - ### ELABORATIONS ## Access restrictions 78592 = The type ''{1}'' is not API (restriction on classpath entry ''{0}'') diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DocCommentParser.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DocCommentParser.java index b559ead1de..1f73e1c662 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DocCommentParser.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DocCommentParser.java @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ @@ -328,6 +332,11 @@ class DocCommentParser extends AbstractCommentParser { } @Override + protected Object createModuleTypeReference(int primitiveToken, int moduleRefTokenCount) { + return createTypeReference(primitiveToken); + } + + @Override protected boolean parseIdentifierTag(boolean report) { if (super.parseIdentifierTag(report)) { createTag(); |