88 */
99package org .jline .script ;
1010
11- import java .io .File ;
12- import java .io .FileOutputStream ;
13- import java .io .OutputStream ;
14- import java .io .PrintStream ;
11+ import java .io .*;
1512import java .lang .reflect .Constructor ;
1613import java .lang .reflect .Field ;
1714import java .lang .reflect .Method ;
1815import java .lang .reflect .Modifier ;
19- import java .nio .file .Path ;
16+ import java .nio .file .* ;
2017import java .util .*;
2118import java .util .regex .Matcher ;
2219import java .util .regex .Pattern ;
2522import groovy .lang .*;
2623import org .apache .groovy .ast .tools .ImmutablePropertyUtils ;
2724import org .codehaus .groovy .control .messages .SyntaxErrorMessage ;
25+ import org .codehaus .groovy .runtime .metaclass .MissingMethodExceptionNoStack ;
2826import org .codehaus .groovy .syntax .SyntaxException ;
2927import org .jline .builtins .Nano .SyntaxHighlighter ;
3028import org .jline .builtins .Styles ;
@@ -79,6 +77,7 @@ public enum Format {JSON, GROOVY, NONE}
7977 private static final Pattern PATTERN_CLASS_DEF = Pattern .compile ("^class\\ s+(" + REGEX_VAR + ") .*?\\ {.*?}(|\n )$"
8078 , Pattern .DOTALL );
8179 private static final Pattern PATTERN_CLASS_NAME = Pattern .compile ("(.*?)\\ .([A-Z].*)" );
80+ private static final Pattern PATTERN_LOAD_CLASS = Pattern .compile ("(new\\ s+)*\\ s*(([a-z]+\\ .)*)([A-Z]+[a-zA-Z]*)+(\\ ..*|\\ (.*|)" );
8281 private static final List <String > DEFAULT_IMPORTS = Arrays .asList ("java.lang.*" , "java.util.*" , "java.io.*"
8382 , "java.net.*" , "groovy.lang.*" , "groovy.util.*"
8483 , "java.math.BigInteger" , "java.math.BigDecimal" );
@@ -267,17 +266,48 @@ public Object execute(String statement) throws Exception {
267266 out = "def " + name + methods .get (name );
268267 }
269268 } else {
270- StringBuilder e = new StringBuilder ();
269+ out = executeStatement (shell , imports , statement );
270+ }
271+ return out ;
272+ }
273+
274+ private static Object executeStatement (GroovyShell shell , Map <String , String > imports , String statement ) throws IOException {
275+ boolean classLoaded = false ;
276+ int idx = statement .indexOf ("=" ) + 1 ;
277+ Matcher matcher = PATTERN_LOAD_CLASS .matcher (statement .substring (idx ));
278+ if (matcher .matches ()) {
279+ String fileName = convertNull (matcher .group (2 )) + matcher .group (4 );
280+ fileName = fileName .replace ("." , "/" );
281+ for (String type : Arrays .asList (".groovy" , ".java" )) {
282+ File file = new File (fileName + type );
283+ if (file .exists ()) {
284+ try {
285+ shell .evaluate (file );
286+ } catch (MissingMethodExceptionNoStack ignore ) {
287+
288+ }
289+ classLoaded = true ;
290+ statement = statement .substring (0 , idx ) + convertNull (matcher .group (1 )) + matcher .group (4 )
291+ + convertNull (matcher .group (5 ));
292+ break ;
293+ }
294+ }
295+ }
296+ StringBuilder e = new StringBuilder ();
297+ if (!classLoaded ) {
271298 for (Map .Entry <String , String > entry : imports .entrySet ()) {
272299 e .append (entry .getValue ()).append ("\n " );
273300 }
274- e .append (statement );
275- if (classDef (statement )) {
276- e .append ("; null" );
277- }
278- out = shell .evaluate (e .toString ());
279301 }
280- return out ;
302+ e .append (statement );
303+ if (classDef (statement )) {
304+ e .append ("; null" );
305+ }
306+ return shell .evaluate (e .toString ());
307+ }
308+
309+ private static String convertNull (String string ) {
310+ return string == null ? "" : string ;
281311 }
282312
283313 @ Override
@@ -323,7 +353,7 @@ private boolean functionDef(String statement) throws Exception{
323353 return out ;
324354 }
325355
326- private boolean classDef (String statement ) {
356+ private static boolean classDef (String statement ) {
327357 return PATTERN_CLASS_DEF .matcher (statement ).matches ();
328358 }
329359
@@ -552,6 +582,41 @@ private static Map<String,String> getFields(Class<?> clazz, boolean all, boolean
552582 return out ;
553583 }
554584
585+ private static Set <String > fileDomain () {
586+ return nextFileDomain (null , 0 );
587+ }
588+
589+ private static Set <String > nextFileDomain (String domain , int position ) {
590+ String separator = FileSystems .getDefault ().getSeparator ();
591+ if (separator .equals ("\\ " )) {
592+ separator += separator ;
593+ }
594+ String dom ;
595+ if (domain != null ) {
596+ dom = domain .isEmpty () ? ".*" + separator : separator + domain .replace ("." , separator );
597+ } else {
598+ dom = separator ;
599+ }
600+ PathMatcher matcher = FileSystems .getDefault ().getPathMatcher ("regex:\\ ." + dom
601+ + "[A-Z]+[a-zA-Z]*\\ .(groovy|java)" );
602+ Set <String > out = new HashSet <>();
603+ try {
604+ List <Path > paths = Files .walk (Paths .get ("." )).filter (matcher ::matches ).collect (Collectors .toList ());
605+ for (Path p : paths ) {
606+ if (!p .getFileName ().toString ().matches ("[A-Z]+[a-zA-Z]*\\ .(groovy|java)" )){
607+ continue ;
608+ }
609+ String [] s = p .toString ().split (separator );
610+ if (s .length > position + 1 ) {
611+ out .add (s [position + 1 ].split (".(groovy|java)" )[0 ]);
612+ }
613+ }
614+ } catch (Exception ignore ) {
615+
616+ }
617+ return out ;
618+ }
619+
555620 public static Set <String > nextDomain (String domain , CandidateType type ) {
556621 return nextDomain (domain , new AccessRules (), type );
557622 }
@@ -562,8 +627,14 @@ public static Set<String> nextDomain(String domain, AccessRules access, Candidat
562627 for (String p : loadedPackages ()) {
563628 out .add (p .split ("\\ ." )[0 ]);
564629 }
630+ if (type != CandidateType .PACKAGE ) {
631+ out .addAll (nextFileDomain ("" , 0 ));
632+ }
565633 } else if ((domain .split ("\\ ." )).length < 2 ) {
566634 out = names (domain );
635+ if (type != CandidateType .PACKAGE ) {
636+ out .addAll (nextFileDomain (domain , 1 ));
637+ }
567638 } else {
568639 try {
569640 for (Class <?> c : classesForPackage (domain )) {
@@ -592,6 +663,9 @@ && noStaticFields(c, access.allFields))) {
592663 }
593664 }
594665 }
666+ if (out .isEmpty () && type != CandidateType .PACKAGE ) {
667+ out .addAll (nextFileDomain (domain , domain .split ("\\ ." ).length ));
668+ }
595669 } catch (ClassNotFoundException e ) {
596670 if (Log .isDebugEnabled ()) {
597671 e .printStackTrace ();
@@ -853,6 +927,9 @@ public void complete(LineReader reader, ParsedLine commandLine, List<Candidate>
853927 try {
854928 param = wordbuffer .substring (eqsep + 1 , varsep );
855929 Class <?> clazz = classResolver (param );
930+ if (clazz == null ) {
931+ clazz = (Class <?>)inspector .execute (param + ".class" );
932+ }
856933 if (clazz != null ) {
857934 doStaticMethodCandidates (candidates , clazz , curBuf );
858935 }
@@ -991,6 +1068,7 @@ private Set<String> retrieveConstructors(boolean all) {
9911068 it .remove ();
9921069 }
9931070 }
1071+ out .addAll (Helpers .fileDomain ());
9941072 return out ;
9951073 }
9961074
@@ -1008,6 +1086,7 @@ private Set<String> retrieveClassesWithStaticMethods() {
10081086 it .remove ();
10091087 }
10101088 }
1089+ out .addAll (Helpers .fileDomain ());
10111090 return out ;
10121091 }
10131092 }
@@ -1091,7 +1170,11 @@ public Class<?> evaluateClass(String objectStatement) {
10911170 if (!objectStatement .contains ("." ) ) {
10921171 out = (Class <?>)execute (objectStatement + ".class" );
10931172 } else {
1094- out = Class .forName (objectStatement );
1173+ try {
1174+ out = Class .forName (objectStatement );
1175+ } catch (ClassNotFoundException e ) {
1176+ out = (Class <?>)execute (objectStatement + ".class" );
1177+ }
10951178 }
10961179 }
10971180 } catch (Exception e ) {
@@ -1107,14 +1190,10 @@ public Object execute(String statement) {
11071190 System .setOut (nullstream );
11081191 System .setErr (nullstream );
11091192 }
1110- Object out ;
1193+ Object out = null ;
11111194 try {
1112- StringBuilder e = new StringBuilder ();
1113- for (Map .Entry <String , String > entry : imports .entrySet ()) {
1114- e .append (entry .getValue ()).append ("\n " );
1115- }
1116- e .append (statement );
1117- out = shell .evaluate (e .toString ());
1195+ out = executeStatement (shell , imports , statement );
1196+ } catch (IOException ignore ) {
11181197 } finally {
11191198 System .setOut (origOut );
11201199 System .setErr (origErr );
@@ -1481,7 +1560,7 @@ private CmdDesc checkSyntax(CmdLine line) {
14811560 } else {
14821561 try {
14831562 execute (objEquation );
1484- } catch (groovy . lang . MissingPropertyException e ) {
1563+ } catch (MissingPropertyException e ) {
14851564 mainDesc .addAll (doExceptionMessage (e ));
14861565 out .setErrorPattern (Pattern .compile ("\\ b" + e .getProperty () + "\\ b" ));
14871566 } catch (java .util .regex .PatternSyntaxException e ) {
0 commit comments