3030 */
3131package org .scijava .script .autocompletion ;
3232
33+ import java .lang .reflect .Array ;
34+ import java .lang .reflect .Field ;
35+ import java .lang .reflect .Method ;
3336import java .util .ArrayList ;
37+ import java .util .Arrays ;
3438import java .util .Collections ;
3539import java .util .Comparator ;
3640import java .util .List ;
41+ import java .util .Map ;
3742import javax .script .Bindings ;
3843import javax .script .ScriptContext ;
3944import javax .script .ScriptEngine ;
@@ -62,8 +67,20 @@ public AutoCompletionResult autocomplete(String code, int index, ScriptEngine en
6267 List <String > matches = new ArrayList <>();
6368 int startIndex = 0 ;
6469
65- // Naive autocompletion with variables in the engine scope
66- matches .addAll (engineVariablesCompleter (code , index , engine ));
70+ if (code .endsWith ("." )) {
71+ // Autocompletion with all the attributes of the object
72+ matches .addAll (this .engineAttributesCompleter (code , index , engine ));
73+
74+ } else if (code .contains ("." )) {
75+ List codeList = Arrays .asList (code .split ("\\ ." ));
76+ String objectString = (String ) codeList .get (codeList .size () - 2 );
77+ String fieldBeginWith = (String ) codeList .get (codeList .size () - 1 );
78+ matches .addAll (this .engineAttributesCompleter (objectString + "." , fieldBeginWith , index , engine ));
79+
80+ } else {
81+ // Autocompletion with variables in the engine scope
82+ matches .addAll (this .engineVariablesCompleter (code , index , engine ));
83+ }
6784
6885 // Sort matches alphabetcially
6986 Collections .sort (matches , new SortIgnoreCase ());
@@ -80,6 +97,29 @@ private List<String> engineVariablesCompleter(String code, int index, ScriptEngi
8097 for (String key : bindings .keySet ()) {
8198 if (key .toLowerCase ().startsWith (code .toLowerCase ())) {
8299 matches .add (key );
100+ };
101+ }
102+ return matches ;
103+
104+ }
105+
106+ private List <String > engineAttributesCompleter (String objectString , int index , ScriptEngine engine ) {
107+ return this .engineAttributesCompleter (objectString , "" , index , engine );
108+ }
109+
110+ private List <String > engineAttributesCompleter (String objectString , String fieldBeginWith , int index , ScriptEngine engine ) {
111+ List <String > matches = new ArrayList <>();
112+
113+ Bindings bindings = engine .getBindings (ScriptContext .ENGINE_SCOPE );
114+
115+ for (String key : bindings .keySet ()) {
116+ if (objectString .endsWith (key + "." )) {
117+ Object obj = bindings .get (key );
118+ for (Field field : obj .getClass ().getDeclaredFields ()) {
119+ if (field .getName ().toLowerCase ().startsWith (fieldBeginWith .toLowerCase ())) {
120+ matches .add (objectString + field .getName ());
121+ }
122+ }
83123 }
84124 }
85125
0 commit comments