Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal')
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java24
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IJavadocTypeReference.java27
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java163
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocQualifiedTypeReference.java16
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocSingleTypeReference.java14
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java12
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java113
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java3
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java109
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties12
10 files changed, 472 insertions, 21 deletions
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java
index 3e17e1538f..aacb0bb7c3 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java
@@ -13,7 +13,8 @@
* Stephan Herrmann - Contribution for bug 295551
* Jesper S Moller - Contributions for
* Bug 405066 - [1.8][compiler][codegen] Implement code generation infrastructure for JSR335
- * Frits Jalvingh - contributions for bug 533830.
+ * Frits Jalvingh - contributions for bug 533830.
+ * Red Hat Inc. - add module-info Javadoc support
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.ast;
@@ -22,6 +23,7 @@ import java.util.Comparator;
import org.eclipse.jdt.core.compiler.CategorizedProblem;
import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.internal.compiler.ASTVisitor;
import org.eclipse.jdt.internal.compiler.ClassFile;
import org.eclipse.jdt.internal.compiler.CompilationResult;
@@ -345,7 +347,7 @@ public void finalizeProblems() {
String key = CompilerOptions.optionKeyFromIrritant(id);
this.scope.problemReporter().problemNotAnalysed(inits[iToken], key);
} else {
- this.scope.problemReporter().unusedWarningToken(inits[iToken]);
+ this.scope.problemReporter().unusedWarningToken(inits[iToken]);
}
}
}
@@ -557,7 +559,7 @@ private boolean isLambdaExpressionCopyContext(ReferenceContext context) {
if (context instanceof LambdaExpression && context != ((LambdaExpression) context).original())
return true; // Do not record from copies. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=441929
Scope cScope = context instanceof AbstractMethodDeclaration ? ((AbstractMethodDeclaration) context).scope :
- context instanceof TypeDeclaration ? ((TypeDeclaration) context).scope :
+ context instanceof TypeDeclaration ? ((TypeDeclaration) context).scope :
context instanceof LambdaExpression ? ((LambdaExpression) context).scope :
null;
return cScope != null ? isLambdaExpressionCopyContext(cScope.parent.referenceContext()) : false;
@@ -565,7 +567,7 @@ private boolean isLambdaExpressionCopyContext(ReferenceContext context) {
public void recordSuppressWarnings(IrritantSet irritants, Annotation annotation, int scopeStart, int scopeEnd, ReferenceContext context) {
if (isLambdaExpressionCopyContext(context))
return; // Do not record from copies. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=441929
-
+
if (this.suppressWarningIrritants == null) {
this.suppressWarningIrritants = new IrritantSet[3];
this.suppressWarningAnnotations = new Annotation[3];
@@ -603,7 +605,7 @@ public void record(LocalTypeBinding localType) {
}
/*
- * Keep track of all lambda/method reference expressions, so as to be able to look it up later without
+ * Keep track of all lambda/method reference expressions, so as to be able to look it up later without
* having to traverse AST. Return the "ordinal" returned by the enclosing type.
*/
public int record(FunctionalExpression expression) {
@@ -619,6 +621,7 @@ public int record(FunctionalExpression expression) {
public void resolve() {
int startingTypeIndex = 0;
boolean isPackageInfo = isPackageInfo();
+ boolean isModuleInfo = isModuleInfo();
if (this.types != null && isPackageInfo) {
// resolve synthetic type declaration
final TypeDeclaration syntheticTypeDeclaration = this.types[0];
@@ -637,6 +640,17 @@ public void resolve() {
this.javadoc.resolve(syntheticTypeDeclaration.staticInitializerScope);
}
startingTypeIndex = 1;
+ } else if (this.moduleDeclaration != null && isModuleInfo) {
+ if (this.javadoc != null) {
+ this.javadoc.resolve((MethodScope)this.moduleDeclaration.scope);
+ } else if (this.moduleDeclaration.binding != null) {
+ ProblemReporter reporter = this.scope.problemReporter();
+ int severity = reporter.computeSeverity(IProblem.JavadocMissing);
+ if (severity != ProblemSeverities.Ignore) {
+ reporter.javadocModuleMissing(this.moduleDeclaration.declarationSourceStart, this.moduleDeclaration.bodyStart,
+ severity);
+ }
+ }
} else {
// resolve compilation unit javadoc package if any
if (this.javadoc != null) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IJavadocTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IJavadocTypeReference.java
new file mode 100644
index 0000000000..c21cdaec28
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IJavadocTypeReference.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2019 Red Hat Inc. 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
+ *
+ * Contributors:
+ * Red Hat Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+/**
+ * Interface to allow Javadoc parser to collect both JavaSingleTypeReference and JavaQualifiedTypeReferences
+ *
+ * @author jjohnstn
+ *
+ */
+public interface IJavadocTypeReference {
+
+ public int getTagSourceStart();
+ public int getTagSourceEnd();
+
+}
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 308c39c3be..087d33fc8f 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, 2018 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -33,6 +33,8 @@ public class Javadoc extends ASTNode {
public TypeReference[] exceptionReferences; // @throws, @exception
public JavadocReturnStatement returnStatement; // @return
public Expression[] seeReferences; // @see
+ public IJavadocTypeReference[] usesReferences; // @uses
+ public IJavadocTypeReference[] providesReferences; // @provides
public long[] inheritedPositions = null;
// bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=51600
// Store param references for tag with invalid syntax
@@ -262,8 +264,8 @@ public class Javadoc extends ASTNode {
return;
}
// Do nothing - This is to mimic the SDK's javadoc tool behavior, which neither
- // sanity checks nor generates documentation using comments at the CU scope
- // (unless the unit happens to be package-info.java - in which case we don't come here.)
+ // sanity checks nor generates documentation using comments at the CU scope
+ // (unless the unit happens to be package-info.java - in which case we don't come here.)
}
/*
@@ -318,7 +320,7 @@ public class Javadoc extends ASTNode {
MethodBinding current = methDecl.binding;
// work 'against' better inference in 1.8 (otherwise comparing (G<T> with G<Object>) would fail):
if (methScope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_8
- && current.typeVariables != Binding.NO_TYPE_VARIABLES)
+ && current.typeVariables != Binding.NO_TYPE_VARIABLES)
{
current = current.asRawMethod(methScope.environment());
}
@@ -326,7 +328,7 @@ public class Javadoc extends ASTNode {
superRef = true;
}
}
- }
+ }
}
}
}
@@ -385,6 +387,11 @@ public class Javadoc extends ASTNode {
for (int i = 0; i < length; i++) {
this.invalidParameters[i].resolve(methScope, false, false);
}
+
+ if (methScope.isModuleScope()) {
+ resolveUsesTags(methScope, reportMissing);
+ resolveProvidesTags(methScope, reportMissing);
+ }
}
private void resolveReference(Expression reference, Scope scope) {
@@ -561,6 +568,148 @@ public class Javadoc extends ASTNode {
}
/*
+ * Resolve @uses tags while block scope
+ */
+ private void resolveUsesTags(BlockScope scope, boolean reportMissing) {
+ ModuleDeclaration moduleDecl = (ModuleDeclaration)scope.referenceContext();
+ int usesTagsSize = this.usesReferences == null ? 0 : this.usesReferences.length;
+
+ // If no referenced module then report a problem for each uses tag
+ if (moduleDecl == null) {
+ for (int i = 0; i < usesTagsSize; i++) {
+ IJavadocTypeReference uses = this.usesReferences[i];
+ scope.problemReporter().javadocUnexpectedTag(uses.getTagSourceStart(), uses.getTagSourceEnd());
+ }
+ return;
+ }
+
+ // If no uses tags then report a problem for each uses reference
+ int usesSize = moduleDecl.usesCount;
+ if (usesTagsSize == 0) {
+ if (reportMissing) {
+ for (int i = 0; i < usesSize; i++) {
+ UsesStatement uses = moduleDecl.uses[i];
+ scope.problemReporter().javadocMissingUsesTag(uses.serviceInterface, uses.sourceStart, uses.sourceEnd, moduleDecl.binding.modifiers);
+ }
+ }
+ } else {
+ TypeBinding[] bindings = new TypeBinding[usesTagsSize];
+ int maxBindings = 0;
+
+ // Scan all @uses tags
+ for (int i = 0; i < usesTagsSize; i++) {
+ TypeReference usesRef = (TypeReference)this.usesReferences[i];
+ try {
+ usesRef.resolve(scope);
+ if (usesRef.resolvedType != null && usesRef.resolvedType.isValidBinding()) {
+ // Verify duplicated tags
+ boolean found = false;
+ for (int j = 0; j < maxBindings && !found; j++) {
+ if (bindings[j].equals(usesRef.resolvedType)) {
+ scope.problemReporter().javadocDuplicatedUsesTag(usesRef.sourceStart, usesRef.sourceEnd);
+ found = true;
+ }
+ }
+ if (!found) {
+ bindings[maxBindings++] = usesRef.resolvedType;
+ }
+ }
+ } catch (Exception e) {
+ scope.problemReporter().javadocInvalidUsesClass(usesRef.sourceStart, usesRef.sourceEnd);
+ }
+ }
+
+ // Look for undocumented uses
+ if (reportMissing) {
+ for (int i = 0; i < usesSize; i++) {
+ UsesStatement uses = moduleDecl.uses[i];
+ boolean found = false;
+ for (int j = 0; j < maxBindings && !found; j++) {
+ TypeBinding binding = bindings[j];
+ if (uses.serviceInterface.getTypeBinding(scope).equals(binding)) {
+ found = true;
+ }
+ }
+ if (!found) {
+ scope.problemReporter().javadocMissingUsesTag(uses.serviceInterface, uses.sourceStart, uses.sourceEnd, moduleDecl.binding.modifiers);
+ }
+ }
+ }
+ }
+ }
+
+ /*
+ * Resolve @provides tags while block scope
+ */
+ private void resolveProvidesTags(BlockScope scope, boolean reportMissing) {
+ ModuleDeclaration moduleDecl = (ModuleDeclaration)scope.referenceContext();
+ int providesTagsSize = this.providesReferences == null ? 0 : this.providesReferences.length;
+
+ // If no referenced module then report a problem for each uses tag
+ if (moduleDecl == null) {
+ for (int i = 0; i < providesTagsSize; i++) {
+ IJavadocTypeReference provides = this.providesReferences[i];
+ scope.problemReporter().javadocUnexpectedTag(provides.getTagSourceStart(), provides.getTagSourceEnd());
+ }
+ return;
+ }
+
+ // If no uses tags then report a problem for each uses reference
+ int providesSize = moduleDecl.servicesCount;
+ if (providesTagsSize == 0) {
+ if (reportMissing) {
+ for (int i = 0; i < providesSize; i++) {
+ ProvidesStatement provides = moduleDecl.services[i];
+ scope.problemReporter().javadocMissingProvidesTag(provides.serviceInterface, provides.sourceStart, provides.sourceEnd, moduleDecl.binding.modifiers);
+ }
+ }
+ } else {
+ TypeBinding[] bindings = new TypeBinding[providesTagsSize];
+ int maxBindings = 0;
+
+ // Scan all @provides tags
+ for (int i = 0; i < providesTagsSize; i++) {
+ TypeReference providesRef = (TypeReference)this.providesReferences[i];
+ try {
+ providesRef.resolve(scope);
+ if (providesRef.resolvedType != null && providesRef.resolvedType.isValidBinding()) {
+ // Verify duplicated tags
+ boolean found = false;
+ for (int j = 0; j < maxBindings && !found; j++) {
+ if (bindings[j].equals(providesRef.resolvedType)) {
+ scope.problemReporter().javadocDuplicatedProvidesTag(providesRef.sourceStart, providesRef.sourceEnd);
+ found = true;
+ }
+ }
+ if (!found) {
+ bindings[maxBindings++] = providesRef.resolvedType;
+ }
+ }
+ } catch (Exception e) {
+ scope.problemReporter().javadocInvalidProvidesClass(providesRef.sourceStart, providesRef.sourceEnd);
+ }
+ }
+
+ // Look for undocumented uses
+ if (reportMissing) {
+ for (int i = 0; i < providesSize; i++) {
+ ProvidesStatement provides = moduleDecl.services[i];
+ boolean found = false;
+ for (int j = 0; j < maxBindings && !found; j++) {
+ TypeBinding binding = bindings[j];
+ if (provides.serviceInterface.getTypeBinding(scope).equals(binding)) {
+ found = true;
+ }
+ }
+ if (!found) {
+ scope.problemReporter().javadocMissingProvidesTag(provides.serviceInterface, provides.sourceStart, provides.sourceEnd, moduleDecl.binding.modifiers);
+ }
+ }
+ }
+ }
+ }
+
+ /*
* Resolve @param tags for type parameters
*/
private void resolveTypeParameterTags(Scope scope, boolean reportMissing) {
@@ -604,7 +753,7 @@ public class Javadoc extends ASTNode {
// If no param tags then report a problem for each declaration type parameter
if (parameters != null) {
- // https://bugs.eclipse.org/bugs/show_bug.cgi?id=324850, avoid secondary errors when <= 1.4
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=324850, avoid secondary errors when <= 1.4
reportMissing = reportMissing && scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5;
int typeParametersLength = parameters.length;
if (paramTypeParamLength == 0) {
@@ -830,7 +979,7 @@ public class Javadoc extends ASTNode {
mainLoop: for (int i=0; i<length; i++) {
char[][] compoundName = imports[i].compoundName;
int compoundNameLength = compoundName.length;
- if ((imports[i].onDemand && compoundNameLength == computedCompoundName.length-1)
+ if ((imports[i].onDemand && compoundNameLength == computedCompoundName.length-1)
|| (compoundNameLength == computedCompoundName.length)) {
for (int j = compoundNameLength; --j >= 0;) {
if (CharOperation.equals(imports[i].compoundName[j], computedCompoundName[j])) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocQualifiedTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocQualifiedTypeReference.java
index 3ed38f0990..ef06cca0e4 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocQualifiedTypeReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocQualifiedTypeReference.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2014 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -25,7 +25,7 @@ import org.eclipse.jdt.internal.compiler.lookup.Scope;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
-public class JavadocQualifiedTypeReference extends QualifiedTypeReference {
+public class JavadocQualifiedTypeReference extends QualifiedTypeReference implements IJavadocTypeReference {
public int tagSourceStart, tagSourceEnd;
public PackageBinding packageBinding;
@@ -72,7 +72,7 @@ public class JavadocQualifiedTypeReference extends QualifiedTypeReference {
protected void reportDeprecatedType(TypeBinding type, Scope scope) {
scope.problemReporter().javadocDeprecatedType(type, this, scope.getDeclarationModifiers());
}
-
+
@Override
protected void reportDeprecatedType(TypeBinding type, Scope scope, int index) {
scope.problemReporter().javadocDeprecatedType(type, this, scope.getDeclarationModifiers(), index);
@@ -107,4 +107,14 @@ public class JavadocQualifiedTypeReference extends QualifiedTypeReference {
visitor.visit(this, scope);
visitor.endVisit(this, scope);
}
+
+ @Override
+ public int getTagSourceStart() {
+ return this.tagSourceStart;
+ }
+
+ @Override
+ public int getTagSourceEnd() {
+ return this.tagSourceEnd;
+ }
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocSingleTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocSingleTypeReference.java
index b64689b105..8a9ed4072d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocSingleTypeReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocSingleTypeReference.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2018 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -29,7 +29,7 @@ import org.eclipse.jdt.internal.compiler.lookup.Scope;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
-public class JavadocSingleTypeReference extends SingleTypeReference {
+public class JavadocSingleTypeReference extends SingleTypeReference implements IJavadocTypeReference {
public int tagSourceStart, tagSourceEnd;
public PackageBinding packageBinding;
@@ -129,4 +129,14 @@ public class JavadocSingleTypeReference extends SingleTypeReference {
visitor.visit(this, scope);
visitor.endVisit(this, scope);
}
+
+ @Override
+ public int getTagSourceStart() {
+ return this.tagSourceStart;
+ }
+
+ @Override
+ public int getTagSourceEnd() {
+ return this.tagSourceEnd;
+ }
}
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 4f7a7b95b6..9b90a4f978 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
@@ -18,6 +18,7 @@ import java.util.List;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.core.compiler.InvalidInputException;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.util.Util;
@@ -102,6 +103,14 @@ public abstract class AbstractCommentParser implements JavadocTagConstants {
protected int astLengthPtr;
protected int[] astLengthStack;
+ // Uses stack
+ protected int usesReferencesPtr = -1;
+ protected TypeReference[] usesReferencesStack;
+
+ // Provides stack
+ protected int providesReferencesPtr = -1;
+ protected TypeReference[] providesReferencesStack;
+
protected AbstractCommentParser(Parser sourceParser) {
this.sourceParser = sourceParser;
@@ -456,6 +465,7 @@ public abstract class AbstractCommentParser implements JavadocTagConstants {
}
updateDocComment();
} catch (Exception ex) {
+ ex.printStackTrace();
validComment = false;
}
return validComment;
@@ -501,7 +511,7 @@ public abstract class AbstractCommentParser implements JavadocTagConstants {
return Util.getLineNumber(position, this.lineEnds, 0, this.lineEnds.length-1);
}
- private int getTokenEndPosition() {
+ protected int getTokenEndPosition() {
if (this.scanner.getCurrentTokenEndPosition() > this.lineEnd) {
return this.lineEnd;
} else {
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 8663caba08..0fe67daee5 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
@@ -17,7 +17,23 @@ import java.util.List;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.core.compiler.InvalidInputException;
-import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.Expression;
+import org.eclipse.jdt.internal.compiler.ast.IJavadocTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.Javadoc;
+import org.eclipse.jdt.internal.compiler.ast.JavadocAllocationExpression;
+import org.eclipse.jdt.internal.compiler.ast.JavadocArgumentExpression;
+import org.eclipse.jdt.internal.compiler.ast.JavadocArrayQualifiedTypeReference;
+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.JavadocQualifiedTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.JavadocReturnStatement;
+import org.eclipse.jdt.internal.compiler.ast.JavadocSingleNameReference;
+import org.eclipse.jdt.internal.compiler.ast.JavadocSingleTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.util.Util;
@@ -27,6 +43,7 @@ import org.eclipse.jdt.internal.compiler.util.Util;
public class JavadocParser extends AbstractCommentParser {
private static final JavadocSingleNameReference[] NO_SINGLE_NAME_REFERENCE = new JavadocSingleNameReference[0];
private static final JavadocSingleTypeReference[] NO_SINGLE_TYPE_REFERENCE = new JavadocSingleTypeReference[0];
+ private static final JavadocQualifiedTypeReference[] NO_QUALIFIED_TYPE_REFERENCE = new JavadocQualifiedTypeReference[0];
private static final TypeReference[] NO_TYPE_REFERENCE = new TypeReference[0];
private static final Expression[] NO_EXPRESSION = new Expression[0];
@@ -629,7 +646,9 @@ public class JavadocParser extends AbstractCommentParser {
}
} else if (length == TAG_PROVIDES_LENGTH && CharOperation.equals(TAG_PROVIDES, tagName, 0, length)) {
this.tagValue = TAG_PROVIDES_VALUE;
- this.tagWaitingForDescription = this.tagValue;
+ if (!this.inlineTagStarted) {
+ valid = parseProvidesReference();
+ }
}
break;
case 'r':
@@ -677,7 +696,9 @@ public class JavadocParser extends AbstractCommentParser {
case 'u':
if (length == TAG_USES_LENGTH && CharOperation.equals(TAG_USES, tagName, 0, length)) {
this.tagValue = TAG_USES_VALUE;
- this.tagWaitingForDescription = this.tagValue;
+ if (!this.inlineTagStarted) {
+ valid = parseUsesReference();
+ }
}
break;
case 'v':
@@ -951,6 +972,18 @@ public class JavadocParser extends AbstractCommentParser {
System.arraycopy(this.invalidParamReferencesStack, 0, this.docComment.invalidParameters, 0, this.invalidParamReferencesPtr+1);
}
+ this.docComment.usesReferences = this.usesReferencesPtr >= 0 ? new IJavadocTypeReference[this.usesReferencesPtr+1] : NO_QUALIFIED_TYPE_REFERENCE;
+ for (int i = 0; i <= this.usesReferencesPtr; ++i) {
+ TypeReference ref = this.usesReferencesStack[i];
+ this.docComment.usesReferences[i] = (IJavadocTypeReference)ref;
+ }
+
+ this.docComment.providesReferences = this.providesReferencesPtr >= 0 ? new IJavadocTypeReference[this.providesReferencesPtr+1] : NO_QUALIFIED_TYPE_REFERENCE;
+ for (int i = 0; i <= this.providesReferencesPtr; ++i) {
+ TypeReference ref = this.providesReferencesStack[i];
+ this.docComment.providesReferences[i] = (IJavadocTypeReference)ref;
+ }
+
// If no nodes stored return
if (this.astLengthPtr == -1) {
return;
@@ -1013,4 +1046,78 @@ public class JavadocParser extends AbstractCommentParser {
System.arraycopy(this.docComment.paramTypeParameters, paramTypeParamPtr, this.docComment.paramTypeParameters = new JavadocSingleTypeReference[size - paramTypeParamPtr], 0, size - paramTypeParamPtr);
}
}
+
+ /*
+ * Parse @uses tag declaration
+ */
+ protected boolean parseUsesReference() {
+ int start = this.scanner.currentPosition;
+ try {
+ Object typeRef = parseQualifiedName(true);
+ if (this.abort) return false; // May be aborted by specialized parser
+ if (typeRef == null) {
+ if (this.reportProblems)
+ this.sourceParser.problemReporter().javadocMissingUsesClassName(this.tagSourceStart, this.tagSourceEnd, this.sourceParser.modifiers);
+ } else {
+ return pushUsesReference(typeRef);
+ }
+ } catch (InvalidInputException ex) {
+ if (this.reportProblems) this.sourceParser.problemReporter().javadocInvalidUsesClass(start, getTokenEndPosition());
+ }
+ return false;
+ }
+
+ protected boolean pushUsesReference(Object typeRef) {
+ // TODO Auto-generated method stub
+ if (this.usesReferencesPtr == -1l) {
+ this.usesReferencesStack = new TypeReference[10];
+ }
+ int stackLength = this.usesReferencesStack.length;
+ if (++this.usesReferencesPtr >= stackLength) {
+ System.arraycopy(
+ this.usesReferencesStack, 0,
+ this.usesReferencesStack = new TypeReference[stackLength + AST_STACK_INCREMENT], 0,
+ stackLength);
+ }
+ this.usesReferencesStack[this.usesReferencesPtr] = (TypeReference)typeRef;
+ return true;
+ }
+
+ /*
+ * Parse @uses tag declaration
+ */
+ protected boolean parseProvidesReference() {
+ int start = this.scanner.currentPosition;
+ try {
+ Object typeRef = parseQualifiedName(true);
+ if (this.abort) return false; // May be aborted by specialized parser
+ if (typeRef == null) {
+ if (this.reportProblems)
+ this.sourceParser.problemReporter().javadocMissingProvidesClassName(this.tagSourceStart, this.tagSourceEnd, this.sourceParser.modifiers);
+ } else {
+ return pushProvidesReference(typeRef);
+ }
+ } catch (InvalidInputException ex) {
+ if (this.reportProblems) this.sourceParser.problemReporter().javadocInvalidProvidesClass(start, getTokenEndPosition());
+ }
+ return false;
+ }
+
+ protected boolean pushProvidesReference(Object typeRef) {
+ // TODO Auto-generated method stub
+ if (this.providesReferencesPtr == -1l) {
+ this.providesReferencesStack = new TypeReference[10];
+ }
+ int stackLength = this.providesReferencesStack.length;
+ if (++this.providesReferencesPtr >= stackLength) {
+ System.arraycopy(
+ this.providesReferencesStack, 0,
+ this.providesReferencesStack = new TypeReference[stackLength + AST_STACK_INCREMENT], 0,
+ stackLength);
+ }
+ this.providesReferencesStack[this.providesReferencesPtr] = (TypeReference)typeRef;
+ return true;
+
+ }
+
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
index db0af41079..71f2eadf6a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
@@ -5935,6 +5935,9 @@ protected void consumeModuleHeader() {
}
protected void consumeModuleDeclaration() {
// ModuleDeclaration ::= ModuleHeader ModuleBody
+ this.compilationUnit.javadoc = this.javadoc;
+ this.javadoc = null;
+
int length = this.astLengthStack[this.astLengthPtr--];
int[] flag = new int[length + 1]; //plus one -- see <HERE>
int size1 = 0, size2 = 0, size3 = 0, size4 = 0, size5 = 0;
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 c227f5b093..d0bb1be1ef 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
@@ -546,6 +546,14 @@ public static int getIrritant(int problemID) {
case IProblem.JavadocInvalidThrowsClassName:
case IProblem.JavadocDuplicateThrowsClassName:
case IProblem.JavadocMissingThrowsClassName:
+ case IProblem.JavadocDuplicateProvidesTag:
+ case IProblem.JavadocDuplicateUsesTag:
+ case IProblem.JavadocInvalidUsesClass:
+ case IProblem.JavadocInvalidUsesClassName:
+ case IProblem.JavadocInvalidProvidesClass:
+ case IProblem.JavadocInvalidProvidesClassName:
+ case IProblem.JavadocMissingProvidesClassName:
+ case IProblem.JavadocMissingUsesClassName:
case IProblem.JavadocMissingSeeReference:
case IProblem.JavadocInvalidValueReference:
case IProblem.JavadocUndefinedField:
@@ -589,8 +597,10 @@ public static int getIrritant(int problemID) {
return CompilerOptions.InvalidJavadoc;
case IProblem.JavadocMissingParamTag:
+ case IProblem.JavadocMissingProvidesTag:
case IProblem.JavadocMissingReturnTag:
case IProblem.JavadocMissingThrowsTag:
+ case IProblem.JavadocMissingUsesTag:
return CompilerOptions.MissingJavadocTags;
case IProblem.JavadocMissing:
@@ -5219,6 +5229,9 @@ public void javadocDuplicatedParamTag(char[] token, int sourceStart, int sourceE
sourceEnd);
}
}
+public void javadocDuplicatedProvidesTag(int sourceStart, int sourceEnd){
+ this.handle(IProblem.JavadocDuplicateProvidesTag, NoArgument, NoArgument, sourceStart, sourceEnd);
+}
public void javadocDuplicatedReturnTag(int sourceStart, int sourceEnd){
this.handle(IProblem.JavadocDuplicateReturnTag, NoArgument, NoArgument, sourceStart, sourceEnd);
}
@@ -5245,6 +5258,11 @@ public void javadocDuplicatedThrowsClassName(TypeReference typeReference, int mo
typeReference.sourceEnd);
}
}
+public void javadocDuplicatedUsesTag(
+
+ int sourceStart, int sourceEnd){
+ this.handle(IProblem.JavadocDuplicateUsesTag, NoArgument, NoArgument, sourceStart, sourceEnd);
+}
public void javadocEmptyReturnTag(int sourceStart, int sourceEnd, int modifiers) {
int severity = computeSeverity(IProblem.JavadocEmptyReturnTag);
if (severity == ProblemSeverities.Ignore) return;
@@ -5692,6 +5710,24 @@ public void javadocInvalidParamTagName(int sourceStart, int sourceEnd) {
public void javadocInvalidParamTypeParameter(int sourceStart, int sourceEnd) {
this.handle(IProblem.JavadocInvalidParamTagTypeParameter, NoArgument, NoArgument, sourceStart, sourceEnd);
}
+public void javadocInvalidProvidesClass(int sourceStart, int sourceEnd) {
+ this.handle(IProblem.JavadocInvalidProvidesClass, NoArgument, NoArgument, sourceStart, sourceEnd);
+}
+
+public void javadocInvalidProvidesClassName(TypeReference typeReference, int modifiers) {
+ int severity = computeSeverity(IProblem.JavadocInvalidProvidesClassName);
+ if (severity == ProblemSeverities.Ignore) return;
+ if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) {
+ String[] arguments = new String[] {String.valueOf(typeReference.resolvedType.sourceName())};
+ this.handle(
+ IProblem.JavadocInvalidProvidesClassName,
+ arguments,
+ arguments,
+ severity,
+ typeReference.sourceStart,
+ typeReference.sourceEnd);
+ }
+}
public void javadocInvalidReference(int sourceStart, int sourceEnd) {
this.handle(IProblem.JavadocInvalidSeeReference, NoArgument, NoArgument, sourceStart, sourceEnd);
}
@@ -5770,6 +5806,24 @@ public void javadocInvalidType(ASTNode location, TypeBinding type, int modifiers
location.sourceEnd);
}
}
+public void javadocInvalidUsesClass(int sourceStart, int sourceEnd) {
+ this.handle(IProblem.JavadocInvalidUsesClass, NoArgument, NoArgument, sourceStart, sourceEnd);
+}
+
+public void javadocInvalidUsesClassName(TypeReference typeReference, int modifiers) {
+ int severity = computeSeverity(IProblem.JavadocInvalidUsesClassName);
+ if (severity == ProblemSeverities.Ignore) return;
+ if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) {
+ String[] arguments = new String[] {String.valueOf(typeReference.resolvedType.sourceName())};
+ this.handle(
+ IProblem.JavadocInvalidUsesClassName,
+ arguments,
+ arguments,
+ severity,
+ typeReference.sourceStart,
+ typeReference.sourceEnd);
+ }
+}
public void javadocInvalidValueReference(int sourceStart, int sourceEnd, int modifiers) {
if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers))
this.handle(IProblem.JavadocInvalidValueReference, NoArgument, NoArgument, sourceStart, sourceEnd);
@@ -5800,6 +5854,20 @@ public void javadocMissing(int sourceStart, int sourceEnd, int severity, int mod
}
}
}
+public void javadocModuleMissing(int sourceStart, int sourceEnd, int severity){
+ if (severity == ProblemSeverities.Ignore) return;
+ boolean report = this.options.getSeverity(CompilerOptions.MissingJavadocComments) != ProblemSeverities.Ignore;
+ if (report) {
+ String[] arguments = new String[] { "module" }; //$NON-NLS-1$
+ this.handle(
+ IProblem.JavadocMissing,
+ arguments,
+ arguments,
+ severity,
+ sourceStart,
+ sourceEnd);
+ }
+}
public void javadocMissingHashCharacter(int sourceStart, int sourceEnd, String ref){
int severity = computeSeverity(IProblem.JavadocMissingHashCharacter);
if (severity == ProblemSeverities.Ignore) return;
@@ -5837,6 +5905,26 @@ public void javadocMissingParamTag(char[] name, int sourceStart, int sourceEnd,
sourceEnd);
}
}
+public void javadocMissingProvidesClassName(int sourceStart, int sourceEnd, int modifiers){
+ if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) {
+ this.handle(IProblem.JavadocMissingProvidesClassName, NoArgument, NoArgument, sourceStart, sourceEnd);
+ }
+}
+public void javadocMissingProvidesTag(TypeReference typeRef, int sourceStart, int sourceEnd, int modifiers){
+ int severity = computeSeverity(IProblem.JavadocMissingProvidesTag);
+ if (severity == ProblemSeverities.Ignore) return;
+ boolean report = this.options.getSeverity(CompilerOptions.MissingJavadocTags) != ProblemSeverities.Ignore;
+ if (report) {
+ String[] arguments = new String[] { String.valueOf(typeRef.resolvedType.sourceName()) };
+ this.handle(
+ IProblem.JavadocMissingProvidesTag,
+ arguments,
+ arguments,
+ severity,
+ sourceStart,
+ sourceEnd);
+ }
+}
public void javadocMissingReference(int sourceStart, int sourceEnd, int modifiers){
if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers))
this.handle(IProblem.JavadocMissingSeeReference, NoArgument, NoArgument, sourceStart, sourceEnd);
@@ -5887,6 +5975,27 @@ public void javadocMissingThrowsTag(TypeReference typeRef, int modifiers){
typeRef.sourceEnd);
}
}
+public void javadocMissingUsesClassName(int sourceStart, int sourceEnd, int modifiers){
+ if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) {
+ this.handle(IProblem.JavadocMissingUsesClassName, NoArgument, NoArgument, sourceStart, sourceEnd);
+ }
+}
+
+public void javadocMissingUsesTag(TypeReference typeRef, int sourceStart, int sourceEnd, int modifiers){
+ int severity = computeSeverity(IProblem.JavadocMissingUsesTag);
+ if (severity == ProblemSeverities.Ignore) return;
+ boolean report = this.options.getSeverity(CompilerOptions.MissingJavadocTags) != ProblemSeverities.Ignore;
+ if (report) {
+ String[] arguments = new String[] { String.valueOf(typeRef.resolvedType.sourceName()) };
+ this.handle(
+ IProblem.JavadocMissingUsesTag,
+ arguments,
+ arguments,
+ severity,
+ sourceStart,
+ sourceEnd);
+ }
+}
public void javadocUndeclaredParamTagName(char[] token, int sourceStart, int sourceEnd, int modifiers) {
int severity = computeSeverity(IProblem.JavadocInvalidParamName);
if (severity == ProblemSeverities.Ignore) return;
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 c859ddd4db..8c4171797b 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
@@ -1013,6 +1013,18 @@
1717 = yield may be a restricted identifier in future and may be disallowed as a type name
1718 = yield is a restricted identifier and cannot be used as type name
+# Additional doc
+1800 = Missing uses tag
+1801 = Duplicate uses tag
+1802 = Missing uses class name
+1803 = Invalid uses class name
+1804 = Invalid uses class
+1805 = Missing provides tag
+1806 = Duplicate provides tag
+1807 = Missing provides class name
+1808 = Invalid provides class name
+1809 = Invalid provides class
+
### ELABORATIONS
## Access restrictions
78592 = The type ''{1}'' is not API (restriction on classpath entry ''{0}'')

Back to the top