You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@netbeans.apache.org by lk...@apache.org on 2020/09/24 15:16:07 UTC

[netbeans] branch master updated: Show types for chained method invocations.

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 <jl...@netbeans.org>
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: 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