Skip to content

Commit c803928

Browse files
committed
added importclass command to SublimeJava REPL
1 parent 57c1103 commit c803928

1 file changed

Lines changed: 145 additions & 29 deletions

File tree

SublimeJava.java

Lines changed: 145 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -289,52 +289,164 @@ private static boolean isPackage(String packageName)
289289
return false;
290290
}
291291

292-
private static void completePackage(String packageName)
293-
throws IOException
292+
private static Map<String, Set<String>> importMap = new HashMap<String, Set<String>>();
293+
private static final String CLASS_NAME_RE = "(?:$|.)?(\\w+).class";
294+
private static final String DIGITS_CLASS_NAME_RE = "\\d+";
295+
296+
private static Pattern classnamePattern, digitsClassnamePattern;
297+
static
294298
{
295-
ArrayList<String> paths = new ArrayList<String>();
299+
classnamePattern = Pattern.compile(CLASS_NAME_RE);
300+
digitsClassnamePattern = Pattern.compile(DIGITS_CLASS_NAME_RE);
301+
}
302+
303+
private static void addToImportMap(String classFileName)
304+
{
305+
Matcher classnameMatcher = classnamePattern.matcher(classFileName);
306+
if (classnameMatcher.find())
307+
{
308+
String classname = classnameMatcher.group(1);
309+
Matcher digitsClassnameMatcher = digitsClassnamePattern.matcher(classname);
310+
if (!digitsClassnameMatcher.find())
311+
{
312+
if (!importMap.containsKey(classname)) {
313+
importMap.put(classname, new HashSet<String>());
314+
}
315+
String fullClassname = classFileName.replace("/", ".").replace(".class", "");
316+
if (fullClassname.startsWith("."))
317+
{
318+
fullClassname = fullClassname.substring(1);
319+
}
320+
importMap.get(classname).add(fullClassname);
321+
}
322+
}
323+
}
324+
325+
protected static String[] getClasspathEntries()
326+
{
327+
Set<String> paths = new HashSet<String>();
296328
paths.add("java/lang/String.class");
297329
for (String s : System.getProperty("java.class.path").split(System.getProperty("path.separator")))
298330
{
299-
if (!paths.contains(s))
300-
paths.add(s);
331+
paths.add(s);
301332
}
333+
return paths.toArray(new String[0]);
334+
}
302335

303-
packageName = packageName.replace(".", "/");
304-
305-
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
306-
for (String s : paths)
336+
protected static URL getUrlFromClasspathEntry(ClassLoader classLoader, String classpathEntry, String packagePath)
337+
{
338+
URL url = null;
339+
if (classpathEntry.endsWith(".class"))
340+
url = classLoader.getResource(classpathEntry);
341+
else
307342
{
308-
URL url = null;
309-
if (s.endsWith(".class"))
310-
url = classLoader.getResource(s);
343+
String path = "file://" + new File(classpathEntry).getAbsolutePath();
344+
if (path.endsWith(".jar"))
345+
{
346+
path = "jar:" + path + "!/" + packagePath;
347+
}
311348
else
312349
{
313-
String path = "file://" + new File(s).getAbsolutePath();
314-
if (path.endsWith(".jar"))
350+
path += "/" + packagePath;
351+
}
352+
try
353+
{
354+
System.err.println("path: " + path);
355+
url = new URL(path);
356+
}
357+
catch (Exception e)
358+
{}
359+
}
360+
return url;
361+
}
362+
363+
protected static void importClass(String classname)
364+
throws IOException
365+
{
366+
boolean importMapPopulated = importMap.size() > 0;
367+
368+
if (!importMapPopulated) {
369+
String[] paths = getClasspathEntries();
370+
371+
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
372+
for (String s : paths)
373+
{
374+
URL url = getUrlFromClasspathEntry(classLoader, s, "");
375+
if (url == null)
376+
continue;
377+
System.err.println("s: " + s);
378+
System.err.println("url: " + url);
379+
380+
String filename = URLDecoder.decode(url.getFile(), "UTF-8");
381+
if (url.getProtocol().equals("jar"))
315382
{
316-
path = "jar:" + path + "!/" + packageName;
383+
filename = filename.substring(5, filename.indexOf("!"));
384+
385+
JarFile jf = new JarFile(filename);
386+
Enumeration<JarEntry> entries = jf.entries();
387+
while (entries.hasMoreElements())
388+
{
389+
addToImportMap(entries.nextElement().getName());
390+
}
317391
}
318392
else
319393
{
320-
path += "/" + packageName;
321-
}
322-
try
323-
{
324-
System.err.println("path: " + path);
325-
url = new URL(path);
394+
File folder = new File(filename);
395+
File[] classFiles = getClassFilesNotInJar(folder).toArray(new File[0]);
396+
for (File classFile : classFiles)
397+
{
398+
addToImportMap(classFile.getAbsolutePath().substring(folder.getAbsolutePath().length()));
399+
}
326400
}
327-
catch (Exception e)
328-
{}
329401
}
402+
}
403+
404+
Set<String> possibleImports = importMap.get(classname);
405+
if (possibleImports != null)
406+
{
407+
for (String impClass : possibleImports)
408+
{
409+
System.out.println(impClass + "\tclass" + sep + impClass);
410+
}
411+
}
412+
}
413+
414+
protected static Set<File> getClassFilesNotInJar(File current)
415+
{
416+
Set<File> classFiles = new HashSet<File>();
417+
if (current.isFile() && current.getName().endsWith(".class"))
418+
{
419+
classFiles.add(current);
420+
}
421+
else if (current.isDirectory())
422+
{
423+
for (File file : current.listFiles())
424+
{
425+
classFiles.addAll(getClassFilesNotInJar(file));
426+
}
427+
}
428+
return classFiles;
429+
}
430+
431+
protected static void completePackage(String packageName)
432+
throws IOException
433+
{
434+
String[] paths = getClasspathEntries();
435+
436+
String packagePath = packageName.replace(".", "/");
437+
438+
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
439+
for (String s : paths)
440+
{
441+
URL url = getUrlFromClasspathEntry(classLoader, s, packagePath);
330442
if (url == null)
331443
continue;
332444
System.err.println("s: " + s);
333-
System.err.println("packagename: " + packageName);
445+
System.err.println("packagename: " + packagePath);
334446
System.err.println("url: " + url);
335447

336448
String filename = URLDecoder.decode(url.getFile(), "UTF-8");
337-
ArrayList<String> packages = new ArrayList<String>();
449+
Set<String> packages = new HashSet<String>();
338450
if (url.getProtocol().equals("jar"))
339451
{
340452
filename = filename.substring(5, filename.indexOf("!"));
@@ -344,16 +456,15 @@ private static void completePackage(String packageName)
344456
while (entries.hasMoreElements())
345457
{
346458
String name = entries.nextElement().getName();
347-
if (name.startsWith(packageName))
459+
if (name.startsWith(packagePath))
348460
{
349-
name = name.substring(packageName.length()+1);
461+
name = name.substring(packagePath.length()+1);
350462
int idx = name.indexOf('/');
351463
if (idx != -1)
352464
{
353465
name = name.substring(0, idx);
354-
if (!packages.contains(name))
466+
if (packages.add(name))
355467
{
356-
packages.add(name);
357468
System.out.println(name + "\tpackage" + sep + name);
358469
}
359470
continue;
@@ -417,6 +528,11 @@ public static void main(String... unusedargs)
417528
System.err.println("quitting upon request");
418529
return;
419530
}
531+
else if (args[0].equals("-importclass"))
532+
{
533+
importClass(args[1]);
534+
continue;
535+
}
420536
else if (args[0].equals("-findclass"))
421537
{
422538
String line = null;

0 commit comments

Comments
 (0)