Named result variables

Jan Lahoda jan.lahoda at oracle.com
Mon Nov 2 15:07:35 UTC 2015


Hi Robert,

Attached is a crude prototype implementing the proposal - the shortcut 
to active the function is Alt-Enter.

(Many things, like using simple names whenever possible, could be 
improved in the prototype, but hopefully good enough for experimenting.)

Jan

On 30.10.2015 07:48, Robert Field wrote:
> Keep in mind I'm open to any solution.
>
> Let me frame my idea as a strawman so it is easier to shoot arrows at :-)
>
> Think: source code transformations that IDEs sometimes do.
> So, in this case say, ...
> You type in a complex expression expr. Then you press ctrl-V. The tool
> generates the type typedecl and an equals sign and sticks the cursor
> between them so you can type the variable name:
>
>        typedecl. |   = expr:
>
> Where | represents the cursor position.
>
> Jan can tell me if this is even something jline can do.
>
> The idea is, like tab, you type characters which don't correspond to
> valid Java, but what you see is valid.
>
> Of course what character is typed to initiate this is arbitrary.
>
> Ideas...
>
> -Robert
>
>
>
> On October 29, 2015 11:17:24 PM Robert Field <robert.field at oracle.com>
> wrote:
>
>> Thanks Cay  putting this out for discussion, would love to come up
>> with some nice solution for this.  I would like to avoid something
>> that straddles the snippet and command worlds which are now distinct.
>>
>> I don't think I expressed my idea very clearly -- mostly because it
>> isn't at all clear to me ;-)
>> What I was thinking was something vaguely tab completion like, in that
>> you wind up looking at a well formed snippet not all of which you
>> explicitly typed. But not literally a tab nor completion.
>>
>> Thanks,
>> Robert
>>
>>
>> On October 29, 2015 6:50:46 PM Cay Horstmann <cay at horstmann.com> wrote:
>>
>>> When I teach, I like to use jshell for quick demos. I might predefine
>>>
>>> <T> Set<T> setOf(T... values) { return new
>>> TreeSet<>(Arrays.asList(values)); }
>>>
>>> and then construct two sets:
>>>
>>> Set<Integer> set1 = setOf(1, 2, 3);
>>> Set<Integer> set2 = setOf(2, 3, 5);
>>> set1.removeAll(set2)
>>>
>>> Except, that's a lot of typing, so I don't do that. I do
>>>
>>> setOf(1, 2, 3);
>>> setOf(2, 3, 5);
>>> $1.removeAll($2)
>>>
>>> Note the absence of types. The $n are automatically typed.
>>>
>>> But I lose track of those $n prettty soon. It would be nice if i could
>>> name them.
>>>
>>> I brought this up at the Java One presentation and suggested
>>>
>>> /var set1 $1
>>>
>>> or
>>>
>>> /var set2
>>>
>>> to name the last $n.
>>>
>>> Robert thought that was a bit too much like inventing a new langauge
>>> feature and suggested that one might be able to solve this with tab
>>> completion instead.
>>>
>>> I thought about this a bit and couldn't come up with a compelling way.
>>> Right now, when one hits Tab on a blank line, one is offered a
>>> collection of well over 400 possible completions (types, packages,
>>> classes, $ variables). Using that to get to something like Set<Integer>
>>> or TreeMap<String, TreeSet<Integer>> isn't satisfactory.
>>>
>>> Does anyone else think that an easy way of naming results is worthwhile?
>>> Any ideas on what the user interface should be?
>>>
>>> Cheers,
>>>
>>> Cay
>>>
>>>
>>> --
>>>
>>> Cay S. Horstmann | http://horstmann.com | mailto:cay at horstmann.com
-------------- next part --------------
# HG changeset patch
# Parent  986a7f7a5601514afbe9c500f3391cc8f8b6029b

diff -r 986a7f7a5601 -r 45237629888e src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java
--- a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java	Mon Nov 02 15:04:30 2015 +0100
+++ b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java	Mon Nov 02 15:57:52 2015 +0100
@@ -144,6 +144,7 @@
         bind(DOCUMENTATION_SHORTCUT, (ActionListener) evt -> documentation(repl));
         bind(CTRL_UP, (ActionListener) evt -> moveHistoryToSnippet(((EditingHistory) in.getHistory())::previousSnippet));
         bind(CTRL_DOWN, (ActionListener) evt -> moveHistoryToSnippet(((EditingHistory) in.getHistory())::nextSnippet));
+        bind(ALT_ENTER, (ActionListener) evt -> computeType());
     }
 
     @Override
@@ -216,6 +217,7 @@
     private static final String DOCUMENTATION_SHORTCUT = "\033\133\132"; //Shift-TAB
     private static final String CTRL_UP = "\033\133\061\073\065\101"; //Ctrl-UP
     private static final String CTRL_DOWN = "\033\133\061\073\065\102"; //Ctrl-DOWN
+    private static final String ALT_ENTER = "\033\015"; //Alt-ENTER
 
     private void documentation(JShellTool repl) {
         String buffer = in.getCursorBuffer().buffer.toString();
@@ -290,6 +292,17 @@
         history.fullHistoryReplace(source);
     }
 
+    private void computeType() {
+        try {
+            String type = this.repl.analysis.analyzeType(prefix + in.getCursorBuffer().upToCursor());
+            in.setCursorPosition(0);
+            in.putString(type + "  = ");
+            in.setCursorPosition(in.getCursorBuffer().cursor - 3);
+        } catch (IOException ex) {
+            ex.printStackTrace();
+        }
+    }
+
     private static final class JShellUnixTerminal extends NoInterruptUnixTerminal {
 
         private final StopDetectingInputStream input;
diff -r 986a7f7a5601 -r 45237629888e src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysis.java
--- a/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysis.java	Mon Nov 02 15:04:30 2015 +0100
+++ b/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysis.java	Mon Nov 02 15:57:52 2015 +0100
@@ -74,6 +74,8 @@
      */
     SourceCodeAnalysis() {}
 
+    public abstract String analyzeType(String string);
+
     /**
      * The result of <code>analyzeCompletion(String input)</code>.
      * Describes the completeness and position of the first snippet in the given input.
diff -r 986a7f7a5601 -r 45237629888e src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java
--- a/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java	Mon Nov 02 15:04:30 2015 +0100
+++ b/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java	Mon Nov 02 15:57:52 2015 +0100
@@ -1184,4 +1184,31 @@
         }
         return arrayType;
     }
+
+    @Override
+    public String analyzeType(String code) {
+        //?:
+        if (code.trim().isEmpty()) { //TODO: comment handling
+            code += ";";
+        }
+        OuterWrap codeWrap;
+        switch (guessKind(code)) {
+            case IMPORT:
+                codeWrap = OuterWrap.wrapImport(null, Wrap.importWrap(code + "any.any"));
+                break;
+            case METHOD:
+                codeWrap = wrapInClass(Wrap.classMemberWrap(code));
+                break;
+            default:
+                codeWrap = wrapInClass(Wrap.methodWrap(code));
+                break;
+        }
+        AnalyzeTask at = proc.taskFactory.new AnalyzeTask(codeWrap);
+        SourcePositions sp = at.trees().getSourcePositions();
+        CompilationUnitTree topLevel = at.cuTree();
+        TreePath tp = pathFor(topLevel, sp, codeWrap.snippetIndexToWrapIndex(code.length()));
+
+        return at.trees().getTypeMirror(tp).toString();
+    }
+
 }


More information about the kulla-dev mailing list