8145314: jjs tab-completion should support camel case completion
authorsundar
Mon, 14 Dec 2015 21:53:47 +0530
changeset 34733 dd9867d04e56
parent 34732 6605efbe8447
child 34734 d3a1bd20f5b3
8145314: jjs tab-completion should support camel case completion Reviewed-by: mhaupt, hannesw
nashorn/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/PropertiesHelper.java
--- a/nashorn/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/PropertiesHelper.java	Mon Dec 14 14:27:46 2015 +0100
+++ b/nashorn/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/PropertiesHelper.java	Mon Dec 14 21:53:47 2015 +0530
@@ -31,6 +31,7 @@
 import java.util.Collections;
 import java.util.List;
 import java.util.WeakHashMap;
+import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 import jdk.nashorn.internal.runtime.JSType;
 import jdk.nashorn.internal.runtime.NativeJavaPackage;
@@ -136,6 +137,42 @@
         return props;
     }
 
+    // This method creates a regex Pattern to use to do CamelCase
+    // matching. The pattern is derived from user supplied string
+    // containing one or more upper case characters in it.
+    private static Pattern makeCamelCasePattern(final String str) {
+        assert !str.isEmpty();
+
+        final char[] chars = str.toCharArray();
+        final StringBuilder buf = new StringBuilder();
+        boolean seenUpperCase = false;
+
+        // Skip first char for case check. Even if it is upper case,
+        // we do not want to put lower case matching pattern before
+        // the first letter!
+        buf.append(chars[0]);
+
+        for (int idx = 1; idx < chars.length; idx++) {
+            final char ch = chars[idx];
+            if (ch >= 'A' && ch <= 'Z') {
+                seenUpperCase = true;
+                buf.append("[^A-Z]*");
+            }
+            buf.append(ch);
+        }
+
+        if (seenUpperCase) {
+            // match anything at the end!
+            buf.append(".*");
+            try {
+                return Pattern.compile(buf.toString());
+            } catch (Exception exp) {
+            }
+        }
+
+        return null;
+    }
+
     /**
      * Returns the list of properties of the given object that start with the given prefix.
      *
@@ -145,8 +182,21 @@
      */
     List<String> getProperties(final Object obj, final String prefix) {
         assert prefix != null && !prefix.isEmpty();
-        return getProperties(obj).stream()
+        List<String> allProps = getProperties(obj);
+        List<String> props = allProps.stream()
                    .filter(s -> s.startsWith(prefix))
                    .collect(Collectors.toList());
+
+        // If no match, try CamelCase completion..
+        if (props.isEmpty()) {
+            final Pattern pat = makeCamelCasePattern(prefix);
+            if (pat != null) {
+                return allProps.stream()
+                    .filter(s -> pat.matcher(s).matches())
+                    .collect(Collectors.toList());
+            }
+        }
+
+        return props;
     }
 }