This is an automated email from the ASF dual-hosted git repository.
lkishalmi 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 c9ff717 Show types for chained method invocations.
c9ff717 is described below
commit c9ff7179ff55d10abb217b2b13d3d988489c5f5f
Author: Jan Lahoda <[email protected]>
AuthorDate: Sun Sep 13 12:24:49 2020 +0200
Show types for chained method invocations.
---
.../editor/lib2/view/ParagraphViewChildren.java | 10 +++--
.../base/semantic/SemanticHighlighterBase.java | 49 +++++++++++++++++++++
.../java/editor/base/semantic/TokenList.java | 15 ++++++-
.../java/editor/base/semantic/DetectorTest.java | 51 ++++++++++++++++++++++
4 files changed, 121 insertions(+), 4 deletions(-)
diff --git
a/ide/editor.lib2/src/org/netbeans/modules/editor/lib2/view/ParagraphViewChildren.java
b/ide/editor.lib2/src/org/netbeans/modules/editor/lib2/view/ParagraphViewChildren.java
index 38c2787..3275a68 100644
---
a/ide/editor.lib2/src/org/netbeans/modules/editor/lib2/view/ParagraphViewChildren.java
+++
b/ide/editor.lib2/src/org/netbeans/modules/editor/lib2/view/ParagraphViewChildren.java
@@ -168,8 +168,8 @@ final class ParagraphViewChildren extends
ViewChildren<EditorView> {
view.setRawEndOffset(relEndOffset); // Below offset-gap
view.setParent(pView);
// Possibly assign text layout
- if (view instanceof HighlightsView || (view instanceof
PrependedTextView && ((PrependedTextView) view).getDelegate() instanceof
HighlightsView)) {
- HighlightsView hView = (HighlightsView) (view instanceof
HighlightsView ? view : ((PrependedTextView) view).getDelegate());
+ if (viewOrDelegate(view) instanceof HighlightsView) {
+ HighlightsView hView = (HighlightsView)
viewOrDelegate(view);
// Fill in text layout if necessary
if (hView.getTextLayout() == null) { // Fill in text layout
if (docText == null) {
@@ -430,7 +430,7 @@ final class ParagraphViewChildren extends
ViewChildren<EditorView> {
while (startIndex < endIndex) {
EditorView view = get(startIndex);
Shape childAlloc = getChildAllocation(startIndex, pAlloc);
- if (view.getClass() == NewlineView.class) {
+ if (viewOrDelegate(view).getClass() == NewlineView.class) {
// Extend till end of screen (docView's width)
Rectangle2D.Double childRect =
ViewUtils.shape2Bounds(childAlloc);
DocumentView docView = pView.getDocumentView();
@@ -847,6 +847,10 @@ final class ParagraphViewChildren extends
ViewChildren<EditorView> {
return new StringBuilder(10).append("
x=").append(startVisualOffset(index)).toString();
}
+ private View viewOrDelegate(View view) {
+ return view instanceof PrependedTextView ? ((PrependedTextView)
view).getDelegate() : view;
+ }
+
private static final class IndexAndAlloc {
/**
diff --git
a/java/java.editor.base/src/org/netbeans/modules/java/editor/base/semantic/SemanticHighlighterBase.java
b/java/java.editor.base/src/org/netbeans/modules/java/editor/base/semantic/SemanticHighlighterBase.java
index 00e115d..8146d84 100644
---
a/java/java.editor.base/src/org/netbeans/modules/java/editor/base/semantic/SemanticHighlighterBase.java
+++
b/java/java.editor.base/src/org/netbeans/modules/java/editor/base/semantic/SemanticHighlighterBase.java
@@ -21,6 +21,7 @@ package org.netbeans.modules.java.editor.base.semantic;
import com.sun.source.tree.ClassTree;
import com.sun.source.tree.CompilationUnitTree;
import com.sun.source.tree.ExportsTree;
+import com.sun.source.tree.ExpressionStatementTree;
import com.sun.source.tree.IdentifierTree;
import com.sun.source.tree.LiteralTree;
import com.sun.source.tree.MemberReferenceTree;
@@ -42,9 +43,12 @@ import com.sun.source.util.TreePath;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.IdentityHashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -56,6 +60,7 @@ import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
+import javax.lang.model.type.TypeMirror;
import javax.swing.text.Document;
import org.netbeans.api.java.lexer.JavaTokenId;
import org.netbeans.api.java.source.CompilationInfo;
@@ -714,6 +719,50 @@ public abstract class SemanticHighlighterBase extends
JavaParserResultTask {
}
@Override
+ public Void visitExpressionStatement(ExpressionStatementTree node,
Void p) {
+ List<TreePath> chain = new ArrayList<>(); //TODO: avoid creating
an instance if possible!
+ TreePath current = new TreePath(getCurrentPath(),
node.getExpression());
+ OUTER: while (true) {
+ chain.add(current);
+ switch (current.getLeaf().getKind()) {
+ case METHOD_INVOCATION:
+ MethodInvocationTree mit = (MethodInvocationTree)
current.getLeaf();
+ if (mit.getMethodSelect().getKind() ==
Kind.MEMBER_SELECT) {
+ current = new TreePath(new TreePath(current,
mit.getMethodSelect()), ((MemberSelectTree)
mit.getMethodSelect()).getExpression());
+ break;
+ }
+ break OUTER;
+ default:
+ break OUTER;
+ }
+ }
+ int prevIndex = tl.index();
+ Collections.reverse(chain);
+ List<Pair<String, Integer>> typeToPosition = new ArrayList<>();
+ for (TreePath tp : chain) {
+ long end =
info.getTrees().getSourcePositions().getEndPosition(tp.getCompilationUnit(),
tp.getLeaf());
+ tl.moveToOffset(end);
+ Token t = tl.currentToken();
+ int pos;
+ if (t.id() == JavaTokenId.WHITESPACE && (pos =
t.text().toString().indexOf("\n")) != -1) {
+ TypeMirror type = info.getTrees().getTypeMirror(tp);
+ String typeName =
info.getTypeUtilities().getTypeName(type).toString();
+ if (typeToPosition.isEmpty() ||
!typeName.equals(typeToPosition.get(typeToPosition.size() - 1).first())) {
+ typeToPosition.add(Pair.of(typeName, tl.offset() +
pos));
+ }
+ }
+ }
+ if (typeToPosition.size() >= 2) {
+ for (Pair<String, Integer> typeAndPosition : typeToPosition) {
+ preText.put(new int[] {(int) typeAndPosition.second(),
(int) typeAndPosition.second() + 1},
+ " " +
typeAndPosition.first());
+ }
+ }
+ tl.resetToIndex(prevIndex);
+ return super.visitExpressionStatement(node, p);
+ }
+
+ @Override
public Void visitIdentifier(IdentifierTree tree, Void p) {
if (info.getTreeUtilities().isSynthetic(getCurrentPath()))
return null;
diff --git
a/java/java.editor.base/src/org/netbeans/modules/java/editor/base/semantic/TokenList.java
b/java/java.editor.base/src/org/netbeans/modules/java/editor/base/semantic/TokenList.java
index cadc339..bc942f9 100644
---
a/java/java.editor.base/src/org/netbeans/modules/java/editor/base/semantic/TokenList.java
+++
b/java/java.editor.base/src/org/netbeans/modules/java/editor/base/semantic/TokenList.java
@@ -355,7 +355,20 @@ public class TokenList {
}
});
}
-
+
+ public int offset() {
+ return ts.offset();
+ }
+
+ public int index() {
+ return ts.index();
+ }
+
+ public void resetToIndex(int index) {
+ ts.moveIndex(index);
+ ts.moveNext();
+ }
+
private static List<TokenSequence<?>>
embeddedTokenSequences(TokenHierarchy<Document> th, int offset) {
TokenSequence<?> embedded = th.tokenSequence();
List<TokenSequence<?>> sequences = new ArrayList<TokenSequence<?>>();
diff --git
a/java/java.editor.base/test/unit/src/org/netbeans/modules/java/editor/base/semantic/DetectorTest.java
b/java/java.editor.base/test/unit/src/org/netbeans/modules/java/editor/base/semantic/DetectorTest.java
index 726b65c..c34a3eb 100644
---
a/java/java.editor.base/test/unit/src/org/netbeans/modules/java/editor/base/semantic/DetectorTest.java
+++
b/java/java.editor.base/test/unit/src/org/netbeans/modules/java/editor/base/semantic/DetectorTest.java
@@ -664,6 +664,57 @@ public class DetectorTest extends TestBase {
"[PACKAGE_PRIVATE, CONSTRUCTOR], 2:19-2:25");
}
+ public void testChainTypes() throws Exception {
+ setShowPrependedText(true);
+ performTest("Test.java",
+ "package test;\n" +
+ "public class Test<T> {\n" +
+ " public void test(Test<String> t) {\n" +
+ " t.run1()\n" +
+ " .run2()\n" +
+ " .run3()\n" +
+ " .run4();\n" +
+ " }\n" +
+ " private Test<Integer> run1() {\n" +
+ " return null;\n" +
+ " }\n" +
+ " private Test<String> run2() {\n" +
+ " return null;\n" +
+ " }\n" +
+ " private Test<Integer> run3() {\n" +
+ " return null;\n" +
+ " }\n" +
+ " private Test<String> run4() {\n" +
+ " return null;\n" +
+ " }\n" +
+ "}\n",
+ "[PUBLIC, CLASS, DECLARATION], 1:13-1:17",
+ "[PUBLIC, METHOD, DECLARATION], 2:16-2:20",
+ "[PUBLIC, CLASS], 2:21-2:25",
+ "[PUBLIC, CLASS], 2:26-2:32",
+ "[PARAMETER, DECLARATION], 2:34-2:35",
+ "[PARAMETER], 3:8-3:9",
+ "[PRIVATE, METHOD], 3:10-3:14",
+ "[ Test<Integer>], 3:16-4:0",
+ "[PRIVATE, METHOD], 4:10-4:14",
+ "[ Test<String>], 4:16-5:0",
+ "[PRIVATE, METHOD], 5:10-5:14",
+ "[ Test<Integer>], 5:16-6:0",
+ "[PRIVATE, METHOD], 6:10-6:14",
+ "[PUBLIC, CLASS], 8:12-8:16",
+ "[PUBLIC, CLASS], 8:17-8:24",
+ "[PRIVATE, METHOD, DECLARATION], 8:26-8:30",
+ "[PUBLIC, CLASS], 11:12-11:16",
+ "[PUBLIC, CLASS], 11:17-11:23",
+ "[PRIVATE, METHOD, DECLARATION], 11:25-11:29",
+ "[PUBLIC, CLASS], 14:12-14:16",
+ "[PUBLIC, CLASS], 14:17-14:24",
+ "[PRIVATE, METHOD, DECLARATION], 14:26-14:30",
+ "[PUBLIC, CLASS], 17:12-17:16",
+ "[PUBLIC, CLASS], 17:17-17:23",
+ "[PRIVATE, METHOD, DECLARATION], 17:25-17:29");
+ }
+
private void performTest(String fileName) throws Exception {
performTest(fileName, new Performer() {
public void compute(CompilationController parameter, Document doc,
final ErrorDescriptionSetter setter) {
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists