You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@netbeans.apache.org by db...@apache.org on 2022/05/06 08:10:42 UTC
[netbeans] branch master updated: LSP: Javadoc code completion added. (#4071)
This is an automated email from the ASF dual-hosted git repository.
dbalek pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/netbeans.git
The following commit(s) were added to refs/heads/master by this push:
new 5ddff5d755 LSP: Javadoc code completion added. (#4071)
5ddff5d755 is described below
commit 5ddff5d755ac922addb101cc5a9148fd6cb7d406
Author: Dusan Balek <du...@oracle.com>
AuthorDate: Fri May 6 10:10:36 2022 +0200
LSP: Javadoc code completion added. (#4071)
---
.../base/javadoc/JavadocCompletionUtils.java | 54 +-
.../editor/java/JavaCompletionCollector.java | 343 +++--
.../editor/javadoc/JavadocCompletionCollector.java | 294 +++++
.../java/editor/javadoc/JavadocCompletionItem.java | 178 +--
.../editor/javadoc/JavadocCompletionQuery.java | 1345 +-------------------
...letionQuery.java => JavadocCompletionTask.java} | 938 ++++++--------
.../modules/java/editor/javadoc/TagRegistery.java | 8 +
.../editor/javadoc/JavadocCompletionQueryTest.java | 239 +++-
.../nbcode/nbproject/platform.properties | 2 -
.../modules/java/lsp/server/protocol/Server.java | 2 +-
java/javadoc/nbproject/project.xml | 9 +
.../javadoc/hints/GenerateJavadocCollector.java | 123 ++
12 files changed, 1409 insertions(+), 2126 deletions(-)
diff --git a/java/java.editor.base/src/org/netbeans/modules/java/editor/base/javadoc/JavadocCompletionUtils.java b/java/java.editor.base/src/org/netbeans/modules/java/editor/base/javadoc/JavadocCompletionUtils.java
index 68cd055b19..a0682653d7 100644
--- a/java/java.editor.base/src/org/netbeans/modules/java/editor/base/javadoc/JavadocCompletionUtils.java
+++ b/java/java.editor.base/src/org/netbeans/modules/java/editor/base/javadoc/JavadocCompletionUtils.java
@@ -337,25 +337,63 @@ public final class JavadocCompletionUtils {
}
private static final Set<DocTree.Kind> BLOCK_TAGS =
- EnumSet.of(DocTree.Kind.AUTHOR, DocTree.Kind.DEPRECATED, DocTree.Kind.PARAM,
+ EnumSet.of(DocTree.Kind.AUTHOR, DocTree.Kind.DEPRECATED, DocTree.Kind.EXCEPTION,
+ DocTree.Kind.HIDDEN,DocTree.Kind.PARAM, DocTree.Kind.PROVIDES,
DocTree.Kind.RETURN, DocTree.Kind.SEE, DocTree.Kind.SERIAL,
- DocTree.Kind.SERIAL_DATA, DocTree.Kind.SERIAL_FIELD, DocTree.Kind.SINCE,
- DocTree.Kind.THROWS, DocTree.Kind.UNKNOWN_BLOCK_TAG, DocTree.Kind.VERSION);
+ DocTree.Kind.SERIAL_DATA, DocTree.Kind.SERIAL_FIELD,
+ DocTree.Kind.SINCE, DocTree.Kind.THROWS, DocTree.Kind.USES, DocTree.Kind.VERSION,
+ DocTree.Kind.UNKNOWN_BLOCK_TAG);
public static boolean isBlockTag(DocTreePath tag) {
return BLOCK_TAGS.contains(normalizedKind(tag.getLeaf()));
}
+ private static final Set<DocTree.Kind> INLINE_TAGS =
+ EnumSet.of(DocTree.Kind.CODE, DocTree.Kind.DOC_ROOT, DocTree.Kind.INDEX,
+ DocTree.Kind.INHERIT_DOC, DocTree.Kind.LINK, DocTree.Kind.LINK_PLAIN,
+ DocTree.Kind.LITERAL, DocTree.Kind.SNIPPET, DocTree.Kind.SUMMARY,
+ DocTree.Kind.SYSTEM_PROPERTY, DocTree.Kind.VALUE, DocTree.Kind.UNKNOWN_INLINE_TAG);
+ public static boolean isInlineTag(DocTreePath tag) {
+ return INLINE_TAGS.contains(normalizedKind(tag.getLeaf()));
+ }
+
public static DocTree.Kind normalizedKind(DocTree tag) {
DocTree.Kind normalizedKind = tag.getKind();
if (normalizedKind == com.sun.source.doctree.DocTree.Kind.ERRONEOUS) {
- String errorBody = ((ErroneousTree) tag).getBody();
- switch (errorBody.split("\\s")[0]) {
- case "@throws": normalizedKind = DocTree.Kind.THROWS; break;
- case "@see": normalizedKind = DocTree.Kind.SEE; break;
+ String txt = ((ErroneousTree) tag).getBody().split("\\s")[0];
+ switch (txt) {
+ case "@author": normalizedKind = DocTree.Kind.AUTHOR; break;
+ case "@deprecated": normalizedKind = DocTree.Kind.DEPRECATED; break;
+ case "@exception": normalizedKind = DocTree.Kind.EXCEPTION; break;
+ case "@hidden": normalizedKind = DocTree.Kind.HIDDEN; break;
case "@param": normalizedKind = DocTree.Kind.PARAM; break;
- case "{@value": normalizedKind = DocTree.Kind.VALUE; break;
+ case "@provides": normalizedKind = DocTree.Kind.PROVIDES; break;
+ case "@return": normalizedKind = DocTree.Kind.RETURN; break;
+ case "@see": normalizedKind = DocTree.Kind.SEE; break;
+ case "@serial": normalizedKind = DocTree.Kind.SERIAL; break;
+ case "@serialData": normalizedKind = DocTree.Kind.SERIAL_DATA; break;
+ case "@serialField": normalizedKind = DocTree.Kind.SERIAL_FIELD; break;
+ case "@since": normalizedKind = DocTree.Kind.SINCE; break;
+ case "@throws": normalizedKind = DocTree.Kind.THROWS; break;
+ case "@uses": normalizedKind = DocTree.Kind.USES; break;
+ case "@version": normalizedKind = DocTree.Kind.VERSION; break;
+ case "{@code": normalizedKind = DocTree.Kind.CODE; break;
+ case "{@docRoot": normalizedKind = DocTree.Kind.DOC_ROOT; break;
+ case "{@index": normalizedKind = DocTree.Kind.INDEX; break;
+ case "{@inheritDoc": normalizedKind = DocTree.Kind.INHERIT_DOC; break;
case "{@link": normalizedKind = DocTree.Kind.LINK; break;
case "{@linkplain": normalizedKind = DocTree.Kind.LINK; break;
+ case "{@literal": normalizedKind = DocTree.Kind.LITERAL; break;
+ case "{@snippet": normalizedKind = DocTree.Kind.SNIPPET; break;
+ case "{@summary": normalizedKind = DocTree.Kind.SUMMARY; break;
+ case "{@systemProperty": normalizedKind = DocTree.Kind.SYSTEM_PROPERTY; break;
+ case "{@value": normalizedKind = DocTree.Kind.VALUE; break;
+ default:
+ if (txt.startsWith("@")) {
+ normalizedKind = DocTree.Kind.UNKNOWN_BLOCK_TAG;
+ } else if (txt.startsWith("{@")) {
+ normalizedKind = DocTree.Kind.UNKNOWN_INLINE_TAG;
+ }
+ break;
}
}
return normalizedKind;
diff --git a/java/java.editor/src/org/netbeans/modules/editor/java/JavaCompletionCollector.java b/java/java.editor/src/org/netbeans/modules/editor/java/JavaCompletionCollector.java
index ca35d46d7f..0418229640 100644
--- a/java/java.editor/src/org/netbeans/modules/editor/java/JavaCompletionCollector.java
+++ b/java/java.editor/src/org/netbeans/modules/editor/java/JavaCompletionCollector.java
@@ -110,57 +110,179 @@ public class JavaCompletionCollector implements CompletionCollector {
@Override
public boolean collectCompletions(Document doc, int offset, Completion.Context context, Consumer<Completion> consumer) {
AtomicBoolean ret = new AtomicBoolean(true);
- try {
- ParserManager.parse(Collections.singletonList(Source.create(doc)), new UserTask() {
- @Override
- public void run(ResultIterator resultIterator) throws Exception {
- TokenSequence<JavaTokenId> ts = null;
- for (TokenSequence<?> cand : resultIterator.getSnapshot().getTokenHierarchy().embeddedTokenSequences(offset, false)) {
- if (cand.language() == JavaTokenId.language()) {
- ts = (TokenSequence<JavaTokenId>) cand;
- break;
- }
- }
- if (ts == null) {//No Java on this offset
- return ;
- }
- if (ts.move(offset) == 0 || !ts.moveNext()) {
- if (!ts.movePrevious()) {
- ts.moveNext();
+ if ((context == null || context.getTriggerKind() != Completion.TriggerKind.TriggerCharacter || context.getTriggerCharacter() == '.')
+ && Utilities.isJavaContext(doc, offset, true)) {
+ try {
+ ParserManager.parse(Collections.singletonList(Source.create(doc)), new UserTask() {
+ @Override
+ public void run(ResultIterator resultIterator) throws Exception {
+ TokenSequence<JavaTokenId> ts = SourceUtils.getJavaTokenSequence(resultIterator.getSnapshot().getTokenHierarchy(), offset);
+ if (ts.move(offset) == 0 || !ts.moveNext()) {
+ if (!ts.movePrevious()) {
+ ts.moveNext();
+ }
}
- }
- int len = offset - ts.offset();
- boolean combinedCompletion = context != null && context.getTriggerKind() == Completion.TriggerKind.TriggerForIncompleteCompletions
- || len > 0 && ts.token().length() >= len && ts.token().id() == JavaTokenId.IDENTIFIER;
- CompilationController controller = CompilationController.get(resultIterator.getParserResult(ts.offset()));
- controller.toPhase(JavaSource.Phase.RESOLVED);
- JavaCompletionTask<Completion> task = JavaCompletionTask.create(offset, new ItemFactoryImpl(controller, offset), combinedCompletion ? EnumSet.of(JavaCompletionTask.Options.COMBINED_COMPLETION) : EnumSet.noneOf(JavaCompletionTask.Options.class), () -> false);
- task.run(resultIterator);
- List<Completion> results = task.getResults();
- if (results != null) {
- for (Iterator<Completion> it = results.iterator(); it.hasNext();) {
- Completion item = it.next();
- if (item == null) {
- it.remove();
+ int len = offset - ts.offset();
+ boolean combinedCompletion = context != null && context.getTriggerKind() == Completion.TriggerKind.TriggerForIncompleteCompletions
+ || len > 0 && ts.token().length() >= len && ts.token().id() == JavaTokenId.IDENTIFIER;
+ CompilationController controller = CompilationController.get(resultIterator.getParserResult(ts.offset()));
+ controller.toPhase(JavaSource.Phase.RESOLVED);
+ JavaCompletionTask<Completion> task = JavaCompletionTask.create(offset, new ItemFactoryImpl(controller, offset), combinedCompletion ? EnumSet.of(JavaCompletionTask.Options.COMBINED_COMPLETION) : EnumSet.noneOf(JavaCompletionTask.Options.class), () -> false);
+ task.run(resultIterator);
+ List<Completion> results = task.getResults();
+ if (results != null) {
+ for (Iterator<Completion> it = results.iterator(); it.hasNext();) {
+ Completion item = it.next();
+ if (item == null) {
+ it.remove();
+ }
}
+ results.forEach(consumer);
+ }
+ if (task.hasAdditionalClasses() || task.hasAdditionalMembers()) {
+ ret.set(false);
}
- results.forEach(consumer);
- }
- if (task.hasAdditionalClasses() || task.hasAdditionalMembers()) {
- ret.set(false);
}
- }
- });
- } catch (ParseException ex) {
- Exceptions.printStackTrace(ex);
+ });
+ } catch (ParseException ex) {
+ Exceptions.printStackTrace(ex);
+ }
}
return ret.get();
}
+ public static final Set<String> SUPPORTED_ELEMENT_KINDS = new HashSet<>(Arrays.asList("PACKAGE", "CLASS", "INTERFACE", "ENUM", "ANNOTATION_TYPE", "METHOD", "CONSTRUCTOR", "INSTANCE_INIT", "STATIC_INIT", "FIELD", "ENUM_CONSTANT", "TYPE_PARAMETER", "MODULE"));
+
+ public static Supplier<String> getDocumentation(Document doc, int offset, ElementHandle handle) {
+ return () -> {
+ try {
+ JavaDocumentationTask<Future<String>> task = JavaDocumentationTask.create(offset, handle, new JavaDocumentationTask.DocumentationFactory<Future<String>>() {
+ @Override
+ public Future<String> create(CompilationInfo compilationInfo, Element element, Callable<Boolean> cancel) {
+ return ElementJavadoc.create(compilationInfo, element, cancel).getTextAsync();
+ }
+ }, () -> false);
+ ParserManager.parse(Collections.singletonList(Source.create(doc)), new UserTask() {
+ @Override
+ public void run(ResultIterator resultIterator) throws Exception {
+ task.run(resultIterator);
+ }
+ });
+ return task.getDocumentation().get();
+ } catch (Exception ex) {
+ throw new RuntimeException(ex);
+ }
+ };
+ }
+
+ public static Completion.Kind elementKind2CompletionItemKind(ElementKind kind) {
+ switch (kind) {
+ case PACKAGE:
+ return Completion.Kind.Folder;
+ case ENUM:
+ return Completion.Kind.Enum;
+ case CLASS:
+ return Completion.Kind.Class;
+ case ANNOTATION_TYPE:
+ return Completion.Kind.Interface;
+ case INTERFACE:
+ return Completion.Kind.Interface;
+ case ENUM_CONSTANT:
+ return Completion.Kind.EnumMember;
+ case FIELD:
+ return Completion.Kind.Field;
+ case PARAMETER:
+ return Completion.Kind.Variable;
+ case LOCAL_VARIABLE:
+ return Completion.Kind.Variable;
+ case EXCEPTION_PARAMETER:
+ return Completion.Kind.Variable;
+ case METHOD:
+ return Completion.Kind.Method;
+ case CONSTRUCTOR:
+ return Completion.Kind.Constructor;
+ case TYPE_PARAMETER:
+ return Completion.Kind.TypeParameter;
+ case RESOURCE_VARIABLE:
+ return Completion.Kind.Variable;
+ case MODULE:
+ return Completion.Kind.Module;
+ case STATIC_INIT:
+ case INSTANCE_INIT:
+ case OTHER:
+ default:
+ return Completion.Kind.Text;
+ }
+ }
+
+ public static Supplier<List<TextEdit>> addImport(Document doc, ElementHandle<?> handle) {
+ return () -> {
+ try {
+ TextEdit textEdit = modify2TextEdit(JavaSource.forDocument(doc), copy -> {
+ copy.toPhase(JavaSource.Phase.RESOLVED);
+ Element e = handle.resolve(copy);
+ if (e != null) {
+ copy.rewrite(copy.getCompilationUnit(), GeneratorUtilities.get(copy).addImports(copy.getCompilationUnit(), Collections.singleton(e)));
+ }
+ });
+ return textEdit != null ? Collections.singletonList(textEdit) : null;
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+ };
+ }
+
+ public static boolean isOfKind(Element e, EnumSet<ElementKind> kinds) {
+ if (kinds.contains(e.getKind())) {
+ return true;
+ }
+ for (Element ee : e.getEnclosedElements()) {
+ if (isOfKind(ee, kinds)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static boolean isInDefaultPackage(Element e) {
+ while (e != null && e.getKind() != ElementKind.PACKAGE) {
+ e = e.getEnclosingElement();
+ }
+ return e != null && e.getSimpleName().length() == 0;
+ }
+
+ private static TextEdit modify2TextEdit(JavaSource js, Task<WorkingCopy> task) throws IOException {
+ FileObject[] file = new FileObject[1];
+ ModificationResult changes = js.runModificationTask(wc -> {
+ task.run(wc);
+ file[0] = wc.getFileObject();
+ });
+ List<? extends ModificationResult.Difference> diffs = changes.getDifferences(file[0]);
+ if (diffs == null) {
+ return null;
+ }
+ int startOffset = -1;
+ int endOffset = -1;
+ StringBuilder sb = new StringBuilder();
+ for (ModificationResult.Difference diff : diffs) {
+ int start = diff.getStartPosition().getOffset();
+ int end = diff.getEndPosition().getOffset();
+ String newText = diff.getNewText();
+ if (startOffset < 0 && endOffset < 0) {
+ startOffset = start;
+ endOffset = end;
+ sb.append(newText);
+ } else if (start == endOffset) {
+ endOffset = end;
+ sb.append(newText);
+ }
+ }
+ return startOffset >= 0 && endOffset >= startOffset ? new TextEdit(startOffset, endOffset, sb.toString()) : null;
+ }
+
private static class ItemFactoryImpl implements JavaCompletionTask.TypeCastableItemFactory<Completion>,
JavaCompletionTask.LambdaItemFactory<Completion>, JavaCompletionTask.ModuleItemFactory<Completion> {
- private static final Set<String> SUPPORTED_ELEMENT_KINDS = new HashSet<>(Arrays.asList("PACKAGE", "CLASS", "INTERFACE", "ENUM", "ANNOTATION_TYPE", "METHOD", "CONSTRUCTOR", "INSTANCE_INIT", "STATIC_INIT", "FIELD", "ENUM_CONSTANT", "TYPE_PARAMETER", "MODULE"));
private static final String EMPTY = "";
private static final String ERROR = "<error>";
private static final int DEPRECATED = 10;
@@ -264,7 +386,7 @@ public class JavaCompletionCollector implements CompletionCollector {
.detail(label.insert(0, elem.getQualifiedName()).toString());
ElementHandle<TypeElement> handle = SUPPORTED_ELEMENT_KINDS.contains(elem.getKind().name()) ? ElementHandle.create(elem) : null;
if (handle != null) {
- builder.documentation(getDocumentation(doc, handle));
+ builder.documentation(getDocumentation(doc, offset, handle));
}
if (elements.isDeprecated(elem)) {
builder.addTag(Completion.Tag.Deprecated);
@@ -333,7 +455,7 @@ public class JavaCompletionCollector implements CompletionCollector {
}
ElementHandle<VariableElement> handle = SUPPORTED_ELEMENT_KINDS.contains(elem.getKind().name()) ? ElementHandle.create(elem) : null;
if (handle != null) {
- builder.documentation(getDocumentation(doc, handle));
+ builder.documentation(getDocumentation(doc, offset, handle));
}
if (isDeprecated) {
builder.addTag(Completion.Tag.Deprecated);
@@ -374,7 +496,7 @@ public class JavaCompletionCollector implements CompletionCollector {
.insertTextFormat(Completion.TextFormat.PlainText);
ElementHandle<ExecutableElement> handle = SUPPORTED_ELEMENT_KINDS.contains(elem.getKind().name()) ? ElementHandle.create(elem) : null;
if (handle != null) {
- builder.documentation(getDocumentation(doc, handle));
+ builder.documentation(getDocumentation(doc, offset, handle));
}
try {
TextEdit textEdit = modify2TextEdit(JavaSource.forFileObject(info.getFileObject()), wc -> {
@@ -519,7 +641,7 @@ public class JavaCompletionCollector implements CompletionCollector {
.sortText(String.format("%04d%s", isDeprecated ? 100 + DEPRECATED : 100, elem.getSimpleName().toString()));
ElementHandle<ExecutableElement> handle = SUPPORTED_ELEMENT_KINDS.contains(elem.getKind().name()) ? ElementHandle.create(elem) : null;
if (handle != null) {
- builder.documentation(getDocumentation(doc, handle));
+ builder.documentation(getDocumentation(doc, offset, handle));
}
if (isDeprecated) {
builder.addTag(Completion.Tag.Deprecated);
@@ -621,7 +743,7 @@ public class JavaCompletionCollector implements CompletionCollector {
}
ElementHandle<Element> handle = SUPPORTED_ELEMENT_KINDS.contains(memberElem.getKind().name()) ? ElementHandle.create(memberElem) : null;
if (handle != null) {
- builder.documentation(getDocumentation(doc, handle));
+ builder.documentation(getDocumentation(doc, offset, handle));
}
if (isDeprecated) {
builder.addTag(Completion.Tag.Deprecated);
@@ -885,7 +1007,7 @@ public class JavaCompletionCollector implements CompletionCollector {
.addCommitCharacter('.');
}
if (handle != null) {
- builder.documentation(getDocumentation(doc, handle));
+ builder.documentation(getDocumentation(doc, offset, handle));
if (!addSimpleName && !inImport) {
builder.additionalTextEdits(addImport(doc, handle));
}
@@ -1001,7 +1123,7 @@ public class JavaCompletionCollector implements CompletionCollector {
ElementHandle<ExecutableElement> handle = SUPPORTED_ELEMENT_KINDS.contains(elem.getKind().name()) ? ElementHandle.create(elem) : null;
if (handle != null) {
- builder.documentation(getDocumentation(doc, handle));
+ builder.documentation(getDocumentation(doc, offset, handle));
}
if (isDeprecated) {
builder.addTag(Completion.Tag.Deprecated);
@@ -1092,28 +1214,6 @@ public class JavaCompletionCollector implements CompletionCollector {
return locals;
}
- private Supplier<String> getDocumentation(Document doc, ElementHandle handle) {
- return () -> {
- try {
- JavaDocumentationTask<Future<String>> task = JavaDocumentationTask.create(offset, handle, new JavaDocumentationTask.DocumentationFactory<Future<String>>() {
- @Override
- public Future<String> create(CompilationInfo compilationInfo, Element element, Callable<Boolean> cancel) {
- return ElementJavadoc.create(compilationInfo, element, cancel).getTextAsync();
- }
- }, () -> false);
- ParserManager.parse(Collections.singletonList(Source.create(doc)), new UserTask() {
- @Override
- public void run(ResultIterator resultIterator) throws Exception {
- task.run(resultIterator);
- }
- });
- return task.getDocumentation().get();
- } catch (Exception ex) {
- throw new RuntimeException(ex);
- }
- };
- }
-
private static boolean isSameType(TypeMirror t1, TypeMirror t2, Types types) {
if (types.isSameType(t1, t2)) {
return true;
@@ -1124,25 +1224,6 @@ public class JavaCompletionCollector implements CompletionCollector {
return t2.getKind().isPrimitive() && types.isSameType(t1, types.boxedClass((PrimitiveType)t2).asType());
}
- private static boolean isOfKind(Element e, EnumSet<ElementKind> kinds) {
- if (kinds.contains(e.getKind())) {
- return true;
- }
- for (Element ee : e.getEnclosedElements()) {
- if (isOfKind(ee, kinds)) {
- return true;
- }
- }
- return false;
- }
-
- private static boolean isInDefaultPackage(Element e) {
- while (e != null && e.getKind() != ElementKind.PACKAGE) {
- e = e.getEnclosingElement();
- }
- return e != null && e.getSimpleName().length() == 0;
- }
-
private static boolean allowDiamond(CompilationInfo info, int offset, DeclaredType type) {
TreeUtilities tu = info.getTreeUtilities();
TreePath path = tu.pathFor(offset);
@@ -1174,23 +1255,6 @@ public class JavaCompletionCollector implements CompletionCollector {
return false;
}
- private static Supplier<List<TextEdit>> addImport(Document doc, ElementHandle<?> handle) {
- return () -> {
- try {
- TextEdit textEdit = modify2TextEdit(JavaSource.forDocument(doc), copy -> {
- copy.toPhase(JavaSource.Phase.RESOLVED);
- Element e = handle.resolve(copy);
- if (e != null) {
- copy.rewrite(copy.getCompilationUnit(), GeneratorUtilities.get(copy).addImports(copy.getCompilationUnit(), Collections.singleton(e)));
- }
- });
- return textEdit != null ? Collections.singletonList(textEdit) : null;
- } catch (IOException ex) {
- throw new RuntimeException(ex);
- }
- };
- }
-
private static int findCastEndPosition(TokenSequence<JavaTokenId> ts, int startPos, int endPos) {
TokenSequence<JavaTokenId> last = findLastNonWhitespaceToken(ts, startPos, endPos);
if (last != null && last.token().id() == JavaTokenId.DOT) {
@@ -1221,74 +1285,5 @@ public class JavaCompletionCollector implements CompletionCollector {
}
return null;
}
-
- private static Completion.Kind elementKind2CompletionItemKind(ElementKind kind) {
- switch (kind) {
- case PACKAGE:
- return Completion.Kind.Folder;
- case ENUM:
- return Completion.Kind.Enum;
- case CLASS:
- return Completion.Kind.Class;
- case ANNOTATION_TYPE:
- return Completion.Kind.Interface;
- case INTERFACE:
- return Completion.Kind.Interface;
- case ENUM_CONSTANT:
- return Completion.Kind.EnumMember;
- case FIELD:
- return Completion.Kind.Field;
- case PARAMETER:
- return Completion.Kind.Variable;
- case LOCAL_VARIABLE:
- return Completion.Kind.Variable;
- case EXCEPTION_PARAMETER:
- return Completion.Kind.Variable;
- case METHOD:
- return Completion.Kind.Method;
- case CONSTRUCTOR:
- return Completion.Kind.Constructor;
- case TYPE_PARAMETER:
- return Completion.Kind.TypeParameter;
- case RESOURCE_VARIABLE:
- return Completion.Kind.Variable;
- case MODULE:
- return Completion.Kind.Module;
- case STATIC_INIT:
- case INSTANCE_INIT:
- case OTHER:
- default:
- return Completion.Kind.Text;
- }
- }
-
- private static TextEdit modify2TextEdit(JavaSource js, Task<WorkingCopy> task) throws IOException {
- FileObject[] file = new FileObject[1];
- ModificationResult changes = js.runModificationTask(wc -> {
- task.run(wc);
- file[0] = wc.getFileObject();
- });
- List<? extends ModificationResult.Difference> diffs = changes.getDifferences(file[0]);
- if (diffs == null) {
- return null;
- }
- int startOffset = -1;
- int endOffset = -1;
- StringBuilder sb = new StringBuilder();
- for (ModificationResult.Difference diff : diffs) {
- int start = diff.getStartPosition().getOffset();
- int end = diff.getEndPosition().getOffset();
- String newText = diff.getNewText();
- if (startOffset < 0 && endOffset < 0) {
- startOffset = start;
- endOffset = end;
- sb.append(newText);
- } else if (start == endOffset) {
- endOffset = end;
- sb.append(newText);
- }
- }
- return startOffset >= 0 && endOffset >= startOffset ? new TextEdit(startOffset, endOffset, sb.toString()) : null;
- }
}
}
diff --git a/java/java.editor/src/org/netbeans/modules/java/editor/javadoc/JavadocCompletionCollector.java b/java/java.editor/src/org/netbeans/modules/java/editor/javadoc/JavadocCompletionCollector.java
new file mode 100644
index 0000000000..177e5c4a0b
--- /dev/null
+++ b/java/java.editor/src/org/netbeans/modules/java/editor/javadoc/JavadocCompletionCollector.java
@@ -0,0 +1,294 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.java.editor.javadoc;
+
+import com.sun.source.tree.Scope;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Consumer;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.ExecutableType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import javax.swing.text.Document;
+import org.netbeans.api.editor.mimelookup.MimeRegistration;
+import org.netbeans.api.java.source.CompilationController;
+import org.netbeans.api.java.source.CompilationInfo;
+import org.netbeans.api.java.source.ElementHandle;
+import org.netbeans.api.java.source.JavaSource;
+import org.netbeans.api.java.source.support.ReferencesCount;
+import org.netbeans.api.lsp.Completion;
+import org.netbeans.api.lsp.TextEdit;
+import org.netbeans.modules.editor.java.JavaCompletionCollector;
+import org.netbeans.modules.editor.java.Utilities;
+import org.netbeans.modules.java.editor.base.javadoc.JavadocCompletionUtils;
+import org.netbeans.modules.parsing.api.ParserManager;
+import org.netbeans.modules.parsing.api.ResultIterator;
+import org.netbeans.modules.parsing.api.Source;
+import org.netbeans.modules.parsing.api.UserTask;
+import org.netbeans.modules.parsing.spi.ParseException;
+import org.netbeans.spi.lsp.CompletionCollector;
+import org.openide.util.Exceptions;
+
+/**
+ *
+ * @author Dusan Balek
+ */
+@MimeRegistration(mimeType = "text/x-java", service = CompletionCollector.class)
+public class JavadocCompletionCollector implements CompletionCollector {
+
+ @Override
+ public boolean collectCompletions(Document doc, int offset, Completion.Context context, Consumer<Completion> consumer) {
+ AtomicBoolean ret = new AtomicBoolean(true);
+ if ((context == null || context.getTriggerKind() != Completion.TriggerKind.TriggerCharacter || context.getTriggerCharacter() == '#' || context.getTriggerCharacter() == '@')
+ && JavadocCompletionUtils.isJavadocContext(doc, offset)) {
+ try {
+ ParserManager.parse(Collections.singletonList(Source.create(doc)), new UserTask() {
+ @Override
+ public void run(ResultIterator resultIterator) throws Exception {
+ CompilationController controller = CompilationController.get(resultIterator.getParserResult(offset));
+ controller.toPhase(JavaSource.Phase.ELEMENTS_RESOLVED);
+ JavadocCompletionTask<Completion> task = JavadocCompletionTask.create(offset, new ItemFactoryImpl(controller, offset),
+ context != null && context.getTriggerKind() == Completion.TriggerKind.TriggerForIncompleteCompletions, () -> false);
+ task.run(resultIterator);
+ List<Completion> results = task.getResults();
+ if (results != null) {
+ for (Iterator<Completion> it = results.iterator(); it.hasNext();) {
+ Completion item = it.next();
+ if (item == null) {
+ it.remove();
+ }
+ }
+ results.forEach(consumer);
+ }
+ if (task.hasAdditionalItems()) {
+ ret.set(false);
+ }
+ }
+ });
+ } catch (ParseException ex) {
+ Exceptions.printStackTrace(ex);
+ }
+ }
+ return ret.get();
+ }
+
+ private static class ItemFactoryImpl implements JavadocCompletionTask.ItemFactory<Completion> {
+
+ private final CompilationInfo info;
+ private final Document doc;
+ private final int offset;
+ private final Scope scope;
+
+ public ItemFactoryImpl(CompilationInfo info, int offset) throws IOException {
+ this.info = info;
+ this.doc = info.getDocument();
+ this.offset = offset;
+ this.scope = getScope();
+ }
+
+ @Override
+ public Completion createTagItem(String name, int startOffset) {
+ Builder builder = CompletionCollector.newBuilder(name)
+ .kind(Completion.Kind.Keyword)
+ .sortText(String.format("%04d%s", 1500, name))
+ .insertTextFormat(Completion.TextFormat.PlainText);
+ if (startOffset < offset) {
+ builder.textEdit(new TextEdit(startOffset, offset, name + ' '));
+ } else {
+ builder.insertText(name + ' ');
+ }
+ return builder.build();
+ }
+
+ @Override
+ public Completion createNameItem(String name, int startOffset) {
+ return CompletionCollector.newBuilder(name)
+ .kind(name.charAt(0) == '<' ? Completion.Kind.TypeParameter : Completion.Kind.Variable)
+ .insertText(name + ' ')
+ .sortText(String.format("%04d%s", 1100, name))
+ .insertTextFormat(Completion.TextFormat.PlainText)
+ .build();
+ }
+
+ @Override
+ public Completion createJavadocExecutableItem(CompilationInfo info, ExecutableElement elem, ExecutableType type, int startOffset, boolean isInherited, boolean isDeprecated) {
+ String simpleName = (elem.getKind() == ElementKind.METHOD ? elem : elem.getEnclosingElement()).getSimpleName().toString();
+ Iterator<? extends VariableElement> it = elem.getParameters().iterator();
+ Iterator<? extends TypeMirror> tIt = type.getParameterTypes().iterator();
+ StringBuilder label = new StringBuilder();
+ StringBuilder insertText = new StringBuilder();
+ StringBuilder sortParams = new StringBuilder();
+ label.append(simpleName).append('(');
+ insertText.append(simpleName).append('(');
+ sortParams.append('(');
+ int cnt = 0;
+ while(it.hasNext() && tIt.hasNext()) {
+ TypeMirror tm = tIt.next();
+ if (tm == null) {
+ break;
+ }
+ cnt++;
+ String paramTypeName = Utilities.getTypeName(info, tm, false, elem.isVarArgs() && !tIt.hasNext()).toString();
+ String paramName = it.next().getSimpleName().toString();
+ label.append(paramTypeName).append(' ').append(paramName);
+ sortParams.append(paramTypeName);
+ insertText.append(paramTypeName);
+ if (tIt.hasNext()) {
+ label.append(", ");
+ sortParams.append(',');
+ insertText.append(", ");
+ }
+ }
+ sortParams.append(')');
+ label.append(')');
+ insertText.append(')');
+ TypeMirror retType = type.getReturnType();
+ if (elem.getKind() == ElementKind.METHOD) {
+ label.append(" : ").append(Utilities.getTypeName(info, retType, false).toString());
+ }
+ int priority = elem.getKind() == ElementKind.METHOD ? 1500 : 1650;
+ CompletionCollector.Builder builder = CompletionCollector.newBuilder(label.toString())
+ .kind(JavaCompletionCollector.elementKind2CompletionItemKind(elem.getKind()))
+ .insertTextFormat(Completion.TextFormat.PlainText)
+ .sortText(String.format("%04d%s#%02d%s", priority, simpleName, cnt, sortParams.toString()))
+ .insertText(insertText.toString());
+
+ ElementHandle<ExecutableElement> handle = JavaCompletionCollector.SUPPORTED_ELEMENT_KINDS.contains(elem.getKind().name()) ? ElementHandle.create(elem) : null;
+ if (handle != null) {
+ builder.documentation(JavaCompletionCollector.getDocumentation(doc, offset, handle));
+ }
+ if (isDeprecated) {
+ builder.addTag(Completion.Tag.Deprecated);
+ }
+ return builder.build();
+ }
+
+ @Override
+ public Completion createJavadocTypeItem(CompilationInfo info, TypeElement elem, int startOffset, boolean isDeprecated) {
+ ElementHandle<TypeElement> handle = JavaCompletionCollector.SUPPORTED_ELEMENT_KINDS.contains(elem.getKind().name()) ? ElementHandle.create(elem) : null;
+ return createTypeItem(handle, elem, (DeclaredType) elem.asType(), '#', null, isDeprecated, false);
+ }
+
+ @Override
+ public Completion createJavaTypeItem(CompilationInfo info, TypeElement elem, DeclaredType type, int startOffset, ReferencesCount referencesCount, boolean isDeprecated, boolean smartType) {
+ ElementHandle<TypeElement> handle = JavaCompletionCollector.SUPPORTED_ELEMENT_KINDS.contains(elem.getKind().name()) ? ElementHandle.create(elem) : null;
+ return createTypeItem(handle, elem, type, (char) -1, referencesCount, isDeprecated, false);
+ }
+
+ @Override
+ public Completion createLazyTypeItem(ElementHandle<TypeElement> handle, EnumSet<ElementKind> kinds, int startOffset, ReferencesCount referencesCount, Source source) {
+ TypeElement te = handle.resolve(info);
+ if (te != null && (scope == null || info.getTrees().isAccessible(scope, te)) && JavaCompletionCollector.isOfKind(te, kinds) && (!JavaCompletionCollector.isInDefaultPackage(te) || JavaCompletionCollector.isInDefaultPackage(scope.getEnclosingClass()))) {
+ return createTypeItem(handle, te, (DeclaredType) te.asType(), (char) -1, referencesCount, info.getElements().isDeprecated(te), false);
+ }
+ return null;
+ }
+
+ @Override
+ public Completion createJavaVariableItem(CompilationInfo info, VariableElement elem, TypeMirror type, int startOffset, boolean isInherited, boolean isDeprecated) {
+ int priority = elem.getKind() == ElementKind.ENUM_CONSTANT || elem.getKind() == ElementKind.FIELD ? 1300 : 1200;
+ StringBuilder label = new StringBuilder();
+ label.append(elem.getSimpleName());
+ if (type != null) {
+ label.append(" : ").append(Utilities.getTypeName(info, type, false));
+ }
+ CompletionCollector.Builder builder = CompletionCollector.newBuilder(label.toString())
+ .kind(JavaCompletionCollector.elementKind2CompletionItemKind(elem.getKind()))
+ .sortText(String.format("%04d%s", priority, elem.getSimpleName().toString()))
+ .insertTextFormat(Completion.TextFormat.PlainText)
+ .insertText(elem.getSimpleName().toString());
+ if (type != null && !type.getKind().isPrimitive()) {
+ builder.addCommitCharacter('.');
+ }
+ ElementHandle<VariableElement> handle = JavaCompletionCollector.SUPPORTED_ELEMENT_KINDS.contains(elem.getKind().name()) ? ElementHandle.create(elem) : null;
+ if (handle != null) {
+ builder.documentation(JavaCompletionCollector.getDocumentation(doc, offset, handle));
+ }
+ if (isDeprecated) {
+ builder.addTag(Completion.Tag.Deprecated);
+ }
+ return builder.build();
+ }
+
+ @Override
+ public Completion createPackageItem(String pkgFQN, int startOffset) {
+ final String simpleName = pkgFQN.substring(pkgFQN.lastIndexOf('.') + 1);
+ return CompletionCollector.newBuilder(simpleName)
+ .kind(Completion.Kind.Folder)
+ .sortText(String.format("%04d%s#%s", 1900, simpleName, pkgFQN))
+ .insertText(simpleName + '.')
+ .insertTextFormat(Completion.TextFormat.PlainText)
+ .build();
+ }
+
+ private Completion createTypeItem(ElementHandle<TypeElement> handle, TypeElement elem, DeclaredType type, char commitChar, ReferencesCount referencesCount, boolean isDeprecated, boolean smartType) {
+ String name = elem.getQualifiedName().toString();
+ int idx = name.lastIndexOf('.');
+ String pkgName = idx < 0 ? "" : name.substring(0, idx);
+ StringBuilder label = new StringBuilder();
+ StringBuilder insertText = new StringBuilder();
+ label.append(elem.getSimpleName());
+ if (pkgName.length() > 0) {
+ label.append(" (").append(pkgName).append(')');
+ }
+ if (referencesCount == null) {
+ insertText.append(elem.getSimpleName());
+ } else {
+ if ((type == null || type.getKind() != TypeKind.ERROR) &&
+ EnumSet.range(ElementKind.PACKAGE, ElementKind.INTERFACE).contains(elem.getEnclosingElement().getKind())) {
+ insertText.append(elem.getSimpleName());
+ } else {
+ insertText.append(elem.getQualifiedName());
+ }
+ }
+ CompletionCollector.Builder builder = CompletionCollector.newBuilder(label.toString())
+ .kind(JavaCompletionCollector.elementKind2CompletionItemKind(elem.getKind()))
+ .sortText(String.format("%04d%s#%02d#%s", smartType ? 800 : 1800, elem.getSimpleName().toString(), Utilities.getImportanceLevel(name), pkgName))
+ .insertText(insertText.toString())
+ .insertTextFormat(Completion.TextFormat.PlainText);
+ if (commitChar != -1) {
+ builder.addCommitCharacter('#');
+ }
+ if (handle != null) {
+ builder.documentation(JavaCompletionCollector.getDocumentation(doc, offset, handle));
+ builder.additionalTextEdits(JavaCompletionCollector.addImport(doc, handle));
+ }
+ if (isDeprecated) {
+ builder.addTag(Completion.Tag.Deprecated);
+ }
+ return builder.build();
+ }
+
+ private Scope getScope() {
+ try {
+ return info.getTrees().getScope(info.getTreeUtilities().pathFor(offset));
+ } catch (Exception e) {}
+ return null;
+ }
+ }
+}
diff --git a/java/java.editor/src/org/netbeans/modules/java/editor/javadoc/JavadocCompletionItem.java b/java/java.editor/src/org/netbeans/modules/java/editor/javadoc/JavadocCompletionItem.java
index 83bf3450c7..2215192787 100644
--- a/java/java.editor/src/org/netbeans/modules/java/editor/javadoc/JavadocCompletionItem.java
+++ b/java/java.editor/src/org/netbeans/modules/java/editor/javadoc/JavadocCompletionItem.java
@@ -23,7 +23,7 @@ import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
-import java.util.ArrayList;
+import java.util.EnumSet;
import java.util.List;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
@@ -43,10 +43,12 @@ import javax.swing.text.JTextComponent;
import javax.swing.text.StyledDocument;
import org.netbeans.api.editor.completion.Completion;
import org.netbeans.api.java.source.CompilationInfo;
+import org.netbeans.api.java.source.ElementHandle;
import org.netbeans.api.java.source.support.ReferencesCount;
import org.netbeans.modules.editor.java.JavaCompletionItem;
+import org.netbeans.modules.editor.java.LazyJavaCompletionItem;
import org.netbeans.modules.editor.java.Utilities;
-import org.netbeans.modules.java.editor.javadoc.TagRegistery.TagEntry;
+import org.netbeans.modules.parsing.api.Source;
import org.netbeans.spi.editor.completion.CompletionItem;
import org.netbeans.spi.editor.completion.CompletionTask;
import org.netbeans.spi.editor.completion.support.CompletionUtilities;
@@ -69,10 +71,10 @@ final class JavadocCompletionItem implements CompletionItem {
private static final String BOLD = "<b>"; //NOI18N
private static final String BOLD_END = "</b>"; //NOI18N
- private int substitutionOffset;
- private String txt;
- private String leftHtmlText;
- private String rightHtmlText;
+ private final int substitutionOffset;
+ private final String txt;
+ private final String leftHtmlText;
+ private final String rightHtmlText;
private final String iconPath;
private final int sortPriority;
private ImageIcon icon = null;
@@ -89,26 +91,27 @@ final class JavadocCompletionItem implements CompletionItem {
this.sortPriority = sortPriority;
}
+ @Override
public void defaultAction(JTextComponent component) {
Completion.get().hideAll();
complete(component, txt + ' ', substitutionOffset);
}
+ @Override
public void processKeyEvent(KeyEvent evt) {
}
+ @Override
public final int getPreferredWidth(Graphics g, Font defaultFont) {
- return CompletionUtilities.getPreferredWidth(
- getLeftHtmlText(), getRightHtmlText(), g, defaultFont);
+ return CompletionUtilities.getPreferredWidth(getLeftHtmlText(), getRightHtmlText(), g, defaultFont);
}
- public final void render(Graphics g, Font defaultFont, Color defaultColor,
- Color backgroundColor, int width, int height, boolean selected) {
+ @Override
+ public final void render(Graphics g, Font defaultFont, Color defaultColor, Color backgroundColor, int width, int height, boolean selected) {
if (icon == null) {
icon = createIcon();
}
- CompletionUtilities.renderHtml(icon, getLeftHtmlText(), getRightHtmlText(),
- g, defaultFont, defaultColor, width, height, selected);
+ CompletionUtilities.renderHtml(icon, getLeftHtmlText(), getRightHtmlText(), g, defaultFont, defaultColor, width, height, selected);
}
protected ImageIcon createIcon() {
@@ -116,36 +119,39 @@ final class JavadocCompletionItem implements CompletionItem {
}
protected String getLeftHtmlText() {
- if (leftHtmlText == null) {
- leftHtmlText = txt;
- }
- return leftHtmlText;
+ return leftHtmlText == null ? txt : leftHtmlText;
}
protected String getRightHtmlText() {
return rightHtmlText;
}
+ @Override
public CompletionTask createDocumentationTask() {
return null;
}
+ @Override
public CompletionTask createToolTipTask() {
return null;
}
+ @Override
public boolean instantSubstitution(JTextComponent component) {
return false;
}
+ @Override
public int getSortPriority() {
return sortPriority;
}
+ @Override
public CharSequence getSortText() {
return txt;
}
+ @Override
public CharSequence getInsertPrefix() {
return txt;
}
@@ -155,62 +161,6 @@ final class JavadocCompletionItem implements CompletionItem {
return super.toString() + String.format("[txt:%1$s, substitutionOffset:%2$d]",
txt, substitutionOffset);
}
-
- public static List<CompletionItem> addBlockTagItems(ElementKind kind,
- String prefix, int startOffset) {
-
- List<TagEntry> tags = TagRegistery.getDefault().getTags(kind, false);
- List<CompletionItem> items = new ArrayList<CompletionItem>(tags.size());
- for (TagEntry tagEntry : tags) {
- if (tagEntry.name.startsWith(prefix)) {
- items.add(new JavadocCompletionItem(tagEntry.name, startOffset,
- null, null, JAVADOC_TAG_ICON, 500));
- }
- }
- return items;
- }
-
- public static List<CompletionItem> addInlineTagItems(ElementKind kind,
- String prefix, int startOffset) {
-
- List<TagEntry> tags = TagRegistery.getDefault().getTags(kind, true);
- List<CompletionItem> items = new ArrayList<CompletionItem>(tags.size());
- for (TagEntry tagEntry : tags) {
- if (tagEntry.name.startsWith(prefix)) {
- items.add(new JavadocCompletionItem(tagEntry.name, startOffset,
- null, null, JAVADOC_TAG_ICON, 500));
- }
- }
- return items;
- }
-
- public static CompletionItem createNameItem(String name, int startOffset) {
- // escape type variable name
- String html = name.charAt(0) == '<'
- ? "<" + name.substring(1, name.length() - 1) + ">" // NOI18N
- : name;
- return new JavadocCompletionItem(name, startOffset,
- PARAMETER_COLOR + BOLD + html + BOLD_END + COLOR_END,
- null, JAVADOC_PARAM_ICON, 100);
- }
-
- public static CompletionItem createExecutableItem(CompilationInfo info, ExecutableElement e,
- ExecutableType et, int startOffset, boolean isInherited,
- boolean isDeprecated) {
-
- CompletionItem delegate = JavaCompletionItem.createExecutableItem(
- info, e, et, null, startOffset, null, isInherited, isDeprecated, false, false, false, -1, false, null);
- return new JavadocExecutableItem(delegate, e, startOffset);
- }
-
- public static CompletionItem createTypeItem(CompilationInfo info, TypeElement elem,
- int startOffset, ReferencesCount referencesCount, boolean isDeprecated) {
-
- CompletionItem delegate = JavaCompletionItem.createTypeItem(
- info, elem, (DeclaredType) elem.asType(), startOffset,
- referencesCount, isDeprecated, false, false, false, false, false, null);
- return new JavadocTypeItem(delegate, startOffset);
- }
private static void complete(final JTextComponent comp, final String what, final int where) {
try {
@@ -241,6 +191,59 @@ final class JavadocCompletionItem implements CompletionItem {
}
}
+ public static final class Factory implements JavadocCompletionTask.ItemFactory<CompletionItem> {
+
+ @Override
+ public CompletionItem createTagItem(String name, int startOffset) {
+ return new JavadocCompletionItem(name, startOffset, null, null, JAVADOC_TAG_ICON, 500);
+ }
+
+ @Override
+ public CompletionItem createNameItem(String name, int startOffset) {
+ // escape type variable name
+ String html = name.charAt(0) == '<'
+ ? "<" + name.substring(1, name.length() - 1) + ">" // NOI18N
+ : name;
+ return new JavadocCompletionItem(name, startOffset,
+ PARAMETER_COLOR + BOLD + html + BOLD_END + COLOR_END,
+ null, JAVADOC_PARAM_ICON, 100);
+ }
+
+ @Override
+ public CompletionItem createJavadocExecutableItem(CompilationInfo info, ExecutableElement e, ExecutableType et, int startOffset, boolean isInherited, boolean isDeprecated) {
+ CompletionItem delegate = JavaCompletionItem.createExecutableItem(
+ info, e, et, null, startOffset, null, isInherited, isDeprecated, false, false, false, -1, false, null);
+ return new JavadocExecutableItem(delegate, e, startOffset);
+ }
+
+ @Override
+ public CompletionItem createJavadocTypeItem(CompilationInfo info, TypeElement elem, int startOffset, boolean isDeprecated) {
+ CompletionItem delegate = JavaCompletionItem.createTypeItem(
+ info, elem, (DeclaredType) elem.asType(), startOffset, null, isDeprecated, false, false, false, false, false, null);
+ return new JavadocTypeItem(delegate, startOffset);
+ }
+
+ @Override
+ public CompletionItem createJavaTypeItem(CompilationInfo info, TypeElement elem, DeclaredType type, int startOffset, ReferencesCount referencesCount, boolean isDeprecated, boolean smartType) {
+ return JavaCompletionItem.createTypeItem(info, elem, type, startOffset, referencesCount, isDeprecated, false, false, false, smartType, false, null);
+ }
+
+ @Override
+ public CompletionItem createLazyTypeItem(ElementHandle<TypeElement> handle, EnumSet<ElementKind> kinds, int startOffset, ReferencesCount referencesCount, Source source) {
+ return LazyJavaCompletionItem.createTypeItem(handle, kinds, startOffset, referencesCount, source, false, false, false, null);
+ }
+
+ @Override
+ public CompletionItem createJavaVariableItem(CompilationInfo info, VariableElement elem, TypeMirror type, int startOffset, boolean isInherited, boolean isDeprecated) {
+ return JavaCompletionItem.createVariableItem(info, elem, type, null, startOffset, null, isInherited, isDeprecated, false, -1, null);
+ }
+
+ @Override
+ public CompletionItem createPackageItem(String pkgFQN, int startOffset) {
+ return JavaCompletionItem.createPackageItem(pkgFQN, startOffset, false);
+ }
+ }
+
/**
* Reuses UI of {@code JavaCompletionItem.createExecutableItem} and
* implements own text substitution.
@@ -298,6 +301,7 @@ final class JavadocCompletionItem implements CompletionItem {
return ptype;
}
+ @Override
public void defaultAction(JTextComponent component) {
if (component != null) {
Completion.get().hideDocumentation();
@@ -319,29 +323,32 @@ final class JavadocCompletionItem implements CompletionItem {
}
}
+ @Override
public void processKeyEvent(KeyEvent evt) {
// nothing special
}
+ @Override
public int getPreferredWidth(Graphics g, Font defaultFont) {
return delegate.getPreferredWidth(g, defaultFont);
}
- public void render(Graphics g, Font defaultFont, Color defaultColor,
- Color backgroundColor, int width, int height, boolean selected) {
-
- delegate.render(g, defaultFont, defaultColor, backgroundColor,
- width, height, selected);
+ @Override
+ public void render(Graphics g, Font defaultFont, Color defaultColor, Color backgroundColor, int width, int height, boolean selected) {
+ delegate.render(g, defaultFont, defaultColor, backgroundColor, width, height, selected);
}
+ @Override
public CompletionTask createDocumentationTask() {
return delegate.createDocumentationTask();
}
+ @Override
public CompletionTask createToolTipTask() {
return delegate.createToolTipTask();
}
+ @Override
public boolean instantSubstitution(JTextComponent component) {
if (component != null) {
try {
@@ -359,14 +366,17 @@ final class JavadocCompletionItem implements CompletionItem {
return true;
}
+ @Override
public int getSortPriority() {
return delegate.getSortPriority();
}
+ @Override
public CharSequence getSortText() {
return delegate.getSortText();
}
+ @Override
public CharSequence getInsertPrefix() {
return delegate.getInsertPrefix();
}
@@ -389,10 +399,12 @@ final class JavadocCompletionItem implements CompletionItem {
this.delegate = item;
}
+ @Override
public void defaultAction(JTextComponent component) {
delegate.defaultAction(component);
}
+ @Override
public void processKeyEvent(KeyEvent evt) {
if (evt.getID() == KeyEvent.KEY_TYPED) {
if (Utilities.getJavadocCompletionSelectors().indexOf(evt.getKeyChar()) >= 0) {
@@ -406,37 +418,43 @@ final class JavadocCompletionItem implements CompletionItem {
}
}
+ @Override
public int getPreferredWidth(Graphics g, Font defaultFont) {
return delegate.getPreferredWidth(g, defaultFont);
}
+ @Override
public void render(Graphics g, Font defaultFont, Color defaultColor,
Color backgroundColor, int width, int height, boolean selected) {
-
- delegate.render(g, defaultFont, defaultColor, backgroundColor,
- width, height, selected);
+ delegate.render(g, defaultFont, defaultColor, backgroundColor, width, height, selected);
}
+ @Override
public CompletionTask createDocumentationTask() {
return delegate.createDocumentationTask();
}
+ @Override
public CompletionTask createToolTipTask() {
return delegate.createToolTipTask();
}
+ @Override
public boolean instantSubstitution(JTextComponent component) {
return delegate.instantSubstitution(component);
}
+ @Override
public int getSortPriority() {
return delegate.getSortPriority();
}
+ @Override
public CharSequence getSortText() {
return delegate.getSortText();
}
+ @Override
public CharSequence getInsertPrefix() {
return delegate.getInsertPrefix();
}
diff --git a/java/java.editor/src/org/netbeans/modules/java/editor/javadoc/JavadocCompletionQuery.java b/java/java.editor/src/org/netbeans/modules/java/editor/javadoc/JavadocCompletionQuery.java
index ffc908ac16..c276c07366 100644
--- a/java/java.editor/src/org/netbeans/modules/java/editor/javadoc/JavadocCompletionQuery.java
+++ b/java/java.editor/src/org/netbeans/modules/java/editor/javadoc/JavadocCompletionQuery.java
@@ -19,73 +19,15 @@
package org.netbeans.modules.java.editor.javadoc;
-import com.sun.source.doctree.DocCommentTree;
-import com.sun.source.doctree.DocTree;
-import com.sun.source.doctree.DocTree.Kind;
-import com.sun.source.doctree.ErroneousTree;
-import com.sun.source.doctree.ParamTree;
-import com.sun.source.doctree.ReferenceTree;
-import com.sun.source.tree.ExpressionTree;
-import com.sun.source.tree.Scope;
-import com.sun.source.util.DocSourcePositions;
-import com.sun.source.util.DocTreeFactory;
-import com.sun.source.util.DocTreePath;
-import com.sun.source.util.DocTreePathScanner;
-import com.sun.source.util.DocTrees;
-import com.sun.source.util.SourcePositions;
-import com.sun.source.util.TreePath;
-import com.sun.source.util.Trees;
-import java.io.IOException;
-import java.lang.reflect.Field;
-import java.util.ArrayList;
import java.util.Collections;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
import java.util.List;
-import java.util.Set;
-import java.util.concurrent.ExecutionException;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ElementKind;
-import static javax.lang.model.element.ElementKind.*;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.Modifier;
-import javax.lang.model.element.PackageElement;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.element.TypeParameterElement;
-import javax.lang.model.element.VariableElement;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.ExecutableType;
-import javax.lang.model.type.TypeKind;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.type.TypeVariable;
-import javax.lang.model.util.Elements;
-import javax.lang.model.util.Types;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.JTextComponent;
import org.netbeans.api.editor.completion.Completion;
-import org.netbeans.api.java.lexer.JavadocTokenId;
-import org.netbeans.api.java.source.ClassIndex;
-import org.netbeans.api.java.source.ClasspathInfo;
-import org.netbeans.api.java.source.CompilationController;
-import org.netbeans.api.java.source.CompilationInfo;
-import org.netbeans.api.java.source.ElementHandle;
-import org.netbeans.api.java.source.ElementUtilities;
-import org.netbeans.api.java.source.JavaSource;
-import org.netbeans.api.java.source.Task;
-import org.netbeans.api.java.source.TreeUtilities;
-import org.netbeans.api.java.source.support.ReferencesCount;
-import org.netbeans.api.lexer.Token;
-import org.netbeans.api.lexer.TokenSequence;
-import org.netbeans.modules.editor.java.JavaCompletionItem;
-import org.netbeans.modules.editor.java.LazyJavaCompletionItem;
-import org.netbeans.modules.java.completion.Utilities;
-import org.netbeans.modules.java.editor.base.javadoc.JavadocCompletionUtils;
+import org.netbeans.modules.parsing.api.ParserManager;
+import org.netbeans.modules.parsing.api.Source;
+import org.netbeans.modules.parsing.spi.ParseException;
import org.netbeans.spi.editor.completion.CompletionItem;
import org.netbeans.spi.editor.completion.CompletionProvider;
import org.netbeans.spi.editor.completion.CompletionResultSet;
@@ -98,15 +40,11 @@ import org.openide.util.Exceptions;
*/
final class JavadocCompletionQuery extends AsyncCompletionQuery{
- private static final String CLASS_KEYWORD = "class"; //NOI18N
private final int queryType;
private int caretOffset;
private List<CompletionItem> items;
- private boolean hasAdditionalItems;
private JTextComponent component;
- private boolean ignoreCancel;
-
public JavadocCompletionQuery(int queryType) {
this.queryType = queryType;
@@ -120,10 +58,28 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
@Override
protected void query(CompletionResultSet resultSet, Document doc, int caretOffset) {
try {
- queryImpl(resultSet, doc, caretOffset);
- } catch (InterruptedException ex) {
- Exceptions.printStackTrace(ex);
- } catch (ExecutionException ex) {
+ this.caretOffset = caretOffset;
+ items = null;
+ Source source = Source.create(doc);
+ if (source != null) {
+ if ((queryType & CompletionProvider.COMPLETION_QUERY_TYPE) != 0) {
+ JavadocCompletionTask<CompletionItem> task = JavadocCompletionTask.create(caretOffset, new JavadocCompletionItem.Factory(),
+ queryType == CompletionProvider.COMPLETION_ALL_QUERY_TYPE, this::isTaskCancelled);
+ setCompletionHack(true);
+ ParserManager.parse(Collections.singletonList(source), task);
+ setCompletionHack(false);
+ items = task.getResults();
+ if (items != null) {
+ resultSet.addAllItems(items);
+ }
+ resultSet.setHasAdditionalItems(task.hasAdditionalItems());
+ int anchorOffset = task.getAnchorOffset();
+ if (anchorOffset > -1) {
+ resultSet.setAnchorOffset(anchorOffset);
+ }
+ }
+ }
+ } catch (ParseException ex) {
Exceptions.printStackTrace(ex);
} finally {
resultSet.finish();
@@ -155,41 +111,6 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
return true;
}
- static List<CompletionItem> runCompletionQuery(int queryType, Document doc, int caret) {
- JavadocCompletionQuery q = new JavadocCompletionQuery(queryType);
- JavadocContext jdctx = new JavadocContext();
-
- q.items = new ArrayList<CompletionItem>();
- q.caretOffset = caret;
- q.ignoreCancel = true;
-
- q.runInJavac(JavaSource.forDocument(doc), jdctx);
-
- return q.items;
- }
-
- private void queryImpl(CompletionResultSet resultSet, Document doc, int caretOffset) throws InterruptedException, ExecutionException {
- JavadocContext jdctx = new JavadocContext();
- items = new ArrayList<CompletionItem>();
- this.caretOffset = caretOffset;
- runInJavac(JavaSource.forDocument(doc), jdctx);
-
- if (!ignoreCancel && isTaskCancelled()) {
- return;
- }
-
- if ((queryType & CompletionProvider.COMPLETION_QUERY_TYPE) != 0) {
- if (!items.isEmpty()) {
- resultSet.addAllItems(items);
- }
- resultSet.setHasAdditionalItems(hasAdditionalItems);
- }
-
- if (jdctx.anchorOffset >= 0) {
- resultSet.setAnchorOffset(jdctx.anchorOffset);
- }
- }
-
/** #145615: this helps to work around the issue with stuck
* {@code JavaSource.runWhenScanFinished}
* It is copied from {@code JavaCompletionQuery}.
@@ -199,1215 +120,19 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
component.putClientProperty("completion-active", flag); //NOI18N
}
}
-
- private void runInJavac(JavaSource js, final JavadocContext jdctx) {
- try {
- if (js == null) {
- return;
- }
-
- js.runUserActionTask(new Task<CompilationController>() {
-
- public void run(CompilationController javac) throws Exception {
- if (!ignoreCancel && isTaskCancelled()) {
- return;
- }
- if (!JavadocCompletionUtils.isJavadocContext(javac.getTokenHierarchy(), caretOffset)) {
- return;
- }
- setCompletionHack(true);
- JavaSource.Phase toPhase = javac.toPhase(JavaSource.Phase.ELEMENTS_RESOLVED);
- if (toPhase != JavaSource.Phase.ELEMENTS_RESOLVED) {
- return;
- }
- try {
- jdctx.javac = javac;
- if (resolveContext(javac, jdctx)) {
- analyzeContext(jdctx);
- }
- } finally {
- jdctx.javac = null;
- if (component != null) {
- setCompletionHack(false);
- }
- }
- }
- }, true);
- } catch (IOException ex) {
- Exceptions.printStackTrace(ex);
- }
- }
-
- private boolean resolveContext(CompilationInfo javac, JavadocContext jdctx) throws IOException {
- jdctx.doc = javac.getDocument();
- // find class context: class, method, ...
- DocTrees trees = javac.getDocTrees();
- TreePath javadocFor = JavadocCompletionUtils.findJavadoc(javac, this.caretOffset);
- if (javadocFor == null) {
- return false;
- }
- jdctx.javadocFor = javadocFor;
- DocCommentTree docCommentTree = trees.getDocCommentTree(javadocFor);
- if (docCommentTree == null) {
- return false;
- }
- jdctx.comment = docCommentTree;
- Element elm = trees.getElement(javadocFor);
- if (elm == null) {
- return false;
- }
- jdctx.handle = ElementHandle.create(elm);
- jdctx.commentFor = elm;
- jdctx.jdts = JavadocCompletionUtils.findJavadocTokenSequence(javac, this.caretOffset);
- if (jdctx.jdts == null) {
- return false;
- }
- jdctx.positions = (DocSourcePositions) trees.getSourcePositions();
- return jdctx.positions != null;
- }
-
- private void analyzeContext(JavadocContext jdctx) {
- TokenSequence<JavadocTokenId> jdts = jdctx.jdts;
- if (jdts == null) {
- return;
- }
-
- jdts.move(this.caretOffset);
- if (!jdts.moveNext() && !jdts.movePrevious()) {
- // XXX solve /***/
- // provide block tags, inline tags, html
- return;
- }
-
- if (this.caretOffset - jdts.offset() == 0) {
- // if position in token == 0 resolve CC according to previous token
- jdts.movePrevious();
- }
-
- switch (jdts.token().id()) {
- case TAG:
- resolveTagToken(jdctx);
- break;
- case IDENT:
- resolveIdent(jdctx);
- break;
- case DOT:
- resolveDotToken(jdctx);
- break;
- case HASH:
- resolveHashToken(jdctx);
- break;
- case OTHER_TEXT:
- resolveOtherText(jdctx, jdts);
- break;
- case HTML_TAG:
- resolveHTMLToken(jdctx);
- break;
- }
- }
-
- void resolveTagToken(JavadocContext jdctx) {
- assert jdctx.jdts.token() != null;
- assert jdctx.jdts.token().id() == JavadocTokenId.TAG;
-
- DocTreePath tag = getTag(jdctx, caretOffset);
- if (tag == null) {
- // eg * description @
- return;
- }
- if (JavadocCompletionUtils.isBlockTag(tag)) {
- resolveBlockTag(tag, jdctx);
- } else {
- resolveInlineTag(tag, jdctx);
- }
- }
-
- void resolveBlockTag(DocTreePath tag, JavadocContext jdctx) {
- int pos;
- String prefix;
- if (tag != null) {
- pos = (int) jdctx.positions.getStartPosition(jdctx.javac.getCompilationUnit(), jdctx.comment, tag.getLeaf());
- prefix = JavadocCompletionUtils.getCharSequence(jdctx.doc, pos, caretOffset).toString();
- } else {
- prefix = ""; // NOI18N
- pos = caretOffset;
- }
-
- items.addAll(JavadocCompletionItem.addBlockTagItems(jdctx.handle.getKind(), prefix, pos));
- jdctx.anchorOffset = pos;
- }
-
- void resolveInlineTag(DocTreePath tag, JavadocContext jdctx) {
- int pos;
- String prefix;
- if (tag != null) {
- pos = (int) jdctx.positions.getStartPosition(jdctx.javac.getCompilationUnit(), jdctx.comment, tag.getLeaf()) + 1;
- prefix = JavadocCompletionUtils.getCharSequence(jdctx.doc, pos, caretOffset).toString();
- jdctx.anchorOffset = pos;
- } else {
- pos = caretOffset;
- prefix = ""; // NOI18N
- jdctx.anchorOffset = pos;
- }
- items.addAll(JavadocCompletionItem.addInlineTagItems(jdctx.handle.getKind(), prefix, pos));
- }
-
- private int skipWhitespacesBackwards(final JavadocContext jdctx, final int offset) {
- jdctx.jdts.move(offset);
-
- while (jdctx.jdts.movePrevious()) {
- Token t = jdctx.jdts.token();
-
- if (t.id() != JavadocTokenId.OTHER_TEXT) return jdctx.jdts.offset();
-
- CharSequence text = t.text();
-
- for (int i = 0; i < text.length(); i++) {
- if (!Character.isWhitespace(text.charAt(i))) {
- //XXX: does not handle the leading '*' correctly
- return jdctx.jdts.offset();
- }
- }
- }
-
- return jdctx.jdts.moveNext() ? jdctx.jdts.offset() : offset;
- }
-
- private DocTreePath getTag(final JavadocContext jdctx, final int offset) {
- final DocTreePath[] result = new DocTreePath[1];
- final int normalizedOffset = skipWhitespacesBackwards(jdctx, offset);
- new DocTreePathScanner<Void, Void>() {
- @Override public Void scan(DocTree node, Void p) {
- if ( node != null
- && jdctx.positions.getStartPosition(jdctx.javac.getCompilationUnit(), jdctx.comment, node) <= normalizedOffset
- && jdctx.positions.getEndPosition(jdctx.javac.getCompilationUnit(), jdctx.comment, node) >= normalizedOffset) {
- result[0] = new DocTreePath(getCurrentPath(), node);
- return super.scan(node, p);
- }
-
- return null;
- }
- }.scan(new DocTreePath(jdctx.javadocFor, jdctx.comment), null);
-
- return result[0];
- }
-
- private static final Set<ElementKind> EXECUTABLE = EnumSet.of(ElementKind.METHOD, ElementKind.CONSTRUCTOR);
-
- void resolveIdent(JavadocContext jdctx) {
- TokenSequence<JavadocTokenId> jdts = jdctx.jdts;
- assert jdts.token() != null;
- assert jdts.token().id() == JavadocTokenId.IDENT;
- // @see package.Class[.NestedClass]#member[()]
- // START -> TAG OT(WS+) MEMBER_SELECT|CLASS_SELECT
- // CLASS_SELECT -> IDENT | IDENT DOT CLASS_SELECT | IDENT MEMBER_SELECT
- // MEMBER_SELECT -> HASH IDENT OT('(')
-
- // @see org.Clazz#meth(int p, int q)
- // TAG OT(' ') IDENT DOT IDENT HASH IDENT OT('(') IDENT OT(' ') IDENT OT(', ') IDENT OT(' ') IDENT OT(')\n...')
- // @see Clazz#meth(int p, int q)
- // @see #meth(int p, int q)
- // @see Clazz.NestedClazz
-
- // Parenthesis content:
- // param types not neccessary to be imported or fqn!!!
- // param types may be fqn
- // param types never contains generics
- // params may contain name but they not necessary match the real names
- // param list may contain spaces
- // no space allowed between member and parenthesis
-
- DocTreePath tag = getTag(jdctx, caretOffset);
- if (tag != null) {
- insideTag(tag, jdctx);
- }
- }
-
- void resolveDotToken(JavadocContext jdctx) {
- assert jdctx.jdts.token() != null;
- assert jdctx.jdts.token().id() == JavadocTokenId.DOT;
-
- DocTreePath tag = getTag(jdctx, caretOffset);
- if (tag != null) {
- insideTag(tag, jdctx);
- }
- }
-
- void resolveHashToken(JavadocContext jdctx) {
- assert jdctx.jdts.token() != null;
- assert jdctx.jdts.token().id() == JavadocTokenId.HASH;
-
- DocTreePath tag = getTag(jdctx, caretOffset);
- if (tag != null) {
- insideTag(tag, jdctx);
- }
- }
-
- void resolveHTMLToken(JavadocContext jdctx) {
- assert jdctx.jdts.token() != null;
- assert jdctx.jdts.token().id() == JavadocTokenId.HTML_TAG;
-
- DocTreePath tag = getTag(jdctx, caretOffset);
- if (tag != null && tag.getLeaf().getKind() == Kind.PARAM) {
- // type param
- insideParamTag(tag, jdctx);
- }
- }
-
- private void insideTag(DocTreePath tag, JavadocContext jdctx) {
- switch (JavadocCompletionUtils.normalizedKind(tag.getLeaf())) {
- case IDENTIFIER:
- if (tag.getParentPath() == null || tag.getParentPath().getLeaf().getKind() != Kind.PARAM)
- break;
- tag = tag.getParentPath();
- //intentional fall-through:
- case PARAM:
- insideParamTag(tag, jdctx);
- break;
- case SEE: case THROWS: case VALUE:
- case LINK: case LINK_PLAIN://XXX: was only unclosed???
- insideSeeTag(tag, jdctx);
- break;
- case REFERENCE:
- insideReference(tag, jdctx);
- break;
- }
- }
-
- private void insideSeeTag(DocTreePath tag, JavadocContext jdctx) {
- TokenSequence<JavadocTokenId> jdts = jdctx.jdts;
- assert jdts.token() != null;
- int start = (int) jdctx.positions.getStartPosition(jdctx.javac.getCompilationUnit(), jdctx.comment, tag.getLeaf());
-
- boolean isThrowsKind = JavadocCompletionUtils.normalizedKind(tag.getLeaf()) == Kind.THROWS;
- if (isThrowsKind && !(EXECUTABLE.contains(jdctx.commentFor.getKind()))) {
- // illegal tag in this context
- return;
- }
-
- jdts.move(start + (JavadocCompletionUtils.isBlockTag(tag)? 0: 1));
- // @see|@link|@throws
- if (!jdts.moveNext() || caretOffset <= jdts.offset() + jdts.token().length()) {
- return;
- }
- // white space
- if (!jdts.moveNext() || caretOffset <= jdts.offset()) {
- return;
- }
-
- boolean noPrefix = false;
-
- if (caretOffset <= jdts.offset() + jdts.token().length()) {
- int pos = caretOffset - jdts.offset();
- CharSequence cs = jdts.token().text();
- cs = pos < cs.length()? cs.subSequence(0, pos): cs;
-
- if (JavadocCompletionUtils.isWhiteSpace(cs)
- || JavadocCompletionUtils.isLineBreak(jdts.token(), pos)) {
- noPrefix = true;
- } else {
- // broken syntax
- return;
- }
- } else if (! (JavadocCompletionUtils.isWhiteSpace(jdts.token())
- || JavadocCompletionUtils.isLineBreak(jdts.token()) )) {
- // not java reference
- return;
- } else if (jdts.moveNext()) {
- int end = (int) jdctx.positions.getEndPosition(jdctx.javac.getCompilationUnit(), jdctx.comment, tag.getLeaf());
- insideReference(JavadocCompletionUtils.normalizedKind(tag.getLeaf()), jdts.offset(), end, jdctx);
- }
-
- if (noPrefix) {
- // complete all types + members
-
- if (isThrowsKind) {
- completeThrowsOrPkg(null, "", caretOffset, jdctx); // NOI18N
- } else {
- completeClassOrPkg(null, "", caretOffset, jdctx); // NOI18N
- }
- jdctx.anchorOffset = caretOffset;
- return;
- }
- }
-
- private void insideReference(DocTreePath tag, JavadocContext jdctx) {
- ReferenceTree ref = (ReferenceTree) tag.getLeaf();
- Kind kind = tag.getParentPath().getLeaf().getKind();
- int start = (int) jdctx.positions.getStartPosition(jdctx.javac.getCompilationUnit(), jdctx.comment, ref);
- int end = (int) jdctx.positions.getEndPosition(jdctx.javac.getCompilationUnit(), jdctx.comment, ref);
-
- insideReference(kind, start, end, jdctx);
- }
-
- private void insideReference(Kind enclosingKind, int start, int end, JavadocContext jdctx) {
- // complete type
- CharSequence cs = JavadocCompletionUtils.getCharSequence(jdctx.doc, start, end);
- StringBuilder sb = new StringBuilder();
- for (int i = caretOffset - start - 1; i >= 0; i--) {
- char c = cs.charAt(i);
- if (c == '#') {
- // complete class member
- String prefix = sb.toString();
- int substitutionOffset = caretOffset - sb.length();
- jdctx.anchorOffset = substitutionOffset;
- if (i == 0) {
- if (enclosingKind == Kind.VALUE) {
- addLocalConstants(jdctx, prefix, substitutionOffset);
- } else {
- addLocalMembersAndVars(jdctx, prefix, substitutionOffset);
- }
- } else {
- TypeElement scopeType = jdctx.commentFor.getKind().isClass() || jdctx.commentFor.getKind().isInterface() ? (TypeElement) jdctx.commentFor
- : jdctx.javac.getElementUtilities().enclosingTypeElement(jdctx.commentFor);
- TypeMirror type =
- jdctx.javac.getTreeUtilities().parseType(cs.subSequence(0, i).toString(), scopeType);
- if (enclosingKind == Kind.VALUE) {
- addMemberConstants(jdctx, prefix, substitutionOffset, type);
- } else {
- addMembers(jdctx, prefix, substitutionOffset, type, jdctx.javac.getTypes().asElement(type),
- EnumSet.<ElementKind>of(ENUM_CONSTANT, FIELD, METHOD, CONSTRUCTOR),
- null);
- }
- }
- return;
- } else if (c == '.') {
- // complete class or package
- String prefix = sb.toString();
- String fqn = cs.subSequence(0, i).toString();
- int substitutionOffset = caretOffset - sb.length();
- jdctx.anchorOffset = substitutionOffset;
- if (enclosingKind == Kind.THROWS) {
- completeThrowsOrPkg(fqn, prefix, substitutionOffset, jdctx);
- } else {
- completeClassOrPkg(fqn, prefix, substitutionOffset, jdctx);
- }
- return;
- } else {
- sb.insert(0, c);
- }
- }
- // complete class or package
- String prefix = sb.toString();
- String fqn = null;
- int substitutionOffset = caretOffset - sb.length();
- jdctx.anchorOffset = substitutionOffset;
- if (enclosingKind == Kind.THROWS) {
- completeThrowsOrPkg(fqn, prefix, substitutionOffset, jdctx);
- } else {
- completeClassOrPkg(fqn, prefix, substitutionOffset, jdctx);
- }
- }
-
- private void insideParamTag(DocTreePath tag, JavadocContext jdctx) {
- TokenSequence<JavadocTokenId> jdts = jdctx.jdts;
- assert jdts.token() != null;
- int start = (int) jdctx.positions.getStartPosition(jdctx.javac.getCompilationUnit(), jdctx.comment, tag.getLeaf());
-
- jdts.move(start);
- // @param
- if (!jdts.moveNext() || caretOffset <= jdts.offset() + jdts.token().length()) {
- return;
- }
- // white space
- if (!jdts.moveNext() || caretOffset <= jdts.offset()) {
- return;
- }
-
- if (caretOffset <= jdts.offset() + jdts.token().length()) {
- int pos = caretOffset - jdts.offset();
- CharSequence cs = jdts.token().text();
- cs = pos < cs.length()? cs.subSequence(0, pos): cs;
-
- if (JavadocCompletionUtils.isWhiteSpace(cs)
- || JavadocCompletionUtils.isLineBreak(jdts.token(), pos)) {
- // none prefix
- jdctx.anchorOffset = caretOffset;
- completeParamName(tag, "", caretOffset, jdctx); // NOI18N
- return;
- } else {
- // broken syntax
- return;
- }
- }
-
- jdts.moveNext(); // param name
- if (!(jdts.token().id() == JavadocTokenId.IDENT || jdts.token().id() == JavadocTokenId.HTML_TAG)) {
- // broken syntax
- return;
- }
- if (caretOffset <= jdts.offset() + jdts.token().length()) {
- CharSequence prefix = jdts.token().text().subSequence(0, caretOffset - jdts.offset());
- jdctx.anchorOffset = jdts.offset();
- completeParamName(tag, prefix.toString(), jdts.offset(), jdctx);
- return;
- }
- }
-
- private void completeParamName(DocTreePath tag, String prefix, int substitutionOffset, JavadocContext jdctx) {
- if (EXECUTABLE.contains(jdctx.commentFor.getKind())) {
- List<? extends DocTree> blockTags = jdctx.comment.getBlockTags();
- ExecutableElement method = (ExecutableElement) jdctx.commentFor;
- for (VariableElement param : method.getParameters()) {
- String name = param.getSimpleName().toString();
-
- if (!containsParam(blockTags, name) && name.startsWith(prefix)) {
- items.add(JavadocCompletionItem.createNameItem(name, substitutionOffset));
- }
- }
-
- completeTypeVarName(jdctx.commentFor, prefix, substitutionOffset);
- } else if (jdctx.commentFor.getKind().isClass() || jdctx.commentFor.getKind().isInterface()) {
- completeTypeVarName(jdctx.commentFor, prefix, substitutionOffset);
- }
- }
- private boolean containsParam(List<? extends DocTree> blockTags, String name) {
- for (DocTree blockTag : blockTags) {
- if(blockTag.getKind() == Kind.PARAM) {
- ParamTree param = (ParamTree) blockTag;
- if(name.contentEquals(param.getName().getName())) {
- return true;
- }
- }
- }
- return false;
- }
-
- private void completeTypeVarName(Element forElement, String prefix, int substitutionOffset) {
- if (prefix.length() > 0) {
- if (prefix.charAt(0) == '<') {
- prefix = prefix.substring(1, prefix.length());
- } else {
- // not type param
- return;
- }
- }
- List<? extends TypeParameterElement> tparams = (forElement.getKind().isClass() || forElement.getKind().isInterface())
- ? ((TypeElement) forElement).getTypeParameters()
- : ((ExecutableElement) forElement).getTypeParameters();
-
- for (TypeParameterElement typeVariable : tparams) {
- String name = typeVariable.getSimpleName().toString();
- if (name.startsWith(prefix)) {
- items.add(JavadocCompletionItem.createNameItem(
- '<' + name + '>', substitutionOffset));
- }
- }
- }
-
- private void completeClassOrPkg(String fqn, String prefix, int substitutionOffset, JavadocContext jdctx) {
- String pkgPrefix;
- if (fqn == null) {
- pkgPrefix = prefix;
- addTypes(EnumSet.<ElementKind>of(CLASS, INTERFACE, ENUM, ANNOTATION_TYPE),
- null, null, prefix, substitutionOffset, jdctx);
-
- } else {
- pkgPrefix = fqn + '.' + prefix;
- PackageElement pkgElm = jdctx.javac.getElements().getPackageElement(fqn);
- if (pkgElm != null) {
- addPackageContent(pkgElm,
- EnumSet.<ElementKind>of(CLASS, INTERFACE, ENUM, ANNOTATION_TYPE),
- null, null, prefix, substitutionOffset, jdctx);
- }
-
- TypeElement typeElm = jdctx.javac.getElements().getTypeElement(fqn);
- if (typeElm != null) {
- // inner classes
- addInnerClasses(typeElm,
- EnumSet.<ElementKind>of(CLASS, INTERFACE, ENUM, ANNOTATION_TYPE),
- null, null, prefix, substitutionOffset, jdctx);
- }
- }
-
- for (String pkgName : jdctx.javac.getClasspathInfo().getClassIndex().getPackageNames(pkgPrefix, true, EnumSet.allOf(ClassIndex.SearchScope.class)))
- if (pkgName.length() > 0 && !Utilities.isExcluded(pkgName + "."))
- items.add(JavaCompletionItem.createPackageItem(pkgName, substitutionOffset, false));
- }
-
- private void completeThrowsOrPkg(String fqn, String prefix, int substitutionOffset, JavadocContext jdctx) {
- final Elements elements = jdctx.javac.getElements();
- final Set<Element> excludes = new HashSet<Element>();
- String pkgPrefix;
-
- // add declared Throwables
- ExecutableElement method = (ExecutableElement) jdctx.commentFor;
- for (TypeMirror type : method.getThrownTypes()) {
- if (type.getKind() != TypeKind.DECLARED) continue;
- TypeElement clazz = (TypeElement) ((DeclaredType) type).asElement();
- String typeName = clazz.getSimpleName().toString();
- if (startsWith(typeName, prefix)) {
- String qualTypeName = clazz.getQualifiedName().toString();
- TypeElement typeElement = elements.getTypeElement(qualTypeName);
- if (typeElement == null) {
- continue;
- }
- items.add(JavaCompletionItem.createTypeItem(
- jdctx.javac, typeElement, (DeclaredType) typeElement.asType(),
- substitutionOffset, /*XXX:*/typeName != qualTypeName ? jdctx.getReferencesCount() : null,
- elements.isDeprecated(typeElement), false, false, false, true, false, null));
- excludes.add(typeElement);
- }
- }
-
- // add other Throwables
- if (fqn == null) {
- pkgPrefix = prefix;
- addTypes(EnumSet.<ElementKind>of(CLASS),
- findDeclaredType("java.lang.Throwable", elements), // NOI18N
- excludes, prefix, substitutionOffset, jdctx);
-
- } else {
- pkgPrefix = fqn + '.' + prefix;
-
- PackageElement pkgElm = elements.getPackageElement(fqn);
- if (pkgElm != null) {
- addPackageContent(pkgElm,
- EnumSet.<ElementKind>of(CLASS),
- findDeclaredType("java.lang.Throwable", elements), // NOI18N
- excludes, prefix, substitutionOffset, jdctx);
- }
-
- TypeElement typeElm = elements.getTypeElement(fqn);
- if (typeElm != null) {
- // inner classes
- addInnerClasses(typeElm,
- EnumSet.<ElementKind>of(CLASS),
- findDeclaredType("java.lang.Throwable", elements), // NOI18N
- excludes, prefix, substitutionOffset, jdctx);
- }
- }
-
-
- // add packages
-
- for (String pkgName : jdctx.javac.getClasspathInfo().getClassIndex().getPackageNames(pkgPrefix, true, EnumSet.allOf(ClassIndex.SearchScope.class)))
- if (pkgName.length() > 0)
- items.add(JavaCompletionItem.createPackageItem(pkgName, substitutionOffset, false));
- }
-
- private static DeclaredType findDeclaredType(CharSequence fqn, Elements elements) {
- TypeElement re = elements.getTypeElement(fqn);
- if (re != null) {
- TypeMirror asType = re.asType();
- if (asType.getKind() == TypeKind.DECLARED) {
- return (DeclaredType) asType;
- }
- }
- return null;
- }
-
- private void addMembers(final JavadocContext env, final String prefix, final int substitutionOffset, final TypeMirror type, final Element elem, final EnumSet<ElementKind> kinds, final DeclaredType baseType) {
- Set<? extends TypeMirror> smartTypes = /*queryType == COMPLETION_QUERY_TYPE ? env.getSmartTypes() :*/ null;
- final CompilationInfo controller = env.javac;
- final Trees trees = controller.getTrees();
- final Elements elements = controller.getElements();
- final Types types = controller.getTypes();
- final TreeUtilities tu = controller.getTreeUtilities();
- final ElementUtilities eu = controller.getElementUtilities();
- TypeElement typeElem = type.getKind() == TypeKind.DECLARED ? (TypeElement)((DeclaredType)type).asElement() : null;
-// final boolean isStatic = elem != null && (elem.getKind().isClass() || elem.getKind().isInterface() || elem.getKind() == TYPE_PARAMETER);
-// final boolean isSuperCall = elem != null && elem.getKind().isField() && elem.getSimpleName().contentEquals(SUPER_KEYWORD);
- Element docelm = env.handle.resolve(controller);
- TreePath docpath = docelm != null ? trees.getPath(docelm) : null;
- final Scope scope = docpath != null ? trees.getScope(docpath) : tu.scopeFor(caretOffset);
- TypeElement enclClass = scope.getEnclosingClass();
- final TypeMirror enclType = enclClass != null ? enclClass.asType() : null;
- ElementUtilities.ElementAcceptor acceptor = new ElementUtilities.ElementAcceptor() {
- public boolean accept(Element e, TypeMirror t) {
- switch (e.getKind()) {
- case FIELD:
- String name = e.getSimpleName().toString();
- return Utilities.startsWith(name, prefix) && !CLASS_KEYWORD.equals(name)
- && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e));
-// &&
-// isOfKindAndType(asMemberOf(e, t, types), e, kinds, baseType, scope, trees, types) &&
-// tu.isAccessible(scope, e, isSuperCall && enclType != null ? enclType : t) &&
-// (!isStatic || e.getModifiers().contains(Modifier.STATIC)) &&
-// (isStatic || !e.getSimpleName().contentEquals(THIS_KEYWORD)) &&
-// ((isStatic && !inImport) /*|| !e.getSimpleName().contentEquals(CLASS_KEYWORD)*/);
- case ENUM_CONSTANT:
- return Utilities.startsWith(e.getSimpleName().toString(), prefix) &&
- (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) &&
-// isOfKindAndType(asMemberOf(e, t, types), e, kinds, baseType, scope, trees, types) &&
- trees.isAccessible(scope, e, (DeclaredType)t);
- case METHOD:
- String sn = e.getSimpleName().toString();
- return Utilities.startsWith(sn, prefix) &&
- (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) &&
- (!Utilities.isExcludeMethods() || !Utilities.isExcluded(eu.getElementName(e.getEnclosingElement(), true) + "." + sn)); //NOI18N
-// &&
-// isOfKindAndType(((ExecutableType)asMemberOf(e, t, types)).getReturnType(), e, kinds, baseType, scope, trees, types) &&
-// (isSuperCall && e.getModifiers().contains(PROTECTED) || tu.isAccessible(scope, e, isSuperCall && enclType != null ? enclType : t)) &&
-// (!isStatic || e.getModifiers().contains(Modifier.STATIC));
-// case CLASS:
-// case ENUM:
-// case INTERFACE:
-// case ANNOTATION_TYPE:
-// return Utilities.startsWith(e.getSimpleName().toString(), prefix) &&
-// (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) &&
-// isOfKindAndType(e.asType(), e, kinds, baseType, scope, trees, types) &&
-// tu.isAccessible(scope, e, t) && isStatic;
- case CONSTRUCTOR:
- return (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) &&
-// isOfKindAndType(e.getEnclosingElement().asType(), e, kinds, baseType, scope, trees, types) &&
- (trees.isAccessible(scope, e, (DeclaredType)t) || (elem.getModifiers().contains(Modifier.ABSTRACT) && !e.getModifiers().contains(Modifier.PRIVATE)));
-// &&
-// isStatic;
- }
- return false;
- }
- };
- for(Element e : controller.getElementUtilities().getMembers(type, acceptor)) {
- switch (e.getKind()) {
- case ENUM_CONSTANT:
- case FIELD:
- TypeMirror tm = type.getKind() == TypeKind.DECLARED ? types.asMemberOf((DeclaredType)type, e) : e.asType();
- items.add(JavaCompletionItem.createVariableItem(controller, (VariableElement) e, tm, null, substitutionOffset, null, typeElem != e.getEnclosingElement(), elements.isDeprecated(e), /*isOfSmartType(env, tm, smartTypes)*/false, -1, null));
- break;
- case CONSTRUCTOR:
- case METHOD:
- ExecutableType et = (ExecutableType)(type.getKind() == TypeKind.DECLARED ? types.asMemberOf((DeclaredType)type, e) : e.asType());
-// items.add(JavaCompletionItem.createExecutableItem((ExecutableElement) e, et, substitutionOffset, typeElem != e.getEnclosingElement(), elements.isDeprecated(e), inImport, /*isOfSmartType(env, et.getReturnType(), smartTypes)*/false));
- items.add(JavadocCompletionItem.createExecutableItem(controller, (ExecutableElement) e, et, substitutionOffset, typeElem != e.getEnclosingElement(), elements.isDeprecated(e)));
- break;
-// case CLASS:
-// case ENUM:
-// case INTERFACE:
-// case ANNOTATION_TYPE:
-// DeclaredType dt = (DeclaredType)(type.getKind() == TypeKind.DECLARED ? types.asMemberOf((DeclaredType)type, e) : e.asType());
-// results.add(JavaCompletionItem.createTypeItem((TypeElement)e, dt, anchorOffset, false, elements.isDeprecated(e), insideNew, false));
-// break;
- }
- }
- }
-
- private void addMemberConstants(final JavadocContext env, final String prefix, final int substitutionOffset, final TypeMirror type) {
- final CompilationInfo controller = env.javac;
- final Trees trees = controller.getTrees();
- final Elements elements = controller.getElements();
- final Types types = controller.getTypes();
- final TreeUtilities tu = controller.getTreeUtilities();
- TypeElement typeElem = type.getKind() == TypeKind.DECLARED ? (TypeElement)((DeclaredType)type).asElement() : null;
- Element docelm = env.handle.resolve(controller);
- TreePath docpath = docelm != null ? trees.getPath(docelm) : null;
- final Scope scope = docpath != null ? trees.getScope(docpath) : tu.scopeFor(caretOffset);
- ElementUtilities.ElementAcceptor acceptor = new ElementUtilities.ElementAcceptor() {
- public boolean accept(Element e, TypeMirror t) {
- switch (e.getKind()) {
- case FIELD:
- String name = e.getSimpleName().toString();
- return ((VariableElement)e).getConstantValue() != null
- && Utilities.startsWith(name, prefix) && !CLASS_KEYWORD.equals(name)
- && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e));
- case ENUM_CONSTANT:
- return ((VariableElement)e).getConstantValue() != null &&
- Utilities.startsWith(e.getSimpleName().toString(), prefix) &&
- (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) &&
- trees.isAccessible(scope, e, (DeclaredType)t);
- }
- return false;
- }
- };
- for(Element e : controller.getElementUtilities().getMembers(type, acceptor)) {
- switch (e.getKind()) {
- case ENUM_CONSTANT:
- case FIELD:
- TypeMirror tm = type.getKind() == TypeKind.DECLARED ? types.asMemberOf((DeclaredType)type, e) : e.asType();
- items.add(JavaCompletionItem.createVariableItem(controller, (VariableElement) e, tm, null, substitutionOffset, null, typeElem != e.getEnclosingElement(), elements.isDeprecated(e), /*isOfSmartType(env, tm, smartTypes)*/false, -1, null));
- break;
- }
- }
- }
-
- private void addLocalConstants(final JavadocContext env, final String prefix, final int substitutionOffset) {
- final CompilationInfo controller = env.javac;
- final Elements elements = controller.getElements();
- final Types types = controller.getTypes();
- final TreeUtilities tu = controller.getTreeUtilities();
- final Trees trees = controller.getTrees();
- Element docelm = env.handle.resolve(controller);
- TreePath docpath = docelm != null ? trees.getPath(docelm) : null;
- final Scope scope = docpath != null ? trees.getScope(docpath) : tu.scopeFor(caretOffset);
- final TypeElement enclClass = scope.getEnclosingClass();
- ElementUtilities.ElementAcceptor acceptor = new ElementUtilities.ElementAcceptor() {
- public boolean accept(Element e, TypeMirror t) {
- switch (e.getKind()) {
- case FIELD:
- String name = e.getSimpleName().toString();
- return ((VariableElement)e).getConstantValue() != null
- && Utilities.startsWith(name, prefix) && !CLASS_KEYWORD.equals(name)
- && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e));
- case ENUM_CONSTANT:
- return ((VariableElement)e).getConstantValue() != null &&
- Utilities.startsWith(e.getSimpleName().toString(), prefix) &&
- (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) &&
- trees.isAccessible(scope, e, (DeclaredType)t);
- }
- return false;
- }
- };
- for (Element e : controller.getElementUtilities().getLocalMembersAndVars(scope, acceptor)) {
- switch (e.getKind()) {
- case ENUM_CONSTANT:
- items.add(JavaCompletionItem.createVariableItem(controller, (VariableElement)e, e.asType(), null, substitutionOffset, null, scope.getEnclosingClass() != e.getEnclosingElement(), elements.isDeprecated(e), false/*isOfSmartType(env, e.asType(), smartTypes)*/, -1, null));
- break;
- case FIELD:
- TypeMirror tm = asMemberOf(e, enclClass != null ? enclClass.asType() : null, types);
- items.add(JavaCompletionItem.createVariableItem(controller, (VariableElement)e, tm, null, substitutionOffset, null, scope.getEnclosingClass() != e.getEnclosingElement(), elements.isDeprecated(e), false/*isOfSmartType(env, tm, smartTypes)*/, -1, null));
- break;
- }
- }
- }
-
- private void addLocalMembersAndVars(final JavadocContext env, final String prefix, final int substitutionOffset) {
- final CompilationInfo controller = env.javac;
- final Elements elements = controller.getElements();
- final Types types = controller.getTypes();
- final TreeUtilities tu = controller.getTreeUtilities();
- final Trees trees = controller.getTrees();
- Element docelm = env.handle.resolve(controller);
- TreePath docpath = docelm != null ? trees.getPath(docelm) : null;
- final Scope scope = docpath != null ? trees.getScope(docpath) : tu.scopeFor(caretOffset);
- Set<? extends TypeMirror> smartTypes = null;
-// if (queryType == COMPLETION_QUERY_TYPE) {
-// smartTypes = env.getSmartTypes();
-// if (smartTypes != null) {
-// for (TypeMirror st : smartTypes) {
-// if (st.getKind().isPrimitive())
-// st = types.boxedClass((PrimitiveType)st).asType();
-// if (st.getKind() == TypeKind.DECLARED) {
-// final DeclaredType type = (DeclaredType)st;
-// final TypeElement element = (TypeElement)type.asElement();
-// if (withinScope(env, element))
-// continue;
-// final boolean isStatic = element.getKind().isClass() || element.getKind().isInterface();
-// final Set<? extends TypeMirror> finalSmartTypes = smartTypes;
-// ElementUtilities.ElementAcceptor acceptor = new ElementUtilities.ElementAcceptor() {
-// public boolean accept(Element e, TypeMirror t) {
-// return (!isStatic || e.getModifiers().contains(STATIC)) &&
-// Utilities.startsWith(e.getSimpleName().toString(), prefix) &&
-// tu.isAccessible(scope, e, t) &&
-// (e.getKind().isField() && isOfSmartType(env, ((VariableElement)e).asType(), finalSmartTypes) || e.getKind() == METHOD && isOfSmartType(env, ((ExecutableElement)e).getReturnType(), finalSmartTypes));
-// }
-// };
-// for (Element ee : controller.getElementUtilities().getMembers(type, acceptor)) {
-// if (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(ee))
-// results.add(JavaCompletionItem.createStaticMemberItem(type, ee, types.asMemberOf(type, ee), anchorOffset, elements.isDeprecated(ee)));
-// }
-// }
-// }
-// }
-// }
- final TypeElement enclClass = scope.getEnclosingClass();
-// final boolean isStatic = enclClass == null ? false :
-// (tu.isStaticContext(scope) || (env.getPath().getLeaf().getKind() == Tree.Kind.BLOCK && ((BlockTree)env.getPath().getLeaf()).isStatic()));
-// final Collection<? extends Element> illegalForwardRefs = env.getForwardReferences();
- final ExecutableElement method = scope.getEnclosingMethod();
- ElementUtilities.ElementAcceptor acceptor = new ElementUtilities.ElementAcceptor() {
- public boolean accept(Element e, TypeMirror t) {
- switch (e.getKind()) {
- case CONSTRUCTOR:
- return Utilities.startsWith(e.getEnclosingElement().getSimpleName().toString(), prefix) &&
- (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) &&
-// (!isStatic || e.getModifiers().contains(STATIC)) &&
- trees.isAccessible(scope, e, (DeclaredType)t);
-// case LOCAL_VARIABLE:
-// case EXCEPTION_PARAMETER:
-// case PARAMETER:
-// return Utilities.startsWith(e.getSimpleName().toString(), prefix) &&
-// (method == e.getEnclosingElement() || e.getModifiers().contains(FINAL) ||
-// (method == null && (e.getEnclosingElement().getKind() == INSTANCE_INIT ||
-// e.getEnclosingElement().getKind() == STATIC_INIT))) &&
-// !illegalForwardRefs.contains(e);
- case FIELD:
-// if (e.getSimpleName().contentEquals(THIS_KEYWORD) || e.getSimpleName().contentEquals(SUPER_KEYWORD))
-// return Utilities.startsWith(e.getSimpleName().toString(), prefix) && !isStatic;
- String name = e.getSimpleName().toString();
- return Utilities.startsWith(name, prefix) && !CLASS_KEYWORD.equals(name)
- && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e));
-// String name = e.getSimpleName().toString();
-// return !name.equals(THIS_KEYWORD) && !name.equals(SUPER_KEYWORD)
-// && Utilities.startsWith(name, prefix);
- case ENUM_CONSTANT:
- return Utilities.startsWith(e.getSimpleName().toString(), prefix) &&
-// !illegalForwardRefs.contains(e) &&
-// (!isStatic || e.getModifiers().contains(STATIC)) &&
- (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) &&
- trees.isAccessible(scope, e, (DeclaredType)t);
- case METHOD:
- return Utilities.startsWith(e.getSimpleName().toString(), prefix) &&
- (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) &&
-// (!isStatic || e.getModifiers().contains(STATIC)) &&
- trees.isAccessible(scope, e, (DeclaredType)t);
- }
- return false;
- }
- };
- for (Element e : controller.getElementUtilities().getLocalMembersAndVars(scope, acceptor)) {
- switch (e.getKind()) {
- case ENUM_CONSTANT:
- items.add(JavaCompletionItem.createVariableItem(controller, (VariableElement)e, e.asType(), null, substitutionOffset, null, scope.getEnclosingClass() != e.getEnclosingElement(), elements.isDeprecated(e), false/*isOfSmartType(env, e.asType(), smartTypes)*/, -1, null));
- break;
- case FIELD:
- String name = e.getSimpleName().toString();
- TypeMirror tm = asMemberOf(e, enclClass != null ? enclClass.asType() : null, types);
- items.add(JavaCompletionItem.createVariableItem(controller, (VariableElement)e, tm, null, substitutionOffset, null, scope.getEnclosingClass() != e.getEnclosingElement(), elements.isDeprecated(e), false/*isOfSmartType(env, tm, smartTypes)*/, -1, null));
- break;
- case CONSTRUCTOR:
- case METHOD:
- ExecutableType et = (ExecutableType)asMemberOf(e, enclClass != null ? enclClass.asType() : null, types);
-// items.add(JavaCompletionItem.createExecutableItem((ExecutableElement)e, et, substitutionOffset, scope.getEnclosingClass() != e.getEnclosingElement(), elements.isDeprecated(e), false, false/*isOfSmartType(env, et.getReturnType(), smartTypes)*/));
- items.add(JavadocCompletionItem.createExecutableItem(controller, (ExecutableElement) e, et, substitutionOffset, scope.getEnclosingClass() != e.getEnclosingElement(), elements.isDeprecated(e)));
- break;
- }
- }
- }
-
- private static TypeMirror asMemberOf(Element element, TypeMirror type, Types types) {
- TypeMirror ret = element.asType();
- TypeMirror enclType = element.getEnclosingElement().asType();
- if (enclType.getKind() == TypeKind.DECLARED)
- enclType = types.erasure(enclType);
- while(type != null && type.getKind() == TypeKind.DECLARED) {
- if (types.isSubtype(type, enclType)) {
- ret = types.asMemberOf((DeclaredType)type, element);
- break;
- }
- type = ((DeclaredType)type).getEnclosingType();
- }
- return ret;
- }
-
- private void addTypes(EnumSet<ElementKind> kinds, DeclaredType baseType,
- Set<? extends Element> toExclude, String prefix,
- int substitutionOffset, JavadocContext jdctx) {
-
- if (queryType == CompletionProvider.COMPLETION_ALL_QUERY_TYPE) {
- if (baseType == null) {
- addAllTypes(jdctx, kinds, toExclude, prefix, substitutionOffset);
- } else {
- Elements elements = jdctx.javac.getElements();
- for(DeclaredType subtype : getSubtypesOf(baseType, prefix, jdctx)) {
- TypeElement elem = (TypeElement)subtype.asElement();
- if ((toExclude == null || !toExclude.contains(elem)) && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(elem)))
- items.add(JavaCompletionItem.createTypeItem(jdctx.javac, elem, subtype, substitutionOffset, jdctx.getReferencesCount(), elements.isDeprecated(elem), false, false, false, false, false, null));
- }
- }
- } else {
- addLocalAndImportedTypes(jdctx, kinds, baseType, toExclude, prefix, substitutionOffset);
- hasAdditionalItems = true;
- }
- }
-
- private void addLocalAndImportedTypes(final JavadocContext env, final EnumSet<ElementKind> kinds, final DeclaredType baseType, final Set<? extends Element> toExclude, final String prefix, int substitutionOffset) {
- final CompilationInfo controller = env.javac;
- final Trees trees = controller.getTrees();
- final Elements elements = controller.getElements();
- final Types types = controller.getTypes();
- final TreeUtilities tu = controller.getTreeUtilities();
- Element docelm = env.handle.resolve(controller);
- TreePath docpath = docelm != null ? trees.getPath(docelm) : null;
- final Scope scope = docpath != null ? trees.getScope(docpath) : tu.scopeFor(caretOffset);
- final TypeElement enclClass = scope.getEnclosingClass();
- final boolean isStatic = enclClass == null ? false : tu.isStaticContext(scope);
- ElementUtilities.ElementAcceptor acceptor = new ElementUtilities.ElementAcceptor() {
- public boolean accept(Element e, TypeMirror t) {
- if ((toExclude == null || !toExclude.contains(e)) && (e.getKind().isClass() || e.getKind().isInterface() || e.getKind() == TYPE_PARAMETER)) {
- String name = e.getSimpleName().toString();
- return name.length() > 0 && !Character.isDigit(name.charAt(0)) && startsWith(name, prefix) &&
- (!isStatic || e.getModifiers().contains(Modifier.STATIC)) && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) && isOfKindAndType(e.asType(), e, kinds, baseType, scope, trees, types);
- }
- return false;
- }
- };
- for(Element e : controller.getElementUtilities().getLocalMembersAndVars(scope, acceptor)) {
- switch (e.getKind()) {
- case CLASS:
- case ENUM:
- case INTERFACE:
- case ANNOTATION_TYPE:
- items.add(JavadocCompletionItem.createTypeItem(env.javac, (TypeElement) e, substitutionOffset, null, elements.isDeprecated(e)));
- break;
- }
- }
- acceptor = new ElementUtilities.ElementAcceptor() {
- public boolean accept(Element e, TypeMirror t) {
- if ((e.getKind().isClass() || e.getKind().isInterface())) {
- return (toExclude == null || !toExclude.contains(e)) && startsWith(e.getSimpleName().toString(), prefix) &&
- (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) && trees.isAccessible(scope, (TypeElement)e) &&
- isOfKindAndType(e.asType(), e, kinds, baseType, scope, trees, types);
- }
- return false;
- }
- };
- for (TypeElement e : controller.getElementUtilities().getGlobalTypes(acceptor)) {
- items.add(JavadocCompletionItem.createTypeItem(env.javac, e, substitutionOffset, null, elements.isDeprecated(e)));
- }
- }
-
- private void addAllTypes(JavadocContext env, EnumSet<ElementKind> kinds, Set<? extends Element> toExclude, String prefix, int substitutionOffset) {
-// String prefix = env.getPrefix();
- CompilationInfo controller = env.javac;
- boolean isCaseSensitive = false;
- ClassIndex.NameKind kind =
- isCaseSensitive? ClassIndex.NameKind.PREFIX : ClassIndex.NameKind.CASE_INSENSITIVE_PREFIX;
-// ClassIndex.NameKind kind = env.isCamelCasePrefix() ?
-// Utilities.isCaseSensitive() ? ClassIndex.NameKind.CAMEL_CASE : ClassIndex.NameKind.CAMEL_CASE_INSENSITIVE :
-// Utilities.isCaseSensitive() ? ClassIndex.NameKind.PREFIX : ClassIndex.NameKind.CASE_INSENSITIVE_PREFIX;
- Set<ElementHandle<Element>> excludeHandles = null;
- if (toExclude != null) {
- excludeHandles = new HashSet<ElementHandle<Element>>(toExclude.size());
- for (Element el : toExclude) {
- excludeHandles.add(ElementHandle.create(el));
- }
- }
- for(ElementHandle<TypeElement> name : controller.getClasspathInfo().getClassIndex().getDeclaredTypes(prefix, kind, EnumSet.allOf(ClassIndex.SearchScope.class))) {
- if ((excludeHandles == null || !excludeHandles.contains(name)) && !isAnnonInner(name)) {
- items.add(LazyJavaCompletionItem.createTypeItem(name, kinds, substitutionOffset, env.getReferencesCount(), controller.getSnapshot().getSource(), false, false, false, null));
- }
- }
- }
-
- private void addInnerClasses(TypeElement te, EnumSet<ElementKind> kinds, DeclaredType baseType, Set<? extends Element> toExclude, String prefix, int substitutionOffset, JavadocContext jdctx) {
- CompilationInfo controller = jdctx.javac;
- Element srcEl = jdctx.handle.resolve(controller);
- Elements elements = controller.getElements();
- Types types = controller.getTypes();
- Trees trees = controller.getTrees();
- TreeUtilities tu = controller.getTreeUtilities();
- TreePath docpath = srcEl != null ? trees.getPath(srcEl) : null;
- Scope scope = docpath != null ? trees.getScope(docpath) : tu.scopeFor(caretOffset);
- for (Element e : controller.getElementUtilities().getMembers(te.asType(), null)) {
- if ((e.getKind().isClass() || e.getKind().isInterface()) && (toExclude == null || !toExclude.contains(e))) {
- String name = e.getSimpleName().toString();
- if (Utilities.startsWith(name, prefix) && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) && trees.isAccessible(scope, (TypeElement)e) && isOfKindAndType(e.asType(), e, kinds, baseType, scope, trees, types)) {
- items.add(JavadocCompletionItem.createTypeItem(jdctx.javac, (TypeElement) e, substitutionOffset, null, elements.isDeprecated(e)/*, isOfSmartType(env, e.asType(), smartTypes)*/));
- }
- }
- }
- }
-
- private void addPackageContent(PackageElement pe, EnumSet<ElementKind> kinds, DeclaredType baseType, Set<? extends Element> toExclude, String prefix, int substitutionOffset, JavadocContext jdctx) {
- CompilationInfo controller = jdctx.javac;
- Element srcEl = jdctx.handle.resolve(controller);
- Elements elements = controller.getElements();
- Types types = controller.getTypes();
- Trees trees = controller.getTrees();
- TreeUtilities tu = controller.getTreeUtilities();
- ElementUtilities eu = controller.getElementUtilities();
- TreePath docpath = srcEl != null ? trees.getPath(srcEl) : null;
- Scope scope = docpath != null ? trees.getScope(docpath) : tu.scopeFor(caretOffset);
- for(Element e : pe.getEnclosedElements()) {
- if ((e.getKind().isClass() || e.getKind().isInterface()) && (toExclude == null || !toExclude.contains(e))) {
- String name = e.getSimpleName().toString();
- if (Utilities.startsWith(name, prefix) && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e))
- && trees.isAccessible(scope, (TypeElement)e)
- && isOfKindAndType(e.asType(), e, kinds, baseType, scope, trees, types)
- && !Utilities.isExcluded(eu.getElementName(e, true))) {
- items.add(JavadocCompletionItem.createTypeItem(jdctx.javac, (TypeElement) e, substitutionOffset, null, elements.isDeprecated(e)/*, isOfSmartType(env, e.asType(), smartTypes)*/));
- }
- }
- }
- }
-
- private boolean isOfKindAndType(TypeMirror type, Element e, EnumSet<ElementKind> kinds, TypeMirror base, Scope scope, Trees trees, Types types) {
- if (type.getKind() != TypeKind.ERROR && kinds.contains(e.getKind())) {
- if (base == null)
- return true;
- if (types.isSubtype(type, base))
- return true;
- }
- if ((e.getKind().isClass() || e.getKind().isInterface()) &&
- (kinds.contains(ANNOTATION_TYPE) || kinds.contains(CLASS) || kinds.contains(ENUM) || kinds.contains(INTERFACE))) {
- DeclaredType dt = (DeclaredType)e.asType();
- for (Element ee : e.getEnclosedElements())
- if (trees.isAccessible(scope, ee, dt) && isOfKindAndType(ee.asType(), ee, kinds, base, scope, trees, types))
- return true;
- }
- return false;
- }
-
- private static boolean isAnnonInner(ElementHandle<TypeElement> elem) {
- String name = elem.getQualifiedName();
- int idx = name.lastIndexOf('.'); //NOI18N
- String simpleName = idx > -1 ? name.substring(idx + 1) : name;
- return simpleName.length() == 0 || Character.isDigit(simpleName.charAt(0));
- }
- /* copied from JavaCompletionProvider */
- private List<DeclaredType> getSubtypesOf(DeclaredType baseType, String prefix, JavadocContext jdctx) {
- if (((TypeElement)baseType.asElement()).getQualifiedName().contentEquals("java.lang.Object"))
- return Collections.emptyList();
- LinkedList<DeclaredType> subtypes = new LinkedList<DeclaredType>();
- CompilationInfo controller = jdctx.javac;
- Types types = controller.getTypes();
- Trees trees = controller.getTrees();
- TreeUtilities tu = controller.getTreeUtilities();
- Element resolvedElm = jdctx.handle.resolve(controller);
- TreePath docpath = resolvedElm != null ? trees.getPath(resolvedElm) : null;
- Scope scope = docpath != null ? trees.getScope(docpath) : tu.scopeFor(caretOffset);
- if (prefix != null && prefix.length() > 2 && baseType.getTypeArguments().isEmpty()) {
- // XXX resolve camels
-// ClassIndex.NameKind kind = env.isCamelCasePrefix() ?
- ClassIndex.NameKind kind = false ?
- Utilities.isCaseSensitive() ? ClassIndex.NameKind.CAMEL_CASE : ClassIndex.NameKind.CAMEL_CASE_INSENSITIVE :
- Utilities.isCaseSensitive() ? ClassIndex.NameKind.PREFIX : ClassIndex.NameKind.CASE_INSENSITIVE_PREFIX;
- for(ElementHandle<TypeElement> handle : controller.getClasspathInfo().getClassIndex().getDeclaredTypes(prefix, kind, EnumSet.allOf(ClassIndex.SearchScope.class))) {
- TypeElement te = handle.resolve(controller);
- if (te != null && trees.isAccessible(scope, te) && types.isSubtype(types.getDeclaredType(te), baseType))
- subtypes.add(types.getDeclaredType(te));
- }
- } else {
- HashSet<TypeElement> elems = new HashSet<TypeElement>();
- LinkedList<DeclaredType> bases = new LinkedList<DeclaredType>();
- bases.add(baseType);
- ClassIndex index = controller.getClasspathInfo().getClassIndex();
- while(!bases.isEmpty()) {
- DeclaredType head = bases.remove();
- TypeElement elem = (TypeElement)head.asElement();
- if (!elems.add(elem))
- continue;
- if (startsWith(elem.getSimpleName().toString(), prefix) && trees.isAccessible(scope, elem))
- subtypes.add(head);
- List<? extends TypeMirror> tas = head.getTypeArguments();
- boolean isRaw = !tas.iterator().hasNext();
- subtypes:
- for (ElementHandle<TypeElement> eh : index.getElements(ElementHandle.create(elem), EnumSet.of(ClassIndex.SearchKind.IMPLEMENTORS),EnumSet.allOf(ClassIndex.SearchScope.class))) {
- TypeElement e = eh.resolve(controller);
- if (e != null) {
- if (trees.isAccessible(scope, e)) {
- if (isRaw) {
- DeclaredType dt = types.getDeclaredType(e);
- bases.add(dt);
- } else {
- HashMap<Element, TypeMirror> map = new HashMap<Element, TypeMirror>();
- TypeMirror sup = e.getSuperclass();
- if (sup.getKind() == TypeKind.DECLARED && ((DeclaredType)sup).asElement() == elem) {
- DeclaredType dt = (DeclaredType)sup;
- Iterator<? extends TypeMirror> ittas = tas.iterator();
- Iterator<? extends TypeMirror> it = dt.getTypeArguments().iterator();
- while(it.hasNext() && ittas.hasNext()) {
- TypeMirror basetm = ittas.next();
- TypeMirror stm = it.next();
- if (basetm != stm) {
- if (stm.getKind() == TypeKind.TYPEVAR) {
- map.put(((TypeVariable)stm).asElement(), basetm);
- } else {
- continue subtypes;
- }
- }
- }
- if (it.hasNext() != ittas.hasNext()) {
- continue subtypes;
- }
- } else {
- for (TypeMirror tm : e.getInterfaces()) {
- if (((DeclaredType)tm).asElement() == elem) {
- DeclaredType dt = (DeclaredType)tm;
- Iterator<? extends TypeMirror> ittas = tas.iterator();
- Iterator<? extends TypeMirror> it = dt.getTypeArguments().iterator();
- while(it.hasNext() && ittas.hasNext()) {
- TypeMirror basetm = ittas.next();
- TypeMirror stm = it.next();
- if (basetm != stm) {
- if (stm.getKind() == TypeKind.TYPEVAR) {
- map.put(((TypeVariable)stm).asElement(), basetm);
- } else {
- continue subtypes;
- }
- }
- }
- if (it.hasNext() != ittas.hasNext()) {
- continue subtypes;
- }
- break;
- }
- }
- }
- bases.add(getDeclaredType(e, map, types));
- }
- }
- } else {
- Logger.getLogger("global").log(Level.FINE, String.format("Cannot resolve: %s on bootpath: %s classpath: %s sourcepath: %s\n", eh.toString(),
- controller.getClasspathInfo().getClassPath(ClasspathInfo.PathKind.BOOT),
- controller.getClasspathInfo().getClassPath(ClasspathInfo.PathKind.COMPILE),
- controller.getClasspathInfo().getClassPath(ClasspathInfo.PathKind.SOURCE)));
- }
- }
- }
- }
- return subtypes;
- }
-
- private DeclaredType getDeclaredType(TypeElement e, HashMap<? extends Element, ? extends TypeMirror> map, Types types) {
- List<? extends TypeParameterElement> tpes = e.getTypeParameters();
- TypeMirror[] targs = new TypeMirror[tpes.size()];
- int i = 0;
- for (Iterator<? extends TypeParameterElement> it = tpes.iterator(); it.hasNext();) {
- TypeParameterElement tpe = it.next();
- TypeMirror t = map.get(tpe);
- targs[i++] = t != null ? t : tpe.asType();
- }
- Element encl = e.getEnclosingElement();
- if ((encl.getKind().isClass() || encl.getKind().isInterface()) && !((TypeElement)encl).getTypeParameters().isEmpty())
- return types.getDeclaredType(getDeclaredType((TypeElement)encl, map, types), e, targs);
- return types.getDeclaredType(e, targs);
- }
-
- private boolean startsWith(String theString, String prefix) {
- // XXX isCamelCasePrefix
- return /*env.isCamelCasePrefix()*/false ? Utilities.isCaseSensitive() ?
- Utilities.startsWithCamelCase(theString, prefix) :
- Utilities.startsWithCamelCase(theString, prefix) || Utilities.startsWith(theString, prefix) :
- Utilities.startsWith(theString, prefix);
- }
-
- void resolveOtherText(JavadocContext jdctx, TokenSequence<JavadocTokenId> jdts) {
- Token<JavadocTokenId> token = jdts.token();
- assert token != null;
- assert token.id() == JavadocTokenId.OTHER_TEXT;
-
- CharSequence text = token.text();
- int pos = caretOffset - jdts.offset();
- DocTreePath tag = getTag(jdctx, caretOffset);
- if (pos > 0 && pos <= text.length() && text.charAt(pos - 1) == '{') {
- if (tag != null && !JavadocCompletionUtils.isBlockTag(tag)) {
- int start = (int) jdctx.positions.getStartPosition(jdctx.javac.getCompilationUnit(), jdctx.comment, tag.getLeaf());
- if (start + 1 != caretOffset) {
- return;
- }
- }
- resolveInlineTag(null, jdctx);
- return;
- }
-
- if (tag != null) {
- insideTag(tag, jdctx);
- if (JavadocCompletionUtils.isBlockTag(tag) && JavadocCompletionUtils.isLineBreak(token, pos)) {
- resolveBlockTag(null, jdctx);
+ static List<CompletionItem> runCompletionQuery(int queryType, Document doc, int caret) {
+ JavadocCompletionTask<CompletionItem> task = JavadocCompletionTask.create(caret, new JavadocCompletionItem.Factory(),
+ queryType == CompletionProvider.COMPLETION_ALL_QUERY_TYPE, null);
+ Source source = Source.create(doc);
+ if (source != null) {
+ try {
+ ParserManager.parse(Collections.singletonList(source), task);
+ } catch (ParseException ex) {
+ Exceptions.printStackTrace(ex);
}
- } else if (JavadocCompletionUtils.isLineBreak(token, pos)) {
- resolveBlockTag(null, jdctx);
}
+ return task.getResults();
}
-
- static final class JavadocContext {
- int anchorOffset = -1;
- ElementHandle<Element> handle;
- Element commentFor;
- DocCommentTree comment;
- DocSourcePositions positions;
- TokenSequence<JavadocTokenId> jdts;
- Document doc;
- CompilationInfo javac;
- private ReferencesCount count;
- private TreePath javadocFor;
- ReferencesCount getReferencesCount() {
- if (count == null)
- count = ReferencesCount.get(javac.getClasspathInfo());
- return count;
- }
- }
}
diff --git a/java/java.editor/src/org/netbeans/modules/java/editor/javadoc/JavadocCompletionQuery.java b/java/java.editor/src/org/netbeans/modules/java/editor/javadoc/JavadocCompletionTask.java
similarity index 56%
copy from java/java.editor/src/org/netbeans/modules/java/editor/javadoc/JavadocCompletionQuery.java
copy to java/java.editor/src/org/netbeans/modules/java/editor/javadoc/JavadocCompletionTask.java
index ffc908ac16..7b5f00f569 100644
--- a/java/java.editor/src/org/netbeans/modules/java/editor/javadoc/JavadocCompletionQuery.java
+++ b/java/java.editor/src/org/netbeans/modules/java/editor/javadoc/JavadocCompletionTask.java
@@ -16,27 +16,20 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.netbeans.modules.java.editor.javadoc;
import com.sun.source.doctree.DocCommentTree;
import com.sun.source.doctree.DocTree;
-import com.sun.source.doctree.DocTree.Kind;
-import com.sun.source.doctree.ErroneousTree;
import com.sun.source.doctree.ParamTree;
import com.sun.source.doctree.ReferenceTree;
-import com.sun.source.tree.ExpressionTree;
import com.sun.source.tree.Scope;
import com.sun.source.util.DocSourcePositions;
-import com.sun.source.util.DocTreeFactory;
import com.sun.source.util.DocTreePath;
import com.sun.source.util.DocTreePathScanner;
import com.sun.source.util.DocTrees;
-import com.sun.source.util.SourcePositions;
import com.sun.source.util.TreePath;
import com.sun.source.util.Trees;
import java.io.IOException;
-import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumSet;
@@ -46,12 +39,11 @@ import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
-import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Callable;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
-import static javax.lang.model.element.ElementKind.*;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.PackageElement;
@@ -65,10 +57,9 @@ import javax.lang.model.type.TypeMirror;
import javax.lang.model.type.TypeVariable;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
-import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
-import javax.swing.text.JTextComponent;
-import org.netbeans.api.editor.completion.Completion;
+import org.netbeans.api.annotations.common.NonNull;
+import org.netbeans.api.annotations.common.NullAllowed;
import org.netbeans.api.java.lexer.JavadocTokenId;
import org.netbeans.api.java.source.ClassIndex;
import org.netbeans.api.java.source.ClasspathInfo;
@@ -77,167 +68,84 @@ import org.netbeans.api.java.source.CompilationInfo;
import org.netbeans.api.java.source.ElementHandle;
import org.netbeans.api.java.source.ElementUtilities;
import org.netbeans.api.java.source.JavaSource;
-import org.netbeans.api.java.source.Task;
import org.netbeans.api.java.source.TreeUtilities;
import org.netbeans.api.java.source.support.ReferencesCount;
import org.netbeans.api.lexer.Token;
import org.netbeans.api.lexer.TokenSequence;
-import org.netbeans.modules.editor.java.JavaCompletionItem;
-import org.netbeans.modules.editor.java.LazyJavaCompletionItem;
import org.netbeans.modules.java.completion.Utilities;
import org.netbeans.modules.java.editor.base.javadoc.JavadocCompletionUtils;
-import org.netbeans.spi.editor.completion.CompletionItem;
-import org.netbeans.spi.editor.completion.CompletionProvider;
-import org.netbeans.spi.editor.completion.CompletionResultSet;
-import org.netbeans.spi.editor.completion.support.AsyncCompletionQuery;
-import org.openide.util.Exceptions;
+import org.netbeans.modules.java.editor.javadoc.TagRegistery.TagEntry;
+import org.netbeans.modules.parsing.api.ResultIterator;
+import org.netbeans.modules.parsing.api.Source;
+import org.netbeans.modules.parsing.api.UserTask;
+import org.netbeans.modules.parsing.spi.Parser;
-/**
- *
- * @author Jan Pokorsky
- */
-final class JavadocCompletionQuery extends AsyncCompletionQuery{
-
- private static final String CLASS_KEYWORD = "class"; //NOI18N
- private final int queryType;
-
- private int caretOffset;
- private List<CompletionItem> items;
- private boolean hasAdditionalItems;
- private JTextComponent component;
- private boolean ignoreCancel;
-
+public class JavadocCompletionTask<T> extends UserTask {
- public JavadocCompletionQuery(int queryType) {
- this.queryType = queryType;
+ public static <I> JavadocCompletionTask<I> create(final int caretOffset, @NonNull final ItemFactory<I> factory, boolean isAllQueryType, @NullAllowed final Callable<Boolean> cancel) {
+ return new JavadocCompletionTask<>(caretOffset, factory, isAllQueryType, cancel);
}
- @Override
- protected void prepareQuery(JTextComponent component) {
- this.component = component;
+ public static interface ItemFactory<T> {
+ T createTagItem(String name, int startOffset);
+ T createNameItem(String name, int startOffset);
+ T createJavadocExecutableItem(CompilationInfo info, ExecutableElement e, ExecutableType et, int startOffset, boolean isInherited, boolean isDeprecated);
+ T createJavadocTypeItem(CompilationInfo info, TypeElement elem, int startOffset, boolean isDeprecated);
+ T createJavaTypeItem(CompilationInfo info, TypeElement elem, DeclaredType type, int startOffset, ReferencesCount referencesCount, boolean isDeprecated, boolean smartType);
+ T createLazyTypeItem(ElementHandle<TypeElement> handle, EnumSet<ElementKind> kinds, int startOffset, ReferencesCount referencesCount, Source source);
+ T createJavaVariableItem(CompilationInfo info, VariableElement elem, TypeMirror type, int startOffset, boolean isInherited, boolean isDeprecated);
+ T createPackageItem(String pkgFQN, int startOffset);
}
- @Override
- protected void query(CompletionResultSet resultSet, Document doc, int caretOffset) {
- try {
- queryImpl(resultSet, doc, caretOffset);
- } catch (InterruptedException ex) {
- Exceptions.printStackTrace(ex);
- } catch (ExecutionException ex) {
- Exceptions.printStackTrace(ex);
- } finally {
- resultSet.finish();
- }
+ private static final Set<ElementKind> EXECUTABLE = EnumSet.of(ElementKind.METHOD, ElementKind.CONSTRUCTOR);
+ private static final String CLASS_KEYWORD = "class"; //NOI18N
+
+ private final List<T> items = new ArrayList<>();
+ private final int caretOffset;
+ private final ItemFactory<T> factory;
+ private final boolean isAllQueryType;
+ private final Callable<Boolean> cancel;
+ private int anchorOffset = -1;
+ private boolean hasAdditionalItems = false;
+
+ private JavadocCompletionTask(int caretOffset, ItemFactory<T> factory, boolean isAllQueryType, Callable<Boolean> cancel) {
+ this.caretOffset = caretOffset;
+ this.factory = factory;
+ this.isAllQueryType = isAllQueryType;
+ this.cancel = cancel;
}
@Override
- protected boolean canFilter(JTextComponent component) {
- final int newOffset = component.getSelectionStart();
- final Document doc = component.getDocument();
- if (newOffset > caretOffset && items != null && !items.isEmpty()) {
- try {
- String prefix = doc.getText(caretOffset, newOffset - caretOffset);
- if (!isJavaIdentifierPart(prefix)) {
- Completion.get().hideDocumentation();
- Completion.get().hideCompletion();
- }
- } catch (BadLocationException ble) {
+ public void run(ResultIterator resultIterator) throws Exception {
+ Parser.Result result = resultIterator.getParserResult(caretOffset);
+ CompilationController controller = result != null ? CompilationController.get(result) : null;
+ if (controller != null && (cancel == null || !cancel.call())) {
+ if (!JavadocCompletionUtils.isJavadocContext(controller.getTokenHierarchy(), caretOffset)) {
+ return;
}
- }
- return false;
- }
-
- private boolean isJavaIdentifierPart(String text) {
- for (int i = 0; i < text.length(); i++) {
- if (!(Character.isJavaIdentifierPart(text.charAt(i))))
- return false;
- }
- return true;
- }
-
- static List<CompletionItem> runCompletionQuery(int queryType, Document doc, int caret) {
- JavadocCompletionQuery q = new JavadocCompletionQuery(queryType);
- JavadocContext jdctx = new JavadocContext();
-
- q.items = new ArrayList<CompletionItem>();
- q.caretOffset = caret;
- q.ignoreCancel = true;
-
- q.runInJavac(JavaSource.forDocument(doc), jdctx);
-
- return q.items;
- }
-
- private void queryImpl(CompletionResultSet resultSet, Document doc, int caretOffset) throws InterruptedException, ExecutionException {
- JavadocContext jdctx = new JavadocContext();
- items = new ArrayList<CompletionItem>();
- this.caretOffset = caretOffset;
- runInJavac(JavaSource.forDocument(doc), jdctx);
-
- if (!ignoreCancel && isTaskCancelled()) {
- return;
- }
-
- if ((queryType & CompletionProvider.COMPLETION_QUERY_TYPE) != 0) {
- if (!items.isEmpty()) {
- resultSet.addAllItems(items);
+ JavaSource.Phase toPhase = controller.toPhase(JavaSource.Phase.ELEMENTS_RESOLVED);
+ if (toPhase != JavaSource.Phase.ELEMENTS_RESOLVED) {
+ return;
+ }
+ JavadocContext jdctx = new JavadocContext(controller);
+ if (resolveContext(controller, jdctx)) {
+ analyzeContext(jdctx);
}
- resultSet.setHasAdditionalItems(hasAdditionalItems);
- }
-
- if (jdctx.anchorOffset >= 0) {
- resultSet.setAnchorOffset(jdctx.anchorOffset);
}
}
- /** #145615: this helps to work around the issue with stuck
- * {@code JavaSource.runWhenScanFinished}
- * It is copied from {@code JavaCompletionQuery}.
- */
- private void setCompletionHack(boolean flag) {
- if (component != null) {
- component.putClientProperty("completion-active", flag); //NOI18N
- }
+ public List<T> getResults() {
+ return items;
}
-
- private void runInJavac(JavaSource js, final JavadocContext jdctx) {
- try {
- if (js == null) {
- return;
- }
- js.runUserActionTask(new Task<CompilationController>() {
+ public boolean hasAdditionalItems() {
+ return hasAdditionalItems;
+ }
- public void run(CompilationController javac) throws Exception {
- if (!ignoreCancel && isTaskCancelled()) {
- return;
- }
- if (!JavadocCompletionUtils.isJavadocContext(javac.getTokenHierarchy(), caretOffset)) {
- return;
- }
- setCompletionHack(true);
- JavaSource.Phase toPhase = javac.toPhase(JavaSource.Phase.ELEMENTS_RESOLVED);
- if (toPhase != JavaSource.Phase.ELEMENTS_RESOLVED) {
- return;
- }
- try {
- jdctx.javac = javac;
- if (resolveContext(javac, jdctx)) {
- analyzeContext(jdctx);
- }
- } finally {
- jdctx.javac = null;
- if (component != null) {
- setCompletionHack(false);
- }
- }
- }
- }, true);
- } catch (IOException ex) {
- Exceptions.printStackTrace(ex);
- }
+ public int getAnchorOffset() {
+ return anchorOffset;
}
-
+
private boolean resolveContext(CompilationInfo javac, JavadocContext jdctx) throws IOException {
jdctx.doc = javac.getDocument();
// find class context: class, method, ...
@@ -265,25 +173,22 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
jdctx.positions = (DocSourcePositions) trees.getSourcePositions();
return jdctx.positions != null;
}
-
+
private void analyzeContext(JavadocContext jdctx) {
TokenSequence<JavadocTokenId> jdts = jdctx.jdts;
if (jdts == null) {
return;
}
-
jdts.move(this.caretOffset);
if (!jdts.moveNext() && !jdts.movePrevious()) {
// XXX solve /***/
// provide block tags, inline tags, html
return;
}
-
if (this.caretOffset - jdts.offset() == 0) {
// if position in token == 0 resolve CC according to previous token
jdts.movePrevious();
}
-
switch (jdts.token().id()) {
case TAG:
resolveTagToken(jdctx);
@@ -309,7 +214,6 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
void resolveTagToken(JavadocContext jdctx) {
assert jdctx.jdts.token() != null;
assert jdctx.jdts.token().id() == JavadocTokenId.TAG;
-
DocTreePath tag = getTag(jdctx, caretOffset);
if (tag == null) {
// eg * description @
@@ -321,7 +225,7 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
resolveInlineTag(tag, jdctx);
}
}
-
+
void resolveBlockTag(DocTreePath tag, JavadocContext jdctx) {
int pos;
String prefix;
@@ -332,68 +236,64 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
prefix = ""; // NOI18N
pos = caretOffset;
}
-
- items.addAll(JavadocCompletionItem.addBlockTagItems(jdctx.handle.getKind(), prefix, pos));
- jdctx.anchorOffset = pos;
+ addBlockTagItems(jdctx.handle.getKind(), prefix, pos);
+ anchorOffset = pos;
}
-
+
void resolveInlineTag(DocTreePath tag, JavadocContext jdctx) {
int pos;
String prefix;
if (tag != null) {
pos = (int) jdctx.positions.getStartPosition(jdctx.javac.getCompilationUnit(), jdctx.comment, tag.getLeaf()) + 1;
prefix = JavadocCompletionUtils.getCharSequence(jdctx.doc, pos, caretOffset).toString();
- jdctx.anchorOffset = pos;
+ anchorOffset = pos;
} else {
pos = caretOffset;
prefix = ""; // NOI18N
- jdctx.anchorOffset = pos;
+ anchorOffset = pos;
}
- items.addAll(JavadocCompletionItem.addInlineTagItems(jdctx.handle.getKind(), prefix, pos));
+ addInlineTagItems(jdctx.handle.getKind(), prefix, pos);
}
private int skipWhitespacesBackwards(final JavadocContext jdctx, final int offset) {
- jdctx.jdts.move(offset);
-
- while (jdctx.jdts.movePrevious()) {
+ if (jdctx.jdts.move(offset) == 0 || !jdctx.jdts.moveNext()) {
+ jdctx.jdts.movePrevious();
+ }
+ do {
Token t = jdctx.jdts.token();
-
- if (t.id() != JavadocTokenId.OTHER_TEXT) return jdctx.jdts.offset();
-
+ if (t.id() != JavadocTokenId.OTHER_TEXT) {
+ return jdctx.jdts.offset();
+ }
CharSequence text = t.text();
-
for (int i = 0; i < text.length(); i++) {
if (!Character.isWhitespace(text.charAt(i))) {
//XXX: does not handle the leading '*' correctly
- return jdctx.jdts.offset();
+ return jdctx.jdts.offset();
}
}
- }
-
+ } while (jdctx.jdts.movePrevious());
return jdctx.jdts.moveNext() ? jdctx.jdts.offset() : offset;
}
-
+
private DocTreePath getTag(final JavadocContext jdctx, final int offset) {
final DocTreePath[] result = new DocTreePath[1];
final int normalizedOffset = skipWhitespacesBackwards(jdctx, offset);
new DocTreePathScanner<Void, Void>() {
- @Override public Void scan(DocTree node, Void p) {
- if ( node != null
- && jdctx.positions.getStartPosition(jdctx.javac.getCompilationUnit(), jdctx.comment, node) <= normalizedOffset
- && jdctx.positions.getEndPosition(jdctx.javac.getCompilationUnit(), jdctx.comment, node) >= normalizedOffset) {
- result[0] = new DocTreePath(getCurrentPath(), node);
+ @Override
+ public Void scan(DocTree node, Void p) {
+ if (node != null && jdctx.positions.getStartPosition(jdctx.javac.getCompilationUnit(), jdctx.comment, node) <= normalizedOffset && jdctx.positions.getEndPosition(jdctx.javac.getCompilationUnit(), jdctx.comment, node) >= normalizedOffset) {
+ final DocTreePath docTreePath = new DocTreePath(getCurrentPath(), node);
+ if (JavadocCompletionUtils.isBlockTag(docTreePath) || JavadocCompletionUtils.isInlineTag(docTreePath)) {
+ result[0] = docTreePath;
+ }
return super.scan(node, p);
}
-
return null;
}
}.scan(new DocTreePath(jdctx.javadocFor, jdctx.comment), null);
-
return result[0];
}
-
- private static final Set<ElementKind> EXECUTABLE = EnumSet.of(ElementKind.METHOD, ElementKind.CONSTRUCTOR);
-
+
void resolveIdent(JavadocContext jdctx) {
TokenSequence<JavadocTokenId> jdts = jdctx.jdts;
assert jdts.token() != null;
@@ -402,13 +302,11 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
// START -> TAG OT(WS+) MEMBER_SELECT|CLASS_SELECT
// CLASS_SELECT -> IDENT | IDENT DOT CLASS_SELECT | IDENT MEMBER_SELECT
// MEMBER_SELECT -> HASH IDENT OT('(')
-
// @see org.Clazz#meth(int p, int q)
// TAG OT(' ') IDENT DOT IDENT HASH IDENT OT('(') IDENT OT(' ') IDENT OT(', ') IDENT OT(' ') IDENT OT(')\n...')
// @see Clazz#meth(int p, int q)
// @see #meth(int p, int q)
// @see Clazz.NestedClazz
-
// Parenthesis content:
// param types not neccessary to be imported or fqn!!!
// param types may be fqn
@@ -416,56 +314,57 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
// params may contain name but they not necessary match the real names
// param list may contain spaces
// no space allowed between member and parenthesis
-
DocTreePath tag = getTag(jdctx, caretOffset);
if (tag != null) {
insideTag(tag, jdctx);
}
}
-
+
void resolveDotToken(JavadocContext jdctx) {
assert jdctx.jdts.token() != null;
assert jdctx.jdts.token().id() == JavadocTokenId.DOT;
-
DocTreePath tag = getTag(jdctx, caretOffset);
if (tag != null) {
insideTag(tag, jdctx);
}
}
-
+
void resolveHashToken(JavadocContext jdctx) {
assert jdctx.jdts.token() != null;
assert jdctx.jdts.token().id() == JavadocTokenId.HASH;
-
DocTreePath tag = getTag(jdctx, caretOffset);
if (tag != null) {
insideTag(tag, jdctx);
}
}
-
+
void resolveHTMLToken(JavadocContext jdctx) {
assert jdctx.jdts.token() != null;
assert jdctx.jdts.token().id() == JavadocTokenId.HTML_TAG;
-
DocTreePath tag = getTag(jdctx, caretOffset);
- if (tag != null && tag.getLeaf().getKind() == Kind.PARAM) {
+ if (tag != null && JavadocCompletionUtils.normalizedKind(tag.getLeaf()) == DocTree.Kind.PARAM) {
// type param
insideParamTag(tag, jdctx);
}
}
-
+
private void insideTag(DocTreePath tag, JavadocContext jdctx) {
switch (JavadocCompletionUtils.normalizedKind(tag.getLeaf())) {
case IDENTIFIER:
- if (tag.getParentPath() == null || tag.getParentPath().getLeaf().getKind() != Kind.PARAM)
+ if (tag.getParentPath() == null || tag.getParentPath().getLeaf().getKind() != DocTree.Kind.PARAM) {
break;
+ }
tag = tag.getParentPath();
- //intentional fall-through:
+ //intentional fall-through:
case PARAM:
insideParamTag(tag, jdctx);
break;
- case SEE: case THROWS: case VALUE:
- case LINK: case LINK_PLAIN://XXX: was only unclosed???
+ case SEE:
+ case THROWS:
+ case VALUE:
+ case LINK:
+ case LINK_PLAIN:
+ //XXX: was only unclosed???
insideSeeTag(tag, jdctx);
break;
case REFERENCE:
@@ -473,19 +372,17 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
break;
}
}
-
+
private void insideSeeTag(DocTreePath tag, JavadocContext jdctx) {
TokenSequence<JavadocTokenId> jdts = jdctx.jdts;
assert jdts.token() != null;
int start = (int) jdctx.positions.getStartPosition(jdctx.javac.getCompilationUnit(), jdctx.comment, tag.getLeaf());
-
- boolean isThrowsKind = JavadocCompletionUtils.normalizedKind(tag.getLeaf()) == Kind.THROWS;
+ boolean isThrowsKind = JavadocCompletionUtils.normalizedKind(tag.getLeaf()) == DocTree.Kind.THROWS;
if (isThrowsKind && !(EXECUTABLE.contains(jdctx.commentFor.getKind()))) {
// illegal tag in this context
return;
}
-
- jdts.move(start + (JavadocCompletionUtils.isBlockTag(tag)? 0: 1));
+ jdts.move(start + (JavadocCompletionUtils.isBlockTag(tag) ? 0 : 1));
// @see|@link|@throws
if (!jdts.moveNext() || caretOffset <= jdts.offset() + jdts.token().length()) {
return;
@@ -494,53 +391,44 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
if (!jdts.moveNext() || caretOffset <= jdts.offset()) {
return;
}
-
boolean noPrefix = false;
-
if (caretOffset <= jdts.offset() + jdts.token().length()) {
int pos = caretOffset - jdts.offset();
CharSequence cs = jdts.token().text();
- cs = pos < cs.length()? cs.subSequence(0, pos): cs;
-
- if (JavadocCompletionUtils.isWhiteSpace(cs)
- || JavadocCompletionUtils.isLineBreak(jdts.token(), pos)) {
+ cs = pos < cs.length() ? cs.subSequence(0, pos) : cs;
+ if (JavadocCompletionUtils.isWhiteSpace(cs) || JavadocCompletionUtils.isLineBreak(jdts.token(), pos)) {
noPrefix = true;
} else {
// broken syntax
return;
}
- } else if (! (JavadocCompletionUtils.isWhiteSpace(jdts.token())
- || JavadocCompletionUtils.isLineBreak(jdts.token()) )) {
+ } else if (!(JavadocCompletionUtils.isWhiteSpace(jdts.token()) || JavadocCompletionUtils.isLineBreak(jdts.token()))) {
// not java reference
return;
} else if (jdts.moveNext()) {
int end = (int) jdctx.positions.getEndPosition(jdctx.javac.getCompilationUnit(), jdctx.comment, tag.getLeaf());
insideReference(JavadocCompletionUtils.normalizedKind(tag.getLeaf()), jdts.offset(), end, jdctx);
}
-
if (noPrefix) {
// complete all types + members
-
if (isThrowsKind) {
completeThrowsOrPkg(null, "", caretOffset, jdctx); // NOI18N
} else {
completeClassOrPkg(null, "", caretOffset, jdctx); // NOI18N
}
- jdctx.anchorOffset = caretOffset;
- return;
+ anchorOffset = caretOffset;
}
}
-
+
private void insideReference(DocTreePath tag, JavadocContext jdctx) {
ReferenceTree ref = (ReferenceTree) tag.getLeaf();
- Kind kind = tag.getParentPath().getLeaf().getKind();
+ DocTree.Kind kind = tag.getParentPath().getLeaf().getKind();
int start = (int) jdctx.positions.getStartPosition(jdctx.javac.getCompilationUnit(), jdctx.comment, ref);
- int end = (int) jdctx.positions.getEndPosition(jdctx.javac.getCompilationUnit(), jdctx.comment, ref);
-
+ int end = (int) jdctx.positions.getEndPosition(jdctx.javac.getCompilationUnit(), jdctx.comment, ref);
insideReference(kind, start, end, jdctx);
}
- private void insideReference(Kind enclosingKind, int start, int end, JavadocContext jdctx) {
+ private void insideReference(DocTree.Kind enclosingKind, int start, int end, JavadocContext jdctx) {
// complete type
CharSequence cs = JavadocCompletionUtils.getCharSequence(jdctx.doc, start, end);
StringBuilder sb = new StringBuilder();
@@ -550,24 +438,20 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
// complete class member
String prefix = sb.toString();
int substitutionOffset = caretOffset - sb.length();
- jdctx.anchorOffset = substitutionOffset;
+ anchorOffset = substitutionOffset;
if (i == 0) {
- if (enclosingKind == Kind.VALUE) {
+ if (enclosingKind == DocTree.Kind.VALUE) {
addLocalConstants(jdctx, prefix, substitutionOffset);
} else {
addLocalMembersAndVars(jdctx, prefix, substitutionOffset);
}
} else {
- TypeElement scopeType = jdctx.commentFor.getKind().isClass() || jdctx.commentFor.getKind().isInterface() ? (TypeElement) jdctx.commentFor
- : jdctx.javac.getElementUtilities().enclosingTypeElement(jdctx.commentFor);
- TypeMirror type =
- jdctx.javac.getTreeUtilities().parseType(cs.subSequence(0, i).toString(), scopeType);
- if (enclosingKind == Kind.VALUE) {
+ TypeElement scopeType = jdctx.commentFor.getKind().isClass() || jdctx.commentFor.getKind().isInterface() ? (TypeElement) jdctx.commentFor : jdctx.javac.getElementUtilities().enclosingTypeElement(jdctx.commentFor);
+ TypeMirror type = jdctx.javac.getTreeUtilities().parseType(cs.subSequence(0, i).toString(), scopeType);
+ if (enclosingKind == DocTree.Kind.VALUE) {
addMemberConstants(jdctx, prefix, substitutionOffset, type);
} else {
- addMembers(jdctx, prefix, substitutionOffset, type, jdctx.javac.getTypes().asElement(type),
- EnumSet.<ElementKind>of(ENUM_CONSTANT, FIELD, METHOD, CONSTRUCTOR),
- null);
+ addMembers(jdctx, prefix, substitutionOffset, type, jdctx.javac.getTypes().asElement(type), EnumSet.<ElementKind>of(ElementKind.ENUM_CONSTANT, ElementKind.FIELD, ElementKind.METHOD, ElementKind.CONSTRUCTOR), null);
}
}
return;
@@ -576,8 +460,8 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
String prefix = sb.toString();
String fqn = cs.subSequence(0, i).toString();
int substitutionOffset = caretOffset - sb.length();
- jdctx.anchorOffset = substitutionOffset;
- if (enclosingKind == Kind.THROWS) {
+ anchorOffset = substitutionOffset;
+ if (enclosingKind == DocTree.Kind.THROWS) {
completeThrowsOrPkg(fqn, prefix, substitutionOffset, jdctx);
} else {
completeClassOrPkg(fqn, prefix, substitutionOffset, jdctx);
@@ -591,19 +475,18 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
String prefix = sb.toString();
String fqn = null;
int substitutionOffset = caretOffset - sb.length();
- jdctx.anchorOffset = substitutionOffset;
- if (enclosingKind == Kind.THROWS) {
+ anchorOffset = substitutionOffset;
+ if (enclosingKind == DocTree.Kind.THROWS) {
completeThrowsOrPkg(fqn, prefix, substitutionOffset, jdctx);
} else {
completeClassOrPkg(fqn, prefix, substitutionOffset, jdctx);
}
}
-
+
private void insideParamTag(DocTreePath tag, JavadocContext jdctx) {
TokenSequence<JavadocTokenId> jdts = jdctx.jdts;
assert jdts.token() != null;
int start = (int) jdctx.positions.getStartPosition(jdctx.javac.getCompilationUnit(), jdctx.comment, tag.getLeaf());
-
jdts.move(start);
// @param
if (!jdts.moveNext() || caretOffset <= jdts.offset() + jdts.token().length()) {
@@ -613,16 +496,13 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
if (!jdts.moveNext() || caretOffset <= jdts.offset()) {
return;
}
-
if (caretOffset <= jdts.offset() + jdts.token().length()) {
int pos = caretOffset - jdts.offset();
CharSequence cs = jdts.token().text();
- cs = pos < cs.length()? cs.subSequence(0, pos): cs;
-
- if (JavadocCompletionUtils.isWhiteSpace(cs)
- || JavadocCompletionUtils.isLineBreak(jdts.token(), pos)) {
+ cs = pos < cs.length() ? cs.subSequence(0, pos) : cs;
+ if (JavadocCompletionUtils.isWhiteSpace(cs) || JavadocCompletionUtils.isLineBreak(jdts.token(), pos)) {
// none prefix
- jdctx.anchorOffset = caretOffset;
+ anchorOffset = caretOffset;
completeParamName(tag, "", caretOffset, jdctx); // NOI18N
return;
} else {
@@ -630,7 +510,6 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
return;
}
}
-
jdts.moveNext(); // param name
if (!(jdts.token().id() == JavadocTokenId.IDENT || jdts.token().id() == JavadocTokenId.HTML_TAG)) {
// broken syntax
@@ -638,24 +517,21 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
}
if (caretOffset <= jdts.offset() + jdts.token().length()) {
CharSequence prefix = jdts.token().text().subSequence(0, caretOffset - jdts.offset());
- jdctx.anchorOffset = jdts.offset();
+ anchorOffset = jdts.offset();
completeParamName(tag, prefix.toString(), jdts.offset(), jdctx);
- return;
}
}
-
+
private void completeParamName(DocTreePath tag, String prefix, int substitutionOffset, JavadocContext jdctx) {
if (EXECUTABLE.contains(jdctx.commentFor.getKind())) {
List<? extends DocTree> blockTags = jdctx.comment.getBlockTags();
ExecutableElement method = (ExecutableElement) jdctx.commentFor;
for (VariableElement param : method.getParameters()) {
String name = param.getSimpleName().toString();
-
if (!containsParam(blockTags, name) && name.startsWith(prefix)) {
- items.add(JavadocCompletionItem.createNameItem(name, substitutionOffset));
+ items.add(factory.createNameItem(name, substitutionOffset));
}
}
-
completeTypeVarName(jdctx.commentFor, prefix, substitutionOffset);
} else if (jdctx.commentFor.getKind().isClass() || jdctx.commentFor.getKind().isInterface()) {
completeTypeVarName(jdctx.commentFor, prefix, substitutionOffset);
@@ -664,9 +540,9 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
private boolean containsParam(List<? extends DocTree> blockTags, String name) {
for (DocTree blockTag : blockTags) {
- if(blockTag.getKind() == Kind.PARAM) {
+ if (blockTag.getKind() == DocTree.Kind.PARAM) {
ParamTree param = (ParamTree) blockTag;
- if(name.contentEquals(param.getName().getName())) {
+ if (name.contentEquals(param.getName().getName())) {
return true;
}
}
@@ -683,58 +559,49 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
return;
}
}
- List<? extends TypeParameterElement> tparams = (forElement.getKind().isClass() || forElement.getKind().isInterface())
- ? ((TypeElement) forElement).getTypeParameters()
- : ((ExecutableElement) forElement).getTypeParameters();
-
+ List<? extends TypeParameterElement> tparams = (forElement.getKind().isClass() || forElement.getKind().isInterface()) ? ((TypeElement) forElement).getTypeParameters() : ((ExecutableElement) forElement).getTypeParameters();
for (TypeParameterElement typeVariable : tparams) {
String name = typeVariable.getSimpleName().toString();
if (name.startsWith(prefix)) {
- items.add(JavadocCompletionItem.createNameItem(
- '<' + name + '>', substitutionOffset));
+ items.add(factory.createNameItem('<' + name + '>', substitutionOffset));
}
}
}
-
+
private void completeClassOrPkg(String fqn, String prefix, int substitutionOffset, JavadocContext jdctx) {
String pkgPrefix;
if (fqn == null) {
pkgPrefix = prefix;
- addTypes(EnumSet.<ElementKind>of(CLASS, INTERFACE, ENUM, ANNOTATION_TYPE),
- null, null, prefix, substitutionOffset, jdctx);
-
+ addTypes(EnumSet.<ElementKind>of(ElementKind.CLASS, ElementKind.INTERFACE, ElementKind.ENUM, ElementKind.ANNOTATION_TYPE), null, null, prefix, substitutionOffset, jdctx);
} else {
pkgPrefix = fqn + '.' + prefix;
PackageElement pkgElm = jdctx.javac.getElements().getPackageElement(fqn);
if (pkgElm != null) {
- addPackageContent(pkgElm,
- EnumSet.<ElementKind>of(CLASS, INTERFACE, ENUM, ANNOTATION_TYPE),
- null, null, prefix, substitutionOffset, jdctx);
+ addPackageContent(pkgElm, EnumSet.<ElementKind>of(ElementKind.CLASS, ElementKind.INTERFACE, ElementKind.ENUM, ElementKind.ANNOTATION_TYPE), null, null, prefix, substitutionOffset, jdctx);
}
-
TypeElement typeElm = jdctx.javac.getElements().getTypeElement(fqn);
if (typeElm != null) {
// inner classes
- addInnerClasses(typeElm,
- EnumSet.<ElementKind>of(CLASS, INTERFACE, ENUM, ANNOTATION_TYPE),
- null, null, prefix, substitutionOffset, jdctx);
+ addInnerClasses(typeElm, EnumSet.<ElementKind>of(ElementKind.CLASS, ElementKind.INTERFACE, ElementKind.ENUM, ElementKind.ANNOTATION_TYPE), null, null, prefix, substitutionOffset, jdctx);
+ }
+ }
+ for (String pkgName : jdctx.javac.getClasspathInfo().getClassIndex().getPackageNames(pkgPrefix, true, EnumSet.allOf(ClassIndex.SearchScope.class))) {
+ if (pkgName.length() > 0 && !Utilities.isExcluded(pkgName + ".")) {
+ items.add(factory.createPackageItem(pkgName, substitutionOffset));
}
}
-
- for (String pkgName : jdctx.javac.getClasspathInfo().getClassIndex().getPackageNames(pkgPrefix, true, EnumSet.allOf(ClassIndex.SearchScope.class)))
- if (pkgName.length() > 0 && !Utilities.isExcluded(pkgName + "."))
- items.add(JavaCompletionItem.createPackageItem(pkgName, substitutionOffset, false));
}
-
+
private void completeThrowsOrPkg(String fqn, String prefix, int substitutionOffset, JavadocContext jdctx) {
final Elements elements = jdctx.javac.getElements();
final Set<Element> excludes = new HashSet<Element>();
String pkgPrefix;
-
- // add declared Throwables
+ // add declared Throwables
ExecutableElement method = (ExecutableElement) jdctx.commentFor;
for (TypeMirror type : method.getThrownTypes()) {
- if (type.getKind() != TypeKind.DECLARED) continue;
+ if (type.getKind() != TypeKind.DECLARED) {
+ continue;
+ }
TypeElement clazz = (TypeElement) ((DeclaredType) type).asElement();
String typeName = clazz.getSimpleName().toString();
if (startsWith(typeName, prefix)) {
@@ -743,51 +610,38 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
if (typeElement == null) {
continue;
}
- items.add(JavaCompletionItem.createTypeItem(
- jdctx.javac, typeElement, (DeclaredType) typeElement.asType(),
- substitutionOffset, /*XXX:*/typeName != qualTypeName ? jdctx.getReferencesCount() : null,
- elements.isDeprecated(typeElement), false, false, false, true, false, null));
+ items.add(factory.createJavaTypeItem(jdctx.javac, typeElement, (DeclaredType) typeElement.asType(), substitutionOffset, /*XXX:*/ typeName != qualTypeName ? jdctx.getReferencesCount() : null, elements.isDeprecated(typeElement), true));
excludes.add(typeElement);
}
}
-
- // add other Throwables
+ // add other Throwables
if (fqn == null) {
pkgPrefix = prefix;
- addTypes(EnumSet.<ElementKind>of(CLASS),
- findDeclaredType("java.lang.Throwable", elements), // NOI18N
- excludes, prefix, substitutionOffset, jdctx);
-
+ addTypes(EnumSet.<ElementKind>of(ElementKind.CLASS), findDeclaredType("java.lang.Throwable", elements), // NOI18N
+ excludes, prefix, substitutionOffset, jdctx);
} else {
pkgPrefix = fqn + '.' + prefix;
-
PackageElement pkgElm = elements.getPackageElement(fqn);
if (pkgElm != null) {
- addPackageContent(pkgElm,
- EnumSet.<ElementKind>of(CLASS),
- findDeclaredType("java.lang.Throwable", elements), // NOI18N
- excludes, prefix, substitutionOffset, jdctx);
+ addPackageContent(pkgElm, EnumSet.<ElementKind>of(ElementKind.CLASS), findDeclaredType("java.lang.Throwable", elements), // NOI18N
+ excludes, prefix, substitutionOffset, jdctx);
}
-
TypeElement typeElm = elements.getTypeElement(fqn);
if (typeElm != null) {
// inner classes
- addInnerClasses(typeElm,
- EnumSet.<ElementKind>of(CLASS),
- findDeclaredType("java.lang.Throwable", elements), // NOI18N
- excludes, prefix, substitutionOffset, jdctx);
+ addInnerClasses(typeElm, EnumSet.<ElementKind>of(ElementKind.CLASS), findDeclaredType("java.lang.Throwable", elements), // NOI18N
+ excludes, prefix, substitutionOffset, jdctx);
}
}
-
-
// add packages
-
- for (String pkgName : jdctx.javac.getClasspathInfo().getClassIndex().getPackageNames(pkgPrefix, true, EnumSet.allOf(ClassIndex.SearchScope.class)))
- if (pkgName.length() > 0)
- items.add(JavaCompletionItem.createPackageItem(pkgName, substitutionOffset, false));
+ for (String pkgName : jdctx.javac.getClasspathInfo().getClassIndex().getPackageNames(pkgPrefix, true, EnumSet.allOf(ClassIndex.SearchScope.class))) {
+ if (pkgName.length() > 0) {
+ items.add(factory.createPackageItem(pkgName, substitutionOffset));
+ }
+ }
}
-
- private static DeclaredType findDeclaredType(CharSequence fqn, Elements elements) {
+
+ private DeclaredType findDeclaredType(CharSequence fqn, Elements elements) {
TypeElement re = elements.getTypeElement(fqn);
if (re != null) {
TypeMirror asType = re.asType();
@@ -797,88 +651,100 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
}
return null;
}
-
+
+ private void addBlockTagItems(ElementKind kind, String prefix, int startOffset) {
+ List<TagEntry> tags = TagRegistery.getDefault().getTags(kind, false);
+ for (TagEntry tagEntry : tags) {
+ if (tagEntry.name.startsWith(prefix)) {
+ items.add(factory.createTagItem(tagEntry.name, startOffset));
+ }
+ }
+ }
+
+ private void addInlineTagItems(ElementKind kind, String prefix, int startOffset) {
+ List<TagEntry> tags = TagRegistery.getDefault().getTags(kind, true);
+ for (TagEntry tagEntry : tags) {
+ if (tagEntry.name.startsWith(prefix)) {
+ items.add(factory.createTagItem(tagEntry.name, startOffset));
+ }
+ }
+ }
+
private void addMembers(final JavadocContext env, final String prefix, final int substitutionOffset, final TypeMirror type, final Element elem, final EnumSet<ElementKind> kinds, final DeclaredType baseType) {
- Set<? extends TypeMirror> smartTypes = /*queryType == COMPLETION_QUERY_TYPE ? env.getSmartTypes() :*/ null;
+ // Set<? extends TypeMirror> smartTypes = /*queryType == COMPLETION_QUERY_TYPE ? env.getSmartTypes() :*/ null;
final CompilationInfo controller = env.javac;
final Trees trees = controller.getTrees();
final Elements elements = controller.getElements();
final Types types = controller.getTypes();
final TreeUtilities tu = controller.getTreeUtilities();
final ElementUtilities eu = controller.getElementUtilities();
- TypeElement typeElem = type.getKind() == TypeKind.DECLARED ? (TypeElement)((DeclaredType)type).asElement() : null;
-// final boolean isStatic = elem != null && (elem.getKind().isClass() || elem.getKind().isInterface() || elem.getKind() == TYPE_PARAMETER);
-// final boolean isSuperCall = elem != null && elem.getKind().isField() && elem.getSimpleName().contentEquals(SUPER_KEYWORD);
+ TypeElement typeElem = type.getKind() == TypeKind.DECLARED ? (TypeElement) ((DeclaredType) type).asElement() : null;
+ // final boolean isStatic = elem != null && (elem.getKind().isClass() || elem.getKind().isInterface() || elem.getKind() == TYPE_PARAMETER);
+ // final boolean isSuperCall = elem != null && elem.getKind().isField() && elem.getSimpleName().contentEquals(SUPER_KEYWORD);
Element docelm = env.handle.resolve(controller);
TreePath docpath = docelm != null ? trees.getPath(docelm) : null;
final Scope scope = docpath != null ? trees.getScope(docpath) : tu.scopeFor(caretOffset);
TypeElement enclClass = scope.getEnclosingClass();
- final TypeMirror enclType = enclClass != null ? enclClass.asType() : null;
+ // final TypeMirror enclType = enclClass != null ? enclClass.asType() : null;
ElementUtilities.ElementAcceptor acceptor = new ElementUtilities.ElementAcceptor() {
public boolean accept(Element e, TypeMirror t) {
switch (e.getKind()) {
case FIELD:
String name = e.getSimpleName().toString();
- return Utilities.startsWith(name, prefix) && !CLASS_KEYWORD.equals(name)
- && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e));
-// &&
-// isOfKindAndType(asMemberOf(e, t, types), e, kinds, baseType, scope, trees, types) &&
-// tu.isAccessible(scope, e, isSuperCall && enclType != null ? enclType : t) &&
-// (!isStatic || e.getModifiers().contains(Modifier.STATIC)) &&
-// (isStatic || !e.getSimpleName().contentEquals(THIS_KEYWORD)) &&
-// ((isStatic && !inImport) /*|| !e.getSimpleName().contentEquals(CLASS_KEYWORD)*/);
+ return Utilities.startsWith(name, prefix) && !CLASS_KEYWORD.equals(name) && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e));
+ // &&
+ // isOfKindAndType(asMemberOf(e, t, types), e, kinds, baseType, scope, trees, types) &&
+ // tu.isAccessible(scope, e, isSuperCall && enclType != null ? enclType : t) &&
+ // (!isStatic || e.getModifiers().contains(Modifier.STATIC)) &&
+ // (isStatic || !e.getSimpleName().contentEquals(THIS_KEYWORD)) &&
+ // ((isStatic && !inImport) /*|| !e.getSimpleName().contentEquals(CLASS_KEYWORD)*/);
case ENUM_CONSTANT:
- return Utilities.startsWith(e.getSimpleName().toString(), prefix) &&
- (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) &&
-// isOfKindAndType(asMemberOf(e, t, types), e, kinds, baseType, scope, trees, types) &&
- trees.isAccessible(scope, e, (DeclaredType)t);
+ return Utilities.startsWith(e.getSimpleName().toString(), prefix) && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) && // isOfKindAndType(asMemberOf(e, t, types), e, kinds, baseType, scope, trees, types) &&
+ trees.isAccessible(scope, e, (DeclaredType) t);
case METHOD:
String sn = e.getSimpleName().toString();
- return Utilities.startsWith(sn, prefix) &&
- (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) &&
- (!Utilities.isExcludeMethods() || !Utilities.isExcluded(eu.getElementName(e.getEnclosingElement(), true) + "." + sn)); //NOI18N
-// &&
-// isOfKindAndType(((ExecutableType)asMemberOf(e, t, types)).getReturnType(), e, kinds, baseType, scope, trees, types) &&
-// (isSuperCall && e.getModifiers().contains(PROTECTED) || tu.isAccessible(scope, e, isSuperCall && enclType != null ? enclType : t)) &&
-// (!isStatic || e.getModifiers().contains(Modifier.STATIC));
-// case CLASS:
-// case ENUM:
-// case INTERFACE:
-// case ANNOTATION_TYPE:
-// return Utilities.startsWith(e.getSimpleName().toString(), prefix) &&
-// (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) &&
-// isOfKindAndType(e.asType(), e, kinds, baseType, scope, trees, types) &&
-// tu.isAccessible(scope, e, t) && isStatic;
+ return Utilities.startsWith(sn, prefix) && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) && (!Utilities.isExcludeMethods() || !Utilities.isExcluded(eu.getElementName(e.getEnclosingElement(), true) + "." + sn)); //NOI18N
+ // &&
+ // isOfKindAndType(((ExecutableType)asMemberOf(e, t, types)).getReturnType(), e, kinds, baseType, scope, trees, types) &&
+ // (isSuperCall && e.getModifiers().contains(PROTECTED) || tu.isAccessible(scope, e, isSuperCall && enclType != null ? enclType : t)) &&
+ // (!isStatic || e.getModifiers().contains(Modifier.STATIC));
+ // case CLASS:
+ // case ENUM:
+ // case INTERFACE:
+ // case ANNOTATION_TYPE:
+ // return Utilities.startsWith(e.getSimpleName().toString(), prefix) &&
+ // (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) &&
+ // isOfKindAndType(e.asType(), e, kinds, baseType, scope, trees, types) &&
+ // tu.isAccessible(scope, e, t) && isStatic;
case CONSTRUCTOR:
- return (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) &&
-// isOfKindAndType(e.getEnclosingElement().asType(), e, kinds, baseType, scope, trees, types) &&
- (trees.isAccessible(scope, e, (DeclaredType)t) || (elem.getModifiers().contains(Modifier.ABSTRACT) && !e.getModifiers().contains(Modifier.PRIVATE)));
-// &&
-// isStatic;
+ return (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) && // isOfKindAndType(e.getEnclosingElement().asType(), e, kinds, baseType, scope, trees, types) &&
+ (trees.isAccessible(scope, e, (DeclaredType) t) || (elem.getModifiers().contains(Modifier.ABSTRACT) && !e.getModifiers().contains(Modifier.PRIVATE)));
+ // &&
+ // isStatic;
}
return false;
}
};
- for(Element e : controller.getElementUtilities().getMembers(type, acceptor)) {
+ for (Element e : controller.getElementUtilities().getMembers(type, acceptor)) {
switch (e.getKind()) {
case ENUM_CONSTANT:
case FIELD:
- TypeMirror tm = type.getKind() == TypeKind.DECLARED ? types.asMemberOf((DeclaredType)type, e) : e.asType();
- items.add(JavaCompletionItem.createVariableItem(controller, (VariableElement) e, tm, null, substitutionOffset, null, typeElem != e.getEnclosingElement(), elements.isDeprecated(e), /*isOfSmartType(env, tm, smartTypes)*/false, -1, null));
+ TypeMirror tm = type.getKind() == TypeKind.DECLARED ? types.asMemberOf((DeclaredType) type, e) : e.asType();
+ items.add(factory.createJavaVariableItem(controller, (VariableElement) e, tm, substitutionOffset, typeElem != e.getEnclosingElement(), elements.isDeprecated(e)));
break;
case CONSTRUCTOR:
case METHOD:
- ExecutableType et = (ExecutableType)(type.getKind() == TypeKind.DECLARED ? types.asMemberOf((DeclaredType)type, e) : e.asType());
-// items.add(JavaCompletionItem.createExecutableItem((ExecutableElement) e, et, substitutionOffset, typeElem != e.getEnclosingElement(), elements.isDeprecated(e), inImport, /*isOfSmartType(env, et.getReturnType(), smartTypes)*/false));
- items.add(JavadocCompletionItem.createExecutableItem(controller, (ExecutableElement) e, et, substitutionOffset, typeElem != e.getEnclosingElement(), elements.isDeprecated(e)));
+ ExecutableType et = (ExecutableType) (type.getKind() == TypeKind.DECLARED ? types.asMemberOf((DeclaredType) type, e) : e.asType());
+ // items.add(JavaCompletionItem.createExecutableItem((ExecutableElement) e, et, substitutionOffset, typeElem != e.getEnclosingElement(), elements.isDeprecated(e), inImport, /*isOfSmartType(env, et.getReturnType(), smartTypes)*/false));
+ items.add(factory.createJavadocExecutableItem(controller, (ExecutableElement) e, et, substitutionOffset, typeElem != e.getEnclosingElement(), elements.isDeprecated(e)));
break;
-// case CLASS:
-// case ENUM:
-// case INTERFACE:
-// case ANNOTATION_TYPE:
-// DeclaredType dt = (DeclaredType)(type.getKind() == TypeKind.DECLARED ? types.asMemberOf((DeclaredType)type, e) : e.asType());
-// results.add(JavaCompletionItem.createTypeItem((TypeElement)e, dt, anchorOffset, false, elements.isDeprecated(e), insideNew, false));
-// break;
+ // case CLASS:
+ // case ENUM:
+ // case INTERFACE:
+ // case ANNOTATION_TYPE:
+ // DeclaredType dt = (DeclaredType)(type.getKind() == TypeKind.DECLARED ? types.asMemberOf((DeclaredType)type, e) : e.asType());
+ // results.add(JavaCompletionItem.createTypeItem((TypeElement)e, dt, anchorOffset, false, elements.isDeprecated(e), insideNew, false));
+ // break;
}
}
}
@@ -889,7 +755,7 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
final Elements elements = controller.getElements();
final Types types = controller.getTypes();
final TreeUtilities tu = controller.getTreeUtilities();
- TypeElement typeElem = type.getKind() == TypeKind.DECLARED ? (TypeElement)((DeclaredType)type).asElement() : null;
+ TypeElement typeElem = type.getKind() == TypeKind.DECLARED ? (TypeElement) ((DeclaredType) type).asElement() : null;
Element docelm = env.handle.resolve(controller);
TreePath docpath = docelm != null ? trees.getPath(docelm) : null;
final Scope scope = docpath != null ? trees.getScope(docpath) : tu.scopeFor(caretOffset);
@@ -898,24 +764,19 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
switch (e.getKind()) {
case FIELD:
String name = e.getSimpleName().toString();
- return ((VariableElement)e).getConstantValue() != null
- && Utilities.startsWith(name, prefix) && !CLASS_KEYWORD.equals(name)
- && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e));
+ return ((VariableElement) e).getConstantValue() != null && Utilities.startsWith(name, prefix) && !CLASS_KEYWORD.equals(name) && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e));
case ENUM_CONSTANT:
- return ((VariableElement)e).getConstantValue() != null &&
- Utilities.startsWith(e.getSimpleName().toString(), prefix) &&
- (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) &&
- trees.isAccessible(scope, e, (DeclaredType)t);
+ return ((VariableElement) e).getConstantValue() != null && Utilities.startsWith(e.getSimpleName().toString(), prefix) && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) && trees.isAccessible(scope, e, (DeclaredType) t);
}
return false;
}
};
- for(Element e : controller.getElementUtilities().getMembers(type, acceptor)) {
+ for (Element e : controller.getElementUtilities().getMembers(type, acceptor)) {
switch (e.getKind()) {
case ENUM_CONSTANT:
case FIELD:
- TypeMirror tm = type.getKind() == TypeKind.DECLARED ? types.asMemberOf((DeclaredType)type, e) : e.asType();
- items.add(JavaCompletionItem.createVariableItem(controller, (VariableElement) e, tm, null, substitutionOffset, null, typeElem != e.getEnclosingElement(), elements.isDeprecated(e), /*isOfSmartType(env, tm, smartTypes)*/false, -1, null));
+ TypeMirror tm = type.getKind() == TypeKind.DECLARED ? types.asMemberOf((DeclaredType) type, e) : e.asType();
+ items.add(factory.createJavaVariableItem(controller, (VariableElement) e, tm, substitutionOffset, typeElem != e.getEnclosingElement(), elements.isDeprecated(e)));
break;
}
}
@@ -936,14 +797,9 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
switch (e.getKind()) {
case FIELD:
String name = e.getSimpleName().toString();
- return ((VariableElement)e).getConstantValue() != null
- && Utilities.startsWith(name, prefix) && !CLASS_KEYWORD.equals(name)
- && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e));
+ return ((VariableElement) e).getConstantValue() != null && Utilities.startsWith(name, prefix) && !CLASS_KEYWORD.equals(name) && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e));
case ENUM_CONSTANT:
- return ((VariableElement)e).getConstantValue() != null &&
- Utilities.startsWith(e.getSimpleName().toString(), prefix) &&
- (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) &&
- trees.isAccessible(scope, e, (DeclaredType)t);
+ return ((VariableElement) e).getConstantValue() != null && Utilities.startsWith(e.getSimpleName().toString(), prefix) && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) && trees.isAccessible(scope, e, (DeclaredType) t);
}
return false;
}
@@ -951,11 +807,11 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
for (Element e : controller.getElementUtilities().getLocalMembersAndVars(scope, acceptor)) {
switch (e.getKind()) {
case ENUM_CONSTANT:
- items.add(JavaCompletionItem.createVariableItem(controller, (VariableElement)e, e.asType(), null, substitutionOffset, null, scope.getEnclosingClass() != e.getEnclosingElement(), elements.isDeprecated(e), false/*isOfSmartType(env, e.asType(), smartTypes)*/, -1, null));
+ items.add(factory.createJavaVariableItem(controller, (VariableElement) e, e.asType(), substitutionOffset, scope.getEnclosingClass() != e.getEnclosingElement(), elements.isDeprecated(e)));
break;
case FIELD:
TypeMirror tm = asMemberOf(e, enclClass != null ? enclClass.asType() : null, types);
- items.add(JavaCompletionItem.createVariableItem(controller, (VariableElement)e, tm, null, substitutionOffset, null, scope.getEnclosingClass() != e.getEnclosingElement(), elements.isDeprecated(e), false/*isOfSmartType(env, tm, smartTypes)*/, -1, null));
+ items.add(factory.createJavaVariableItem(controller, (VariableElement) e, tm, substitutionOffset, scope.getEnclosingClass() != e.getEnclosingElement(), elements.isDeprecated(e)));
break;
}
}
@@ -970,77 +826,70 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
Element docelm = env.handle.resolve(controller);
TreePath docpath = docelm != null ? trees.getPath(docelm) : null;
final Scope scope = docpath != null ? trees.getScope(docpath) : tu.scopeFor(caretOffset);
- Set<? extends TypeMirror> smartTypes = null;
-// if (queryType == COMPLETION_QUERY_TYPE) {
-// smartTypes = env.getSmartTypes();
-// if (smartTypes != null) {
-// for (TypeMirror st : smartTypes) {
-// if (st.getKind().isPrimitive())
-// st = types.boxedClass((PrimitiveType)st).asType();
-// if (st.getKind() == TypeKind.DECLARED) {
-// final DeclaredType type = (DeclaredType)st;
-// final TypeElement element = (TypeElement)type.asElement();
-// if (withinScope(env, element))
-// continue;
-// final boolean isStatic = element.getKind().isClass() || element.getKind().isInterface();
-// final Set<? extends TypeMirror> finalSmartTypes = smartTypes;
-// ElementUtilities.ElementAcceptor acceptor = new ElementUtilities.ElementAcceptor() {
-// public boolean accept(Element e, TypeMirror t) {
-// return (!isStatic || e.getModifiers().contains(STATIC)) &&
-// Utilities.startsWith(e.getSimpleName().toString(), prefix) &&
-// tu.isAccessible(scope, e, t) &&
-// (e.getKind().isField() && isOfSmartType(env, ((VariableElement)e).asType(), finalSmartTypes) || e.getKind() == METHOD && isOfSmartType(env, ((ExecutableElement)e).getReturnType(), finalSmartTypes));
-// }
-// };
-// for (Element ee : controller.getElementUtilities().getMembers(type, acceptor)) {
-// if (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(ee))
-// results.add(JavaCompletionItem.createStaticMemberItem(type, ee, types.asMemberOf(type, ee), anchorOffset, elements.isDeprecated(ee)));
-// }
-// }
-// }
-// }
-// }
+ // Set<? extends TypeMirror> smartTypes = null;
+ // if (queryType == COMPLETION_QUERY_TYPE) {
+ // smartTypes = env.getSmartTypes();
+ // if (smartTypes != null) {
+ // for (TypeMirror st : smartTypes) {
+ // if (st.getKind().isPrimitive())
+ // st = types.boxedClass((PrimitiveType)st).asType();
+ // if (st.getKind() == TypeKind.DECLARED) {
+ // final DeclaredType type = (DeclaredType)st;
+ // final TypeElement element = (TypeElement)type.asElement();
+ // if (withinScope(env, element))
+ // continue;
+ // final boolean isStatic = element.getKind().isClass() || element.getKind().isInterface();
+ // final Set<? extends TypeMirror> finalSmartTypes = smartTypes;
+ // ElementUtilities.ElementAcceptor acceptor = new ElementUtilities.ElementAcceptor() {
+ // public boolean accept(Element e, TypeMirror t) {
+ // return (!isStatic || e.getModifiers().contains(STATIC)) &&
+ // Utilities.startsWith(e.getSimpleName().toString(), prefix) &&
+ // tu.isAccessible(scope, e, t) &&
+ // (e.getKind().isField() && isOfSmartType(env, ((VariableElement)e).asType(), finalSmartTypes) || e.getKind() == METHOD && isOfSmartType(env, ((ExecutableElement)e).getReturnType(), finalSmartTypes));
+ // }
+ // };
+ // for (Element ee : controller.getElementUtilities().getMembers(type, acceptor)) {
+ // if (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(ee))
+ // results.add(JavaCompletionItem.createStaticMemberItem(type, ee, types.asMemberOf(type, ee), anchorOffset, elements.isDeprecated(ee)));
+ // }
+ // }
+ // }
+ // }
+ // }
final TypeElement enclClass = scope.getEnclosingClass();
-// final boolean isStatic = enclClass == null ? false :
-// (tu.isStaticContext(scope) || (env.getPath().getLeaf().getKind() == Tree.Kind.BLOCK && ((BlockTree)env.getPath().getLeaf()).isStatic()));
-// final Collection<? extends Element> illegalForwardRefs = env.getForwardReferences();
- final ExecutableElement method = scope.getEnclosingMethod();
+ // final boolean isStatic = enclClass == null ? false :
+ // (tu.isStaticContext(scope) || (env.getPath().getLeaf().getKind() == Tree.Kind.BLOCK && ((BlockTree)env.getPath().getLeaf()).isStatic()));
+ // final Collection<? extends Element> illegalForwardRefs = env.getForwardReferences();
+ // final ExecutableElement method = scope.getEnclosingMethod();
ElementUtilities.ElementAcceptor acceptor = new ElementUtilities.ElementAcceptor() {
public boolean accept(Element e, TypeMirror t) {
switch (e.getKind()) {
case CONSTRUCTOR:
- return Utilities.startsWith(e.getEnclosingElement().getSimpleName().toString(), prefix) &&
- (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) &&
-// (!isStatic || e.getModifiers().contains(STATIC)) &&
- trees.isAccessible(scope, e, (DeclaredType)t);
-// case LOCAL_VARIABLE:
-// case EXCEPTION_PARAMETER:
-// case PARAMETER:
-// return Utilities.startsWith(e.getSimpleName().toString(), prefix) &&
-// (method == e.getEnclosingElement() || e.getModifiers().contains(FINAL) ||
-// (method == null && (e.getEnclosingElement().getKind() == INSTANCE_INIT ||
-// e.getEnclosingElement().getKind() == STATIC_INIT))) &&
-// !illegalForwardRefs.contains(e);
+ return Utilities.startsWith(e.getEnclosingElement().getSimpleName().toString(), prefix) && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) && // (!isStatic || e.getModifiers().contains(STATIC)) &&
+ trees.isAccessible(scope, e, (DeclaredType) t);
+ // case LOCAL_VARIABLE:
+ // case EXCEPTION_PARAMETER:
+ // case PARAMETER:
+ // return Utilities.startsWith(e.getSimpleName().toString(), prefix) &&
+ // (method == e.getEnclosingElement() || e.getModifiers().contains(FINAL) ||
+ // (method == null && (e.getEnclosingElement().getKind() == INSTANCE_INIT ||
+ // e.getEnclosingElement().getKind() == STATIC_INIT))) &&
+ // !illegalForwardRefs.contains(e);
case FIELD:
-// if (e.getSimpleName().contentEquals(THIS_KEYWORD) || e.getSimpleName().contentEquals(SUPER_KEYWORD))
-// return Utilities.startsWith(e.getSimpleName().toString(), prefix) && !isStatic;
+ // if (e.getSimpleName().contentEquals(THIS_KEYWORD) || e.getSimpleName().contentEquals(SUPER_KEYWORD))
+ // return Utilities.startsWith(e.getSimpleName().toString(), prefix) && !isStatic;
String name = e.getSimpleName().toString();
- return Utilities.startsWith(name, prefix) && !CLASS_KEYWORD.equals(name)
- && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e));
-// String name = e.getSimpleName().toString();
-// return !name.equals(THIS_KEYWORD) && !name.equals(SUPER_KEYWORD)
-// && Utilities.startsWith(name, prefix);
+ return Utilities.startsWith(name, prefix) && !CLASS_KEYWORD.equals(name) && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e));
+ // String name = e.getSimpleName().toString();
+ // return !name.equals(THIS_KEYWORD) && !name.equals(SUPER_KEYWORD)
+ // && Utilities.startsWith(name, prefix);
case ENUM_CONSTANT:
- return Utilities.startsWith(e.getSimpleName().toString(), prefix) &&
-// !illegalForwardRefs.contains(e) &&
-// (!isStatic || e.getModifiers().contains(STATIC)) &&
- (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) &&
- trees.isAccessible(scope, e, (DeclaredType)t);
+ return Utilities.startsWith(e.getSimpleName().toString(), prefix) && // !illegalForwardRefs.contains(e) &&
+ // (!isStatic || e.getModifiers().contains(STATIC)) &&
+ (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) && trees.isAccessible(scope, e, (DeclaredType) t);
case METHOD:
- return Utilities.startsWith(e.getSimpleName().toString(), prefix) &&
- (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) &&
-// (!isStatic || e.getModifiers().contains(STATIC)) &&
- trees.isAccessible(scope, e, (DeclaredType)t);
+ return Utilities.startsWith(e.getSimpleName().toString(), prefix) && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) && // (!isStatic || e.getModifiers().contains(STATIC)) &&
+ trees.isAccessible(scope, e, (DeclaredType) t);
}
return false;
}
@@ -1048,51 +897,50 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
for (Element e : controller.getElementUtilities().getLocalMembersAndVars(scope, acceptor)) {
switch (e.getKind()) {
case ENUM_CONSTANT:
- items.add(JavaCompletionItem.createVariableItem(controller, (VariableElement)e, e.asType(), null, substitutionOffset, null, scope.getEnclosingClass() != e.getEnclosingElement(), elements.isDeprecated(e), false/*isOfSmartType(env, e.asType(), smartTypes)*/, -1, null));
+ items.add(factory.createJavaVariableItem(controller, (VariableElement) e, e.asType(), substitutionOffset, scope.getEnclosingClass() != e.getEnclosingElement(), elements.isDeprecated(e)));
break;
case FIELD:
String name = e.getSimpleName().toString();
TypeMirror tm = asMemberOf(e, enclClass != null ? enclClass.asType() : null, types);
- items.add(JavaCompletionItem.createVariableItem(controller, (VariableElement)e, tm, null, substitutionOffset, null, scope.getEnclosingClass() != e.getEnclosingElement(), elements.isDeprecated(e), false/*isOfSmartType(env, tm, smartTypes)*/, -1, null));
+ items.add(factory.createJavaVariableItem(controller, (VariableElement) e, tm, substitutionOffset, scope.getEnclosingClass() != e.getEnclosingElement(), elements.isDeprecated(e)));
break;
case CONSTRUCTOR:
case METHOD:
- ExecutableType et = (ExecutableType)asMemberOf(e, enclClass != null ? enclClass.asType() : null, types);
-// items.add(JavaCompletionItem.createExecutableItem((ExecutableElement)e, et, substitutionOffset, scope.getEnclosingClass() != e.getEnclosingElement(), elements.isDeprecated(e), false, false/*isOfSmartType(env, et.getReturnType(), smartTypes)*/));
- items.add(JavadocCompletionItem.createExecutableItem(controller, (ExecutableElement) e, et, substitutionOffset, scope.getEnclosingClass() != e.getEnclosingElement(), elements.isDeprecated(e)));
+ ExecutableType et = (ExecutableType) asMemberOf(e, enclClass != null ? enclClass.asType() : null, types);
+ // items.add(JavaCompletionItem.createExecutableItem((ExecutableElement)e, et, substitutionOffset, scope.getEnclosingClass() != e.getEnclosingElement(), elements.isDeprecated(e), false, false/*isOfSmartType(env, et.getReturnType(), smartTypes)*/));
+ items.add(factory.createJavadocExecutableItem(controller, (ExecutableElement) e, et, substitutionOffset, scope.getEnclosingClass() != e.getEnclosingElement(), elements.isDeprecated(e)));
break;
}
}
}
- private static TypeMirror asMemberOf(Element element, TypeMirror type, Types types) {
+ private TypeMirror asMemberOf(Element element, TypeMirror type, Types types) {
TypeMirror ret = element.asType();
TypeMirror enclType = element.getEnclosingElement().asType();
- if (enclType.getKind() == TypeKind.DECLARED)
+ if (enclType.getKind() == TypeKind.DECLARED) {
enclType = types.erasure(enclType);
- while(type != null && type.getKind() == TypeKind.DECLARED) {
+ }
+ while (type != null && type.getKind() == TypeKind.DECLARED) {
if (types.isSubtype(type, enclType)) {
- ret = types.asMemberOf((DeclaredType)type, element);
+ ret = types.asMemberOf((DeclaredType) type, element);
break;
}
- type = ((DeclaredType)type).getEnclosingType();
+ type = ((DeclaredType) type).getEnclosingType();
}
return ret;
- }
-
- private void addTypes(EnumSet<ElementKind> kinds, DeclaredType baseType,
- Set<? extends Element> toExclude, String prefix,
- int substitutionOffset, JavadocContext jdctx) {
-
- if (queryType == CompletionProvider.COMPLETION_ALL_QUERY_TYPE) {
+ }
+
+ private void addTypes(EnumSet<ElementKind> kinds, DeclaredType baseType, Set<? extends Element> toExclude, String prefix, int substitutionOffset, JavadocContext jdctx) {
+ if (isAllQueryType) {
if (baseType == null) {
addAllTypes(jdctx, kinds, toExclude, prefix, substitutionOffset);
} else {
Elements elements = jdctx.javac.getElements();
- for(DeclaredType subtype : getSubtypesOf(baseType, prefix, jdctx)) {
- TypeElement elem = (TypeElement)subtype.asElement();
- if ((toExclude == null || !toExclude.contains(elem)) && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(elem)))
- items.add(JavaCompletionItem.createTypeItem(jdctx.javac, elem, subtype, substitutionOffset, jdctx.getReferencesCount(), elements.isDeprecated(elem), false, false, false, false, false, null));
+ for (DeclaredType subtype : getSubtypesOf(baseType, prefix, jdctx)) {
+ TypeElement elem = (TypeElement) subtype.asElement();
+ if ((toExclude == null || !toExclude.contains(elem)) && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(elem))) {
+ items.add(factory.createJavaTypeItem(jdctx.javac, elem, subtype, substitutionOffset, jdctx.getReferencesCount(), elements.isDeprecated(elem), false));
+ }
}
}
} else {
@@ -1114,62 +962,58 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
final boolean isStatic = enclClass == null ? false : tu.isStaticContext(scope);
ElementUtilities.ElementAcceptor acceptor = new ElementUtilities.ElementAcceptor() {
public boolean accept(Element e, TypeMirror t) {
- if ((toExclude == null || !toExclude.contains(e)) && (e.getKind().isClass() || e.getKind().isInterface() || e.getKind() == TYPE_PARAMETER)) {
+ if ((toExclude == null || !toExclude.contains(e)) && (e.getKind().isClass() || e.getKind().isInterface() || e.getKind() == ElementKind.TYPE_PARAMETER)) {
String name = e.getSimpleName().toString();
- return name.length() > 0 && !Character.isDigit(name.charAt(0)) && startsWith(name, prefix) &&
- (!isStatic || e.getModifiers().contains(Modifier.STATIC)) && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) && isOfKindAndType(e.asType(), e, kinds, baseType, scope, trees, types);
+ return name.length() > 0 && !Character.isDigit(name.charAt(0)) && startsWith(name, prefix) && (!isStatic || e.getModifiers().contains(Modifier.STATIC)) && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) && isOfKindAndType(e.asType(), e, kinds, baseType, scope, trees, types);
}
return false;
}
};
- for(Element e : controller.getElementUtilities().getLocalMembersAndVars(scope, acceptor)) {
+ for (Element e : controller.getElementUtilities().getLocalMembersAndVars(scope, acceptor)) {
switch (e.getKind()) {
case CLASS:
case ENUM:
case INTERFACE:
case ANNOTATION_TYPE:
- items.add(JavadocCompletionItem.createTypeItem(env.javac, (TypeElement) e, substitutionOffset, null, elements.isDeprecated(e)));
+ items.add(factory.createJavadocTypeItem(env.javac, (TypeElement) e, substitutionOffset, elements.isDeprecated(e)));
break;
- }
+ }
}
acceptor = new ElementUtilities.ElementAcceptor() {
public boolean accept(Element e, TypeMirror t) {
- if ((e.getKind().isClass() || e.getKind().isInterface())) {
- return (toExclude == null || !toExclude.contains(e)) && startsWith(e.getSimpleName().toString(), prefix) &&
- (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) && trees.isAccessible(scope, (TypeElement)e) &&
- isOfKindAndType(e.asType(), e, kinds, baseType, scope, trees, types);
+ if (e.getKind().isClass() || e.getKind().isInterface()) {
+ return (toExclude == null || !toExclude.contains(e)) && startsWith(e.getSimpleName().toString(), prefix) && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) && trees.isAccessible(scope, (TypeElement) e) && isOfKindAndType(e.asType(), e, kinds, baseType, scope, trees, types);
}
return false;
}
};
for (TypeElement e : controller.getElementUtilities().getGlobalTypes(acceptor)) {
- items.add(JavadocCompletionItem.createTypeItem(env.javac, e, substitutionOffset, null, elements.isDeprecated(e)));
+ items.add(factory.createJavadocTypeItem(env.javac, e, substitutionOffset, elements.isDeprecated(e)));
}
}
private void addAllTypes(JavadocContext env, EnumSet<ElementKind> kinds, Set<? extends Element> toExclude, String prefix, int substitutionOffset) {
-// String prefix = env.getPrefix();
+ // String prefix = env.getPrefix();
CompilationInfo controller = env.javac;
boolean isCaseSensitive = false;
- ClassIndex.NameKind kind =
- isCaseSensitive? ClassIndex.NameKind.PREFIX : ClassIndex.NameKind.CASE_INSENSITIVE_PREFIX;
-// ClassIndex.NameKind kind = env.isCamelCasePrefix() ?
-// Utilities.isCaseSensitive() ? ClassIndex.NameKind.CAMEL_CASE : ClassIndex.NameKind.CAMEL_CASE_INSENSITIVE :
-// Utilities.isCaseSensitive() ? ClassIndex.NameKind.PREFIX : ClassIndex.NameKind.CASE_INSENSITIVE_PREFIX;
+ ClassIndex.NameKind kind = isCaseSensitive ? ClassIndex.NameKind.PREFIX : ClassIndex.NameKind.CASE_INSENSITIVE_PREFIX;
+ // ClassIndex.NameKind kind = env.isCamelCasePrefix() ?
+ // Utilities.isCaseSensitive() ? ClassIndex.NameKind.CAMEL_CASE : ClassIndex.NameKind.CAMEL_CASE_INSENSITIVE :
+ // Utilities.isCaseSensitive() ? ClassIndex.NameKind.PREFIX : ClassIndex.NameKind.CASE_INSENSITIVE_PREFIX;
Set<ElementHandle<Element>> excludeHandles = null;
if (toExclude != null) {
- excludeHandles = new HashSet<ElementHandle<Element>>(toExclude.size());
+ excludeHandles = new HashSet<>(toExclude.size());
for (Element el : toExclude) {
excludeHandles.add(ElementHandle.create(el));
}
}
- for(ElementHandle<TypeElement> name : controller.getClasspathInfo().getClassIndex().getDeclaredTypes(prefix, kind, EnumSet.allOf(ClassIndex.SearchScope.class))) {
+ for (ElementHandle<TypeElement> name : controller.getClasspathInfo().getClassIndex().getDeclaredTypes(prefix, kind, EnumSet.allOf(ClassIndex.SearchScope.class))) {
if ((excludeHandles == null || !excludeHandles.contains(name)) && !isAnnonInner(name)) {
- items.add(LazyJavaCompletionItem.createTypeItem(name, kinds, substitutionOffset, env.getReferencesCount(), controller.getSnapshot().getSource(), false, false, false, null));
+ items.add(factory.createLazyTypeItem(name, kinds, substitutionOffset, env.getReferencesCount(), controller.getSnapshot().getSource()));
}
}
}
-
+
private void addInnerClasses(TypeElement te, EnumSet<ElementKind> kinds, DeclaredType baseType, Set<? extends Element> toExclude, String prefix, int substitutionOffset, JavadocContext jdctx) {
CompilationInfo controller = jdctx.javac;
Element srcEl = jdctx.handle.resolve(controller);
@@ -1182,13 +1026,13 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
for (Element e : controller.getElementUtilities().getMembers(te.asType(), null)) {
if ((e.getKind().isClass() || e.getKind().isInterface()) && (toExclude == null || !toExclude.contains(e))) {
String name = e.getSimpleName().toString();
- if (Utilities.startsWith(name, prefix) && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) && trees.isAccessible(scope, (TypeElement)e) && isOfKindAndType(e.asType(), e, kinds, baseType, scope, trees, types)) {
- items.add(JavadocCompletionItem.createTypeItem(jdctx.javac, (TypeElement) e, substitutionOffset, null, elements.isDeprecated(e)/*, isOfSmartType(env, e.asType(), smartTypes)*/));
+ if (Utilities.startsWith(name, prefix) && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) && trees.isAccessible(scope, (TypeElement) e) && isOfKindAndType(e.asType(), e, kinds, baseType, scope, trees, types)) {
+ items.add(factory.createJavadocTypeItem(jdctx.javac, (TypeElement) e, substitutionOffset, elements.isDeprecated(e)));
}
}
}
}
-
+
private void addPackageContent(PackageElement pe, EnumSet<ElementKind> kinds, DeclaredType baseType, Set<? extends Element> toExclude, String prefix, int substitutionOffset, JavadocContext jdctx) {
CompilationInfo controller = jdctx.javac;
Element srcEl = jdctx.handle.resolve(controller);
@@ -1199,37 +1043,37 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
ElementUtilities eu = controller.getElementUtilities();
TreePath docpath = srcEl != null ? trees.getPath(srcEl) : null;
Scope scope = docpath != null ? trees.getScope(docpath) : tu.scopeFor(caretOffset);
- for(Element e : pe.getEnclosedElements()) {
+ for (Element e : pe.getEnclosedElements()) {
if ((e.getKind().isClass() || e.getKind().isInterface()) && (toExclude == null || !toExclude.contains(e))) {
String name = e.getSimpleName().toString();
- if (Utilities.startsWith(name, prefix) && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e))
- && trees.isAccessible(scope, (TypeElement)e)
- && isOfKindAndType(e.asType(), e, kinds, baseType, scope, trees, types)
- && !Utilities.isExcluded(eu.getElementName(e, true))) {
- items.add(JavadocCompletionItem.createTypeItem(jdctx.javac, (TypeElement) e, substitutionOffset, null, elements.isDeprecated(e)/*, isOfSmartType(env, e.asType(), smartTypes)*/));
+ if (Utilities.startsWith(name, prefix) && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) && trees.isAccessible(scope, (TypeElement) e) && isOfKindAndType(e.asType(), e, kinds, baseType, scope, trees, types) && !Utilities.isExcluded(eu.getElementName(e, true))) {
+ items.add(factory.createJavadocTypeItem(jdctx.javac, (TypeElement) e, substitutionOffset, elements.isDeprecated(e)));
}
}
}
}
-
+
private boolean isOfKindAndType(TypeMirror type, Element e, EnumSet<ElementKind> kinds, TypeMirror base, Scope scope, Trees trees, Types types) {
if (type.getKind() != TypeKind.ERROR && kinds.contains(e.getKind())) {
- if (base == null)
+ if (base == null) {
return true;
- if (types.isSubtype(type, base))
+ }
+ if (types.isSubtype(type, base)) {
return true;
+ }
}
- if ((e.getKind().isClass() || e.getKind().isInterface()) &&
- (kinds.contains(ANNOTATION_TYPE) || kinds.contains(CLASS) || kinds.contains(ENUM) || kinds.contains(INTERFACE))) {
- DeclaredType dt = (DeclaredType)e.asType();
- for (Element ee : e.getEnclosedElements())
- if (trees.isAccessible(scope, ee, dt) && isOfKindAndType(ee.asType(), ee, kinds, base, scope, trees, types))
+ if ((e.getKind().isClass() || e.getKind().isInterface()) && (kinds.contains(ElementKind.ANNOTATION_TYPE) || kinds.contains(ElementKind.CLASS) || kinds.contains(ElementKind.ENUM) || kinds.contains(ElementKind.INTERFACE))) {
+ DeclaredType dt = (DeclaredType) e.asType();
+ for (Element ee : e.getEnclosedElements()) {
+ if (trees.isAccessible(scope, ee, dt) && isOfKindAndType(ee.asType(), ee, kinds, base, scope, trees, types)) {
return true;
+ }
+ }
}
return false;
}
-
- private static boolean isAnnonInner(ElementHandle<TypeElement> elem) {
+
+ private boolean isAnnonInner(ElementHandle<TypeElement> elem) {
String name = elem.getQualifiedName();
int idx = name.lastIndexOf('.'); //NOI18N
String simpleName = idx > -1 ? name.substring(idx + 1) : name;
@@ -1238,9 +1082,10 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
/* copied from JavaCompletionProvider */
private List<DeclaredType> getSubtypesOf(DeclaredType baseType, String prefix, JavadocContext jdctx) {
- if (((TypeElement)baseType.asElement()).getQualifiedName().contentEquals("java.lang.Object"))
+ if (((TypeElement) baseType.asElement()).getQualifiedName().contentEquals("java.lang.Object")) {
return Collections.emptyList();
- LinkedList<DeclaredType> subtypes = new LinkedList<DeclaredType>();
+ }
+ LinkedList<DeclaredType> subtypes = new LinkedList<>();
CompilationInfo controller = jdctx.javac;
Types types = controller.getTypes();
Trees trees = controller.getTrees();
@@ -1250,31 +1095,32 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
Scope scope = docpath != null ? trees.getScope(docpath) : tu.scopeFor(caretOffset);
if (prefix != null && prefix.length() > 2 && baseType.getTypeArguments().isEmpty()) {
// XXX resolve camels
-// ClassIndex.NameKind kind = env.isCamelCasePrefix() ?
- ClassIndex.NameKind kind = false ?
- Utilities.isCaseSensitive() ? ClassIndex.NameKind.CAMEL_CASE : ClassIndex.NameKind.CAMEL_CASE_INSENSITIVE :
- Utilities.isCaseSensitive() ? ClassIndex.NameKind.PREFIX : ClassIndex.NameKind.CASE_INSENSITIVE_PREFIX;
- for(ElementHandle<TypeElement> handle : controller.getClasspathInfo().getClassIndex().getDeclaredTypes(prefix, kind, EnumSet.allOf(ClassIndex.SearchScope.class))) {
+ // ClassIndex.NameKind kind = env.isCamelCasePrefix() ?
+ ClassIndex.NameKind kind = false ? Utilities.isCaseSensitive() ? ClassIndex.NameKind.CAMEL_CASE : ClassIndex.NameKind.CAMEL_CASE_INSENSITIVE : Utilities.isCaseSensitive() ? ClassIndex.NameKind.PREFIX : ClassIndex.NameKind.CASE_INSENSITIVE_PREFIX;
+ for (ElementHandle<TypeElement> handle : controller.getClasspathInfo().getClassIndex().getDeclaredTypes(prefix, kind, EnumSet.allOf(ClassIndex.SearchScope.class))) {
TypeElement te = handle.resolve(controller);
- if (te != null && trees.isAccessible(scope, te) && types.isSubtype(types.getDeclaredType(te), baseType))
+ if (te != null && trees.isAccessible(scope, te) && types.isSubtype(types.getDeclaredType(te), baseType)) {
subtypes.add(types.getDeclaredType(te));
+ }
}
} else {
- HashSet<TypeElement> elems = new HashSet<TypeElement>();
- LinkedList<DeclaredType> bases = new LinkedList<DeclaredType>();
+ HashSet<TypeElement> elems = new HashSet<>();
+ LinkedList<DeclaredType> bases = new LinkedList<>();
bases.add(baseType);
ClassIndex index = controller.getClasspathInfo().getClassIndex();
- while(!bases.isEmpty()) {
+ while (!bases.isEmpty()) {
DeclaredType head = bases.remove();
- TypeElement elem = (TypeElement)head.asElement();
- if (!elems.add(elem))
+ TypeElement elem = (TypeElement) head.asElement();
+ if (!elems.add(elem)) {
continue;
- if (startsWith(elem.getSimpleName().toString(), prefix) && trees.isAccessible(scope, elem))
+ }
+ if (startsWith(elem.getSimpleName().toString(), prefix) && trees.isAccessible(scope, elem)) {
subtypes.add(head);
+ }
List<? extends TypeMirror> tas = head.getTypeArguments();
boolean isRaw = !tas.iterator().hasNext();
subtypes:
- for (ElementHandle<TypeElement> eh : index.getElements(ElementHandle.create(elem), EnumSet.of(ClassIndex.SearchKind.IMPLEMENTORS),EnumSet.allOf(ClassIndex.SearchScope.class))) {
+ for (ElementHandle<TypeElement> eh : index.getElements(ElementHandle.create(elem), EnumSet.of(ClassIndex.SearchKind.IMPLEMENTORS), EnumSet.allOf(ClassIndex.SearchScope.class))) {
TypeElement e = eh.resolve(controller);
if (e != null) {
if (trees.isAccessible(scope, e)) {
@@ -1282,18 +1128,18 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
DeclaredType dt = types.getDeclaredType(e);
bases.add(dt);
} else {
- HashMap<Element, TypeMirror> map = new HashMap<Element, TypeMirror>();
+ HashMap<Element, TypeMirror> map = new HashMap<>();
TypeMirror sup = e.getSuperclass();
- if (sup.getKind() == TypeKind.DECLARED && ((DeclaredType)sup).asElement() == elem) {
- DeclaredType dt = (DeclaredType)sup;
+ if (sup.getKind() == TypeKind.DECLARED && ((DeclaredType) sup).asElement() == elem) {
+ DeclaredType dt = (DeclaredType) sup;
Iterator<? extends TypeMirror> ittas = tas.iterator();
Iterator<? extends TypeMirror> it = dt.getTypeArguments().iterator();
- while(it.hasNext() && ittas.hasNext()) {
+ while (it.hasNext() && ittas.hasNext()) {
TypeMirror basetm = ittas.next();
TypeMirror stm = it.next();
if (basetm != stm) {
if (stm.getKind() == TypeKind.TYPEVAR) {
- map.put(((TypeVariable)stm).asElement(), basetm);
+ map.put(((TypeVariable) stm).asElement(), basetm);
} else {
continue subtypes;
}
@@ -1304,16 +1150,16 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
}
} else {
for (TypeMirror tm : e.getInterfaces()) {
- if (((DeclaredType)tm).asElement() == elem) {
- DeclaredType dt = (DeclaredType)tm;
+ if (((DeclaredType) tm).asElement() == elem) {
+ DeclaredType dt = (DeclaredType) tm;
Iterator<? extends TypeMirror> ittas = tas.iterator();
Iterator<? extends TypeMirror> it = dt.getTypeArguments().iterator();
- while(it.hasNext() && ittas.hasNext()) {
+ while (it.hasNext() && ittas.hasNext()) {
TypeMirror basetm = ittas.next();
TypeMirror stm = it.next();
if (basetm != stm) {
if (stm.getKind() == TypeKind.TYPEVAR) {
- map.put(((TypeVariable)stm).asElement(), basetm);
+ map.put(((TypeVariable) stm).asElement(), basetm);
} else {
continue subtypes;
}
@@ -1330,10 +1176,7 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
}
}
} else {
- Logger.getLogger("global").log(Level.FINE, String.format("Cannot resolve: %s on bootpath: %s classpath: %s sourcepath: %s\n", eh.toString(),
- controller.getClasspathInfo().getClassPath(ClasspathInfo.PathKind.BOOT),
- controller.getClasspathInfo().getClassPath(ClasspathInfo.PathKind.COMPILE),
- controller.getClasspathInfo().getClassPath(ClasspathInfo.PathKind.SOURCE)));
+ Logger.getLogger("global").log(Level.FINE, String.format("Cannot resolve: %s on bootpath: %s classpath: %s sourcepath: %s\n", eh.toString(), controller.getClasspathInfo().getClassPath(ClasspathInfo.PathKind.BOOT), controller.getClasspathInfo().getClassPath(ClasspathInfo.PathKind.COMPILE), controller.getClasspathInfo().getClassPath(ClasspathInfo.PathKind.SOURCE)));
}
}
}
@@ -1351,24 +1194,21 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
targs[i++] = t != null ? t : tpe.asType();
}
Element encl = e.getEnclosingElement();
- if ((encl.getKind().isClass() || encl.getKind().isInterface()) && !((TypeElement)encl).getTypeParameters().isEmpty())
- return types.getDeclaredType(getDeclaredType((TypeElement)encl, map, types), e, targs);
+ if ((encl.getKind().isClass() || encl.getKind().isInterface()) && !((TypeElement) encl).getTypeParameters().isEmpty()) {
+ return types.getDeclaredType(getDeclaredType((TypeElement) encl, map, types), e, targs);
+ }
return types.getDeclaredType(e, targs);
}
private boolean startsWith(String theString, String prefix) {
// XXX isCamelCasePrefix
- return /*env.isCamelCasePrefix()*/false ? Utilities.isCaseSensitive() ?
- Utilities.startsWithCamelCase(theString, prefix) :
- Utilities.startsWithCamelCase(theString, prefix) || Utilities.startsWith(theString, prefix) :
- Utilities.startsWith(theString, prefix);
+ return /*env.isCamelCasePrefix()*/ false ? Utilities.isCaseSensitive() ? Utilities.startsWithCamelCase(theString, prefix) : Utilities.startsWithCamelCase(theString, prefix) || Utilities.startsWith(theString, prefix) : Utilities.startsWith(theString, prefix);
}
-
+
void resolveOtherText(JavadocContext jdctx, TokenSequence<JavadocTokenId> jdts) {
Token<JavadocTokenId> token = jdts.token();
assert token != null;
assert token.id() == JavadocTokenId.OTHER_TEXT;
-
CharSequence text = token.text();
int pos = caretOffset - jdts.offset();
DocTreePath tag = getTag(jdctx, caretOffset);
@@ -1382,7 +1222,6 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
resolveInlineTag(null, jdctx);
return;
}
-
if (tag != null) {
insideTag(tag, jdctx);
if (JavadocCompletionUtils.isBlockTag(tag) && JavadocCompletionUtils.isLineBreak(token, pos)) {
@@ -1392,22 +1231,27 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
resolveBlockTag(null, jdctx);
}
}
-
- static final class JavadocContext {
- int anchorOffset = -1;
- ElementHandle<Element> handle;
- Element commentFor;
- DocCommentTree comment;
- DocSourcePositions positions;
- TokenSequence<JavadocTokenId> jdts;
- Document doc;
- CompilationInfo javac;
+
+ private static class JavadocContext {
+
+ private final CompilationInfo javac;
+ private ElementHandle<Element> handle;
+ private Element commentFor;
+ private DocCommentTree comment;
+ private DocSourcePositions positions;
+ private TokenSequence<JavadocTokenId> jdts;
+ private Document doc;
private ReferencesCount count;
private TreePath javadocFor;
- ReferencesCount getReferencesCount() {
+
+ private JavadocContext(CompilationInfo javac) {
+ this.javac = javac;
+ }
+
+ private ReferencesCount getReferencesCount() {
if (count == null)
count = ReferencesCount.get(javac.getClasspathInfo());
return count;
}
- }
+ }
}
diff --git a/java/java.editor/src/org/netbeans/modules/java/editor/javadoc/TagRegistery.java b/java/java.editor/src/org/netbeans/modules/java/editor/javadoc/TagRegistery.java
index 5b4f67fd0c..c8384251be 100644
--- a/java/java.editor/src/org/netbeans/modules/java/editor/javadoc/TagRegistery.java
+++ b/java/java.editor/src/org/netbeans/modules/java/editor/javadoc/TagRegistery.java
@@ -101,7 +101,15 @@ final class TagRegistery {
addTag("@code", true, ALL_KINDS);
addTag("@snippet", true, ALL_KINDS);
+ addTag("@summary", true, ALL_KINDS);
+ addTag("@systemProperty", true, EnumSet.<ElementKind>of(
+ ElementKind.ANNOTATION_TYPE, ElementKind.CLASS,
+ ElementKind.CONSTRUCTOR, ElementKind.ENUM,
+ ElementKind.ENUM_CONSTANT, ElementKind.FIELD,
+ ElementKind.INTERFACE, ElementKind.METHOD,
+ ElementKind.MODULE, ElementKind.PACKAGE));
addTag("@docRoot", true, ALL_KINDS);
+ addTag("@index", true, ALL_KINDS);
// just in empty tag description
addTag("@inheritDoc", true, EnumSet.of(ElementKind.METHOD));
addTag("@link", true, ALL_KINDS);
diff --git a/java/java.editor/test/unit/src/org/netbeans/modules/java/editor/javadoc/JavadocCompletionQueryTest.java b/java/java.editor/test/unit/src/org/netbeans/modules/java/editor/javadoc/JavadocCompletionQueryTest.java
index ac02447e55..74e42e0f69 100644
--- a/java/java.editor/test/unit/src/org/netbeans/modules/java/editor/javadoc/JavadocCompletionQueryTest.java
+++ b/java/java.editor/test/unit/src/org/netbeans/modules/java/editor/javadoc/JavadocCompletionQueryTest.java
@@ -45,6 +45,238 @@ public class JavadocCompletionQueryTest extends JavadocTestSupport {
return suite;
}
+ public void testBlockTagsCompletion() throws Exception {
+ String code =
+ "package p;\n" +
+ "class Clazz {\n" +
+ " /**\n" +
+ " * |\n" +
+ " */\n" +
+ " void method(int p1, int p2) {\n" +
+ " }\n" +
+ "}\n";
+
+ performCompletionTest(code, "@deprecated:", "@exception:", "@hidden:", "@param:", "@return:", "@see:", "@serialData:", "@since:", "@throws:");
+ }
+
+ public void testBlockTagsCompletion1() throws Exception {
+ String code =
+ "package p;\n" +
+ "class Clazz {\n" +
+ " /**\n" +
+ " * This is javadoc for method.\n" +
+ " * |\n" +
+ " */\n" +
+ " void method(int p1, int p2) {\n" +
+ " }\n" +
+ "}\n";
+
+ performCompletionTest(code, "@deprecated:", "@exception:", "@hidden:", "@param:", "@return:", "@see:", "@serialData:", "@since:", "@throws:");
+ }
+
+ public void testBlockTagsCompletion2() throws Exception {
+ String code =
+ "package p;\n" +
+ "class Clazz {\n" +
+ " /**\n" +
+ " * @|\n" +
+ " */\n" +
+ " void method(int p1, int p2) {\n" +
+ " }\n" +
+ "}\n";
+
+ performCompletionTest(code, "@deprecated:", "@exception:", "@hidden:", "@param:", "@return:", "@see:", "@serialData:", "@since:", "@throws:");
+ }
+
+ public void testBlockTagsCompletion3() throws Exception {
+ String code =
+ "package p;\n" +
+ "class Clazz {\n" +
+ " /**\n" +
+ " * This is javadoc for method.\n" +
+ " * @|\n" +
+ " */\n" +
+ " void method(int p1, int p2) {\n" +
+ " }\n" +
+ "}\n";
+
+ performCompletionTest(code, "@deprecated:", "@exception:", "@hidden:", "@param:", "@return:", "@see:", "@serialData:", "@since:", "@throws:");
+ }
+
+ public void testBlockTagsCompletion4() throws Exception {
+ String code =
+ "package p;\n" +
+ "class Clazz {\n" +
+ " /**\n" +
+ " * @p|\n" +
+ " */\n" +
+ " void method(int p1, int p2) {\n" +
+ " }\n" +
+ "}\n";
+
+ performCompletionTest(code, "@param:");
+ }
+
+ public void testBlockTagsCompletion5() throws Exception {
+ String code =
+ "package p;\n" +
+ "class Clazz {\n" +
+ " /**\n" +
+ " * This is javadoc for method.\n" +
+ " * @p|\n" +
+ " */\n" +
+ " void method(int p1, int p2) {\n" +
+ " }\n" +
+ "}\n";
+
+ performCompletionTest(code, "@param:");
+ }
+
+ public void testBlockTagsCompletion6() throws Exception {
+ String code =
+ "package p;\n" +
+ "class Clazz {\n" +
+ " /**\n" +
+ " * @p|aram\n" +
+ " */\n" +
+ " void method(int p1, int p2) {\n" +
+ " }\n" +
+ "}\n";
+
+ performCompletionTest(code, "@param:");
+ }
+
+ public void testBlockTagsCompletion7() throws Exception {
+ String code =
+ "package p;\n" +
+ "class Clazz {\n" +
+ " /**\n" +
+ " * This is javadoc for method.\n" +
+ " * @p|aram\n" +
+ " */\n" +
+ " void method(int p1, int p2) {\n" +
+ " }\n" +
+ "}\n";
+
+ performCompletionTest(code, "@param:");
+ }
+
+ public void testInlineTagsCompletion() throws Exception {
+ String code =
+ "package p;\n" +
+ "class Clazz {\n" +
+ " /**\n" +
+ " * {|\n" +
+ " */\n" +
+ " void method(int p1, int p2) {\n" +
+ " }\n" +
+ "}\n";
+
+ performCompletionTest(code, "@code:", "@docRoot:", "@index:", "@inheritDoc:", "@link:", "@linkplain:", "@literal:", "@snippet:", "@summary:", "@systemProperty:");
+ }
+
+ public void testInlineTagsCompletion1() throws Exception {
+ String code =
+ "package p;\n" +
+ "class Clazz {\n" +
+ " /**\n" +
+ " * This is javadoc for method.\n" +
+ " * {|\n" +
+ " */\n" +
+ " void method(int p1, int p2) {\n" +
+ " }\n" +
+ "}\n";
+
+ performCompletionTest(code, "@code:", "@docRoot:", "@index:", "@inheritDoc:", "@link:", "@linkplain:", "@literal:", "@snippet:", "@summary:", "@systemProperty:");
+ }
+
+ public void testInlineTagsCompletion2() throws Exception {
+ String code =
+ "package p;\n" +
+ "class Clazz {\n" +
+ " /**\n" +
+ " * {@|\n" +
+ " */\n" +
+ " void method(int p1, int p2) {\n" +
+ " }\n" +
+ "}\n";
+
+ performCompletionTest(code, "@code:", "@docRoot:", "@index:", "@inheritDoc:", "@link:", "@linkplain:", "@literal:", "@snippet:", "@summary:", "@systemProperty:");
+ }
+
+ public void testInlineTagsCompletion3() throws Exception {
+ String code =
+ "package p;\n" +
+ "class Clazz {\n" +
+ " /**\n" +
+ " * This is javadoc for method.\n" +
+ " * {@|\n" +
+ " */\n" +
+ " void method(int p1, int p2) {\n" +
+ " }\n" +
+ "}\n";
+
+ performCompletionTest(code, "@code:", "@docRoot:", "@index:", "@inheritDoc:", "@link:", "@linkplain:", "@literal:", "@snippet:", "@summary:", "@systemProperty:");
+ }
+
+ public void testInlineTagsCompletion4() throws Exception {
+ String code =
+ "package p;\n" +
+ "class Clazz {\n" +
+ " /**\n" +
+ " * {@l|\n" +
+ " */\n" +
+ " void method(int p1, int p2) {\n" +
+ " }\n" +
+ "}\n";
+
+ performCompletionTest(code, "@link:", "@linkplain:", "@literal:");
+ }
+
+ public void testInlineTagsCompletion5() throws Exception {
+ String code =
+ "package p;\n" +
+ "class Clazz {\n" +
+ " /**\n" +
+ " * This is javadoc for method.\n" +
+ " * {@l|\n" +
+ " */\n" +
+ " void method(int p1, int p2) {\n" +
+ " }\n" +
+ "}\n";
+
+ performCompletionTest(code, "@link:", "@linkplain:", "@literal:");
+ }
+
+ public void testInlineTagsCompletion6() throws Exception {
+ String code =
+ "package p;\n" +
+ "class Clazz {\n" +
+ " /**\n" +
+ " * {@l|ink\n" +
+ " */\n" +
+ " void method(int p1, int p2) {\n" +
+ " }\n" +
+ "}\n";
+
+ performCompletionTest(code, "@link:", "@linkplain:", "@literal:");
+ }
+
+ public void testInlineTagsCompletion7() throws Exception {
+ String code =
+ "package p;\n" +
+ "class Clazz {\n" +
+ " /**\n" +
+ " * This is javadoc for method.\n" +
+ " * {@l|ink\n" +
+ " */\n" +
+ " void method(int p1, int p2) {\n" +
+ " }\n" +
+ "}\n";
+
+ performCompletionTest(code, "@link:", "@linkplain:", "@literal:");
+ }
+
public void testParamNameCompletionForMethod() throws Exception {
String code =
"package p;\n" +
@@ -117,17 +349,16 @@ public class JavadocCompletionQueryTest extends JavadocTestSupport {
performCompletionTest(code, "p1:", "p2:");
}
- public void XtestParamNameCompletionForClass() throws Exception {
- //XXX: ???
+ public void testParamNameCompletionForClass() throws Exception {
String code =
"package p;\n" +
"/**\n" +
- " * @param P|\n" +
+ " * @param <P|\n" +
" */\n" +
"class Clazz<P1,P2> {\n" +
"}\n";
- performCompletionTest(code, "P1:", "P2:");
+ performCompletionTest(code, "<P1>:", "<P2>:");
}
public void testLink1() throws Exception {
diff --git a/java/java.lsp.server/nbcode/nbproject/platform.properties b/java/java.lsp.server/nbcode/nbproject/platform.properties
index d48788bbc4..db5d41b90b 100644
--- a/java/java.lsp.server/nbcode/nbproject/platform.properties
+++ b/java/java.lsp.server/nbcode/nbproject/platform.properties
@@ -153,7 +153,6 @@ disabled.modules=\
org.netbeans.modules.html.custom,\
org.netbeans.modules.html.editor,\
org.netbeans.modules.html.knockout,\
- org.netbeans.modules.html.parser,\
org.netbeans.modules.html.validation,\
org.netbeans.modules.httpserver,\
org.netbeans.modules.hudson,\
@@ -190,7 +189,6 @@ disabled.modules=\
org.netbeans.modules.java.navigation,\
org.netbeans.modules.java.source.compat8,\
org.netbeans.modules.java.testrunner.ant,\
- org.netbeans.modules.javadoc,\
org.netbeans.modules.javascript.bower,\
org.netbeans.modules.javascript.cdnjs,\
org.netbeans.modules.javascript.grunt,\
diff --git a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/Server.java b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/Server.java
index 0da258c35c..b1e26e645b 100644
--- a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/Server.java
+++ b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/Server.java
@@ -702,7 +702,7 @@ public final class Server {
capabilities.setTextDocumentSync(textDocumentSyncOptions);
CompletionOptions completionOptions = new CompletionOptions();
completionOptions.setResolveProvider(true);
- completionOptions.setTriggerCharacters(Collections.singletonList("."));
+ completionOptions.setTriggerCharacters(Arrays.asList(".", "#", "@", "*"));
capabilities.setCompletionProvider(completionOptions);
capabilities.setHoverProvider(true);
CodeActionOptions codeActionOptions = new CodeActionOptions(Arrays.asList(CodeActionKind.QuickFix, CodeActionKind.Source, CodeActionKind.SourceOrganizeImports, CodeActionKind.Refactor));
diff --git a/java/javadoc/nbproject/project.xml b/java/javadoc/nbproject/project.xml
index 94f56cdfb0..595112181d 100644
--- a/java/javadoc/nbproject/project.xml
+++ b/java/javadoc/nbproject/project.xml
@@ -43,6 +43,15 @@
<specification-version>1.0</specification-version>
</run-dependency>
</dependency>
+ <dependency>
+ <code-name-base>org.netbeans.api.lsp</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <release-version>1</release-version>
+ <specification-version>1.10</specification-version>
+ </run-dependency>
+ </dependency>
<dependency>
<code-name-base>org.netbeans.libs.javacapi</code-name-base>
<build-prerequisite/>
diff --git a/java/javadoc/src/org/netbeans/modules/javadoc/hints/GenerateJavadocCollector.java b/java/javadoc/src/org/netbeans/modules/javadoc/hints/GenerateJavadocCollector.java
new file mode 100644
index 0000000000..88dee530e4
--- /dev/null
+++ b/java/javadoc/src/org/netbeans/modules/javadoc/hints/GenerateJavadocCollector.java
@@ -0,0 +1,123 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.javadoc.hints;
+
+import com.sun.source.tree.Tree;
+import com.sun.source.util.TreePath;
+import java.io.IOException;
+import java.util.function.Consumer;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Element;
+import javax.swing.text.Document;
+import org.netbeans.api.editor.mimelookup.MimeRegistration;
+import org.netbeans.api.java.lexer.JavaTokenId;
+import org.netbeans.api.java.source.CompilationController;
+import org.netbeans.api.java.source.JavaSource;
+import org.netbeans.api.java.source.SourceUtils;
+import org.netbeans.api.java.source.Task;
+import org.netbeans.api.java.source.TreeUtilities;
+import org.netbeans.api.lexer.TokenHierarchy;
+import org.netbeans.api.lexer.TokenSequence;
+import org.netbeans.api.lsp.Completion;
+import org.netbeans.spi.lsp.CompletionCollector;
+import org.openide.filesystems.FileObject;
+import org.openide.util.Exceptions;
+import org.openide.util.NbBundle;
+
+/**
+ *
+ * @author Dusan Balek
+ */
+@MimeRegistration(mimeType = "text/x-java", service = CompletionCollector.class) //NOI18N
+public class GenerateJavadocCollector implements CompletionCollector {
+
+ @NbBundle.Messages({
+ "DN_JavadocComment=Javadoc comment",
+ })
+ @Override
+ public boolean collectCompletions(Document doc, int offset, Completion.Context context, Consumer<Completion> consumer) {
+ if (context != null && context.getTriggerKind() == Completion.TriggerKind.TriggerCharacter && context.getTriggerCharacter() == '*') {
+ TokenSequence<JavaTokenId> ts = SourceUtils.getJavaTokenSequence(TokenHierarchy.get(doc), offset);
+ if (ts != null) {
+ ts.move(offset);
+ if (ts.moveNext() && ts.token().id() == JavaTokenId.JAVADOC_COMMENT) {
+ int jdBeginOffset = ts.offset();
+ String text = ts.token().text().toString();
+ if (text.substring(3, text.length() - 2).trim().isEmpty()) {
+ JavaSource js = JavaSource.forDocument(doc);
+ if (js != null) {
+ FileObject file = js.getFileObjects().iterator().next();
+ SourceVersion sv = JavadocUtilities.resolveSourceVersion(file);
+ final JavadocGenerator gen = new JavadocGenerator(sv);
+ gen.updateSettings(file);
+ try {
+ js.runUserActionTask(new Task<CompilationController>() {
+ @Override
+ public void run(CompilationController cc) throws Exception {
+ cc.toPhase(JavaSource.Phase.ELEMENTS_RESOLVED);
+ int offsetBehindJavadoc = ts.offset() + ts.token().length();
+ while (ts.moveNext()) {
+ JavaTokenId tid = ts.token().id();
+ if (tid != JavaTokenId.WHITESPACE && tid != JavaTokenId.LINE_COMMENT && tid != JavaTokenId.BLOCK_COMMENT) {
+ offsetBehindJavadoc = ts.offset() + 1;
+ break;
+ }
+ }
+ TreePath tp = cc.getTreeUtilities().pathFor(offsetBehindJavadoc);
+ while (tp != null && !TreeUtilities.CLASS_TREE_KINDS.contains(tp.getLeaf().getKind())
+ && tp.getLeaf().getKind() != Tree.Kind.METHOD && tp.getLeaf().getKind() != Tree.Kind.VARIABLE) {
+ tp = tp.getParentPath();
+ }
+ if (tp != null && cc.getTrees().getSourcePositions().getStartPosition(tp.getCompilationUnit(), tp.getLeaf()) >= jdBeginOffset) {
+ Element el = cc.getTrees().getElement(tp);
+ if (el != null) {
+ String javadoc = gen.generateComment(el, cc);
+ if (javadoc != null) {
+ StringBuilder sb = new StringBuilder("\n * ${0}"); //NOI18N
+ boolean first = true;
+ for (String s : javadoc.split("\n")) { //NOI18N
+ if (first && s.isEmpty()) {
+ sb.append('\n');
+ } else {
+ sb.append(" * ").append(s).append('\n'); //NOI18N
+ }
+ first = false;
+ }
+ consumer.accept(CompletionCollector.newBuilder(Bundle.DN_JavadocComment())
+ .kind(Completion.Kind.Snippet)
+ .insertText(sb.toString())
+ .insertTextFormat(Completion.TextFormat.Snippet)
+ .documentation(javadoc)
+ .build());
+ }
+ }
+ }
+ }
+ }, true);
+ } catch (IOException ex) {
+ Exceptions.printStackTrace(ex);
+ }
+ }
+ }
+ }
+ }
+ }
+ return true;
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@netbeans.apache.org
For additional commands, e-mail: commits-help@netbeans.apache.org
For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists