07/19/2015 - Fixed enjarify.
07/20/2015 - Bibl sexified the boot loading time.
07/20/2015 - Decode APK Resources is selected by default.
07/20/2015 - Made the security manager slightly safer, it can still be
targeted but not as obviously now.
07/20/2015 - Added CLI to the boot page.
07/21/2015 - Added support for offline mode in case you cannot connect
to github for some reason. (kicks in after 7 seconds)
07/21/2015 - Added fatjar option back, in case anyone wants a 100%
portable version.
07/21/2015 - Made it so it now shows the decompiler it's using -
http://i.imgur.com/yMEzXwv.png.
07/21/2015 - Rewrote the file system, it now shows the path of the jar
it's got loaded.
07/21/2015 - Now it shows if the decompiler is in editable mode or not.
07/21/2015 - Fixed Enjarify bug from new security manager.
07/22/2015 - Fixed a typo (Thanks affffsdsd)
07/22/2015 - Finally added icons to the File Navigator, credits to
http://famfamfam.com/lab/icons/silk/ for the icons.
07/22/2015 - JD-GUI is now the default decompiler for GUI.
07/22/2015 - Added Set Python 3.X to the UI.
07/22/2015 - Fixed krakatau/export as jar bug introduced by file system
update.
07/22/2015 - Sped up krakatau decompiler/disassembler on big files.
07/22/2015 - Made it so when you press enter on the file navigation pane
it opens the class.
07/22/2015 - The Quick file search now opens the files again.
07/23/2015 - Fixed opening single files and file folders into BCV
07/24/2015 - Added File>Reload Resources.
07/26/2015 - Fixed the view pane refresh after toggling a viewer, it's
now flawless.
07/26/2015 - Fixed Krakatau Disassembler.
07/26/2015 - Mibbzz is gay once again.
07/30/2015 - Removed Janino Compiler & moved to Javac, it can now
compile decompiled classes again.
07/30/2015 - Affssdd fixed the File Navigator Pane's Quick Class Search.
07/30/2015 - Fixed a process leak in KrakatauDisassembler.
07/30/2015 - Started working on converting all the decompilers to launch
in their own process in an effort to reduce BCV resources (only for
non-fatjar version).
This commit is contained in:
Konloch 2015-07-30 13:39:17 -06:00
parent a654899888
commit 89a14066da

AI 샘플 코드 생성 중입니다

Loading...
107 changed files with 909 additions and 37941 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
BytecodeViewer 2.9.8.jar Normal file

Binary file not shown.

View File

@ -385,4 +385,33 @@ Changelog:
07/16/2015 - Removed the FileFilter classes.
07/16/2015 - Updated the decompiler class to make more sense.
07/16/2015 - Started working on BCV CLI.
07/16/2015 - Finished BCV CLI.
07/16/2015 - Finished BCV CLI.
--- 2.9.8 ---:
07/19/2015 - Fixed enjarify.
07/20/2015 - Bibl sexified the boot loading time.
07/20/2015 - Decode APK Resources is selected by default.
07/20/2015 - Made the security manager slightly safer, it can still be targeted but not as obviously now.
07/20/2015 - Added CLI to the boot page.
07/21/2015 - Added support for offline mode in case you cannot connect to github for some reason. (kicks in after 7 seconds)
07/21/2015 - Added fatjar option back, in case anyone wants a 100% portable version.
07/21/2015 - Made it so it now shows the decompiler it's using - http://i.imgur.com/yMEzXwv.png.
07/21/2015 - Rewrote the file system, it now shows the path of the jar it's got loaded.
07/21/2015 - Now it shows if the decompiler is in editable mode or not.
07/21/2015 - Fixed Enjarify bug from new security manager.
07/22/2015 - Fixed a typo (Thanks affffsdsd)
07/22/2015 - Finally added icons to the File Navigator, credits to http://famfamfam.com/lab/icons/silk/ for the icons.
07/22/2015 - JD-GUI is now the default decompiler for GUI.
07/22/2015 - Added Set Python 3.X to the UI.
07/22/2015 - Fixed krakatau/export as jar bug introduced by file system update.
07/22/2015 - Sped up krakatau decompiler/disassembler on big files.
07/22/2015 - Made it so when you press enter on the file navigation pane it opens the class.
07/22/2015 - The Quick file search now opens the files again.
07/23/2015 - Fixed opening single files and file folders into BCV
07/24/2015 - Added File>Reload Resources.
07/26/2015 - Fixed the view pane refresh after toggling a viewer, it's now flawless.
07/26/2015 - Fixed Krakatau Disassembler.
07/26/2015 - Mibbzz is gay once again.
07/30/2015 - Removed Janino Compiler & moved to Javac, it can now compile decompiled classes again.
07/30/2015 - Affssdd fixed the File Navigator Pane's Quick Class Search.
07/30/2015 - Fixed a process leak in KrakatauDisassembler.
07/30/2015 - Started working on converting all the decompilers to launch in their own process in an effort to reduce BCV resources (only for non-fatjar version).

View File

@ -12,7 +12,7 @@
<lib>w32api/libuser32.a</lib>
<lib>w32api/libadvapi32.a</lib>
<lib>w32api/libshell32.a</lib>
<jar>H:\Repo\BCV\bytecode-viewer\BytecodeViewer 2.9.7.jar</jar>
<jar>H:\Repo\BCV\bytecode-viewer\BytecodeViewer 2.9.8.jar</jar>
<outfile>H:\Repo\BCV\bytecode-viewer\BytecodeViewer.exe</outfile>
<errTitle></errTitle>
<cmdLine></cmdLine>

Binary file not shown.

BIN
libs/janino.jar Normal file

Binary file not shown.

View File

@ -1,56 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino;
import org.codehaus.janino.util.enumerator.Enumerator;
import org.codehaus.janino.util.enumerator.EnumeratorFormatException;
/** Return value for {@link IClass.IMember#getAccess}. */
public final
class Access extends Enumerator {
/** Representation of PRIVATE accessibility. */
public static final Access PRIVATE = new Access("private");
/** Representation of PROTECTED accessibility. */
public static final Access PROTECTED = new Access("protected");
/** Representation of DEFAULT accessibility. */
public static final Access DEFAULT = new Access("/*default*/");
/** Representation of PUBLIC accessibility. */
public static final Access PUBLIC = new Access("public");
// These MUST be declared exactly like this:
private Access(String name) { super(name); }
/** @return The {@code name} converted to {@link Access} */
public static Access
fromString(String name) throws EnumeratorFormatException {
return (Access) Enumerator.fromString(name, Access.class);
}
}

View File

@ -1,74 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino;
import java.util.Map;
/** This {@link ClassLoader} allows for the loading of a set of Java&trade; classes provided in class file format. */
@SuppressWarnings({ "rawtypes", "unchecked" }) public
class ByteArrayClassLoader extends ClassLoader {
/**
* The given {@link Map} of classes must not be modified afterwards.
*
* @param classes String className => byte[] data
*/
public
ByteArrayClassLoader(Map<String /*className*/, byte[] /*data*/> classes) { this.classes = classes; }
/** @see #ByteArrayClassLoader(Map) */
public
ByteArrayClassLoader(Map<String /*className*/, byte[] /*data*/> classes, ClassLoader parent) {
super(parent);
this.classes = classes;
}
/**
* Implements {@link ClassLoader#findClass(String)}.
* <p>
* Notice that, although nowhere documented, no more than one thread at a time calls this
* method, because {@link ClassLoader#loadClass(java.lang.String)} is
* <code>synchronized</code>.
*/
@Override protected Class
findClass(String name) throws ClassNotFoundException {
byte[] data = (byte[]) this.classes.get(name);
if (data == null) throw new ClassNotFoundException(name);
// Notice: Not inheriting the protection domain will cause problems with Java Web Start /
// JNLP. See
// http://jira.codehaus.org/browse/JANINO-104
// http://www.nabble.com/-Help-jel--java.security.AccessControlException-to13073723.html
return super.defineClass(
name, // name
data, 0, data.length, // b, off, len
this.getClass().getProtectionDomain() // protectionDomain
);
}
private final Map<String /*className*/, byte[] /*data*/> classes;
}

View File

@ -1,218 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
import org.codehaus.janino.util.ClassFile;
import org.codehaus.janino.util.resource.DirectoryResourceCreator;
import org.codehaus.janino.util.resource.DirectoryResourceFinder;
import org.codehaus.janino.util.resource.PathResourceFinder;
import org.codehaus.janino.util.resource.Resource;
import org.codehaus.janino.util.resource.ResourceCreator;
import org.codehaus.janino.util.resource.ResourceFinder;
/**
* A {@link org.codehaus.janino.JavaSourceClassLoader} that uses a resource storage provided by the application to cache
* compiled classes and thus saving unnecessary recompilations.
* <p>
* The application provides access to the resource storeage through a pair of a {@link
* org.codehaus.janino.util.resource.ResourceFinder} and a {@link org.codehaus.janino.util.resource.ResourceCreator}
* (see {@link #CachingJavaSourceClassLoader(ClassLoader, ResourceFinder, String, ResourceFinder, ResourceCreator)}.
* <p>
* See {@link org.codehaus.janino.JavaSourceClassLoader#main(String[])} for an example how to use this class.
* <p>
* <b>Notice:</b> You must NOT rely on that this class stores some particular data in some particular resources through
* the given {@code classFileCacheResourceFinder/Creator}! These serve only as a means for the {@link
* CachingJavaSourceClassLoader} to persistently cache some data between invocations. In other words: If you want to
* compile {@code .java} files into {@code .class} files, then don't use <i>this</i> class but {@link Compiler}
* instead!
*/
@SuppressWarnings({ "rawtypes", "unchecked" }) public
class CachingJavaSourceClassLoader extends JavaSourceClassLoader {
private final ResourceFinder classFileCacheResourceFinder;
private final ResourceCreator classFileCacheResourceCreator;
private final ResourceFinder sourceFinder;
/**
* See {@link #CachingJavaSourceClassLoader(ClassLoader, ResourceFinder, String, ResourceFinder, ResourceCreator)}.
*
* @param optionalSourcePath Directories to scan for source files
* @param cacheDirectory Directory to use for caching generated class files (see class description)
*/
public
CachingJavaSourceClassLoader(
ClassLoader parentClassLoader,
File[] optionalSourcePath,
String optionalCharacterEncoding,
File cacheDirectory
) {
this(
parentClassLoader, // parentClassLoader
( // sourceFinder
optionalSourcePath == null
? (ResourceFinder) new DirectoryResourceFinder(new File("."))
: (ResourceFinder) new PathResourceFinder(optionalSourcePath)
),
optionalCharacterEncoding, // optionalCharacterEncoding
new DirectoryResourceFinder(cacheDirectory), // classFileCacheResourceFinder
new DirectoryResourceCreator(cacheDirectory) // classFileCacheResourceCreator
);
}
/**
* Notice that this class is thread-safe if and only if the {@code classFileCacheResourceCreator} stores its data
* atomically, i.e. the {@code classFileCacheResourceFinder} sees the resource written by the {@code
* classFileCacheResourceCreator} only after the {@link OutputStream} is closed.
* <p>
* In order to make the caching scheme work, both the {@code classFileCacheResourceFinder} and the {@code
* sourceFinder} must support the {@link org.codehaus.janino.util.resource.Resource#lastModified()} method, so that
* the modification time of the source and the class files can be compared.
*
* @param parentClassLoader Attempt to load classes through this one before looking for source files
* @param sourceFinder Finds Java&trade; source for class {@code pkg.Cls} in resource {@code
* pkg/Cls.java}
* @param optionalCharacterEncoding Encoding of Java&trade; source or {@code null} for platform default
* encoding
* @param classFileCacheResourceFinder Finds precompiled class {@code pkg.Cls} in resource {@code pkg/Cls.class}
* (see class description)
* @param classFileCacheResourceCreator Stores compiled class {@code pkg.Cls} in resource {@code pkg/Cls.class} (see
* class description)
*/
public
CachingJavaSourceClassLoader(
ClassLoader parentClassLoader,
ResourceFinder sourceFinder,
String optionalCharacterEncoding,
ResourceFinder classFileCacheResourceFinder,
ResourceCreator classFileCacheResourceCreator
) {
super(parentClassLoader, sourceFinder, optionalCharacterEncoding);
this.classFileCacheResourceFinder = classFileCacheResourceFinder;
this.classFileCacheResourceCreator = classFileCacheResourceCreator;
this.sourceFinder = sourceFinder;
}
/**
* Override {@link JavaSourceClassLoader#generateBytecodes(String)} to implement class file caching.
*
* @return String name => byte[] bytecode, or {@code null} if no source code could be found
* @throws ClassNotFoundException Compilation problems or class file cache I/O problems
*/
@Override protected Map<String /*name*/, byte[] /*bytecode*/>
generateBytecodes(String className) throws ClassNotFoundException {
// Check whether a class file resource exists in the cache.
{
Resource classFileResource = this.classFileCacheResourceFinder.findResource(
ClassFile.getClassFileResourceName(className)
);
if (classFileResource != null) {
// Check whether a source file resource exists.
Resource sourceResource = this.sourceFinder.findResource(ClassFile.getSourceResourceName(className));
if (sourceResource == null) return null;
// Check whether the class file is up-to-date.
if (sourceResource.lastModified() < classFileResource.lastModified()) {
// Yes, it is... read the bytecode from the file and define the class.
byte[] bytecode;
try {
bytecode = CachingJavaSourceClassLoader.readResource(classFileResource);
} catch (IOException ex) {
throw new ClassNotFoundException("Reading class file from \"" + classFileResource + "\"", ex);
}
Map<String /*name*/, byte[] /*bytecode*/> m = new HashMap();
m.put(className, bytecode);
return m;
}
}
}
// Cache miss... generate the bytecode from source.
Map<String /*name*/, byte[] /*bytecode*/> bytecodes = super.generateBytecodes(className);
if (bytecodes == null) return null;
// Write the generated bytecodes to the class file cache.
for (Map.Entry<String, byte[]> me : bytecodes.entrySet()) {
String className2 = (String) me.getKey();
byte[] bytecode = (byte[]) me.getValue();
try {
CachingJavaSourceClassLoader.writeResource(
this.classFileCacheResourceCreator,
ClassFile.getClassFileResourceName(className2),
bytecode
);
} catch (IOException ex) {
throw new ClassNotFoundException(
"Writing class file to \"" + ClassFile.getClassFileResourceName(className2) + "\"",
ex
);
}
}
return bytecodes;
}
/** Reads all bytes from the given resource. */
private static byte[]
readResource(Resource r) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[4096];
InputStream is = r.open();
try {
for (;;) {
int cnt = is.read(buffer);
if (cnt == -1) break;
baos.write(buffer, 0, cnt);
}
} finally {
try { is.close(); } catch (IOException ex) {}
}
return baos.toByteArray();
}
/** Create a resource with the given name and store the data in it. */
private static void
writeResource(ResourceCreator resourceCreator, String resourceName, byte[] data) throws IOException {
OutputStream os = resourceCreator.createResource(resourceName);
try {
os.write(data);
} finally {
try { os.close(); } catch (IOException ex) {}
}
}
}

View File

@ -1,445 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import org.codehaus.commons.compiler.CompileException;
import org.codehaus.commons.compiler.CompilerFactoryFactory;
import org.codehaus.commons.compiler.Cookable;
import org.codehaus.commons.compiler.IClassBodyEvaluator;
import org.codehaus.commons.compiler.ICompilerFactory;
import org.codehaus.commons.compiler.Location;
/**
* The <code>optionalClassLoader</code> serves two purposes:
* <ul>
* <li>It is used to look for classes referenced by the class body.
* <li>It is used to load the generated Java&trade; class
* into the JVM; directly if it is a subclass of {@link
* ByteArrayClassLoader}, or by creation of a temporary
* {@link ByteArrayClassLoader} if not.
* </ul>
* A number of "convenience constructors" exist that execute the setup steps instantly.
*/
@SuppressWarnings("rawtypes") public
class ClassBodyEvaluator extends SimpleCompiler implements IClassBodyEvaluator {
private static final Class[] ZERO_CLASSES = new Class[0];
private String[] optionalDefaultImports;
private String className = IClassBodyEvaluator.DEFAULT_CLASS_NAME;
private Class optionalExtendedType;
private Class[] implementedTypes = ClassBodyEvaluator.ZERO_CLASSES;
private Class result; // null=uncooked
/**
* Equivalent to<pre>
* ClassBodyEvaluator cbe = new ClassBodyEvaluator();
* cbe.cook(classBody);</pre>
*
* @see #ClassBodyEvaluator()
* @see Cookable#cook(String)
*/
public
ClassBodyEvaluator(String classBody) throws CompileException { this.cook(classBody); }
/**
* Equivalent to<pre>
* ClassBodyEvaluator cbe = new ClassBodyEvaluator();
* cbe.cook(optionalFileName, is);</pre>
*
* @see #ClassBodyEvaluator()
* @see Cookable#cook(String, InputStream)
*/
public
ClassBodyEvaluator(String optionalFileName, InputStream is) throws CompileException, IOException {
this.cook(optionalFileName, is);
}
/**
* Equivalent to<pre>
* ClassBodyEvaluator cbe = new ClassBodyEvaluator();
* cbe.cook(optionalFileName, reader);</pre>
*
* @see #ClassBodyEvaluator()
* @see Cookable#cook(String, Reader)
*/
public
ClassBodyEvaluator(String optionalFileName, Reader reader) throws CompileException, IOException {
this.cook(optionalFileName, reader);
}
/**
* Equivalent to<pre>
* ClassBodyEvaluator cbe = new ClassBodyEvaluator();
* cbe.setParentClassLoader(optionalParentClassLoader);
* cbe.cook(scanner);</pre>
*
* @see #ClassBodyEvaluator()
* @see SimpleCompiler#setParentClassLoader(ClassLoader)
* @see Cookable#cook(Reader)
*/
public
ClassBodyEvaluator(Scanner scanner, ClassLoader optionalParentClassLoader) throws CompileException, IOException {
this.setParentClassLoader(optionalParentClassLoader);
this.cook(scanner);
}
/**
* Equivalent to<pre>
* ClassBodyEvaluator cbe = new ClassBodyEvaluator();
* cbe.setExtendedType(optionalExtendedType);
* cbe.setImplementedTypes(implementedTypes);
* cbe.setParentClassLoader(optionalParentClassLoader);
* cbe.cook(scanner);</pre>
*
* @see #ClassBodyEvaluator()
* @see #setExtendedClass(Class)
* @see #setImplementedInterfaces(Class[])
* @see SimpleCompiler#setParentClassLoader(ClassLoader)
* @see Cookable#cook(Reader)
*/
public
ClassBodyEvaluator(
Scanner scanner,
Class optionalExtendedType,
Class[] implementedTypes,
ClassLoader optionalParentClassLoader
) throws CompileException, IOException {
this.setExtendedClass(optionalExtendedType);
this.setImplementedInterfaces(implementedTypes);
this.setParentClassLoader(optionalParentClassLoader);
this.cook(scanner);
}
/**
* Equivalent to<pre>
* ClassBodyEvaluator cbe = new ClassBodyEvaluator();
* cbe.setClassName(className);
* cbe.setExtendedType(optionalExtendedType);
* cbe.setImplementedTypes(implementedTypes);
* cbe.setParentClassLoader(optionalParentClassLoader);
* cbe.cook(scanner);</pre>
*
* @see #ClassBodyEvaluator()
* @see #setClassName(String)
* @see #setExtendedClass(Class)
* @see #setImplementedInterfaces(Class[])
* @see SimpleCompiler#setParentClassLoader(ClassLoader)
* @see Cookable#cook(Reader)
*/
public
ClassBodyEvaluator(
Scanner scanner,
String className,
Class optionalExtendedType,
Class[] implementedTypes,
ClassLoader optionalParentClassLoader
) throws CompileException, IOException {
this.setClassName(className);
this.setExtendedClass(optionalExtendedType);
this.setImplementedInterfaces(implementedTypes);
this.setParentClassLoader(optionalParentClassLoader);
this.cook(scanner);
}
public ClassBodyEvaluator() {}
@Override public void
setDefaultImports(String[] optionalDefaultImports) {
this.assertNotCooked();
this.optionalDefaultImports = optionalDefaultImports;
}
@Override public void
setClassName(String className) {
if (className == null) throw new NullPointerException();
this.assertNotCooked();
this.className = className;
}
@Override public void
setExtendedClass(Class optionalExtendedType) {
this.assertNotCooked();
this.optionalExtendedType = optionalExtendedType;
}
/** @deprecated */
@Deprecated @Override public void
setExtendedType(Class optionalExtendedClass) {
this.setExtendedClass(optionalExtendedClass);
}
@Override public void
setImplementedInterfaces(Class[] implementedTypes) {
if (implementedTypes == null) {
throw new NullPointerException(
"Zero implemented types must be specified as 'new Class[0]', not 'null'"
);
}
this.assertNotCooked();
this.implementedTypes = implementedTypes;
}
/** @deprecated */
@Deprecated @Override public void
setImplementedTypes(Class[] implementedInterfaces) {
this.setImplementedInterfaces(implementedInterfaces);
}
@Override public void
cook(Scanner scanner) throws CompileException, IOException {
Parser parser = new Parser(scanner);
Java.CompilationUnit compilationUnit = this.makeCompilationUnit(parser);
// Add class declaration.
Java.ClassDeclaration cd = this.addPackageMemberClassDeclaration(scanner.location(), compilationUnit);
// Parse class body declarations (member declarations) until EOF.
while (!parser.peekEof()) {
parser.parseClassBodyDeclaration(cd);
}
// Compile and load it.
this.result = this.compileToClass(compilationUnit);
}
/**
* Create a {@link Java.CompilationUnit}, set the default imports, and parse the import declarations.
* <p>
* If the <code>optionalParser</code> is given, a sequence of IMPORT directives is parsed from it and added to the
* compilation unit.
*/
protected final Java.CompilationUnit
makeCompilationUnit(Parser optionalParser) throws CompileException, IOException {
Java.CompilationUnit cu = (
new Java.CompilationUnit(optionalParser == null
? null
: optionalParser.getScanner().getFileName())
);
// Set default imports.
if (this.optionalDefaultImports != null) {
for (String defaultImport : this.optionalDefaultImports) {
Scanner s = new Scanner(null, new StringReader(defaultImport));
Parser parser2 = new Parser(s);
cu.addImportDeclaration(parser2.parseImportDeclarationBody());
if (!parser2.peekEof()) {
throw new CompileException(
"Unexpected token '" + parser2.peek() + "' in default import",
s.location()
);
}
}
}
// Parse all available IMPORT declarations.
if (optionalParser != null) {
while (optionalParser.peek("import")) {
cu.addImportDeclaration(optionalParser.parseImportDeclaration());
}
}
return cu;
}
/**
* To the given {@link Java.CompilationUnit}, add
* <ul>
* <li>A class declaration with the configured name, superclass and interfaces
* <li>A method declaration with the given return type, name, parameter names and values and thrown exceptions
* </ul>
*
* @return The created {@link Java.ClassDeclaration} object
*/
protected Java.PackageMemberClassDeclaration
addPackageMemberClassDeclaration(Location location, Java.CompilationUnit compilationUnit) throws CompileException {
String cn = this.className;
int idx = cn.lastIndexOf('.');
if (idx != -1) {
compilationUnit.setPackageDeclaration(new Java.PackageDeclaration(location, cn.substring(0, idx)));
cn = cn.substring(idx + 1);
}
Java.PackageMemberClassDeclaration tlcd = new Java.PackageMemberClassDeclaration(
location, // location
null, // optionalDocComment
new Java.Modifiers(Mod.PUBLIC), // modifiers
cn, // name
null, // optionalTypeParameters
this.classToType(location, this.optionalExtendedType), // optionalExtendedType
this.classesToTypes(location, this.implementedTypes) // implementedTypes
);
compilationUnit.addPackageMemberTypeDeclaration(tlcd);
return tlcd;
}
/**
* Compile the given compilation unit, load all generated classes, and return the class with the given name.
*
* @param compilationUnit
* @return The loaded class
*/
protected final Class
compileToClass(Java.CompilationUnit compilationUnit) throws CompileException {
// Compile and load the compilation unit.
ClassLoader cl = this.compileToClassLoader(compilationUnit);
// Find the generated class by name.
try {
return cl.loadClass(this.className);
} catch (ClassNotFoundException ex) {
throw new JaninoRuntimeException((
"SNO: Generated compilation unit does not declare class '"
+ this.className
+ "'"
), ex);
}
}
@Override public Class
getClazz() {
if (this.getClass() != ClassBodyEvaluator.class) {
throw new IllegalStateException("Must not be called on derived instances");
}
if (this.result == null) throw new IllegalStateException("Must only be called after 'cook()'");
return this.result;
}
@Override public Object
createInstance(Reader reader) throws CompileException, IOException {
this.cook(reader);
try {
return this.getClazz().newInstance();
} catch (InstantiationException ie) {
CompileException ce = new CompileException((
"Class is abstract, an interface, an array class, a primitive type, or void; "
+ "or has no zero-parameter constructor"
), null);
ce.initCause(ie);
throw ce; // SUPPRESS CHECKSTYLE AvoidHidingCause
} catch (IllegalAccessException iae) {
CompileException ce = new CompileException(
"The class or its zero-parameter constructor is not accessible",
null
);
ce.initCause(iae);
throw ce; // SUPPRESS CHECKSTYLE AvoidHidingCause
}
}
/**
* Use {@link #createInstance(Reader)} instead:
* <pre>
* IClassBodyEvaluator cbe = {@link CompilerFactoryFactory}.{@link
* CompilerFactoryFactory#getDefaultCompilerFactory() getDefaultCompilerFactory}().{@link
* ICompilerFactory#newClassBodyEvaluator() newClassBodyEvaluator}();
* if (optionalBaseType != null) {
* if (optionalBaseType.isInterface()) {
* cbe.{@link #setImplementedInterfaces setImplementedInterfaces}(new Class[] { optionalBaseType });
* } else {
* cbe.{@link #setExtendedClass(Class) setExtendedClass}(optionalBaseType);
* }
* }
* cbe.{@link #setParentClassLoader(ClassLoader) setParentClassLoader}(optionalParentClassLoader);
* cbe.{@link IClassBodyEvaluator#createInstance(Reader) createInstance}(reader);
* </pre>
*
* @see #createInstance(Reader)
*/
public static Object
createFastClassBodyEvaluator(
Scanner scanner,
Class optionalBaseType,
ClassLoader optionalParentClassLoader
) throws CompileException, IOException {
return ClassBodyEvaluator.createFastClassBodyEvaluator(
scanner, // scanner
IClassBodyEvaluator.DEFAULT_CLASS_NAME, // className
( // optionalExtendedType
optionalBaseType != null && !optionalBaseType.isInterface()
? optionalBaseType
: null
),
( // implementedTypes
optionalBaseType != null && optionalBaseType.isInterface()
? new Class[] { optionalBaseType }
: new Class[0]
),
optionalParentClassLoader // optionalParentClassLoader
);
}
/**
* Use {@link #createInstance(Reader)} instead:
* <pre>
* IClassBodyEvaluator cbe = {@link CompilerFactoryFactory}.{@link
* CompilerFactoryFactory#getDefaultCompilerFactory() getDefaultCompilerFactory}().{@link
* ICompilerFactory#newClassBodyEvaluator() newClassBodyEvaluator}();
* cbe.{@link #setExtendedClass(Class) setExtendedClass}(optionalExtendedClass);
* cbe.{@link #setImplementedInterfaces(Class[]) setImplementedInterfaces}(implementedInterfaces);
* cbe.{@link #setParentClassLoader(ClassLoader) setParentClassLoader}(optionalParentClassLoader);
* cbe.{@link IClassBodyEvaluator#createInstance(Reader) createInstance}(reader);
* </pre>
*
* @see #createInstance(Reader)
* @deprecated Use {@link #createInstance(Reader)} instead.
*/
@Deprecated public static Object
createFastClassBodyEvaluator(
Scanner scanner,
String className,
Class optionalExtendedClass,
Class[] implementedInterfaces,
ClassLoader optionalParentClassLoader
) throws CompileException, IOException {
ClassBodyEvaluator cbe = new ClassBodyEvaluator();
cbe.setClassName(className);
cbe.setExtendedClass(optionalExtendedClass);
cbe.setImplementedInterfaces(implementedInterfaces);
cbe.setParentClassLoader(optionalParentClassLoader);
cbe.cook(scanner);
Class c = cbe.getClazz();
try {
return c.newInstance();
} catch (InstantiationException e) {
throw new CompileException( // SUPPRESS CHECKSTYLE AvoidHidingCause
e.getMessage(),
null
);
} catch (IllegalAccessException e) {
// SNO - type and default constructor of generated class are PUBLIC.
throw new JaninoRuntimeException(e.toString(), e);
}
}
}

View File

@ -1,438 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.codehaus.commons.compiler.CompileException;
import org.codehaus.janino.util.ClassFile;
import org.codehaus.janino.util.ClassFile.ConstantClassInfo;
/** A wrapper object that turns a {@link ClassFile} object into an {@link IClass}. */
@SuppressWarnings({ "rawtypes", "unchecked" }) public
class ClassFileIClass extends IClass {
private static final boolean DEBUG = false;
private final ClassFile classFile;
private final IClassLoader iClassLoader;
private final short accessFlags;
private final Map<ClassFile.FieldInfo, IField> resolvedFields = new HashMap();
/**
* @param classFile Source of data
* @param iClassLoader {@link IClassLoader} through which to load other classes
*/
public
ClassFileIClass(ClassFile classFile, IClassLoader iClassLoader) {
this.classFile = classFile;
this.iClassLoader = iClassLoader;
// Determine class access flags.
this.accessFlags = classFile.accessFlags;
}
// Implement IClass.
@Override protected IConstructor[]
getDeclaredIConstructors2() {
List iConstructors = new ArrayList();
for (ClassFile.MethodInfo mi : this.classFile.methodInfos) {
IInvocable ii;
try {
ii = this.resolveMethod(mi);
} catch (ClassNotFoundException ex) {
throw new JaninoRuntimeException(ex.getMessage(), ex);
}
if (ii instanceof IConstructor) iConstructors.add(ii);
}
return (IConstructor[]) iConstructors.toArray(new IConstructor[iConstructors.size()]);
}
@Override protected IMethod[]
getDeclaredIMethods2() {
List<IMethod> iMethods = new ArrayList();
for (ClassFile.MethodInfo mi : this.classFile.methodInfos) {
// Skip JDK 1.5 synthetic methods (e.g. those generated for
// covariant return values).
if (Mod.isSynthetic(mi.getModifierFlags())) continue;
IInvocable ii;
try {
ii = this.resolveMethod(mi);
} catch (ClassNotFoundException ex) {
throw new JaninoRuntimeException(ex.getMessage(), ex);
}
if (ii instanceof IMethod) iMethods.add((IMethod) ii);
}
return (IMethod[]) iMethods.toArray(new IMethod[iMethods.size()]);
}
@Override protected IField[]
getDeclaredIFields2() {
IField[] ifs = new IClass.IField[this.classFile.fieldInfos.size()];
for (int i = 0; i < this.classFile.fieldInfos.size(); ++i) {
try {
ifs[i] = this.resolveField((ClassFile.FieldInfo) this.classFile.fieldInfos.get(i));
} catch (ClassNotFoundException ex) {
throw new JaninoRuntimeException(ex.getMessage(), ex);
}
}
return ifs;
}
@Override protected IClass[]
getDeclaredIClasses2() throws CompileException {
ClassFile.InnerClassesAttribute ica = this.classFile.getInnerClassesAttribute();
if (ica == null) return new IClass[0];
List<IClass> res = new ArrayList();
for (ClassFile.InnerClassesAttribute.Entry e : ica.getEntries()) {
if (e.outerClassInfoIndex == this.classFile.thisClass) {
try {
res.add(this.resolveClass(e.innerClassInfoIndex));
} catch (ClassNotFoundException ex) {
throw new CompileException(ex.getMessage(), null); // SUPPRESS CHECKSTYLE AvoidHidingCause
}
}
}
return (IClass[]) res.toArray(new IClass[res.size()]);
}
@Override protected IClass
getDeclaringIClass2() throws CompileException {
ClassFile.InnerClassesAttribute ica = this.classFile.getInnerClassesAttribute();
if (ica == null) return null;
for (ClassFile.InnerClassesAttribute.Entry e : ica.getEntries()) {
if (e.innerClassInfoIndex == this.classFile.thisClass) {
// Is this an anonymous class?
if (e.outerClassInfoIndex == 0) return null;
try {
return this.resolveClass(e.outerClassInfoIndex);
} catch (ClassNotFoundException ex) {
throw new CompileException(ex.getMessage(), null); // SUPPRESS CHECKSTYLE AvoidHidingCause
}
}
}
return null;
}
@Override protected IClass
getOuterIClass2() throws CompileException {
ClassFile.InnerClassesAttribute ica = this.classFile.getInnerClassesAttribute();
if (ica == null) return null;
for (ClassFile.InnerClassesAttribute.Entry e : ica.getEntries()) {
if (e.innerClassInfoIndex == this.classFile.thisClass) {
if (e.outerClassInfoIndex == 0) {
// Anonymous class or local class.
// TODO: Determine enclosing instance of anonymous class or local class
return null;
} else {
// Member type.
if (Mod.isStatic(e.innerClassAccessFlags)) return null;
try {
return this.resolveClass(e.outerClassInfoIndex);
} catch (ClassNotFoundException ex) {
throw new CompileException(ex.getMessage(), null); // SUPPRESS CHECKSTYLE AvoidHidingCause
}
}
}
}
return null;
}
@Override protected IClass
getSuperclass2() throws CompileException {
if (this.classFile.superclass == 0) return null;
try {
return this.resolveClass(this.classFile.superclass);
} catch (ClassNotFoundException e) {
throw new CompileException(e.getMessage(), null); // SUPPRESS CHECKSTYLE AvoidHidingCause
}
}
@Override public Access
getAccess() { return ClassFileIClass.accessFlags2Access(this.accessFlags); }
@Override public boolean
isFinal() { return Mod.isFinal(this.accessFlags); }
@Override protected IClass[]
getInterfaces2() throws CompileException { return this.resolveClasses(this.classFile.interfaces); }
@Override public boolean
isAbstract() { return Mod.isAbstract(this.accessFlags); }
@Override protected String
getDescriptor2() { return Descriptor.fromClassName(this.classFile.getThisClassName()); }
@Override public boolean
isInterface() { return Mod.isInterface(this.accessFlags); }
@Override public boolean
isArray() { return false; }
@Override public boolean
isPrimitive() { return false; }
@Override public boolean
isPrimitiveNumeric() { return false; }
@Override protected IClass
getComponentType2() { return null; }
/** Resolves all classes referenced by this class file. */
public void
resolveAllClasses() throws ClassNotFoundException {
for (short i = 0; i < this.classFile.getConstantPoolSize(); ++i) {
ClassFile.ConstantPoolInfo cpi = this.classFile.getConstantPoolInfo(i);
if (cpi instanceof ClassFile.ConstantClassInfo) {
this.resolveClass(i);
} else
if (cpi instanceof ClassFile.ConstantNameAndTypeInfo) {
String descriptor = ((ClassFile.ConstantNameAndTypeInfo) cpi).getDescriptor(this.classFile);
if (descriptor.charAt(0) == '(') {
MethodDescriptor md = new MethodDescriptor(descriptor);
this.resolveClass(md.returnFd);
for (String parameterFd : md.parameterFds) this.resolveClass(parameterFd);
} else {
this.resolveClass(descriptor);
}
}
}
}
/** @param index Index of the CONSTANT_Class_info to resolve (JVMS 4.4.1) */
private IClass
resolveClass(short index) throws ClassNotFoundException {
if (ClassFileIClass.DEBUG) System.out.println("index=" + index);
ConstantClassInfo cci = (ConstantClassInfo) this.classFile.getConstantPoolInfo(index);
return this.resolveClass(Descriptor.fromInternalForm(cci.getName(this.classFile)));
}
private IClass
resolveClass(String descriptor) throws ClassNotFoundException {
if (ClassFileIClass.DEBUG) System.out.println("descriptor=" + descriptor);
IClass result = (IClass) this.resolvedClasses.get(descriptor);
if (result != null) return result;
result = this.iClassLoader.loadIClass(descriptor);
if (result == null) throw new ClassNotFoundException(descriptor);
this.resolvedClasses.put(descriptor, result);
return result;
}
private final Map<String /*descriptor*/, IClass> resolvedClasses = new HashMap();
private IClass[]
resolveClasses(short[] ifs) throws CompileException {
IClass[] result = new IClass[ifs.length];
for (int i = 0; i < result.length; ++i) {
try {
result[i] = this.resolveClass(ifs[i]);
} catch (ClassNotFoundException e) {
throw new CompileException(e.getMessage(), null); // SUPPRESS CHECKSTYLE AvoidHidingCause
}
}
return result;
}
/**
* Turn a {@link ClassFile.MethodInfo} into an {@link IInvocable}. This includes the checking and the
* removal of the magic first parameter of an inner class constructor.
*
* @param methodInfo
* @throws ClassNotFoundException
*/
private IInvocable
resolveMethod(final ClassFile.MethodInfo methodInfo) throws ClassNotFoundException {
IInvocable result = (IInvocable) this.resolvedMethods.get(methodInfo);
if (result != null) return result;
// Determine method name.
final String name = methodInfo.getName();
// Determine return type.
MethodDescriptor md = new MethodDescriptor(methodInfo.getDescriptor());
final IClass returnType = this.resolveClass(md.returnFd);
// Determine parameter types.
final IClass[] parameterTypes = new IClass[md.parameterFds.length];
for (int i = 0; i < parameterTypes.length; ++i) parameterTypes[i] = this.resolveClass(md.parameterFds[i]);
// Determine thrown exceptions.
IClass[] tes = null;
ClassFile.AttributeInfo[] ais = methodInfo.getAttributes();
for (ClassFile.AttributeInfo ai : ais) {
if (ai instanceof ClassFile.ExceptionsAttribute) {
ConstantClassInfo[] ccis = ((ClassFile.ExceptionsAttribute) ai).getExceptions(this.classFile);
tes = new IClass[ccis.length];
for (int i = 0; i < tes.length; ++i) {
tes[i] = this.resolveClass(Descriptor.fromInternalForm(ccis[i].getName(this.classFile)));
}
}
}
final IClass[] thrownExceptions = tes == null ? new IClass[0] : tes;
// Determine access.
final Access access = ClassFileIClass.accessFlags2Access(methodInfo.getModifierFlags());
if ("<init>".equals(name)) {
result = new IClass.IConstructor() {
@Override public boolean
isVarargs() { return Mod.isVarargs(methodInfo.getModifierFlags()); }
@Override public IClass[]
getParameterTypes2() throws CompileException {
// Process magic first parameter of inner class constructor.
IClass outerIClass = ClassFileIClass.this.getOuterIClass();
if (outerIClass != null) {
if (parameterTypes.length < 1) {
throw new JaninoRuntimeException("Inner class constructor lacks magic first parameter");
}
if (parameterTypes[0] != outerIClass) {
throw new JaninoRuntimeException(
"Magic first parameter of inner class constructor has type \""
+ parameterTypes[0].toString()
+ "\" instead of that of its enclosing instance (\""
+ outerIClass.toString()
+ "\")"
);
}
IClass[] tmp = new IClass[parameterTypes.length - 1];
System.arraycopy(parameterTypes, 1, tmp, 0, tmp.length);
return tmp;
}
return parameterTypes;
}
@Override public IClass[] getThrownExceptions2() { return thrownExceptions; }
@Override public Access getAccess() { return access; }
@Override public Java.Annotation[] getAnnotations() { return methodInfo.getAnnotations(); }
};
} else {
result = new IClass.IMethod() {
@Override public String
getName() { return name; }
@Override public IClass
getReturnType() { return returnType; }
@Override public boolean
isStatic() { return Mod.isStatic(methodInfo.getModifierFlags()); }
@Override public boolean
isAbstract() { return Mod.isAbstract(methodInfo.getModifierFlags()); }
@Override public boolean
isVarargs() { return Mod.isVarargs(methodInfo.getModifierFlags()); }
@Override public IClass[]
getParameterTypes2() { return parameterTypes; }
@Override public IClass[]
getThrownExceptions2() { return thrownExceptions; }
@Override public Access
getAccess() { return access; }
@Override public Java.Annotation[]
getAnnotations() { return methodInfo.getAnnotations(); }
};
}
this.resolvedMethods.put(methodInfo, result);
return result;
}
private final Map<ClassFile.MethodInfo, IInvocable> resolvedMethods = new HashMap();
private IField
resolveField(final ClassFile.FieldInfo fieldInfo) throws ClassNotFoundException {
IField result = (IField) this.resolvedFields.get(fieldInfo);
if (result != null) return result;
// Determine field name.
final String name = fieldInfo.getName(this.classFile);
// Determine field type.
final String descriptor = fieldInfo.getDescriptor(this.classFile);
final IClass type = this.resolveClass(descriptor);
// Determine optional "constant value" of the field (JLS7 15.28, bullet 14). If a field has a "ConstantValue"
// attribute, we assume that it has a constant value. Notice that this assumption is not always correct,
// because typical Java&trade; compilers do not generate a "ConstantValue" attribute for fields like
// "int RED = 0", because "0" is the default value for an integer field.
ClassFile.ConstantValueAttribute cva = null;
for (ClassFile.AttributeInfo ai : fieldInfo.getAttributes()) {
if (ai instanceof ClassFile.ConstantValueAttribute) {
cva = (ClassFile.ConstantValueAttribute) ai;
break;
}
}
final Object optionalConstantValue = cva == null ? IClass.NOT_CONSTANT : cva.getConstantValue(this.classFile);
final Access access = ClassFileIClass.accessFlags2Access(fieldInfo.getModifierFlags());
result = new IField() {
@Override public Object getConstantValue() { return optionalConstantValue; }
@Override public String getName() { return name; }
@Override public IClass getType() { return type; }
@Override public boolean isStatic() { return Mod.isStatic(fieldInfo.getModifierFlags()); }
@Override public Access getAccess() { return access; }
@Override public Java.Annotation[] getAnnotations() { return fieldInfo.getAnnotations(); }
};
this.resolvedFields.put(fieldInfo, result);
return result;
}
private static Access
accessFlags2Access(short accessFlags) {
return (
Mod.isPublicAccess(accessFlags) ? Access.PUBLIC
: Mod.isProtectedAccess(accessFlags) ? Access.PROTECTED
: Mod.isPrivateAccess(accessFlags) ? Access.PRIVATE
: Access.DEFAULT
);
}
}

View File

@ -1,95 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino;
/** An {@link IClassLoader} that loads {@link IClass}es through a reflection {@link ClassLoader}. */
@SuppressWarnings("rawtypes") public
class ClassLoaderIClassLoader extends IClassLoader {
private static final boolean DEBUG = false;
/** @param classLoader The delegate that loads the classes. */
public
ClassLoaderIClassLoader(ClassLoader classLoader) {
super(
null // optionalParentIClassLoader
);
if (classLoader == null) throw new NullPointerException();
this.classLoader = classLoader;
super.postConstruct();
}
/**
* Equivalent to
* <pre>
* ClassLoaderIClassLoader(Thread.currentThread().getContextClassLoader())
* </pre>
*/
public
ClassLoaderIClassLoader() { this(Thread.currentThread().getContextClassLoader()); }
/** @return The delegate {@link ClassLoader} */
public ClassLoader
getClassLoader() { return this.classLoader; }
@Override protected IClass
findIClass(String descriptor) throws ClassNotFoundException {
Class clazz;
try {
//
// See also [ 931385 ] Janino 2.0 throwing exception on arrays of java.io.File:
//
// "ClassLoader.loadClass()" and "Class.forName()" should be identical,
// but "ClassLoader.loadClass("[Ljava.lang.Object;")" throws a
// ClassNotFoundException under JDK 1.5.0 beta.
// Unclear whether this a beta version bug and SUN will fix this in the final
// release, but "Class.forName()" seems to work fine in all cases, so we
// use that.
//
// clazz = this.classLoader.loadClass(Descriptor.toClassName(descriptor));
clazz = Class.forName(Descriptor.toClassName(descriptor), false, this.classLoader);
} catch (ClassNotFoundException e) {
if (e.getException() == null) {
return null;
} else
{
throw e;
}
}
if (ClassLoaderIClassLoader.DEBUG) System.out.println("clazz = " + clazz);
IClass result = new ReflectionIClass(clazz, this);
this.defineIClass(result);
return result;
}
private final ClassLoader classLoader;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,830 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import org.codehaus.commons.compiler.CompileException;
import org.codehaus.commons.compiler.ErrorHandler;
import org.codehaus.commons.compiler.Location;
import org.codehaus.commons.compiler.WarningHandler;
import org.codehaus.janino.Java.CompilationUnit;
import org.codehaus.janino.util.Benchmark;
import org.codehaus.janino.util.ClassFile;
import org.codehaus.janino.util.StringPattern;
import org.codehaus.janino.util.resource.DirectoryResourceCreator;
import org.codehaus.janino.util.resource.DirectoryResourceFinder;
import org.codehaus.janino.util.resource.FileResource;
import org.codehaus.janino.util.resource.FileResourceCreator;
import org.codehaus.janino.util.resource.PathResourceFinder;
import org.codehaus.janino.util.resource.Resource;
import org.codehaus.janino.util.resource.ResourceCreator;
import org.codehaus.janino.util.resource.ResourceFinder;
/**
* A simplified substitute for the <tt>javac</tt> tool.
*
* Usage:
* <pre>
* java org.codehaus.janino.Compiler \
* [ -d <i>destination-dir</i> ] \
* [ -sourcepath <i>dirlist</i> ] \
* [ -classpath <i>dirlist</i> ] \
* [ -extdirs <i>dirlist</i> ] \
* [ -bootclasspath <i>dirlist</i> ] \
* [ -encoding <i>encoding</i> ] \
* [ -verbose ] \
* [ -g:none ] \
* [ -g:{source,lines,vars} ] \
* [ -warn:<i>pattern-list</i> ] \
* <i>source-file</i> ...
* java org.codehaus.janino.Compiler -help
* </pre>
*/
@SuppressWarnings({ "rawtypes", "unchecked" }) public
class Compiler {
private static final boolean DEBUG = false;
/** Command line interface. */
public static void BCV(String[] args) throws Exception {
File destinationDirectory = Compiler.NO_DESTINATION_DIRECTORY;
File[] optionalSourcePath = null;
File[] classPath = { new File(".") };
File[] optionalExtDirs = null;
File[] optionalBootClassPath = null;
String optionalCharacterEncoding = null;
boolean verbose = false;
boolean debugSource = true;
boolean debugLines = true;
boolean debugVars = false;
StringPattern[] warningHandlePatterns = Compiler.DEFAULT_WARNING_HANDLE_PATTERNS;
boolean rebuild = false;
// Process command line options.
int i;
for (i = 0; i < args.length; ++i) {
String arg = args[i];
if (arg.charAt(0) != '-') break;
if ("-d".equals(arg)) {
destinationDirectory = new File(args[++i]);
} else
if ("-sourcepath".equals(arg)) {
optionalSourcePath = PathResourceFinder.parsePath(args[++i]);
} else
if ("-classpath".equals(arg)) {
classPath = PathResourceFinder.parsePath(args[++i]);
} else
if ("-extdirs".equals(arg)) {
optionalExtDirs = PathResourceFinder.parsePath(args[++i]);
} else
if ("-bootclasspath".equals(arg)) {
optionalBootClassPath = PathResourceFinder.parsePath(args[++i]);
} else
if ("-encoding".equals(arg)) {
optionalCharacterEncoding = args[++i];
} else
if ("-verbose".equals(arg)) {
verbose = true;
} else
if ("-g".equals(arg)) {
debugSource = true;
debugLines = true;
debugVars = true;
} else
if (arg.startsWith("-g:")) {
if (arg.indexOf("none") != -1) debugSource = (debugLines = (debugVars = false));
if (arg.indexOf("source") != -1) debugSource = true;
if (arg.indexOf("lines") != -1) debugLines = true;
if (arg.indexOf("vars") != -1) debugVars = true;
} else
if (arg.startsWith("-warn:")) {
warningHandlePatterns = StringPattern.parseCombinedPattern(arg.substring(6));
} else
if ("-rebuild".equals(arg)) {
rebuild = true;
} else
if ("-help".equals(arg)) {
System.out.printf(Compiler.USAGE, (Object[]) null);
} else
{
System.err.println("Unrecognized command line option \"" + arg + "\"; try \"-help\".");
}
}
// Get source file names.
if (i == args.length) {
System.err.println("No source files given on command line; try \"-help\".");
}
File[] sourceFiles = new File[args.length - i];
for (int j = i; j < args.length; ++j) sourceFiles[j - i] = new File(args[j]);
// Create the compiler object.
final Compiler compiler = new Compiler(
optionalSourcePath,
classPath,
optionalExtDirs,
optionalBootClassPath,
destinationDirectory,
optionalCharacterEncoding,
verbose,
debugSource,
debugLines,
debugVars,
warningHandlePatterns,
rebuild
);
// Compile source files.
compiler.compile(sourceFiles);
}
private static final String USAGE = (
""
+ "Usage:%n"
+ "%n"
+ " java " + Compiler.class.getName() + " [ <option> ] ... <source-file> ...%n"
+ "%n"
+ "Supported <option>s are:%n"
+ " -d <output-dir> Where to save class files%n"
+ " -sourcepath <dirlist> Where to look for other source files%n"
+ " -classpath <dirlist> Where to look for other class files%n"
+ " -extdirs <dirlist> Where to look for other class files%n"
+ " -bootclasspath <dirlist> Where to look for other class files%n"
+ " -encoding <encoding> Encoding of source files, e.g. \"UTF-8\" or \"ISO-8859-1\"%n"
+ " -verbose%n"
+ " -g Generate all debugging info%n"
+ " -g:none Generate no debugging info%n"
+ " -g:{source,lines,vars} Generate only some debugging info%n"
+ " -warn:<pattern-list> Issue certain warnings; examples:%n"
+ " -warn:* Enables all warnings%n"
+ " -warn:IASF Only warn against implicit access to static fields%n"
+ " -warn:*-IASF Enables all warnings, except those against implicit%n"
+ " access to static fields%n"
+ " -warn:*-IA*+IASF Enables all warnings, except those against implicit%n"
+ " accesses, but do warn against implicit access to%n"
+ " static fields%n"
+ " -rebuild Compile all source files, even if the class files%n"
+ " seems up-to-date%n"
+ " -help%n"
+ "%n"
+ "The default encoding in this environment is \"" + Charset.defaultCharset().toString() + "\"."
);
private final ResourceFinder classFileFinder;
/** Special value for "classFileResourceFinder". */
public static final ResourceFinder FIND_NEXT_TO_SOURCE_FILE = null;
private final ResourceCreator classFileCreator;
/** Special value for "classFileResourceCreator". */
public static final ResourceCreator CREATE_NEXT_TO_SOURCE_FILE = null;
private final String optionalCharacterEncoding;
private final Benchmark benchmark;
private final boolean debugSource;
private final boolean debugLines;
private final boolean debugVars;
private WarningHandler optionalWarningHandler;
private ErrorHandler optionalCompileErrorHandler;
private final IClassLoader iClassLoader;
private final List<UnitCompiler> parsedCompilationUnits = new ArrayList();
/**
* Initialize a Java&trade; compiler with the given parameters.
* <p>
* Classes are searched in the following order:
* <ul>
* <li>If {@code optionalBootClassPath} is {@code null}:
* <ul>
* <li>Through the system class loader of the JVM that runs JANINO
* </ul>
* <li>If {@code optionalBootClassPath} is not {@code null}:
* <ul>
* <li>Through the {@code optionalBootClassPath}
* </ul>
* <li>If {@code optionalExtDirs} is not {@code null}:
* <ul>
* <li>Through the {@code optionalExtDirs}
* </ul>
* <li>Through the {@code classPath}
* <li>If {@code optionalSourcePath} is {@code null}:
* <ul>
* <li>Through source files found on the {@code classPath}
* </ul>
* <li>If {@code optionalSourcePath} is not {@code null}:
* <ul>
* <li>Through source files found on the {@code sourcePath}
* </ul>
* </ul>
* <p>
* The file name of a class file that represents class "pkg.Example"
* is determined as follows:
* <ul>
* <li>
* If {@code optionalDestinationDirectory} is not {@link #NO_DESTINATION_DIRECTORY}:
* {@code <i>optionalDestinationDirectory</i>/pkg/Example.class}
* <li>
* If {@code optionalDestinationDirectory} is {@link #NO_DESTINATION_DIRECTORY}:
* {@code dir1/dir2/Example.class} (Assuming that the file name of the
* source file that declares the class was
* {@code dir1/dir2/Any.java}.)
* </ul>
*
* @see #DEFAULT_WARNING_HANDLE_PATTERNS
*/
public
Compiler(
final File[] optionalSourcePath,
final File[] classPath,
final File[] optionalExtDirs,
final File[] optionalBootClassPath,
final File destinationDirectory,
final String optionalCharacterEncoding,
boolean verbose,
boolean debugSource,
boolean debugLines,
boolean debugVars,
StringPattern[] warningHandlePatterns,
boolean rebuild
) {
this(
new PathResourceFinder( // sourceFinder
optionalSourcePath == null ? classPath : optionalSourcePath
),
IClassLoader.createJavacLikePathIClassLoader( // iClassLoader
optionalBootClassPath,
optionalExtDirs,
classPath
),
( // classFileFinder
rebuild
? ResourceFinder.EMPTY_RESOURCE_FINDER
: destinationDirectory == Compiler.NO_DESTINATION_DIRECTORY
? Compiler.FIND_NEXT_TO_SOURCE_FILE
: new DirectoryResourceFinder(destinationDirectory)
),
( // classFileCreator
destinationDirectory == Compiler.NO_DESTINATION_DIRECTORY
? Compiler.CREATE_NEXT_TO_SOURCE_FILE
: new DirectoryResourceCreator(destinationDirectory)
),
optionalCharacterEncoding, // optionalCharacterEncoding
verbose, // verbose
debugSource, // debugSource
debugLines, // debugLines
debugVars, // debugVars
new FilterWarningHandler( // optionalWarningHandler
warningHandlePatterns,
new SimpleWarningHandler() // <= Anonymous class here is complicated because the enclosing instance is
// not fully initialized yet
)
);
this.benchmark.report("*** JANINO - an embedded compiler for the Java(TM) programming language");
this.benchmark.report("*** For more information visit http://janino.codehaus.org");
this.benchmark.report("Source path", optionalSourcePath);
this.benchmark.report("Class path", classPath);
this.benchmark.report("Ext dirs", optionalExtDirs);
this.benchmark.report("Boot class path", optionalBootClassPath);
this.benchmark.report("Destination directory", destinationDirectory);
this.benchmark.report("Character encoding", optionalCharacterEncoding);
this.benchmark.report("Verbose", new Boolean(verbose));
this.benchmark.report("Debug source", new Boolean(debugSource));
this.benchmark.report("Debug lines", new Boolean(debugSource));
this.benchmark.report("Debug vars", new Boolean(debugSource));
this.benchmark.report("Warning handle patterns", warningHandlePatterns);
this.benchmark.report("Rebuild", new Boolean(rebuild));
}
/** Backwards compatibility -- previously, "null" was officially documented. */
public static final File NO_DESTINATION_DIRECTORY = null;
/** Prints warnings to STDERR. */
public static
class SimpleWarningHandler implements WarningHandler {
@Override public void
handleWarning(String handle, String message, Location optionalLocation) {
StringBuilder sb = new StringBuilder();
if (optionalLocation != null) sb.append(optionalLocation).append(": ");
sb.append("Warning ").append(handle).append(": ").append(message);
System.err.println(sb.toString());
}
}
/**
* The default value for the {@code warningHandlerPatterns} parameter of {@link Compiler#Compiler(File[], File[],
* File[], File[], File, String, boolean, boolean, boolean, boolean, StringPattern[], boolean)}.
*/
public static final StringPattern[] DEFAULT_WARNING_HANDLE_PATTERNS = StringPattern.PATTERNS_NONE;
/**
* To mimic the behavior of JAVAC with a missing "-d" command line option,
* pass {@link #FIND_NEXT_TO_SOURCE_FILE} as the {@code classFileResourceFinder} and
* {@link #CREATE_NEXT_TO_SOURCE_FILE} as the {@code classFileResourceCreator}.
* <p>
* If it is impossible to check whether an already-compiled class file
* exists, or if you want to enforce recompilation, pass
* {@link ResourceFinder#EMPTY_RESOURCE_FINDER} as the
* {@code classFileResourceFinder}.
*
* @param sourceFinder Finds extra Java compilation units that need to be compiled (a.k.a. "-sourcepath")
* @param iClassLoader Loads auxiliary {@link IClass}es (a.k.a. "-classpath"), e.g. <code>new
* ClassLoaderIClassLoader(ClassLoader)</code>
* @param classFileFinder Where to look for up-to-date class files that need not be compiled (a.k.a. "-d")
* @param classFileCreator Used to store generated class files (a.k.a. "-d")
* @param optionalWarningHandler Used to issue warnings
*/
public
Compiler(
ResourceFinder sourceFinder,
IClassLoader iClassLoader,
ResourceFinder classFileFinder,
ResourceCreator classFileCreator,
final String optionalCharacterEncoding,
boolean verbose,
boolean debugSource,
boolean debugLines,
boolean debugVars,
WarningHandler optionalWarningHandler
) {
this.classFileFinder = classFileFinder;
this.classFileCreator = classFileCreator;
this.optionalCharacterEncoding = optionalCharacterEncoding;
this.benchmark = new Benchmark(verbose);
this.debugSource = debugSource;
this.debugLines = debugLines;
this.debugVars = debugVars;
this.optionalWarningHandler = optionalWarningHandler;
// Set up the IClassLoader.
this.iClassLoader = new CompilerIClassLoader(sourceFinder, iClassLoader);
}
/**
* Install a custom {@link ErrorHandler}. The default {@link ErrorHandler} prints the first 20 compile errors to
* {@link System#err} and then throws a {@link CompileException}.
* <p>
* Passing {@code null} restores the default {@link ErrorHandler}.
* <p>
* Notice that scan and parse errors are <i>not</i> redirected to this {@link ErrorHandler}, instead, they cause a
* {@link CompileException} to be thrown. Also, the {@link Compiler} may choose to throw {@link CompileException}s
* in certain, fatal compile error situations, even if an {@link ErrorHandler} is installed.
* <p>
* In other words: In situations where compilation can reasonably continue after a compile error, the {@link
* ErrorHandler} is called; all other error conditions cause a {@link CompileException} to be thrown.
*/
public void
setCompileErrorHandler(ErrorHandler optionalCompileErrorHandler) {
this.optionalCompileErrorHandler = optionalCompileErrorHandler;
}
/**
* By default, warnings are discarded, but an application my install a custom {@link WarningHandler}.
*
* @param optionalWarningHandler {@code null} to indicate that no warnings be issued
*/
public void
setWarningHandler(WarningHandler optionalWarningHandler) {
this.optionalWarningHandler = optionalWarningHandler;
}
/**
* Reads a set of Java&trade; compilation units (a.k.a. "source
* files") from the file system, compiles them into a set of "class
* files" and stores these in the file system. Additional source files are
* parsed and compiled on demand through the "source path" set of
* directories.
* <p>
* For example, if the source path comprises the directories "A/B" and "../C",
* then the source file for class "com.acme.Main" is searched in
* <dl>
* <dd>A/B/com/acme/Main.java
* <dd>../C/com/acme/Main.java
* </dl>
* Notice that it does make a difference whether you pass multiple source
* files to {@link #compile(File[])} or if you invoke
* {@link #compile(File[])} multiply: In the former case, the source
* files may contain arbitrary references among each other (even circular
* ones). In the latter case, only the source files on the source path
* may contain circular references, not the {@code sourceFiles}.
* <p>
* This method must be called exactly once after object construction.
* <p>
* Compile errors are reported as described at
* {@link #setCompileErrorHandler(ErrorHandler)}.
*
* @param sourceFiles Contain the compilation units to compile
* @return {@code true} for backwards compatibility (return value can safely be ignored)
* @throws CompileException Fatal compilation error, or the {@link CompileException} thrown be the installed compile
* error handler
* @throws IOException Occurred when reading from the {@code sourceFiles}
*/
public boolean
compile(File[] sourceFiles) throws CompileException, IOException {
this.benchmark.report("Source files", sourceFiles);
Resource[] sourceFileResources = new Resource[sourceFiles.length];
for (int i = 0; i < sourceFiles.length; ++i) sourceFileResources[i] = new FileResource(sourceFiles[i]);
this.compile(sourceFileResources);
return true;
}
/**
* See {@link #compile(File[])}.
*
* @param sourceResources Contain the compilation units to compile
* @return {@code true} for backwards compatibility (return value can safely be ignored)
*/
public boolean
compile(Resource[] sourceResources) throws CompileException, IOException {
// Set up the compile error handler as described at "setCompileErrorHandler()".
final ErrorHandler ceh = (
this.optionalCompileErrorHandler != null
? this.optionalCompileErrorHandler
: new ErrorHandler() {
int compileErrorCount;
@Override public void
handleError(String message, Location optionalLocation) throws CompileException {
CompileException ex = new CompileException(message, optionalLocation);
if (++this.compileErrorCount >= 20) throw ex;
System.err.println(ex.getMessage());
}
}
);
this.benchmark.beginReporting();
try {
// Parse all source files.
this.parsedCompilationUnits.clear();
for (Resource sourceResource : sourceResources) {
if (Compiler.DEBUG) System.out.println("Compiling \"" + sourceResource + "\"");
this.parsedCompilationUnits.add(new UnitCompiler(this.parseCompilationUnit(
sourceResource.getFileName(), // fileName
new BufferedInputStream(sourceResource.open()), // inputStream
this.optionalCharacterEncoding // optionalCharacterEncoding
), this.iClassLoader));
}
// Compile all parsed compilation units. The vector of parsed CUs may grow while they are being compiled,
// but eventually all CUs will be compiled.
for (int i = 0; i < this.parsedCompilationUnits.size(); ++i) {
UnitCompiler unitCompiler = (UnitCompiler) this.parsedCompilationUnits.get(i);
File sourceFile;
{
CompilationUnit compilationUnit = unitCompiler.getCompilationUnit();
if (compilationUnit.optionalFileName == null) throw new JaninoRuntimeException();
sourceFile = new File(compilationUnit.optionalFileName);
}
unitCompiler.setCompileErrorHandler(ceh);
unitCompiler.setWarningHandler(this.optionalWarningHandler);
this.benchmark.beginReporting("Compiling compilation unit \"" + sourceFile + "\"");
ClassFile[] classFiles;
try {
// Compile the compilation unit.
classFiles = unitCompiler.compileUnit(this.debugSource, this.debugLines, this.debugVars);
} finally {
this.benchmark.endReporting();
}
// Store the compiled classes and interfaces into class files.
this.benchmark.beginReporting(
"Storing "
+ classFiles.length
+ " class file(s) resulting from compilation unit \""
+ sourceFile
+ "\""
);
try {
for (ClassFile classFile : classFiles) this.storeClassFile(classFile, sourceFile);
} finally {
this.benchmark.endReporting();
}
}
} finally {
this.benchmark.endReporting("Compiled " + this.parsedCompilationUnits.size() + " compilation unit(s)");
}
return true;
}
/**
* Read one compilation unit from a file and parse it.
* <p>
* The {@code inputStream} is closed before the method returns.
* @return the parsed compilation unit
*/
private Java.CompilationUnit
parseCompilationUnit(
String fileName,
InputStream inputStream,
String optionalCharacterEncoding
) throws CompileException, IOException {
try {
Scanner scanner = new Scanner(fileName, inputStream, optionalCharacterEncoding);
scanner.setWarningHandler(this.optionalWarningHandler);
Parser parser = new Parser(scanner);
parser.setWarningHandler(this.optionalWarningHandler);
this.benchmark.beginReporting("Parsing \"" + fileName + "\"");
try {
return parser.parseCompilationUnit();
} finally {
this.benchmark.endReporting();
}
} finally {
inputStream.close();
}
}
/**
* Construct the name of a file that could store the byte code of the class with the given
* name.
* <p>
* If {@code optionalDestinationDirectory} is non-null, the returned path is the
* {@code optionalDestinationDirectory} plus the package of the class (with dots replaced
* with file separators) plus the class name plus ".class". Example:
* "destdir/pkg1/pkg2/Outer$Inner.class"
* <p>
* If {@code optionalDestinationDirectory} is null, the returned path is the
* directory of the {@code sourceFile} plus the class name plus ".class". Example:
* "srcdir/Outer$Inner.class"
* @param className E.g. "pkg1.pkg2.Outer$Inner"
* @param sourceFile E.g. "srcdir/Outer.java"
* @param optionalDestinationDirectory E.g. "destdir"
*/
public static File
getClassFile(String className, File sourceFile, File optionalDestinationDirectory) {
if (optionalDestinationDirectory != null) {
return new File(optionalDestinationDirectory, ClassFile.getClassFileResourceName(className));
} else {
int idx = className.lastIndexOf('.');
return new File(
sourceFile.getParentFile(),
ClassFile.getClassFileResourceName(className.substring(idx + 1))
);
}
}
/**
* Store the byte code of this {@link ClassFile} in the file system. Directories are created
* as necessary.
* @param classFile
* @param sourceFile Required to compute class file path if no destination directory given
*/
public void
storeClassFile(ClassFile classFile, final File sourceFile) throws IOException {
String classFileResourceName = ClassFile.getClassFileResourceName(classFile.getThisClassName());
// Determine where to create the class file.
ResourceCreator rc;
if (this.classFileCreator != Compiler.CREATE_NEXT_TO_SOURCE_FILE) {
rc = this.classFileCreator;
} else {
// If the JAVAC option "-d" is given, place the class file next
// to the source file, irrespective of the package name.
rc = new FileResourceCreator() {
@Override protected File
getFile(String resourceName) {
return new File(
sourceFile.getParentFile(),
resourceName.substring(resourceName.lastIndexOf('/') + 1)
);
}
};
}
OutputStream os = rc.createResource(classFileResourceName);
try {
classFile.store(os);
} catch (IOException ioe) {
try { os.close(); } catch (IOException e) {}
os = null;
if (!rc.deleteResource(classFileResourceName)) {
IOException ioe2 = new IOException(
"Could not delete incompletely written class file \""
+ classFileResourceName
+ "\""
);
ioe2.initCause(ioe);
throw ioe2; // SUPPRESS CHECKSTYLE AvoidHidingCause
}
throw ioe;
} finally {
if (os != null) try { os.close(); } catch (IOException e) {}
}
}
/**
* A specialized {@link IClassLoader} that loads {@link IClass}es from the following
* sources:
* <ol>
* <li>An already-parsed compilation unit
* <li>A class file in the output directory (if existant and younger than source file)
* <li>A source file in any of the source path directories
* <li>The parent class loader
* </ol>
* Notice that the {@link CompilerIClassLoader} is an inner class of {@link Compiler} and
* heavily uses {@link Compiler}'s members.
*/
private
class CompilerIClassLoader extends IClassLoader {
private final ResourceFinder sourceFinder;
/**
* @param sourceFinder Where to look for source files
* @param optionalParentIClassLoader {@link IClassLoader} through which {@link IClass}es are to be loaded
*/
public
CompilerIClassLoader(ResourceFinder sourceFinder, IClassLoader optionalParentIClassLoader) {
super(optionalParentIClassLoader);
this.sourceFinder = sourceFinder;
super.postConstruct();
}
/**
* @param type field descriptor of the {@IClass} to load, e.g. "Lpkg1/pkg2/Outer$Inner;"
* @return {@code null} if a the type could not be found
* @throws ClassNotFoundException if an exception was raised while loading the {@link IClass}
*/
@Override protected IClass
findIClass(final String type) throws ClassNotFoundException {
if (Compiler.DEBUG) System.out.println("type = " + type);
// Determine the class name.
String className = Descriptor.toClassName(type); // E.g. "pkg1.pkg2.Outer$Inner"
if (Compiler.DEBUG) System.out.println("2 className = \"" + className + "\"");
// Do not attempt to load classes from package "java".
if (className.startsWith("java.")) return null;
// Determine the name of the top-level class.
String topLevelClassName;
{
int idx = className.indexOf('$');
topLevelClassName = idx == -1 ? className : className.substring(0, idx);
}
// Check the already-parsed compilation units.
for (int i = 0; i < Compiler.this.parsedCompilationUnits.size(); ++i) {
UnitCompiler uc = (UnitCompiler) Compiler.this.parsedCompilationUnits.get(i);
IClass res = uc.findClass(topLevelClassName);
if (res != null) {
if (!className.equals(topLevelClassName)) {
res = uc.findClass(className);
if (res == null) return null;
}
this.defineIClass(res);
return res;
}
}
// Search source path for uncompiled class.
final Resource sourceResource = this.sourceFinder.findResource(ClassFile.getSourceResourceName(className));
if (sourceResource == null) return null;
// Find an existing class file.
Resource classFileResource;
if (Compiler.this.classFileFinder != Compiler.FIND_NEXT_TO_SOURCE_FILE) {
classFileResource = Compiler.this.classFileFinder.findResource(
ClassFile.getClassFileResourceName(className)
);
} else {
if (!(sourceResource instanceof FileResource)) return null;
File classFile = new File(
((FileResource) sourceResource).getFile().getParentFile(),
ClassFile.getClassFileResourceName(className.substring(className.lastIndexOf('.') + 1))
);
classFileResource = classFile.exists() ? new FileResource(classFile) : null;
}
// Compare source modification time against class file modification time.
if (classFileResource != null && sourceResource.lastModified() <= classFileResource.lastModified()) {
// The class file is up-to-date; load it.
return this.defineIClassFromClassFileResource(classFileResource);
} else {
// Source file not yet compiled or younger than class file.
return this.defineIClassFromSourceResource(sourceResource, className);
}
}
/**
* Parse the compilation unit stored in the given {@code sourceResource}, remember it in
* {@code Compiler.this.parsedCompilationUnits} (it may declare other classes that
* are needed later), find the declaration of the type with the given
* {@code className}, and define it in the {@link IClassLoader}.
* <p>
* Notice that the CU is not compiled here!
*/
private IClass
defineIClassFromSourceResource(Resource sourceResource, String className) throws ClassNotFoundException {
// Parse the source file.
UnitCompiler uc;
try {
Java.CompilationUnit cu = Compiler.this.parseCompilationUnit(
sourceResource.getFileName(), // fileName
new BufferedInputStream(sourceResource.open()), // inputStream
Compiler.this.optionalCharacterEncoding // optionalCharacterEncoding
);
uc = new UnitCompiler(cu, Compiler.this.iClassLoader);
} catch (IOException ex) {
throw new ClassNotFoundException("Parsing compilation unit \"" + sourceResource + "\"", ex);
} catch (CompileException ex) {
throw new ClassNotFoundException("Parsing compilation unit \"" + sourceResource + "\"", ex);
}
// Remember compilation unit for later compilation.
Compiler.this.parsedCompilationUnits.add(uc);
// Define the class.
IClass res = uc.findClass(className);
if (res == null) {
// This is a really complicated case: We may find a source file on the source
// path that seemingly contains the declaration of the class we are looking
// for, but doesn't. This is possible if the underlying file system has
// case-insensitive file names and/or file names that are limited in length
// (e.g. DOS 8.3).
return null;
}
this.defineIClass(res);
return res;
}
/**
* Open the given {@code classFileResource}, read its contents, define it in the
* {@link IClassLoader}, and resolve it (this step may involve loading more classes).
*/
private IClass
defineIClassFromClassFileResource(Resource classFileResource) throws ClassNotFoundException {
Compiler.this.benchmark.beginReporting("Loading class file \"" + classFileResource.getFileName() + "\"");
try {
InputStream is = null;
ClassFile cf;
try {
is = classFileResource.open();
cf = new ClassFile(new BufferedInputStream(is));
} catch (IOException ex) {
throw new ClassNotFoundException("Opening class file resource \"" + classFileResource + "\"", ex);
} finally {
if (is != null) try { is.close(); } catch (IOException e) {}
}
ClassFileIClass result = new ClassFileIClass(
cf, // classFile
CompilerIClassLoader.this // iClassLoader
);
// Important: We must FIRST call "defineIClass()" so that the
// new IClass is known to the IClassLoader, and THEN
// "resolveAllClasses()", because otherwise endless recursion could
// occur.
this.defineIClass(result);
result.resolveAllClasses();
return result;
} finally {
Compiler.this.benchmark.endReporting();
}
}
}
}

View File

@ -1,78 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino;
import java.security.AccessController;
import java.security.PrivilegedAction;
import org.codehaus.commons.compiler.AbstractCompilerFactory;
import org.codehaus.commons.compiler.AbstractJavaSourceClassLoader;
import org.codehaus.commons.compiler.IClassBodyEvaluator;
import org.codehaus.commons.compiler.ICompilerFactory;
import org.codehaus.commons.compiler.IExpressionEvaluator;
import org.codehaus.commons.compiler.IScriptEvaluator;
import org.codehaus.commons.compiler.ISimpleCompiler;
/** The JANINO implementation of {@link ICompilerFactory}. */
@SuppressWarnings({ "rawtypes", "unchecked" }) public
class CompilerFactory extends AbstractCompilerFactory {
@Override public String
getId() { return "org.codehaus.janino"; }
@Override public String
toString() { return "janino"; }
@Override public String
getImplementationVersion() { return CompilerFactory.class.getPackage().getImplementationVersion(); }
@Override public IExpressionEvaluator
newExpressionEvaluator() { return new ExpressionEvaluator(); }
@Override public IScriptEvaluator
newScriptEvaluator() { return new ScriptEvaluator(); }
@Override public IClassBodyEvaluator
newClassBodyEvaluator() { return new ClassBodyEvaluator(); }
@Override public ISimpleCompiler
newSimpleCompiler() { return new SimpleCompiler(); }
@Override public AbstractJavaSourceClassLoader
newJavaSourceClassLoader() {
return (AbstractJavaSourceClassLoader) AccessController.doPrivileged(new PrivilegedAction() {
@Override public Object run() { return new JavaSourceClassLoader(); }
});
}
@Override public AbstractJavaSourceClassLoader
newJavaSourceClassLoader(final ClassLoader parentClassLoader) {
return (AbstractJavaSourceClassLoader) AccessController.doPrivileged(new PrivilegedAction() {
@Override public Object run() { return new JavaSourceClassLoader(parentClassLoader); }
});
}
}

View File

@ -1,389 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/**
* Helper class that defines useful methods for handling "field descriptors"
* (JVMS 4.3.2) and "method descriptors" (JVMS 4.3.3).<p>
* Typical descriptors are:
* <ul>
* <li><code>I</code> Integer
* <li><code>[I</code> Array of integer
* <li><code>Lpkg1/pkg2/Cls;</code> Class
* <li><code>Lpkg1/pkg2/Outer$Inner;</code> Member class
* </ul>
*/
@SuppressWarnings({ "rawtypes", "unchecked" }) public final
class Descriptor {
private Descriptor() {}
/** @return Whether this {@link Descriptor} describes a reference (i.e. non-primitive) type */
public static boolean
isReference(String d) { return d.length() > 1; }
/**
* @return Whether this {@link Descriptor} describes a class or an interface (and not an array or a primitive type)
*/
public static boolean
isClassOrInterfaceReference(String d) { return d.charAt(0) == 'L'; }
/** @return Whether this {@link Descriptor} describes an array type */
public static boolean
isArrayReference(String d) { return d.charAt(0) == '['; }
/**
* @return The descriptor of the component of the array type {@code d}
* @throws JaninoRuntimeException {@code d} does not describe an array type
*/
public static String
getComponentDescriptor(String d) {
if (d.charAt(0) != '[') {
throw new JaninoRuntimeException(
"Cannot determine component descriptor from non-array descriptor \""
+ d
+ "\""
);
}
return d.substring(1);
}
/**
* @return The number of slots (1 or two) that a value of the type described by {@code d} occupies on the operand
* stack or in the local variable array, or 0 iff {@code d} describes the type VOID
*/
public static short
size(String d) {
if (d.equals(Descriptor.VOID)) return 0;
if (Descriptor.hasSize1(d)) return 1;
if (Descriptor.hasSize2(d)) return 2;
throw new JaninoRuntimeException("No size defined for type \"" + Descriptor.toString(d) + "\"");
}
/** @return {@code true} iff {@code d} describes a primitive type except LONG and DOUBLE, or a reference type */
public static boolean
hasSize1(String d) {
if (d.length() == 1) return "BCFISZ".indexOf(d) != -1;
return Descriptor.isReference(d);
}
/** @return {@code true} iff {@code d} LONG or DOUBLE */
public static boolean
hasSize2(String d) {
return d.equals(Descriptor.LONG) || d.equals(Descriptor.DOUBLE);
}
/**
* Pretty-prints the given descriptor.
*
* @param d A valid field or method descriptor
*/
public static String
toString(String d) {
int idx = 0;
StringBuilder sb = new StringBuilder();
if (d.charAt(0) == '(') {
++idx;
sb.append("(");
while (idx < d.length() && d.charAt(idx) != ')') {
if (idx != 1) sb.append(", ");
idx = Descriptor.toString(d, idx, sb);
}
if (idx >= d.length()) throw new JaninoRuntimeException("Invalid descriptor \"" + d + "\"");
sb.append(") => ");
++idx;
}
Descriptor.toString(d, idx, sb);
return sb.toString();
}
private static int
toString(String d, int idx, StringBuilder sb) {
int dimensions = 0;
while (idx < d.length() && d.charAt(idx) == '[') {
++dimensions;
++idx;
}
if (idx >= d.length()) throw new JaninoRuntimeException("Invalid descriptor \"" + d + "\"");
switch (d.charAt(idx)) {
case 'L':
{
int idx2 = d.indexOf(';', idx);
if (idx2 == -1) throw new JaninoRuntimeException("Invalid descriptor \"" + d + "\"");
sb.append(d.substring(idx + 1, idx2).replace('/', '.'));
idx = idx2;
}
break;
case 'V':
sb.append("void");
break;
case 'B':
sb.append("byte");
break;
case 'C':
sb.append("char");
break;
case 'D':
sb.append("double");
break;
case 'F':
sb.append("float");
break;
case 'I':
sb.append("int");
break;
case 'J':
sb.append("long");
break;
case 'S':
sb.append("short");
break;
case 'Z':
sb.append("boolean");
break;
default:
throw new JaninoRuntimeException("Invalid descriptor \"" + d + "\"");
}
for (; dimensions > 0; --dimensions) sb.append("[]");
return idx + 1;
}
/** Converts a class name as defined by "Class.getName()" into a descriptor. */
public static String
fromClassName(String className) {
String res = (String) Descriptor.CLASS_NAME_TO_DESCRIPTOR.get(className);
if (res != null) { return res; }
if (className.startsWith("[")) return className.replace('.', '/');
return 'L' + className.replace('.', '/') + ';';
}
/**
* Convert a class name in the "internal form" as described in JVMS 4.2 into a descriptor.
* <p>
* Also implement the encoding of array types as described in JVMS 4.4.1.
*/
public static String
fromInternalForm(String internalForm) {
if (internalForm.charAt(0) == '[') return internalForm;
return 'L' + internalForm + ';';
}
/** Converts a field descriptor into a class name as defined by {@link Class#getName()}. */
public static String
toClassName(String d) {
String res = (String) Descriptor.DESCRIPTOR_TO_CLASSNAME.get(d);
if (res != null) { return res; }
char firstChar = d.charAt(0);
if (firstChar == 'L' && d.endsWith(";")) {
// Class or interface -- convert "Ljava/lang/String;" to "java.lang.String".
return d.substring(1, d.length() - 1).replace('/', '.');
}
if (firstChar == '[') {
// Array type -- convert "[Ljava/lang/String;" to "[Ljava.lang.String;".
return d.replace('/', '.');
}
throw new JaninoRuntimeException("(Invalid field descriptor \"" + d + "\")");
}
/** Converts a descriptor into the "internal form" as defined by JVMS 4.2. */
public static String
toInternalForm(String d) {
if (d.charAt(0) != 'L') {
throw new JaninoRuntimeException(
"Attempt to convert non-class descriptor \""
+ d
+ "\" into internal form"
);
}
return d.substring(1, d.length() - 1);
}
/** @return Whether {@code d} describes a primitive type or VOID */
public static boolean
isPrimitive(String d) { return d.length() == 1 && "VBCDFIJSZ".indexOf(d.charAt(0)) != -1; }
/** @return Whether {@code d} describes a primitive type except BOOLEAN and VOID */
public static boolean
isPrimitiveNumeric(String d) { return d.length() == 1 && "BDFIJSC".indexOf(d.charAt(0)) != -1; }
/**
* Returns the package name of a class or interface reference descriptor,
* or <code>null</code> if the class or interface is declared in the
* default package.
*/
public static String
getPackageName(String d) {
if (d.charAt(0) != 'L') {
throw new JaninoRuntimeException("Attempt to get package name of non-class descriptor \"" + d + "\"");
}
int idx = d.lastIndexOf('/');
return idx == -1 ? null : d.substring(1, idx).replace('/', '.');
}
/** Checks whether two reference types are declared in the same package. */
public static boolean
areInSamePackage(String d1, String d2) {
String packageName1 = Descriptor.getPackageName(d1);
String packageName2 = Descriptor.getPackageName(d2);
return packageName1 == null ? packageName2 == null : packageName1.equals(packageName2);
}
/** The field descriptor for the type VOID. */
public static final String VOID = "V";
// Primitive types.
/** The field descriptor for the primitive type BYTE. */
public static final String BYTE = "B";
/** The field descriptor for the primitive type CHAR. */
public static final String CHAR = "C";
/** The field descriptor for the primitive type DOUBLE. */
public static final String DOUBLE = "D";
/** The field descriptor for the primitive type FLOAT. */
public static final String FLOAT = "F";
/** The field descriptor for the primitive type INT. */
public static final String INT = "I";
/** The field descriptor for the primitive type LONG. */
public static final String LONG = "J";
/** The field descriptor for the primitive type SHORT. */
public static final String SHORT = "S";
/** The field descriptor for the primitive type BOOLEAN. */
public static final String BOOLEAN = "Z";
// Annotations.
/** The field descriptor for the annotation {@link java.lang.Override}. */
public static final String JAVA_LANG_OVERRIDE = "Ljava/lang/Override;";
// Classes.
/** The field descriptor for the class {@link java.lang.AssertionError}. */
public static final String JAVA_LANG_ASSERTIONERROR = "Ljava/lang/AssertionError;";
/** The field descriptor for the class {@link java.lang.Boolean}. */
public static final String JAVA_LANG_BOOLEAN = "Ljava/lang/Boolean;";
/** The field descriptor for the class {@link java.lang.Byte}. */
public static final String JAVA_LANG_BYTE = "Ljava/lang/Byte;";
/** The field descriptor for the class {@link java.lang.Character}. */
public static final String JAVA_LANG_CHARACTER = "Ljava/lang/Character;";
/** The field descriptor for the class {@link java.lang.Class}. */
public static final String JAVA_LANG_CLASS = "Ljava/lang/Class;";
/** The field descriptor for the class {@link java.lang.Double}. */
public static final String JAVA_LANG_DOUBLE = "Ljava/lang/Double;";
/** The field descriptor for the class {@link java.lang.Exception}. */
public static final String JAVA_LANG_EXCEPTION = "Ljava/lang/Exception;";
/** The field descriptor for the class {@link java.lang.Error}. */
public static final String JAVA_LANG_ERROR = "Ljava/lang/Error;";
/** The field descriptor for the class {@link java.lang.Float}. */
public static final String JAVA_LANG_FLOAT = "Ljava/lang/Float;";
/** The field descriptor for the class {@link java.lang.Integer}. */
public static final String JAVA_LANG_INTEGER = "Ljava/lang/Integer;";
/** The field descriptor for the class {@link java.lang.Long}. */
public static final String JAVA_LANG_LONG = "Ljava/lang/Long;";
/** The field descriptor for the class {@link java.lang.Object}. */
public static final String JAVA_LANG_OBJECT = "Ljava/lang/Object;";
/** The field descriptor for the class {@link java.lang.RuntimeException}. */
public static final String JAVA_LANG_RUNTIMEEXCEPTION = "Ljava/lang/RuntimeException;";
/** The field descriptor for the class {@link java.lang.Short}. */
public static final String JAVA_LANG_SHORT = "Ljava/lang/Short;";
/** The field descriptor for the class {@link java.lang.String}. */
public static final String JAVA_LANG_STRING = "Ljava/lang/String;";
/** The field descriptor for the class {@link java.lang.StringBuilder}. */
public static final String JAVA_LANG_STRINGBUILDER = "Ljava/lang/StringBuilder;"; // Since 1.5!
/** The field descriptor for the class {@link java.lang.Throwable}. */
public static final String JAVA_LANG_THROWABLE = "Ljava/lang/Throwable;";
// Interfaces.
/** The field descriptor for the interface {@link java.io.Serializable}. */
public static final String JAVA_IO_SERIALIZABLE = "Ljava/io/Serializable;";
/** The field descriptor for the interface {@link java.lang.Cloneable}. */
public static final String JAVA_LANG_CLONEABLE = "Ljava/lang/Cloneable;";
/** The field descriptor for the interface {@link java.lang.Iterable}. */
public static final String JAVA_LANG_ITERABLE = "Ljava/lang/Iterable;";
/** The field descriptor for the interface {@link java.util.Iterator}. */
public static final String JAVA_UTIL_ITERATOR = "Ljava/util/Iterator;";
private static final Map<String, String> DESCRIPTOR_TO_CLASSNAME;
static {
Map<String, String> m = new HashMap();
m.put(Descriptor.VOID, "void");
// Primitive types.
m.put(Descriptor.BYTE, "byte");
m.put(Descriptor.CHAR, "char");
m.put(Descriptor.DOUBLE, "double");
m.put(Descriptor.FLOAT, "float");
m.put(Descriptor.INT, "int");
m.put(Descriptor.LONG, "long");
m.put(Descriptor.SHORT, "short");
m.put(Descriptor.BOOLEAN, "boolean");
// Annotations.
m.put(Descriptor.JAVA_LANG_OVERRIDE, "java.lang.Override");
// Classes.
m.put(Descriptor.JAVA_LANG_ASSERTIONERROR, "java.lang.AssertionError");
m.put(Descriptor.JAVA_LANG_BOOLEAN, "java.lang.Boolean");
m.put(Descriptor.JAVA_LANG_BYTE, "java.lang.Byte");
m.put(Descriptor.JAVA_LANG_CHARACTER, "java.lang.Character");
m.put(Descriptor.JAVA_LANG_CLASS, "java.lang.Class");
m.put(Descriptor.JAVA_LANG_DOUBLE, "java.lang.Double");
m.put(Descriptor.JAVA_LANG_EXCEPTION, "java.lang.Exception");
m.put(Descriptor.JAVA_LANG_ERROR, "java.lang.Error");
m.put(Descriptor.JAVA_LANG_FLOAT, "java.lang.Float");
m.put(Descriptor.JAVA_LANG_INTEGER, "java.lang.Integer");
m.put(Descriptor.JAVA_LANG_LONG, "java.lang.Long");
m.put(Descriptor.JAVA_LANG_OBJECT, "java.lang.Object");
m.put(Descriptor.JAVA_LANG_RUNTIMEEXCEPTION, "java.lang.RuntimeException");
m.put(Descriptor.JAVA_LANG_SHORT, "java.lang.Short");
m.put(Descriptor.JAVA_LANG_STRING, "java.lang.String");
m.put(Descriptor.JAVA_LANG_STRINGBUILDER, "java.lang.StringBuilder");
m.put(Descriptor.JAVA_LANG_THROWABLE, "java.lang.Throwable");
// Interfaces.
m.put(Descriptor.JAVA_IO_SERIALIZABLE, "java.io.Serializable");
m.put(Descriptor.JAVA_LANG_CLONEABLE, "java.lang.Cloneable");
m.put(Descriptor.JAVA_LANG_ITERABLE, "java.lang.Iterable");
m.put(Descriptor.JAVA_UTIL_ITERATOR, "java.util.Iterator");
DESCRIPTOR_TO_CLASSNAME = Collections.unmodifiableMap(m);
}
private static final Map<String, String> CLASS_NAME_TO_DESCRIPTOR;
static {
Map<String, String> m = new HashMap();
for (Map.Entry<String, String> e : Descriptor.DESCRIPTOR_TO_CLASSNAME.entrySet()) {
m.put(e.getValue(), e.getKey());
}
CLASS_NAME_TO_DESCRIPTOR = Collections.unmodifiableMap(m);
}
}

View File

@ -1,445 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.codehaus.commons.compiler.CompileException;
import org.codehaus.commons.compiler.CompilerFactoryFactory;
import org.codehaus.commons.compiler.Cookable;
import org.codehaus.commons.compiler.IClassBodyEvaluator;
import org.codehaus.commons.compiler.ICompilerFactory;
import org.codehaus.commons.compiler.ICookable;
import org.codehaus.commons.compiler.IExpressionEvaluator;
import org.codehaus.commons.compiler.IScriptEvaluator;
import org.codehaus.commons.compiler.ISimpleCompiler;
import org.codehaus.commons.compiler.PrimitiveWrapper;
import org.codehaus.janino.Java.AmbiguousName;
import org.codehaus.janino.Java.BlockStatement;
import org.codehaus.janino.Java.Rvalue;
import org.codehaus.janino.Visitor.RvalueVisitor;
import org.codehaus.janino.util.Traverser;
/**
* This {@link IExpressionEvaluator} is implemented by creating and compiling a temporary
* compilation unit defining one class with one static method with one RETURN statement.
* <p>
* A number of "convenience constructors" exist that execute the set-up steps described for {@link
* IExpressionEvaluator} instantly.
* <p>
* If the parameter and return types of the expression are known at compile time, then a "fast"
* expression evaluator can be instantiated through
* {@link #createFastExpressionEvaluator(String, Class, String[], ClassLoader)}. Expression
* evaluation is faster than through {@link #evaluate(Object[])}, because it is not done through
* reflection but through direct method invocation.
* <p>
* Example:
* <pre>
* public interface Foo {
* int bar(int a, int b);
* }
* ...
* Foo f = (Foo) ExpressionEvaluator.createFastExpressionEvaluator(
* "a + b", // expression to evaluate
* Foo.class, // interface that describes the expression's signature
* new String[] { "a", "b" }, // the parameters' names
* (ClassLoader) null // Use current thread's context class loader
* );
* System.out.println("1 + 2 = " + f.bar(1, 2)); // Evaluate the expression
* </pre>
* Notice: The <code>interfaceToImplement</code> must either be declared <code>public</code>,
* or with package scope in the root package (i.e. "no" package).
* <p>
* On my system (Intel P4, 2 GHz, MS Windows XP, JDK 1.4.1), expression "x + 1"
* evaluates as follows:
* <table>
* <tr><td></td><th>Server JVM</th><th>Client JVM</th></td></tr>
* <tr><td>Normal EE</td><td>23.7 ns</td><td>64.0 ns</td></tr>
* <tr><td>Fast EE</td><td>31.2 ns</td><td>42.2 ns</td></tr>
* </table>
* (How can it be that interface method invocation is slower than reflection for
* the server JVM?)
*/
@SuppressWarnings({ "rawtypes", "unchecked" }) public
class ExpressionEvaluator extends ScriptEvaluator implements IExpressionEvaluator {
private Class[] optionalExpressionTypes;
/**
* Equivalent to<pre>
* ExpressionEvaluator ee = new ExpressionEvaluator();
* ee.setExpressionType(expressionType);
* ee.setParameters(parameterNames, parameterTypes);
* ee.cook(expression);</pre>
*
* @see #ExpressionEvaluator()
* @see ExpressionEvaluator#setExpressionType(Class)
* @see ScriptEvaluator#setParameters(String[], Class[])
* @see Cookable#cook(String)
*/
public
ExpressionEvaluator(
String expression,
Class expressionType,
String[] parameterNames,
Class[] parameterTypes
) throws CompileException {
this.setExpressionType(expressionType);
this.setParameters(parameterNames, parameterTypes);
this.cook(expression);
}
/**
* Equivalent to<pre>
* ExpressionEvaluator ee = new ExpressionEvaluator();
* ee.setExpressionType(expressionType);
* ee.setParameters(parameterNames, parameterTypes);
* ee.setThrownExceptions(thrownExceptions);
* ee.setParentClassLoader(optionalParentClassLoader);
* ee.cook(expression);</pre>
*
* @see #ExpressionEvaluator()
* @see ExpressionEvaluator#setExpressionType(Class)
* @see ScriptEvaluator#setParameters(String[], Class[])
* @see ScriptEvaluator#setThrownExceptions(Class[])
* @see SimpleCompiler#setParentClassLoader(ClassLoader)
* @see Cookable#cook(String)
*/
public
ExpressionEvaluator(
String expression,
Class expressionType,
String[] parameterNames,
Class[] parameterTypes,
Class[] thrownExceptions,
ClassLoader optionalParentClassLoader
) throws CompileException {
this.setExpressionType(expressionType);
this.setParameters(parameterNames, parameterTypes);
this.setThrownExceptions(thrownExceptions);
this.setParentClassLoader(optionalParentClassLoader);
this.cook(expression);
}
/**
* Equivalent to<pre>
* ExpressionEvaluator ee = new ExpressionEvaluator();
* ee.setExpressionType(expressionType);
* ee.setParameters(parameterNames, parameterTypes);
* ee.setThrownExceptions(thrownExceptions);
* ee.setExtendedType(optionalExtendedType);
* ee.setImplementedTypes(implementedTypes);
* ee.setParentClassLoader(optionalParentClassLoader);
* ee.cook(expression);</pre>
*
* @see #ExpressionEvaluator()
* @see ExpressionEvaluator#setExpressionType(Class)
* @see ScriptEvaluator#setParameters(String[], Class[])
* @see ScriptEvaluator#setThrownExceptions(Class[])
* @see ClassBodyEvaluator#setExtendedClass(Class)
* @see ClassBodyEvaluator#setImplementedInterfaces(Class[])
* @see SimpleCompiler#setParentClassLoader(ClassLoader)
* @see Cookable#cook(String)
*/
public
ExpressionEvaluator(
String expression,
Class expressionType,
String[] parameterNames,
Class[] parameterTypes,
Class[] thrownExceptions,
Class optionalExtendedType,
Class[] implementedTypes,
ClassLoader optionalParentClassLoader
) throws CompileException {
this.setExpressionType(expressionType);
this.setParameters(parameterNames, parameterTypes);
this.setThrownExceptions(thrownExceptions);
this.setExtendedClass(optionalExtendedType);
this.setImplementedInterfaces(implementedTypes);
this.setParentClassLoader(optionalParentClassLoader);
this.cook(expression);
}
/**
* Equivalent to<pre>
* ExpressionEvaluator ee = new ExpressionEvaluator();
* ee.setClassName(className);
* ee.setExtendedType(optionalExtendedType);
* ee.setImplementedTypes(implementedTypes);
* ee.setStaticMethod(staticMethod);
* ee.setExpressionType(expressionType);
* ee.setMethodName(methodName);
* ee.setParameters(parameterNames, parameterTypes);
* ee.setThrownExceptions(thrownExceptions);
* ee.setParentClassLoader(optionalParentClassLoader);
* ee.cook(scanner);
*
* @see IExpressionEvaluator
* @see IClassBodyEvaluator#setClassName(String)
* @see IClassBodyEvaluator#setExtendedClass(Class)
* @see IClassBodyEvaluator#setImplementedInterfaces(Class[])
* @see IScriptEvaluator#setStaticMethod(boolean)
* @see IExpressionEvaluator#setExpressionType(Class)
* @see IScriptEvaluator#setMethodName(String)
* @see IScriptEvaluator#setParameters(String[], Class[])
* @see IScriptEvaluator#setThrownExceptions(Class[])
* @see ISimpleCompiler#setParentClassLoader(ClassLoader)
* @see ICookable#cook(Reader)
*/
public
ExpressionEvaluator(
Scanner scanner,
String className,
Class optionalExtendedType,
Class[] implementedTypes,
boolean staticMethod,
Class expressionType,
String methodName,
String[] parameterNames,
Class[] parameterTypes,
Class[] thrownExceptions,
ClassLoader optionalParentClassLoader
) throws CompileException, IOException {
this.setClassName(className);
this.setExtendedClass(optionalExtendedType);
this.setImplementedInterfaces(implementedTypes);
this.setStaticMethod(staticMethod);
this.setExpressionType(expressionType);
this.setMethodName(methodName);
this.setParameters(parameterNames, parameterTypes);
this.setThrownExceptions(thrownExceptions);
this.setParentClassLoader(optionalParentClassLoader);
this.cook(scanner);
}
public ExpressionEvaluator() {}
@Override public void
setExpressionType(Class expressionType) { this.setExpressionTypes(new Class[] { expressionType }); }
@Override public void
setExpressionTypes(Class[] expressionTypes) {
this.assertNotCooked();
this.optionalExpressionTypes = expressionTypes;
Class[] returnTypes = new Class[expressionTypes.length];
for (int i = 0; i < returnTypes.length; ++i) {
Class et = expressionTypes[i];
returnTypes[i] = et == IExpressionEvaluator.ANY_TYPE ? Object.class : et;
}
super.setReturnTypes(returnTypes);
}
/** @deprecated {@link #setExpressionType(Class)} should be called instead. */
@Override @Deprecated public final void
setReturnType(Class returnType) {
throw new AssertionError("Must not be used on an ExpressionEvaluator; use 'setExpressionType()' instead");
}
/** @deprecated {@link #setExpressionTypes(Class[])} should be called instead. */
@Override @Deprecated public final void
setReturnTypes(Class[] returnTypes) {
throw new AssertionError("Must not be used on an ExpressionEvaluator; use 'setExpressionTypes()' instead");
}
@Override protected Class
getDefaultReturnType() { return Object.class; }
@Override protected List<BlockStatement>
makeStatements(int idx, Parser parser) throws CompileException, IOException {
List<BlockStatement> statements = new ArrayList();
// Parse the expression.
Rvalue value = parser.parseExpression().toRvalueOrCompileException();
Class et = (
this.optionalExpressionTypes == null
? IExpressionEvaluator.ANY_TYPE
: this.optionalExpressionTypes[idx]
);
if (et == void.class) {
// ExpressionEvaluator with an expression type "void" is a simple expression statement.
statements.add(new Java.ExpressionStatement(value));
} else {
// Special case: Expression type "ANY_TYPE" means return type "Object" and automatic
// wrapping of primitive types.
if (et == IExpressionEvaluator.ANY_TYPE) {
value = new Java.MethodInvocation(
parser.location(), // location
new Java.ReferenceType( // optionalTarget
parser.location(), // location
new String[] { // identifiers
"org", "codehaus", "commons", "compiler", "PrimitiveWrapper"
},
null // optionalTypeArguments
),
"wrap", // methodName
new Java.Rvalue[] { value } // arguments
);
// Make sure "PrimitiveWrapper" is compiled.
PrimitiveWrapper.wrap(99);
// Verify that "PrimitiveWrapper" is loadable.
this.classToType(null, PrimitiveWrapper.class);
}
// Add a return statement.
statements.add(new Java.ReturnStatement(parser.location(), value));
}
if (!parser.peekEof()) {
throw new CompileException("Unexpected token \"" + parser.peek() + "\"", parser.location());
}
return statements;
}
/**
* <pre>
* {@link IExpressionEvaluator} ee = {@link CompilerFactoryFactory}.{@link
* CompilerFactoryFactory#getDefaultCompilerFactory() getDefaultCompilerFactory}().{@link
* ICompilerFactory#newExpressionEvaluator() newExpressionEvaluator}();
* ee.setParentClassLoader(optionalParentClassLoader);
* return ee.{@link #createFastEvaluator createFastEvaluator}(expression, interfaceToImplement, parameterNames);
* </pre>
*
* @deprecated Use {@link #createFastEvaluator(String, Class, String[])} instead:
*/
@Deprecated public static Object
createFastExpressionEvaluator(
String expression,
Class interfaceToImplement,
String[] parameterNames,
ClassLoader optionalParentClassLoader
) throws CompileException {
IExpressionEvaluator ee = new ExpressionEvaluator();
ee.setParentClassLoader(optionalParentClassLoader);
return ee.createFastEvaluator(expression, interfaceToImplement, parameterNames);
}
/**
* Notice: This method is not declared in {@link IExpressionEvaluator}, and is hence only available in <i>this</i>
* implementation of <code>org.codehaus.commons.compiler</code>. To be independent from this particular
* implementation, try to switch to {@link #createFastEvaluator(Reader, Class, String[])}.
*
* @deprecated Use {@link #createFastEvaluator(Reader, Class, String[])} instead
*/
@Deprecated public static Object
createFastExpressionEvaluator(
Scanner scanner,
String className,
Class optionalExtendedType,
Class interfaceToImplement,
String[] parameterNames,
ClassLoader optionalParentClassLoader
) throws CompileException, IOException {
ExpressionEvaluator ee = new ExpressionEvaluator();
ee.setClassName(className);
ee.setExtendedClass(optionalExtendedType);
ee.setParentClassLoader(optionalParentClassLoader);
return ee.createFastEvaluator(scanner, interfaceToImplement, parameterNames);
}
/**
* Notice: This method is not declared in {@link IExpressionEvaluator}, and is hence only available in <i>this</i>
* implementation of <code>org.codehaus.commons.compiler</code>. To be independent from this particular
* implementation, try to switch to {@link #createFastEvaluator(Reader, Class, String[])}.
*
* @deprecated Use {@link #createFastEvaluator(Reader, Class, String[])} instead
*/
@Deprecated public static Object
createFastExpressionEvaluator(
Scanner scanner,
String[] optionalDefaultImports,
String className,
Class optionalExtendedType,
Class interfaceToImplement,
String[] parameterNames,
ClassLoader optionalParentClassLoader
) throws CompileException, IOException {
ExpressionEvaluator ee = new ExpressionEvaluator();
ee.setClassName(className);
ee.setExtendedClass(optionalExtendedType);
ee.setDefaultImports(optionalDefaultImports);
ee.setParentClassLoader(optionalParentClassLoader);
return ee.createFastEvaluator(scanner, interfaceToImplement, parameterNames);
}
/**
* Guess the names of the parameters used in the given expression. The strategy is to look
* at all "ambiguous names" in the expression (e.g. in "a.b.c.d()", the ambiguous name
* is "a.b.c"), and then at the first components of the ambiguous name.
* <ul>
* <li>If any component starts with an upper-case letter, then ambiguous name is assumed to
* be a type name.
* <li>Otherwise, it is assumed to be a parameter name.
* </ul>
*
* @see Scanner#Scanner(String, Reader)
*/
public static String[]
guessParameterNames(Scanner scanner) throws CompileException, IOException {
Parser parser = new Parser(scanner);
// Eat optional leading import declarations.
while (parser.peek("import")) parser.parseImportDeclaration();
// Parse the expression.
Rvalue rvalue = parser.parseExpression().toRvalueOrCompileException();
if (!parser.peekEof()) {
throw new CompileException("Unexpected token \"" + parser.peek() + "\"", scanner.location());
}
// Traverse the expression for ambiguous names and guess which of them are parameter names.
final Set<String> parameterNames = new HashSet();
rvalue.accept((RvalueVisitor) new Traverser() {
@Override public void
traverseAmbiguousName(AmbiguousName an) {
// If any of the components starts with an upper-case letter, then the ambiguous
// name is most probably a type name, e.g. "System.out" or "java.lang.System.out".
for (String identifier : an.identifiers) {
if (Character.isUpperCase(identifier.charAt(0))) return;
}
// It's most probably a parameter name (although it could be a field name as well).
parameterNames.add(an.identifiers[0]);
}
}.comprehensiveVisitor());
return (String[]) parameterNames.toArray(new String[parameterNames.size()]);
}
}

View File

@ -1,56 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino;
import org.codehaus.commons.compiler.CompileException;
import org.codehaus.commons.compiler.Location;
import org.codehaus.commons.compiler.WarningHandler;
import org.codehaus.janino.util.StringPattern;
/** Invokes a delegate iff the handle of the warning matches one or more of a set of {@link StringPattern}s. */
public
class FilterWarningHandler implements WarningHandler {
private final StringPattern[] handlePatterns;
private final WarningHandler delegate;
/**
* Popular values for the <code>handlePatterns</code> parameter are
* {@link StringPattern#PATTERNS_ALL} and {@link StringPattern#PATTERNS_NONE}.
*/
public
FilterWarningHandler(StringPattern[] handlePatterns, WarningHandler delegate) {
this.handlePatterns = handlePatterns;
this.delegate = delegate;
}
@Override public void
handleWarning(String handle, String message, Location optionalLocation) throws CompileException {
if (StringPattern.matches(this.handlePatterns, handle)) {
this.delegate.handleWarning(handle, message, optionalLocation);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,384 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino;
import java.io.File;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.codehaus.janino.IClass.IConstructor;
import org.codehaus.janino.IClass.IMethod;
import org.codehaus.janino.util.resource.JarDirectoriesResourceFinder;
import org.codehaus.janino.util.resource.PathResourceFinder;
import org.codehaus.janino.util.resource.ResourceFinder;
/** Loads an {@link IClass} by type name. */
@SuppressWarnings({ "rawtypes", "unchecked" }) public abstract
class IClassLoader {
private static final boolean DEBUG = false;
// The following are constants, but cannot be declared FINAL, because they are only initialized by
// "postConstruct()".
// CHECKSTYLE MemberName:OFF
// CHECKSTYLE AbbreviationAsWordInName:OFF
/** Representation of the {@link java.lang.Override} annotation. */
public IClass ANNO_java_lang_Override;
/** Representation of the {@link java.lang.AssertionError} type. */
public IClass TYPE_java_lang_AssertionError;
/** Representation of the {@link java.lang.Boolean} type. */
public IClass TYPE_java_lang_Boolean;
/** Representation of the {@link java.lang.Byte} type. */
public IClass TYPE_java_lang_Byte;
/** Representation of the {@link java.lang.Character} type. */
public IClass TYPE_java_lang_Character;
/** Representation of the {@link java.lang.Class} type. */
public IClass TYPE_java_lang_Class;
/** Representation of the {@link java.lang.Cloneable} type. */
public IClass TYPE_java_lang_Cloneable;
/** Representation of the {@link java.lang.Double} type. */
public IClass TYPE_java_lang_Double;
/** Representation of the {@link java.lang.Exception} type. */
public IClass TYPE_java_lang_Exception;
/** Representation of the {@link java.lang.Error} type. */
public IClass TYPE_java_lang_Error;
/** Representation of the {@link java.lang.Float} type. */
public IClass TYPE_java_lang_Float;
/** Representation of the {@link java.lang.Integer} type. */
public IClass TYPE_java_lang_Integer;
/** Representation of the {@link java.lang.Iterable} type. */
public IClass TYPE_java_lang_Iterable;
/** Representation of the {@link java.lang.Long} type. */
public IClass TYPE_java_lang_Long;
/** Representation of the {@link java.lang.Object} type. */
public IClass TYPE_java_lang_Object;
/** Representation of the {@link java.lang.RuntimeException} type. */
public IClass TYPE_java_lang_RuntimeException;
/** Representation of the {@link java.lang.Short} type. */
public IClass TYPE_java_lang_Short;
/** Representation of the {@link java.lang.String} type. */
public IClass TYPE_java_lang_String;
/** Representation of the {@link java.lang.StringBuilder} type. */
public IClass TYPE_java_lang_StringBuilder;
/** Representation of the {@link java.lang.Throwable} type. */
public IClass TYPE_java_lang_Throwable;
/** Representation of the {@link java.io.Serializable} type. */
public IClass TYPE_java_io_Serializable;
/** Representation of the {@link java.util.Iterator} type. */
public IClass TYPE_java_util_Iterator;
/** Representation of the {@link Iterable#iterator()} method. */
public IMethod METH_java_lang_Iterable__iterator;
/** Representation of the {@link String#concat(String)} method. */
public IMethod METH_java_lang_String__concat__java_lang_String;
/** Representation of the {@link String#valueOf(int)} method. */
public IMethod METH_java_lang_String__valueOf__int;
/** Representation of the {@link String#valueOf(long)} method. */
public IMethod METH_java_lang_String__valueOf__long;
/** Representation of the {@link String#valueOf(float)} method. */
public IMethod METH_java_lang_String__valueOf__float;
/** Representation of the {@link String#valueOf(double)} method. */
public IMethod METH_java_lang_String__valueOf__double;
/** Representation of the {@link String#valueOf(char)} method. */
public IMethod METH_java_lang_String__valueOf__char;
/** Representation of the {@link String#valueOf(boolean)} method. */
public IMethod METH_java_lang_String__valueOf__boolean;
/** Representation of the {@link String#valueOf(Object)} method. */
public IMethod METH_java_lang_String__valueOf__java_lang_Object;
/** Representation of the {@link StringBuilder#append(String)} method. */
public IMethod METH_java_lang_StringBuilder__append__java_lang_String;
/** Representation of the {@link StringBuilder#toString()} method. */
public IMethod METH_java_lang_StringBuilder__toString;
/** Representation of the {@link java.util.Iterator#hasNext()} method. */
public IMethod METH_java_util_Iterator__hasNext;
/** Representation of the {@link java.util.Iterator#next()} method. */
public IMethod METH_java_util_Iterator__next;
/** Representation of the {@link StringBuilder#StringBuilder(String)} constructor. */
public IConstructor CTOR_java_lang_StringBuilder__java_lang_String;
// CHECKSTYLE AbbreviationAsWordInName:ON
// CHECKSTYLE MemberName:ON
public
IClassLoader(IClassLoader optionalParentIClassLoader) {
this.optionalParentIClassLoader = optionalParentIClassLoader;
}
/**
* This method must be called by the constructor of the directly derived
* class. (The reason being is that this method invokes abstract
* {@link #loadIClass(String)} which will not work until the implementing
* class is constructed.)
*/
protected final void
postConstruct() {
try {
this.ANNO_java_lang_Override = this.loadIClass(Descriptor.JAVA_LANG_OVERRIDE);
this.TYPE_java_lang_AssertionError = this.loadIClass(Descriptor.JAVA_LANG_ASSERTIONERROR);
this.TYPE_java_lang_Boolean = this.loadIClass(Descriptor.JAVA_LANG_BOOLEAN);
this.TYPE_java_lang_Byte = this.loadIClass(Descriptor.JAVA_LANG_BYTE);
this.TYPE_java_lang_Character = this.loadIClass(Descriptor.JAVA_LANG_CHARACTER);
this.TYPE_java_lang_Class = this.loadIClass(Descriptor.JAVA_LANG_CLASS);
this.TYPE_java_lang_Cloneable = this.loadIClass(Descriptor.JAVA_LANG_CLONEABLE);
this.TYPE_java_lang_Double = this.loadIClass(Descriptor.JAVA_LANG_DOUBLE);
this.TYPE_java_lang_Exception = this.loadIClass(Descriptor.JAVA_LANG_EXCEPTION);
this.TYPE_java_lang_Error = this.loadIClass(Descriptor.JAVA_LANG_ERROR);
this.TYPE_java_lang_Float = this.loadIClass(Descriptor.JAVA_LANG_FLOAT);
this.TYPE_java_lang_Integer = this.loadIClass(Descriptor.JAVA_LANG_INTEGER);
this.TYPE_java_lang_Iterable = this.loadIClass(Descriptor.JAVA_LANG_ITERABLE);
this.TYPE_java_lang_Long = this.loadIClass(Descriptor.JAVA_LANG_LONG);
this.TYPE_java_lang_Object = this.loadIClass(Descriptor.JAVA_LANG_OBJECT);
this.TYPE_java_lang_RuntimeException = this.loadIClass(Descriptor.JAVA_LANG_RUNTIMEEXCEPTION);
this.TYPE_java_lang_Short = this.loadIClass(Descriptor.JAVA_LANG_SHORT);
this.TYPE_java_lang_String = this.loadIClass(Descriptor.JAVA_LANG_STRING);
this.TYPE_java_lang_StringBuilder = this.loadIClass(Descriptor.JAVA_LANG_STRINGBUILDER);
this.TYPE_java_lang_Throwable = this.loadIClass(Descriptor.JAVA_LANG_THROWABLE);
this.TYPE_java_io_Serializable = this.loadIClass(Descriptor.JAVA_IO_SERIALIZABLE);
this.TYPE_java_util_Iterator = this.loadIClass(Descriptor.JAVA_UTIL_ITERATOR);
// CHECKSTYLE LineLength:OFF
// CHECKSTYLE Whitespace:OFF
this.METH_java_lang_Iterable__iterator = this.TYPE_java_lang_Iterable .findIMethod("iterator", new IClass[0]);
this.METH_java_lang_String__concat__java_lang_String = this.TYPE_java_lang_String .findIMethod("concat", new IClass[] { this.TYPE_java_lang_String });
this.METH_java_lang_String__valueOf__int = this.TYPE_java_lang_String .findIMethod("valueOf", new IClass[] { IClass.INT });
this.METH_java_lang_String__valueOf__long = this.TYPE_java_lang_String .findIMethod("valueOf", new IClass[] { IClass.LONG });
this.METH_java_lang_String__valueOf__float = this.TYPE_java_lang_String .findIMethod("valueOf", new IClass[] { IClass.FLOAT });
this.METH_java_lang_String__valueOf__double = this.TYPE_java_lang_String .findIMethod("valueOf", new IClass[] { IClass.DOUBLE });
this.METH_java_lang_String__valueOf__char = this.TYPE_java_lang_String .findIMethod("valueOf", new IClass[] { IClass.CHAR });
this.METH_java_lang_String__valueOf__boolean = this.TYPE_java_lang_String .findIMethod("valueOf", new IClass[] { IClass.BOOLEAN });
this.METH_java_lang_String__valueOf__java_lang_Object = this.TYPE_java_lang_String .findIMethod("valueOf", new IClass[] { this.TYPE_java_lang_Object });
this.METH_java_lang_StringBuilder__append__java_lang_String = this.TYPE_java_lang_StringBuilder.findIMethod("append", new IClass[] { this.TYPE_java_lang_String });
this.METH_java_lang_StringBuilder__toString = this.TYPE_java_lang_StringBuilder.findIMethod("toString", new IClass[0]);
this.METH_java_util_Iterator__hasNext = this.TYPE_java_util_Iterator .findIMethod("hasNext", new IClass[0]);
this.METH_java_util_Iterator__next = this.TYPE_java_util_Iterator .findIMethod("next", new IClass[0]);
this.CTOR_java_lang_StringBuilder__java_lang_String = this.TYPE_java_lang_StringBuilder.findIConstructor(new IClass[] { this.TYPE_java_lang_String });
// CHECKSTYLE Whitespace:ON
// CHECKSTYLE LineLength:ON
} catch (Exception e) {
throw new JaninoRuntimeException("Cannot load simple types", e);
}
}
/**
* Get an {@link IClass} by field descriptor.
*
* @param fieldDescriptor E.g. 'Lpkg1/pkg2/Outer$Inner;'
* @return {@code null} if an {@link IClass} could not be loaded
* @throws ClassNotFoundException An exception was raised while loading the {@link IClass}
*/
public final IClass
loadIClass(String fieldDescriptor) throws ClassNotFoundException {
if (IClassLoader.DEBUG) System.out.println(this + ": Load type \"" + fieldDescriptor + "\"");
if (Descriptor.isPrimitive(fieldDescriptor)) {
return (
fieldDescriptor.equals(Descriptor.VOID) ? IClass.VOID :
fieldDescriptor.equals(Descriptor.BYTE) ? IClass.BYTE :
fieldDescriptor.equals(Descriptor.CHAR) ? IClass.CHAR :
fieldDescriptor.equals(Descriptor.DOUBLE) ? IClass.DOUBLE :
fieldDescriptor.equals(Descriptor.FLOAT) ? IClass.FLOAT :
fieldDescriptor.equals(Descriptor.INT) ? IClass.INT :
fieldDescriptor.equals(Descriptor.LONG) ? IClass.LONG :
fieldDescriptor.equals(Descriptor.SHORT) ? IClass.SHORT :
fieldDescriptor.equals(Descriptor.BOOLEAN) ? IClass.BOOLEAN :
null
);
}
// Ask parent IClassLoader first.
if (this.optionalParentIClassLoader != null) {
IClass res = this.optionalParentIClassLoader.loadIClass(fieldDescriptor);
if (res != null) return res;
}
// We need to synchronize here because "unloadableIClasses" and
// "loadedIClasses" are unsynchronized containers.
IClass result;
synchronized (this) {
// Class could not be loaded before?
if (this.unloadableIClasses.contains(fieldDescriptor)) return null;
// Class already loaded?
result = (IClass) this.loadedIClasses.get(fieldDescriptor);
if (result != null) return result;
// Special handling for array types.
if (Descriptor.isArrayReference(fieldDescriptor)) {
// Load the component type.
IClass componentIClass = this.loadIClass(
Descriptor.getComponentDescriptor(fieldDescriptor)
);
if (componentIClass == null) return null;
// Now get and define the array type.
IClass arrayIClass = componentIClass.getArrayIClass(this.TYPE_java_lang_Object);
this.loadedIClasses.put(fieldDescriptor, arrayIClass);
return arrayIClass;
}
if (IClassLoader.DEBUG) System.out.println("call IClassLoader.findIClass(\"" + fieldDescriptor + "\")");
// Load the class through the {@link #findIClass(String)} method implemented by the
// derived class.
result = this.findIClass(fieldDescriptor);
if (result == null) {
this.unloadableIClasses.add(fieldDescriptor);
return null;
}
}
if (!result.getDescriptor().equalsIgnoreCase(fieldDescriptor)) {
throw new JaninoRuntimeException(
"\"findIClass()\" returned \""
+ result.getDescriptor()
+ "\" instead of \""
+ fieldDescriptor
+ "\""
);
}
if (IClassLoader.DEBUG) System.out.println(this + ": Loaded type \"" + fieldDescriptor + "\" as " + result);
return result;
}
/**
* Find a new {@link IClass} by descriptor; return <code>null</code> if a class
* for that <code>descriptor</code> could not be found.
* <p>
* Similar {@link java.lang.ClassLoader#findClass(java.lang.String)}, this method
* must
* <ul>
* <li>Get an {@link IClass} object from somewhere for the given type
* <li>Call {@link #defineIClass(IClass)} with that {@link IClass} object as
* the argument
* <li>Return the {@link IClass} object
* </ul>
* <p>
* The format of a <code>descriptor</code> is defined in JVMS 4.3.2. Typical
* descriptors are:
* <ul>
* <li><code>I</code> (Integer)
* <li><code>Lpkg1/pkg2/Cls;</code> (Class declared in package)
* <li><code>Lpkg1/pkg2/Outer$Inner;</code> Member class
* </ul>
* Notice that this method is never called for array types.
* <p>
* Notice that this method is never called from more than one thread at a time.
* In other words, implementations of this method need not be synchronized.
*
* @return <code>null</code> if a class with that descriptor could not be found
* @throws ClassNotFoundException if an exception was raised while loading the class
*/
protected abstract IClass findIClass(String descriptor) throws ClassNotFoundException;
/**
* Define an {@link IClass} in the context of this {@link IClassLoader}.
* If an {@link IClass} with that descriptor already exists, a
* {@link RuntimeException} is thrown.
* <p>
* This method should only be called from an implementation of
* {@link #findIClass(String)}.
*
* @throws RuntimeException A different {@link IClass} object is already defined for this type
*/
protected final void
defineIClass(IClass iClass) {
String descriptor = iClass.getDescriptor();
// Already defined?
IClass loadedIClass = (IClass) this.loadedIClasses.get(descriptor);
if (loadedIClass != null) {
if (loadedIClass == iClass) return;
throw new JaninoRuntimeException("Non-identical definition of IClass \"" + descriptor + "\"");
}
// Define.
this.loadedIClasses.put(descriptor, iClass);
if (IClassLoader.DEBUG) System.out.println(this + ": Defined type \"" + descriptor + "\"");
}
/**
* Create an {@link IClassLoader} that looks for classes in the given "boot class
* path", then in the given "extension directories", and then in the given
* "class path".
* <p>
* The default for the <code>optionalBootClassPath</code> is the path defined in
* the system property "sun.boot.class.path", and the default for the
* <code>optionalExtensionDirs</code> is the path defined in the "java.ext.dirs"
* system property.
*/
public static IClassLoader
createJavacLikePathIClassLoader(
final File[] optionalBootClassPath,
final File[] optionalExtDirs,
final File[] classPath
) {
ResourceFinder bootClassPathResourceFinder = new PathResourceFinder(
optionalBootClassPath == null
? PathResourceFinder.parsePath(System.getProperty("sun.boot.class.path"))
: optionalBootClassPath
);
ResourceFinder extensionDirectoriesResourceFinder = new JarDirectoriesResourceFinder(
optionalExtDirs == null
? PathResourceFinder.parsePath(System.getProperty("java.ext.dirs"))
: optionalExtDirs
);
final ResourceFinder classPathResourceFinder = new PathResourceFinder(classPath);
// We can load classes through "ResourceFinderIClassLoader"s, which means
// they are read into "ClassFile" objects, or we can load classes through
// "ClassLoaderIClassLoader"s, which means they are loaded into the JVM.
//
// In my environment, the latter is slightly faster. No figures about
// resource usage yet.
//
// In applications where the generated classes are not loaded into the
// same JVM instance, we should avoid to use the
// ClassLoaderIClassLoader, because that assumes that final fields have
// a constant value, even if not compile-time-constant but only
// initialization-time constant. The classical example is
// "File.separator", which is non-blank final, but not compile-time-
// constant.
IClassLoader icl;
icl = new ResourceFinderIClassLoader(bootClassPathResourceFinder, null);
icl = new ResourceFinderIClassLoader(extensionDirectoriesResourceFinder, icl);
icl = new ResourceFinderIClassLoader(classPathResourceFinder, icl);
return icl;
}
private final IClassLoader optionalParentIClassLoader;
private final Map<String /*descriptor*/, IClass> loadedIClasses = new HashMap();
private final Set<String /*descriptor*/> unloadableIClasses = new HashSet();
}

View File

@ -1,40 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino;
/**
* All Janino components that throw {@link RuntimeException} throw this subclass
* to allow for client libraries to intercept them more easily.
*/
public
class JaninoRuntimeException extends RuntimeException {
private static final long serialVersionUID = 7155453370536273589L;
public JaninoRuntimeException() {}
public JaninoRuntimeException(String message) { super(message); }
public JaninoRuntimeException(String message, Throwable t) { super(message, t); }
}

File diff suppressed because it is too large Load Diff

View File

@ -1,256 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino;
import java.io.File;
import java.io.Reader;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.codehaus.commons.compiler.AbstractJavaSourceClassLoader;
import org.codehaus.commons.compiler.CompileException;
import org.codehaus.commons.compiler.ErrorHandler;
import org.codehaus.commons.compiler.ICookable;
import org.codehaus.commons.compiler.WarningHandler;
import org.codehaus.janino.util.ClassFile;
import org.codehaus.janino.util.resource.DirectoryResourceFinder;
import org.codehaus.janino.util.resource.PathResourceFinder;
import org.codehaus.janino.util.resource.ResourceFinder;
/**
* A {@link ClassLoader} that, unlike usual {@link ClassLoader}s,
* does not load byte code, but reads Java&trade; source code and then scans, parses,
* compiles and loads it into the virtual machine.
* <p>
* As with any {@link ClassLoader}, it is not possible to "update" classes after they've been
* loaded. The way to achieve this is to give up on the {@link JavaSourceClassLoader} and create
* a new one.
*/
@SuppressWarnings({ "rawtypes", "unchecked" }) public
class JavaSourceClassLoader extends AbstractJavaSourceClassLoader {
public
JavaSourceClassLoader() { this(ClassLoader.getSystemClassLoader()); }
public
JavaSourceClassLoader(ClassLoader parentClassLoader) {
this(
parentClassLoader,
(File[]) null, // optionalSourcePath
null // optionalCharacterEncoding
);
}
/**
* Set up a {@link JavaSourceClassLoader} that finds Java&trade; source code in a file that resides in either of
* the directories specified by the given source path.
*
* @param parentClassLoader See {@link ClassLoader}
* @param optionalSourcePath A collection of directories that are searched for Java&trade; source files in
* the given order
* @param optionalCharacterEncoding The encoding of the Java&trade; source files (<code>null</code> for platform
* default encoding)
*/
public
JavaSourceClassLoader(
ClassLoader parentClassLoader,
File[] optionalSourcePath,
String optionalCharacterEncoding
) {
this(
parentClassLoader, // parentClassLoader
( // sourceFinder
optionalSourcePath == null
? (ResourceFinder) new DirectoryResourceFinder(new File("."))
: (ResourceFinder) new PathResourceFinder(optionalSourcePath)
),
optionalCharacterEncoding // optionalCharacterEncoding
);
}
/**
* Constructs a {@link JavaSourceClassLoader} that finds Java&trade; source code through a given {@link
* ResourceFinder}.
* <p>
* You can specify to include certain debugging information in the generated class files, which
* is useful if you want to debug through the generated classes (see
* {@link Scanner#Scanner(String, Reader)}).
*
* @param parentClassLoader See {@link ClassLoader}
* @param sourceFinder Used to locate additional source files
* @param optionalCharacterEncoding The encoding of the Java&trade; source files (<code>null</code> for platform
* default encoding)
*/
public
JavaSourceClassLoader(
ClassLoader parentClassLoader,
ResourceFinder sourceFinder,
String optionalCharacterEncoding
) {
this(parentClassLoader, new JavaSourceIClassLoader(
sourceFinder, // sourceFinder
optionalCharacterEncoding, // optionalCharacterEncoding
new ClassLoaderIClassLoader(parentClassLoader) // optionalParentIClassLoader
));
}
/**
* Constructs a {@link JavaSourceClassLoader} that finds classes through an {@link JavaSourceIClassLoader}.
*/
public
JavaSourceClassLoader(ClassLoader parentClassLoader, JavaSourceIClassLoader iClassLoader) {
super(parentClassLoader);
this.iClassLoader = iClassLoader;
}
@Override public void
setSourcePath(File[] sourcePath) {
this.iClassLoader.setSourceFinder(new PathResourceFinder(sourcePath));
}
@Override public void
setSourceFileCharacterEncoding(String optionalCharacterEncoding) {
this.iClassLoader.setCharacterEncoding(optionalCharacterEncoding);
}
@Override public void
setDebuggingInfo(boolean debugSource, boolean debugLines, boolean debugVars) {
this.debugSource = debugSource;
this.debugLines = debugLines;
this.debugVars = debugVars;
}
/** @see UnitCompiler#setCompileErrorHandler */
public void
setCompileErrorHandler(ErrorHandler optionalCompileErrorHandler) {
this.iClassLoader.setCompileErrorHandler(optionalCompileErrorHandler);
}
/**
* @see Parser#setWarningHandler(WarningHandler)
* @see UnitCompiler#setCompileErrorHandler
*/
public void
setWarningHandler(WarningHandler optionalWarningHandler) {
this.iClassLoader.setWarningHandler(optionalWarningHandler);
}
/**
* Implementation of {@link ClassLoader#findClass(String)}.
*
* @throws ClassNotFoundException
*/
@Override protected /*synchronized <- No need to synchronize, because 'loadClass()' is synchronized */ Class
findClass(String name) throws ClassNotFoundException {
// Check if the bytecode for that class was generated already.
byte[] bytecode = (byte[]) this.precompiledClasses.remove(name);
if (bytecode == null) {
// Read, scan, parse and compile the right compilation unit.
{
Map<String /*name*/, byte[] /*bytecode*/> bytecodes = this.generateBytecodes(name);
if (bytecodes == null) throw new ClassNotFoundException(name);
this.precompiledClasses.putAll(bytecodes);
}
// Now the bytecode for our class should be available.
bytecode = (byte[]) this.precompiledClasses.remove(name);
if (bytecode == null) {
throw new JaninoRuntimeException(
"SNO: Scanning, parsing and compiling class \""
+ name
+ "\" did not create a class file!?"
);
}
}
return this.defineBytecode(name, bytecode);
}
/**
* This {@link Map} keeps those classes which were already compiled, but not
* yet defined i.e. which were not yet passed to
* {@link ClassLoader#defineClass(java.lang.String, byte[], int, int)}.
*/
private final Map<String /*name*/, byte[] /*bytecode*/> precompiledClasses = new HashMap();
/**
* Find, scan, parse the right compilation unit. Compile the parsed compilation unit to
* bytecode. This may cause more compilation units being scanned and parsed. Continue until
* all compilation units are compiled.
*
* @return String name => byte[] bytecode, or <code>null</code> if no source code could be found
* @throws ClassNotFoundException on compilation problems
*/
protected Map<String /*name*/, byte[] /*bytecode*/>
generateBytecodes(String name) throws ClassNotFoundException {
if (this.iClassLoader.loadIClass(Descriptor.fromClassName(name)) == null) return null;
Map<String /*name*/, byte[] /*bytecode*/> bytecodes = new HashMap();
Set<UnitCompiler> compiledUnitCompilers = new HashSet();
COMPILE_UNITS:
for (;;) {
for (UnitCompiler uc : this.iClassLoader.getUnitCompilers()) {
if (!compiledUnitCompilers.contains(uc)) {
ClassFile[] cfs;
try {
cfs = uc.compileUnit(this.debugSource, this.debugLines, this.debugVars);
} catch (CompileException ex) {
throw new ClassNotFoundException(ex.getMessage(), ex);
}
for (ClassFile cf : cfs) bytecodes.put(cf.getThisClassName(), cf.toByteArray());
compiledUnitCompilers.add(uc);
continue COMPILE_UNITS;
}
}
return bytecodes;
}
}
/**
* @throws ClassFormatError
* @see #setProtectionDomainFactory
*/
private Class
defineBytecode(String className, byte[] ba) {
return this.defineClass(className, ba, 0, ba.length, (
this.optionalProtectionDomainFactory == null
? null
: this.optionalProtectionDomainFactory.getProtectionDomain(ClassFile.getSourceResourceName(className))
));
}
private final JavaSourceIClassLoader iClassLoader;
private boolean debugSource = Boolean.getBoolean(ICookable.SYSTEM_PROPERTY_SOURCE_DEBUGGING_ENABLE);
private boolean debugLines = this.debugSource;
private boolean debugVars = this.debugSource;
}

View File

@ -1,208 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashSet;
import java.util.Set;
import org.codehaus.commons.compiler.CompileException;
import org.codehaus.commons.compiler.ErrorHandler;
import org.codehaus.commons.compiler.Location;
import org.codehaus.commons.compiler.WarningHandler;
import org.codehaus.janino.Java.CompilationUnit;
import org.codehaus.janino.util.ClassFile;
import org.codehaus.janino.util.resource.Resource;
import org.codehaus.janino.util.resource.ResourceFinder;
/**
* This {@link org.codehaus.janino.IClassLoader} finds, scans and parses compilation units.
* <p>
* Notice that it does not compile them!
*/
public
class JavaSourceIClassLoader extends IClassLoader {
private static final boolean DEBUG = false;
private ResourceFinder sourceFinder;
private String optionalCharacterEncoding;
/** Collection of parsed compilation units. */
private final Set<UnitCompiler> unitCompilers = new HashSet<UnitCompiler>();
private ErrorHandler optionalCompileErrorHandler;
private WarningHandler optionalWarningHandler;
public
JavaSourceIClassLoader(
ResourceFinder sourceFinder,
String optionalCharacterEncoding,
IClassLoader optionalParentIClassLoader
) {
super(optionalParentIClassLoader);
this.sourceFinder = sourceFinder;
this.optionalCharacterEncoding = optionalCharacterEncoding;
super.postConstruct();
}
/**
* Returns the set of {@link UnitCompiler}s that were created so far.
*/
public Set<UnitCompiler>
getUnitCompilers() { return this.unitCompilers; }
/** @param pathResourceFinder The source path */
public void
setSourceFinder(ResourceFinder pathResourceFinder) {
this.sourceFinder = pathResourceFinder;
}
/**
* @param optionalCharacterEncoding The name of the charset that is used to read source files, or {@code null} to
* use the platform's 'default charset'
*/
public void
setCharacterEncoding(String optionalCharacterEncoding) {
this.optionalCharacterEncoding = optionalCharacterEncoding;
}
/** @see UnitCompiler#setCompileErrorHandler(ErrorHandler) */
public void
setCompileErrorHandler(ErrorHandler optionalCompileErrorHandler) {
this.optionalCompileErrorHandler = optionalCompileErrorHandler;
}
/**
* @see Parser#setWarningHandler(WarningHandler)
* @see UnitCompiler#setCompileErrorHandler(ErrorHandler)
*/
public void
setWarningHandler(WarningHandler optionalWarningHandler) {
this.optionalWarningHandler = optionalWarningHandler;
}
/**
* @param fieldDescriptor Field descriptor of the {@link IClass} to load, e.g. "Lpkg1/pkg2/Outer$Inner;"
* @throws ClassNotFoundException An exception was raised while loading the {@link IClass}
*/
@Override public IClass
findIClass(final String fieldDescriptor) throws ClassNotFoundException {
if (JavaSourceIClassLoader.DEBUG) System.out.println("type = " + fieldDescriptor);
// Class type.
String className = Descriptor.toClassName(fieldDescriptor); // E.g. "pkg1.pkg2.Outer$Inner"
if (JavaSourceIClassLoader.DEBUG) System.out.println("2 className = \"" + className + "\"");
// Do not attempt to load classes from package "java".
if (className.startsWith("java.")) return null;
// Determine the name of the top-level class.
String topLevelClassName;
{
int idx = className.indexOf('$');
topLevelClassName = idx == -1 ? className : className.substring(0, idx);
}
// Check the already-parsed compilation units.
for (UnitCompiler uc : this.unitCompilers) {
IClass res = uc.findClass(topLevelClassName);
if (res != null) {
if (!className.equals(topLevelClassName)) {
res = uc.findClass(className);
if (res == null) return null;
}
this.defineIClass(res);
return res;
}
}
try {
Java.CompilationUnit cu = this.findCompilationUnit(className);
if (cu == null) return null;
UnitCompiler uc = new UnitCompiler(cu, this);
uc.setCompileErrorHandler(this.optionalCompileErrorHandler);
uc.setWarningHandler(this.optionalWarningHandler);
// Remember compilation unit for later compilation.
this.unitCompilers.add(uc);
// Find the class/interface declaration in the compiled unit.
IClass res = uc.findClass(className);
if (res == null) {
if (className.equals(topLevelClassName)) {
throw new CompileException(
"Compilation unit '" + className + "' does not declare a class with the same name",
(Location) null
);
}
return null;
}
this.defineIClass(res);
return res;
} catch (IOException e) {
throw new ClassNotFoundException("Parsing compilation unit '" + className + "'", e);
} catch (CompileException e) {
throw new ClassNotFoundException("Parsing compilation unit '" + className + "'", e);
}
}
/**
* Finds the Java&trade; source file for the named class through the configured 'source resource finder' and
* parses it.
*
* @return {@code null} iff the source file could not be found
*/
protected CompilationUnit
findCompilationUnit(String className) throws IOException, CompileException {
// Find source file.
Resource sourceResource = this.sourceFinder.findResource(ClassFile.getSourceResourceName(className));
if (sourceResource == null) return null;
if (JavaSourceIClassLoader.DEBUG) System.out.println("sourceResource=" + sourceResource);
// Scan and parse the source file.
InputStream inputStream = sourceResource.open();
try {
Scanner scanner = new Scanner(
sourceResource.getFileName(),
inputStream,
this.optionalCharacterEncoding
);
scanner.setWarningHandler(this.optionalWarningHandler);
Parser parser = new Parser(scanner);
parser.setWarningHandler(this.optionalWarningHandler);
return parser.parseCompilationUnit();
} finally {
try { inputStream.close(); } catch (IOException ex) {}
}
}
}

View File

@ -1,86 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino;
import java.util.ArrayList;
import java.util.List;
/** Representation of a "method descriptor" (JVMS 4.3.3). */
@SuppressWarnings({ "rawtypes", "unchecked" }) public
class MethodDescriptor {
/** The field descriptors of the method parameters. */
public final String[] parameterFds;
/** The field descriptor of the method return value. */
public final String returnFd;
/** */
public
MethodDescriptor(String[] parameterFds, String returnFd) {
this.parameterFds = parameterFds;
this.returnFd = returnFd;
}
/** Parse a method descriptor into parameter FDs and return FDs. */
public
MethodDescriptor(String s) {
if (s.charAt(0) != '(') throw new JaninoRuntimeException();
int from = 1;
List<String> parameterFDs = new ArrayList();
while (s.charAt(from) != ')') {
int to = from;
while (s.charAt(to) == '[') ++to;
if ("BCDFIJSZ".indexOf(s.charAt(to)) != -1) {
++to;
} else
if (s.charAt(to) == 'L') {
for (++to; s.charAt(to) != ';'; ++to);
++to;
} else {
throw new JaninoRuntimeException();
}
parameterFDs.add(s.substring(from, to));
from = to;
}
this.parameterFds = (String[]) parameterFDs.toArray(new String[parameterFDs.size()]);
this.returnFd = s.substring(++from);
}
/** @return The "method descriptor" (JVMS 4.3.3) */
@Override public String
toString() {
StringBuilder sb = new StringBuilder("(");
for (String parameterFd : this.parameterFds) sb.append(parameterFd);
return sb.append(')').append(this.returnFd).toString();
}
/** Patches an additional parameter into a given method descriptor. */
public static String
prependParameter(String md, String parameterFd) { return '(' + parameterFd + md.substring(1); }
}

View File

@ -1,270 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino;
/**
* This class defines constants and convenience methods for the handling of modifiers as defined by the JVM.
* <p>
* Notice: This class should be named <code>IClass.IModifier</code>, but changing the name would break existing client
* code. Thus it won't be renamed until there's a really good reason to do it (maybe with a major design change).
*/
public final
class Mod {
private Mod() {} // Don't instantiate me!
/** An alias for '0' -- <i>no</i> modifiers. */
public static final short NONE = 0x0000;
/**
* The flag indicating 'public accessibility' of the modified element. Methods of interfaces are always {@link
* #PUBLIC}.
*
* @see #PPP
* @see #isPublicAccess(short)
*/
public static final short PUBLIC = 0x0001;
/** @return Whether the given modifier symbolizes {@link #PUBLIC} accessibility */
public static boolean isPublicAccess(short sh) { return (sh & Mod.PPP) == Mod.PUBLIC; }
/**
* The flag indicating 'private accessibility' of the modified element.
*
* @see #PPP
* @see #isPrivateAccess(short)
*/
public static final short PRIVATE = 0x0002;
/** @return Whether the given modifier symbolizes {@link #PRIVATE} accessibility */
public static boolean isPrivateAccess(short sh) { return (sh & Mod.PPP) == Mod.PRIVATE; }
/**
* The flag indicating 'protected accessibility' of the modified element.
*
* @see #PPP
* @see #isProtectedAccess(short)
*/
public static final short PROTECTED = 0x0004;
/** @return Whether the given modifier symbolizes {@link #PROTECTED} accessibility */
public static boolean isProtectedAccess(short sh) { return (sh & Mod.PPP) == Mod.PROTECTED; }
/**
* The flag indicating 'default accessibility' a.k.a. 'package accessibility' of the modified element.
*
* @see #PPP
* @see #isPackageAccess(short)
*/
public static final short PACKAGE = 0x0000;
/** @return Whether the given modifier symbolizes {@link #PACKAGE} (a.k.a. 'default') accessibility */
public static boolean isPackageAccess(short sh) { return (sh & Mod.PPP) == Mod.PACKAGE; }
/** The mask to select the accessibility flags from modifiers. */
public static final short PPP = 0x0007;
/** @return The given {@code modifiers}, but with the accessibility part changed to {@code newAccess} */
public static short
changeAccess(short modifiers, short newAccess) { return (short) ((modifiers & ~Mod.PPP) | newAccess); }
/**
* This flag is set on class or interface initialization methods, STATIC class fields, all interface fields, STATIC
* methods, and STATIC nested classes.
*/
public static final short STATIC = 0x0008;
/** @return Whether the given modifier includes {@link #STATIC} */
public static boolean isStatic(short sh) { return (sh & Mod.STATIC) != 0; }
/**
* This flag is set on FINAL classes, FINAL fields and FINAL methods, and is mutually exclusive with {@link
* #VOLATILE} and {@link #ABSTRACT}.
*/
public static final short FINAL = 0x0010;
/** @return Whether the given modifier includes {@link #INTERFACE} */
public static boolean isFinal(short sh) { return (sh & Mod.FINAL) != 0; }
/**
* This flag is always set on classes, and never set on any other element. Notice that it has the same value as
* {@link #SYNCHRONIZED}, which is OK because {@link #SYNCHRONIZED} is for methods and {@link #SUPER} for classes.
*/
public static final short SUPER = 0x0020;
/** @return Whether the given modifier includes {@link #SUPER} */
public static boolean isSuper(short sh) { return (sh & Mod.SUPER) != 0; }
/**
* This flag is set on SYNCHRONIZED methods. Notice that it has the same value as {@link #SUPER}, which is OK
* because {@link #SYNCHRONIZED} is for methods and {@link #SUPER} for classes.
*/
public static final short SYNCHRONIZED = 0x0020;
/** @return Whether the given modifier includes {@link #SYNCHRONIZED} */
public static boolean isSynchronized(short sh) { return (sh & Mod.SYNCHRONIZED) != 0; }
/**
* This flag is set on VOLATILE fields and is mutually exclusive with {@link #FINAL}. Notice that it has the same
* value as {@link #BRIDGE}, which is OK because {@link #BRIDGE} is for methods and {@link #VOLATILE} for fields.
*/
public static final short VOLATILE = 0x0040;
/** @return Whether the given modifier includes {@link #VOLATILE} */
public static boolean isVolatile(short sh) { return (sh & Mod.VOLATILE) != 0; }
/**
* This flag is set on 'bridge methods' generated by the compiler. Notice that it has the same value as {@link
* #VOLATILE}, which is OK because {@link #BRIDGE} is for methods and {@link #VOLATILE} for fields.
*/
public static final short BRIDGE = 0x0040;
/** @return Whether the given modifier includes {@link #BRIDGE} */
public static boolean isBridge(short sh) { return (sh & Mod.BRIDGE) != 0; }
/**
* This flag is set on TRANSIENT fields. Notice that it has the same value as {@link #VARARGS}, which is OK because
* {@link #VARARGS} is for methods and {@link #TRANSIENT} for fields.
*/
public static final short TRANSIENT = 0x0080;
/** @return Whether the given modifier includes {@link #TRANSIENT} */
public static boolean isTransient(short sh) { return (sh & Mod.TRANSIENT) != 0; }
/**
* This flag is set on 'variable arity' (a.k.a. 'varargs') methods and constructors. Notice that it has the same
* value as {@link #TRANSIENT}, which is OK because {@link #VARARGS} is for methods and {@link #TRANSIENT} for
* fields.
*/
public static final short VARARGS = 0x0080;
/** @return Whether the given modifier includes {@link #VARARGS} */
public static boolean isVarargs(short sh) { return (sh & Mod.VARARGS) != 0; }
/** This flag is set on NATIVE methods, and is mutually exclusive with {@link #ABSTRACT}. */
public static final short NATIVE = 0x0100;
/** @return Whether the given modifier includes {@link #NATIVE} */
public static boolean isNative(short sh) { return (sh & Mod.NATIVE) != 0; }
/**
* This flag is set on interfaces (including nested interfaces), and requires that {@link #ABSTRACT} must also be
* set. {@link #INTERFACE} is mutually exclusive with {@link #FINAL}, {@link #SUPER} and {@link #ENUM}.
*/
public static final short INTERFACE = 0x0200;
/** @return Whether the given modifier includes {@link #INTERFACE} */
public static boolean isInterface(short sh) { return (sh & Mod.INTERFACE) != 0; }
/**
* This flag is set on all interfaces, ABSTRACT classes and ABSTRACT methods, and is mutually exclusive with
* {@link #FINAL}, {@link #NATIVE}, {@link #PRIVATE}, {@link #STATIC} and {@link #SYNCHRONIZED}.
*/
public static final short ABSTRACT = 0x0400;
/** @return Whether the given modifier includes {@link #ABSTRACT} */
public static boolean isAbstract(short sh) { return (sh & Mod.ABSTRACT) != 0; }
/** This flag is set on STRICTFP methods, and is mutually exclusive with {@link #ABSTRACT}. */
public static final short STRICTFP = 0x0800;
/** @return Whether the given modifier includes {@link #STRICTFP} */
public static boolean isStrictfp(short sh) { return (sh & Mod.STRICTFP) != 0; }
// Poorly documented JDK 1.5 modifiers:
/**
* This flag is set on classes, methods and fields that were generated by the compiler and do not appear in the
* source code.
*/
public static final short SYNTHETIC = 0x1000;
/** @return Whether the given modifier includes {@link #SYNTHETIC} */
public static boolean isSynthetic(short sh) { return (sh & Mod.SYNTHETIC) != 0; }
/**
* This flag is set on annotation types (including nested annotation types), and requires that {@link #INTERFACE}
* is also set.
*/
public static final short ANNOTATION = 0x2000;
/** @return Whether the given modifier includes {@link #ANNOTATION} */
public static boolean isAnnotation(short sh) { return (sh & Mod.ANNOTATION) != 0; }
/**
* This flag is set on enumerated types (including nested enumerated types) and enumerated types' elements, and is
* mutually exclusive with {@link #INTERFACE}.
*/
public static final short ENUM = 0x4000;
/** @return Whether the given modifier includes {@link #ENUM} */
public static boolean isEnum(short sh) { return (sh & Mod.ENUM) != 0; }
/**
* Composes and returns a string that maps the given modifier as follows:
* <ul>
* <li>Value zero is mapped to "".
* <li>Non-zero values are mapped to a sequence of words, separated with blanks.
* <li>{@link #VARARGS} is mapped to "transient", because the two flags have the same value
* <li>{@link #SUPER} is mapped to "synchronized", because the two flags have the same value
* <li>{@link #BRIDGE} is mapped to "volatile", because the two flags have the same value
* </ul>
*/
public static String
shortToString(short sh) {
if (sh == 0) return "";
StringBuilder res = new StringBuilder();
for (int i = 0; i < Mod.MAPPINGS.length; i += 2) {
if ((sh & ((Short) Mod.MAPPINGS[i + 1]).shortValue()) == 0) continue;
if (res.length() > 0) res.append(' ');
res.append((String) Mod.MAPPINGS[i]);
}
return res.toString();
}
private static final Object[] MAPPINGS = {
"public", new Short(Mod.PUBLIC),
"private", new Short(Mod.PRIVATE),
"protected", new Short(Mod.PROTECTED),
// "???", new Short(Mod.PACKAGE),
"static", new Short(Mod.STATIC),
"final", new Short(Mod.FINAL),
"synchronized", new Short(Mod.SYNCHRONIZED), // Has the same value as SUPER
// "super", new Short(Mod.SUPER), // Has the same value as SYNCHRONIZED
"volatile", new Short(Mod.VOLATILE), // Has the same value as BRIDGE
// "bridge", new Short(Mod.BRIDGE), // Has the same value as VOLATILE
"transient", new Short(Mod.TRANSIENT), // Has the same value as VARARGS
// "varargs", new Short(Mod.VARARGS), // Has the same value as TRANSIENT
"native", new Short(Mod.NATIVE),
"interface", new Short(Mod.INTERFACE),
"abstract", new Short(Mod.ABSTRACT),
"strictfp", new Short(Mod.STRICTFP),
"enum", new Short(Mod.ENUM),
"synthetic", new Short(Mod.SYNTHETIC),
"@", new Short(Mod.ANNOTATION),
};
}

View File

@ -1,614 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino;
/** Definitions of Java bytecode opcodes. */
final
class Opcode {
private Opcode() {}
// Symbolic JVM opcodes, in alphabetical order.
// CHECKSTYLE JavadocVariable:OFF
public static final byte AALOAD = 50;
public static final byte AASTORE = 83;
public static final byte ACONST_NULL = 1;
public static final byte ALOAD = 25;
public static final byte ALOAD_0 = 42;
public static final byte ALOAD_1 = 43;
public static final byte ALOAD_2 = 44;
public static final byte ALOAD_3 = 45;
public static final byte ANEWARRAY = (byte) 189;
public static final byte ARETURN = (byte) 176;
public static final byte ARRAYLENGTH = (byte) 190;
public static final byte ASTORE = 58;
public static final byte ASTORE_0 = 75;
public static final byte ASTORE_1 = 76;
public static final byte ASTORE_2 = 77;
public static final byte ASTORE_3 = 78;
public static final byte ATHROW = (byte) 191;
public static final byte BALOAD = 51;
public static final byte BASTORE = 84;
public static final byte BIPUSH = 16;
public static final byte CALOAD = 52;
public static final byte CASTORE = 85;
public static final byte CHECKCAST = (byte) 192;
public static final byte D2F = (byte) 144;
public static final byte D2I = (byte) 142;
public static final byte D2L = (byte) 143;
public static final byte DADD = 99;
public static final byte DALOAD = 49;
public static final byte DASTORE = 82;
public static final byte DCMPG = (byte) 152;
public static final byte DCMPL = (byte) 151;
public static final byte DCONST_0 = 14;
public static final byte DCONST_1 = 15;
public static final byte DDIV = 111;
public static final byte DLOAD = 24;
public static final byte DLOAD_0 = 38;
public static final byte DLOAD_1 = 39;
public static final byte DLOAD_2 = 40;
public static final byte DLOAD_3 = 41;
public static final byte DMUL = 107;
public static final byte DNEG = 119;
public static final byte DREM = 115;
public static final byte DRETURN = (byte) 175;
public static final byte DSTORE = 57;
public static final byte DSTORE_0 = 71;
public static final byte DSTORE_1 = 72;
public static final byte DSTORE_2 = 73;
public static final byte DSTORE_3 = 74;
public static final byte DSUB = 103;
public static final byte DUP = 89;
public static final byte DUP_X1 = 90;
public static final byte DUP_X2 = 91;
public static final byte DUP2 = 92;
public static final byte DUP2_X1 = 93;
public static final byte DUP2_X2 = 94;
public static final byte F2D = (byte) 141;
public static final byte F2I = (byte) 139;
public static final byte F2L = (byte) 140;
public static final byte FADD = 98;
public static final byte FALOAD = 48;
public static final byte FASTORE = 81;
public static final byte FCMPG = (byte) 150;
public static final byte FCMPL = (byte) 149;
public static final byte FCONST_0 = 11;
public static final byte FCONST_1 = 12;
public static final byte FCONST_2 = 13;
public static final byte FDIV = 110;
public static final byte FLOAD = 23;
public static final byte FLOAD_0 = 34;
public static final byte FLOAD_1 = 35;
public static final byte FLOAD_2 = 36;
public static final byte FLOAD_3 = 37;
public static final byte FMUL = 106;
public static final byte FNEG = 118;
public static final byte FREM = 114;
public static final byte FRETURN = (byte) 174;
public static final byte FSTORE = 56;
public static final byte FSTORE_0 = 67;
public static final byte FSTORE_1 = 68;
public static final byte FSTORE_2 = 69;
public static final byte FSTORE_3 = 70;
public static final byte FSUB = 102;
public static final byte GETFIELD = (byte) 180;
public static final byte GETSTATIC = (byte) 178;
public static final byte GOTO = (byte) 167;
public static final byte GOTO_W = (byte) 200;
public static final byte I2B = (byte) 145;
public static final byte I2C = (byte) 146;
public static final byte I2D = (byte) 135;
public static final byte I2F = (byte) 134;
public static final byte I2L = (byte) 133;
public static final byte I2S = (byte) 147;
public static final byte IADD = 96;
public static final byte IALOAD = 46;
public static final byte IAND = 126;
public static final byte IASTORE = 79;
public static final byte ICONST_M1 = 2;
public static final byte ICONST_0 = 3;
public static final byte ICONST_1 = 4;
public static final byte ICONST_2 = 5;
public static final byte ICONST_3 = 6;
public static final byte ICONST_4 = 7;
public static final byte ICONST_5 = 8;
public static final byte IDIV = 108;
public static final byte IF_ACMPEQ = (byte) 165;
public static final byte IF_ACMPNE = (byte) 166;
public static final byte IF_ICMPEQ = (byte) 159;
public static final byte IF_ICMPNE = (byte) 160;
public static final byte IF_ICMPLT = (byte) 161;
public static final byte IF_ICMPGE = (byte) 162;
public static final byte IF_ICMPGT = (byte) 163;
public static final byte IF_ICMPLE = (byte) 164;
public static final byte IFEQ = (byte) 153;
public static final byte IFNE = (byte) 154;
public static final byte IFLT = (byte) 155;
public static final byte IFGE = (byte) 156;
public static final byte IFGT = (byte) 157;
public static final byte IFLE = (byte) 158;
public static final byte IFNONNULL = (byte) 199;
public static final byte IFNULL = (byte) 198;
public static final byte IINC = (byte) 132;
public static final byte ILOAD = 21;
public static final byte ILOAD_0 = 26;
public static final byte ILOAD_1 = 27;
public static final byte ILOAD_2 = 28;
public static final byte ILOAD_3 = 29;
public static final byte IMUL = 104;
public static final byte INEG = 116;
public static final byte INSTANCEOF = (byte) 193;
public static final byte INVOKEINTERFACE = (byte) 185;
public static final byte INVOKESPECIAL = (byte) 183;
public static final byte INVOKESTATIC = (byte) 184;
public static final byte INVOKEVIRTUAL = (byte) 182;
public static final byte IOR = (byte) 128;
public static final byte IREM = 112;
public static final byte IRETURN = (byte) 172;
public static final byte ISHL = 120;
public static final byte ISHR = 122;
public static final byte ISTORE = 54;
public static final byte ISTORE_0 = 59;
public static final byte ISTORE_1 = 60;
public static final byte ISTORE_2 = 61;
public static final byte ISTORE_3 = 62;
public static final byte ISUB = 100;
public static final byte IUSHR = 124;
public static final byte IXOR = (byte) 130;
public static final byte JSR = (byte) 168;
public static final byte JSR_W = (byte) 201;
public static final byte L2D = (byte) 138;
public static final byte L2F = (byte) 137;
public static final byte L2I = (byte) 136;
public static final byte LADD = 97;
public static final byte LALOAD = 47;
public static final byte LAND = 127;
public static final byte LASTORE = 80;
public static final byte LCMP = (byte) 148;
public static final byte LCONST_0 = 9;
public static final byte LCONST_1 = 10;
public static final byte LDC = 18;
public static final byte LDC_W = 19;
public static final byte LDC2_W = 20;
public static final byte LDIV = 109;
public static final byte LLOAD = 22;
public static final byte LLOAD_0 = 30;
public static final byte LLOAD_1 = 31;
public static final byte LLOAD_2 = 32;
public static final byte LLOAD_3 = 33;
public static final byte LMUL = 105;
public static final byte LNEG = 117;
public static final byte LOOKUPSWITCH = (byte) 171;
public static final byte LOR = (byte) 129;
public static final byte LREM = 113;
public static final byte LRETURN = (byte) 173;
public static final byte LSHL = 121;
public static final byte LSHR = 123;
public static final byte LSTORE = 55;
public static final byte LSTORE_0 = 63;
public static final byte LSTORE_1 = 64;
public static final byte LSTORE_2 = 65;
public static final byte LSTORE_3 = 66;
public static final byte LSUB = 101;
public static final byte LUSHR = 125;
public static final byte LXOR = (byte) 131;
public static final byte MONITORENTER = (byte) 194;
public static final byte MONITOREXIT = (byte) 195;
public static final byte MULTIANEWARRAY = (byte) 197;
public static final byte NEW = (byte) 187;
public static final byte NEWARRAY = (byte) 188;
public static final byte NOP = 0;
public static final byte POP = 87;
public static final byte POP2 = 88;
public static final byte PUTFIELD = (byte) 181;
public static final byte PUTSTATIC = (byte) 179;
public static final byte RET = (byte) 169;
public static final byte RETURN = (byte) 177;
public static final byte SALOAD = 53;
public static final byte SASTORE = 86;
public static final byte SIPUSH = 17;
public static final byte SWAP = 95;
public static final byte TABLESWITCH = (byte) 170;
public static final byte WIDE = (byte) 196;
// CHECKSTYLE JavadocVariable:ON
// Constants for the "OPCODE_PROPERTIES" array.
/** Special value for {@link #OPCODE_PROPERTIES} indicating that this element represents an invalid opcode. */
public static final short INVALID_OPCODE = -1;
/** Masks the 'stack delta' portion of {@link #OPCODE_PROPERTIES}. */
public static final short SD_MASK = 31;
/**
* Indicates that the opcode represented by this element of {@link #OPCODE_PROPERTIES} reduces the operand stack
* size by 4 elements.
*/
public static final short SD_M4 = 0;
/**
* Indicates that the opcode represented by this element of {@link #OPCODE_PROPERTIES} reduces the operand stack
* size by 3 elements.
*/
public static final short SD_M3 = 1;
/**
* Indicates that the opcode represented by this element of {@link #OPCODE_PROPERTIES} reduces the operand stack
* size by 2 elements.
*/
public static final short SD_M2 = 2;
/**
* Indicates that the opcode represented by this element of {@link #OPCODE_PROPERTIES} reduces the operand stack
* size by 1 element.
*/
public static final short SD_M1 = 3;
/**
* Indicates that the opcode represented by this element of {@link #OPCODE_PROPERTIES} results in the same operand
* stack size.
*/
public static final short SD_P0 = 4;
/**
* Indicates that the opcode represented by this element of {@link #OPCODE_PROPERTIES} increases the operand stack
* size by 1 element.
*/
public static final short SD_P1 = 5;
/**
* Indicates that the opcode represented by this element of {@link #OPCODE_PROPERTIES} increases the operand stack
* size by 2 elements.
*/
public static final short SD_P2 = 6;
/** Indicates that the opcode represented by this element of {@link #OPCODE_PROPERTIES} clears the operand stack. */
public static final short SD_0 = 7;
/** This element of {@link #OPCODE_PROPERTIES} represents the GETFIELD opcode. */
public static final short SD_GETFIELD = 9;
/** This element of {@link #OPCODE_PROPERTIES} represents the GETSTATIC opcode. */
public static final short SD_GETSTATIC = 10;
/** This element of {@link #OPCODE_PROPERTIES} represents the PUTFIELD opcode. */
public static final short SD_PUTFIELD = 11;
/** This element of {@link #OPCODE_PROPERTIES} represents the PUTSTATIC opcode. */
public static final short SD_PUTSTATIC = 12;
/** This element of {@link #OPCODE_PROPERTIES} represents the INVOKEVIRTUAL opcode. */
public static final short SD_INVOKEVIRTUAL = 13;
/** This element of {@link #OPCODE_PROPERTIES} represents the INVOKESPECIAL opcode. */
public static final short SD_INVOKESPECIAL = 14;
/** This element of {@link #OPCODE_PROPERTIES} represents the INVOKESTATIC opcode. */
public static final short SD_INVOKESTATIC = 15;
/** This element of {@link #OPCODE_PROPERTIES} represents the INVOKEINTERFACE opcode. */
public static final short SD_INVOKEINTERFACE = 16;
/** This element of {@link #OPCODE_PROPERTIES} represents the MULTIANEWARRAY opcode. */
public static final short SD_MULTIANEWARRAY = 18;
// Properties of the opcode's first operand.
/** Masks the 'first operand' portion of {@link #OPCODE_PROPERTIES}. */
public static final short OP1_MASK = 15 * 32;
/** The first operand of this opcode is a signed byte. */
public static final short OP1_SB = 1 * 32;
/** The first operand of this opcode is an unsigned byte. */
public static final short OP1_UB = 2 * 32;
/** The first operand of this opcode is a signed short. */
public static final short OP1_SS = 3 * 32;
/** The first operand of this opcode is a one-byte constant pool index. */
public static final short OP1_CP1 = 4 * 32;
/** The first operand of this opcode is a two-byte constant pool index. */
public static final short OP1_CP2 = 5 * 32;
/** The first operand of this opcode is a one-byte local variable array index. */
public static final short OP1_LV1 = 6 * 32;
/** The first operand of this opcode is a two-byte local variable array index. */
public static final short OP1_LV2 = 7 * 32;
/** The first operand of this opcode is a two-byte branch offset. */
public static final short OP1_BO2 = 8 * 32;
/** The first operand of this opcode is a four-byte branch offset. */
public static final short OP1_BO4 = 9 * 32;
/** The first operand of this opcode is a signed byte. */
public static final short OP1_LOOKUPSWITCH = 10 * 32;
/** The first operand of this opcode is a signed byte. */
public static final short OP1_TABLESWITCH = 11 * 32;
/** The first operand of this opcode is a signed byte. */
public static final short OP1_JSR = 12 * 32;
// Properties of the opcode's second operand.
/** Masks the 'second operand' portion of {@link #OPCODE_PROPERTIES}. */
public static final short OP2_MASK = 3 * 512;
/** The second operand of this opcode is a signed byte. */
public static final short OP2_SB = 1 * 512;
/** The second operand of this opcode is a signed short. */
public static final short OP2_SS = 2 * 512;
// Properties of the opcode's third operand.
/** Masks the 'third operand' portion of {@link #OPCODE_PROPERTIES}. */
public static final short OP3_MASK = 1 * 2048;
/** The third operand of this opcode is a signed byte. */
public static final short OP3_SB = 1 * 2048;
// Properties of the opcode's 'implicit' operand.
/** Masks the 'implicit operand' portion of {@link #OPCODE_PROPERTIES}. */
public static final short IO_MASK = 7 * 4096;
/** The local variable wiht index 0 is the opcode's implicit operand. */
public static final short IO_LV_0 = 1 * 4096;
/** The local variable wiht index 1 is the opcode's implicit operand. */
public static final short IO_LV_1 = 2 * 4096;
/** The local variable wiht index 2 is the opcode's implicit operand. */
public static final short IO_LV_2 = 3 * 4096;
/** The local variable wiht index 3 is the opcode's implicit operand. */
public static final short IO_LV_3 = 4 * 4096;
/**
* This opcode never 'completes normally', i.e. it never passes the control flow to the immediately following
* opcode.
*/
public static final short NO_FALLTHROUGH = (short) 32768;
/** The {@code n}th element of this array describes the properties of the JVM opcode {@code n}. */
public static final short[] OPCODE_PROPERTIES = {
// CHECKSTYLE WrapAndIndent:OFF
/* 0*/ /*NOP*/ Opcode.SD_P0,
/*ACONST_NULL*/ Opcode.SD_P1,
/*ICONST_M1*/ Opcode.SD_P1,
/*ICONST_0*/ Opcode.SD_P1,
/*ICONST_1*/ Opcode.SD_P1,
/*ICONST_2*/ Opcode.SD_P1,
/*ICONST_3*/ Opcode.SD_P1,
/*ICONST_4*/ Opcode.SD_P1,
/*ICONST_5*/ Opcode.SD_P1,
/*LCONST_0*/ Opcode.SD_P2,
/* 10*/ /*LCONST_1*/ Opcode.SD_P2,
/*FCONST_0*/ Opcode.SD_P1,
/*FCONST_1*/ Opcode.SD_P1,
/*FCONST_2*/ Opcode.SD_P1,
/*DCONST_0*/ Opcode.SD_P2,
/*DCONST_1*/ Opcode.SD_P2,
/*BIPUSH*/ Opcode.SD_P1 | Opcode.OP1_SB,
/*SIPUSH*/ Opcode.SD_P1 | Opcode.OP1_SS,
/*LDC*/ Opcode.SD_P1 | Opcode.OP1_CP1,
/*LDC_W*/ Opcode.SD_P1 | Opcode.OP1_CP2,
/* 20*/ /*LDC2_W*/ Opcode.SD_P2 | Opcode.OP1_CP2,
/*ILOAD*/ Opcode.SD_P1 | Opcode.OP1_LV1,
/*LLOAD*/ Opcode.SD_P2 | Opcode.OP1_LV1,
/*FLOAD*/ Opcode.SD_P1 | Opcode.OP1_LV1,
/*DLOAD*/ Opcode.SD_P2 | Opcode.OP1_LV1,
/*ALOAD*/ Opcode.SD_P1 | Opcode.OP1_LV1,
/*ILOAD_0*/ Opcode.SD_P1 | Opcode.IO_LV_0,
/*ILOAD_1*/ Opcode.SD_P1 | Opcode.IO_LV_1,
/*ILOAD_2*/ Opcode.SD_P1 | Opcode.IO_LV_2,
/*ILOAD_3*/ Opcode.SD_P1 | Opcode.IO_LV_3,
/* 30*/ /*LLOAD_0*/ Opcode.SD_P2 | Opcode.IO_LV_0,
/*LLOAD_1*/ Opcode.SD_P2 | Opcode.IO_LV_1,
/*LLOAD_2*/ Opcode.SD_P2 | Opcode.IO_LV_2,
/*LLOAD_3*/ Opcode.SD_P2 | Opcode.IO_LV_3,
/*FLOAD_0*/ Opcode.SD_P1 | Opcode.IO_LV_0,
/*FLOAD_1*/ Opcode.SD_P1 | Opcode.IO_LV_1,
/*FLOAD_2*/ Opcode.SD_P1 | Opcode.IO_LV_2,
/*FLOAD_3*/ Opcode.SD_P1 | Opcode.IO_LV_3,
/*DLOAD_0*/ Opcode.SD_P2 | Opcode.IO_LV_0,
/*DLOAD_1*/ Opcode.SD_P2 | Opcode.IO_LV_1,
/* 40*/ /*DLOAD_2*/ Opcode.SD_P2 | Opcode.IO_LV_2,
/*DLOAD_3*/ Opcode.SD_P2 | Opcode.IO_LV_3,
/*ALOAD_0*/ Opcode.SD_P1 | Opcode.IO_LV_0,
/*ALOAD_1*/ Opcode.SD_P1 | Opcode.IO_LV_1,
/*ALOAD_2*/ Opcode.SD_P1 | Opcode.IO_LV_2,
/*ALOAD_3*/ Opcode.SD_P1 | Opcode.IO_LV_3,
/*IALOAD*/ Opcode.SD_M1,
/*LALOAD*/ Opcode.SD_P0,
/*FALOAD*/ Opcode.SD_M1,
/*DALOAD*/ Opcode.SD_P0,
/* 50*/ /*AALOAD*/ Opcode.SD_M1,
/*BALOAD*/ Opcode.SD_M1,
/*CALOAD*/ Opcode.SD_M1,
/*SALOAD*/ Opcode.SD_M1,
/*ISTORE*/ Opcode.SD_M1 | Opcode.OP1_LV1,
/*LSTORE*/ Opcode.SD_M2 | Opcode.OP1_LV1,
/*FSTORE*/ Opcode.SD_M1 | Opcode.OP1_LV1,
/*DSTORE*/ Opcode.SD_M2 | Opcode.OP1_LV1,
/*ASTORE*/ Opcode.SD_M1 | Opcode.OP1_LV1,
/*ISTORE_0*/ Opcode.SD_M1 | Opcode.IO_LV_0,
/* 60*/ /*ISTORE_1*/ Opcode.SD_M1 | Opcode.IO_LV_1,
/*ISTORE_2*/ Opcode.SD_M1 | Opcode.IO_LV_2,
/*ISTORE_3*/ Opcode.SD_M1 | Opcode.IO_LV_3,
/*LSTORE_0*/ Opcode.SD_M2 | Opcode.IO_LV_0,
/*LSTORE_1*/ Opcode.SD_M2 | Opcode.IO_LV_1,
/*LSTORE_2*/ Opcode.SD_M2 | Opcode.IO_LV_2,
/*LSTORE_3*/ Opcode.SD_M2 | Opcode.IO_LV_3,
/*FSTORE_0*/ Opcode.SD_M1 | Opcode.IO_LV_0,
/*FSTORE_1*/ Opcode.SD_M1 | Opcode.IO_LV_1,
/*FSTORE_2*/ Opcode.SD_M1 | Opcode.IO_LV_2,
/* 70*/ /*FSTORE_3*/ Opcode.SD_M1 | Opcode.IO_LV_3,
/*DSTORE_0*/ Opcode.SD_M2 | Opcode.IO_LV_0,
/*DSTORE_1*/ Opcode.SD_M2 | Opcode.IO_LV_1,
/*DSTORE_2*/ Opcode.SD_M2 | Opcode.IO_LV_2,
/*DSTORE_3*/ Opcode.SD_M2 | Opcode.IO_LV_3,
/*ASTORE_0*/ Opcode.SD_M1 | Opcode.IO_LV_0,
/*ASTORE_1*/ Opcode.SD_M1 | Opcode.IO_LV_1,
/*ASTORE_2*/ Opcode.SD_M1 | Opcode.IO_LV_2,
/*ASTORE_3*/ Opcode.SD_M1 | Opcode.IO_LV_3,
/*IASTORE*/ Opcode.SD_M3,
/* 80*/ /*LASTORE*/ Opcode.SD_M4,
/*FASTORE*/ Opcode.SD_M3,
/*DASTORE*/ Opcode.SD_M4,
/*AASTORE*/ Opcode.SD_M3,
/*BASTORE*/ Opcode.SD_M3,
/*CASTORE*/ Opcode.SD_M3,
/*SASTORE*/ Opcode.SD_M3,
/*POP*/ Opcode.SD_M1,
/*POP2*/ Opcode.SD_M2,
/*DUP*/ Opcode.SD_P1,
/* 90*/ /*DUP_X1*/ Opcode.SD_P1,
/*DUP_X2*/ Opcode.SD_P1,
/*DUP2*/ Opcode.SD_P2,
/*DUP2_X1*/ Opcode.SD_P2,
/*DUP2_X2*/ Opcode.SD_P2,
/*SWAP*/ Opcode.SD_P0,
/*IADD*/ Opcode.SD_M1,
/*LADD*/ Opcode.SD_M2,
/*FADD*/ Opcode.SD_M1,
/*DADD*/ Opcode.SD_M2,
/*100*/ /*ISUB*/ Opcode.SD_M1,
/*LSUB*/ Opcode.SD_M2,
/*FSUB*/ Opcode.SD_M1,
/*DSUB*/ Opcode.SD_M2,
/*IMUL*/ Opcode.SD_M1,
/*LMUL*/ Opcode.SD_M2,
/*FMUL*/ Opcode.SD_M1,
/*DMUL*/ Opcode.SD_M2,
/*IDIV*/ Opcode.SD_M1,
/*LDIV*/ Opcode.SD_M2,
/*110*/ /*FDIV*/ Opcode.SD_M1,
/*DDIV*/ Opcode.SD_M2,
/*IREM*/ Opcode.SD_M1,
/*LREM*/ Opcode.SD_M2,
/*FREM*/ Opcode.SD_M1,
/*DREM*/ Opcode.SD_M2,
/*INEG*/ Opcode.SD_P0,
/*LNEG*/ Opcode.SD_P0,
/*FNEG*/ Opcode.SD_P0,
/*DNEG*/ Opcode.SD_P0,
/*120*/ /*ISHL*/ Opcode.SD_M1,
/*LSHL*/ Opcode.SD_M1,
/*ISHR*/ Opcode.SD_M1,
/*LSHR*/ Opcode.SD_M1,
/*IUSHR*/ Opcode.SD_M1,
/*LUSHR*/ Opcode.SD_M1,
/*IAND*/ Opcode.SD_M1,
/*LAND*/ Opcode.SD_M2,
/*IOR*/ Opcode.SD_M1,
/*LOR*/ Opcode.SD_M2,
/*130*/ /*IXOR*/ Opcode.SD_M1,
/*LXOR*/ Opcode.SD_M2,
/*IINC*/ Opcode.SD_P0 | Opcode.OP1_LV1 | Opcode.OP2_SB,
/*I2L*/ Opcode.SD_P1,
/*I2F*/ Opcode.SD_P0,
/*I2D*/ Opcode.SD_P1,
/*L2I*/ Opcode.SD_M1,
/*L2F*/ Opcode.SD_M1,
/*L2D*/ Opcode.SD_P0,
/*F2I*/ Opcode.SD_P0,
/*140*/ /*F2L*/ Opcode.SD_P1,
/*F2D*/ Opcode.SD_P1,
/*D2I*/ Opcode.SD_M1,
/*D2L*/ Opcode.SD_P0,
/*D2F*/ Opcode.SD_M1,
/*I2B*/ Opcode.SD_P0,
/*I2C*/ Opcode.SD_P0,
/*I2S*/ Opcode.SD_P0,
/*LCMP*/ Opcode.SD_M3,
/*FCMPL*/ Opcode.SD_M1,
/*150*/ /*FCMPG*/ Opcode.SD_M1,
/*DCMPL*/ Opcode.SD_M3,
/*DCMPG*/ Opcode.SD_M3,
/*IFEQ*/ Opcode.SD_M1 | Opcode.OP1_BO2,
/*IFNE*/ Opcode.SD_M1 | Opcode.OP1_BO2,
/*IFLT*/ Opcode.SD_M1 | Opcode.OP1_BO2,
/*IFGE*/ Opcode.SD_M1 | Opcode.OP1_BO2,
/*IFGT*/ Opcode.SD_M1 | Opcode.OP1_BO2,
/*IFLE*/ Opcode.SD_M1 | Opcode.OP1_BO2,
/*IF_ICMPEQ*/ Opcode.SD_M2 | Opcode.OP1_BO2,
/*160*/ /*IF_ICMPNE*/ Opcode.SD_M2 | Opcode.OP1_BO2,
/*IF_ICMPLT*/ Opcode.SD_M2 | Opcode.OP1_BO2,
/*IF_ICMPGE*/ Opcode.SD_M2 | Opcode.OP1_BO2,
/*IF_ICMPGT*/ Opcode.SD_M2 | Opcode.OP1_BO2,
/*IF_ICMPLE*/ Opcode.SD_M2 | Opcode.OP1_BO2,
/*IF_ACMPEQ*/ Opcode.SD_M2 | Opcode.OP1_BO2,
/*IF_ACMPNE*/ Opcode.SD_M2 | Opcode.OP1_BO2,
/*GOTO*/ Opcode.SD_P0 | Opcode.OP1_BO2 | Opcode.NO_FALLTHROUGH,
/*JSR*/ Opcode.SD_P0 | Opcode.OP1_JSR,
/*RET*/ Opcode.SD_P0 | Opcode.OP1_LV1 | Opcode.NO_FALLTHROUGH,
/*170*/ /*TABLESWITCH*/ Opcode.SD_M1 | Opcode.OP1_TABLESWITCH,
/*LOOKUPSWITCH*/ Opcode.SD_M1 | Opcode.OP1_LOOKUPSWITCH,
/*IRETURN*/ Opcode.SD_0 | Opcode.NO_FALLTHROUGH,
/*LRETURN*/ Opcode.SD_0 | Opcode.NO_FALLTHROUGH,
/*FRETURN*/ Opcode.SD_0 | Opcode.NO_FALLTHROUGH,
/*DRETURN*/ Opcode.SD_0 | Opcode.NO_FALLTHROUGH,
/*ARETURN*/ Opcode.SD_M1 | Opcode.NO_FALLTHROUGH,
/*RETURN*/ Opcode.SD_0 | Opcode.NO_FALLTHROUGH,
/*GETSTATIC*/ Opcode.SD_GETSTATIC | Opcode.OP1_CP2,
/*PUTSTATIC*/ Opcode.SD_PUTSTATIC | Opcode.OP1_CP2,
/*180*/ /*GETFIELD*/ Opcode.SD_GETFIELD | Opcode.OP1_CP2,
/*PUTFIELD*/ Opcode.SD_PUTFIELD | Opcode.OP1_CP2,
/*INVOKEVIRTUAL*/ Opcode.SD_INVOKEVIRTUAL | Opcode.OP1_CP2,
/*INVOKESPECIAL*/ Opcode.SD_INVOKESPECIAL | Opcode.OP1_CP2,
/*INVOKESTATIC*/ Opcode.SD_INVOKESTATIC | Opcode.OP1_CP2,
/*INVOKEINTERFACE*/ Opcode.SD_INVOKEINTERFACE | Opcode.OP1_CP2 | Opcode.OP2_SB | Opcode.OP3_SB,
/*UNUSED*/ Opcode.INVALID_OPCODE,
/*NEW*/ Opcode.SD_P1 | Opcode.OP1_CP2,
/*NEWARRAY*/ Opcode.SD_P0 | Opcode.OP1_UB,
/*ANEWARRAY*/ Opcode.SD_P0 | Opcode.OP1_CP2,
/*190*/ /*ARRAYLENGTH*/ Opcode.SD_P0,
/*ATHROW*/ Opcode.SD_M1 | Opcode.NO_FALLTHROUGH,
/*CHECKCAST*/ Opcode.SD_P0 | Opcode.OP1_CP2,
/*INSTANCEOF*/ Opcode.SD_P0 | Opcode.OP1_CP2,
/*MONITORENTER*/ Opcode.SD_M1,
/*MONITOREXIT*/ Opcode.SD_M1,
/*WIDE*/ Opcode.INVALID_OPCODE,
/*MULTIANEWARRAY*/ Opcode.SD_MULTIANEWARRAY | Opcode.OP1_CP2 | Opcode.OP2_SB,
/*IFNULL*/ Opcode.SD_M1 | Opcode.OP1_BO2,
/*IFNONNULL*/ Opcode.SD_M1 | Opcode.OP1_BO2,
/*200*/ /*GOTO_W*/ Opcode.SD_P0 | Opcode.OP1_BO4 | Opcode.NO_FALLTHROUGH,
/*JSR_W*/ Opcode.SD_P1 | Opcode.OP1_BO4,
Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
/*210*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
/*220*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
/*230*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
/*240*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
/*250*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
// CHECKSTYLE WrapAndIndent:ON
};
/** The {@code n}th element of this array describes the properties of the JVM opcode {@code WIDE n}. */
public static final short[] WIDE_OPCODE_PROPERTIES = new short[256];
static {
for (int i = 0; i < Opcode.WIDE_OPCODE_PROPERTIES.length; ++i) {
Opcode.WIDE_OPCODE_PROPERTIES[i] = Opcode.INVALID_OPCODE;
}
// load instructions
Opcode.WIDE_OPCODE_PROPERTIES[0xff & Opcode.ILOAD] = Opcode.SD_P1 | Opcode.OP1_LV2;
Opcode.WIDE_OPCODE_PROPERTIES[0xff & Opcode.FLOAD] = Opcode.SD_P1 | Opcode.OP1_LV2;
Opcode.WIDE_OPCODE_PROPERTIES[0xff & Opcode.ALOAD] = Opcode.SD_P1 | Opcode.OP1_LV2;
Opcode.WIDE_OPCODE_PROPERTIES[0xff & Opcode.LLOAD] = Opcode.SD_P2 | Opcode.OP1_LV2;
Opcode.WIDE_OPCODE_PROPERTIES[0xff & Opcode.DLOAD] = Opcode.SD_P2 | Opcode.OP1_LV2;
// store instructions
Opcode.WIDE_OPCODE_PROPERTIES[0xff & Opcode.ISTORE] = Opcode.SD_M1 | Opcode.OP1_LV2;
Opcode.WIDE_OPCODE_PROPERTIES[0xff & Opcode.FSTORE] = Opcode.SD_M1 | Opcode.OP1_LV2;
Opcode.WIDE_OPCODE_PROPERTIES[0xff & Opcode.ASTORE] = Opcode.SD_M1 | Opcode.OP1_LV2;
Opcode.WIDE_OPCODE_PROPERTIES[0xff & Opcode.LSTORE] = Opcode.SD_M2 | Opcode.OP1_LV2;
Opcode.WIDE_OPCODE_PROPERTIES[0xff & Opcode.DSTORE] = Opcode.SD_M2 | Opcode.OP1_LV2;
Opcode.WIDE_OPCODE_PROPERTIES[0xff & Opcode.IINC] = Opcode.SD_P0 | Opcode.OP1_LV2 | Opcode.OP2_SS;
Opcode.WIDE_OPCODE_PROPERTIES[0xff & Opcode.RET] = Opcode.SD_P0 | Opcode.OP1_LV2;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,384 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import org.codehaus.commons.compiler.CompileException;
import org.codehaus.commons.compiler.Location;
/** Wraps a {@link java.lang.Class} in an {@link org.codehaus.janino.IClass}. */
@SuppressWarnings("rawtypes")
class ReflectionIClass extends IClass {
private final Class clazz;
private final IClassLoader iClassLoader;
/** @param iClassLoader Required to load other {@link IClass}es on {@code get...()} */
public
ReflectionIClass(Class clazz, IClassLoader iClassLoader) {
this.clazz = clazz;
this.iClassLoader = iClassLoader;
}
@Override protected IConstructor[]
getDeclaredIConstructors2() {
Constructor[] constructors = this.clazz.getDeclaredConstructors();
IConstructor[] result = new IConstructor[constructors.length];
for (int i = 0; i < constructors.length; ++i) {
result[i] = new ReflectionIConstructor(constructors[i]);
}
return result;
}
@Override protected IMethod[]
getDeclaredIMethods2() {
Method[] methods = this.clazz.getDeclaredMethods();
if (methods.length == 0 && this.clazz.isArray()) {
return new IMethod[] { new IMethod() {
@Override public String getName() { return "clone"; }
@Override public IClass getReturnType() { return ReflectionIClass.this.iClassLoader.TYPE_java_lang_Object; } // SUPPRESS CHECKSTYLE LineLength
@Override public boolean isAbstract() { return false; }
@Override public boolean isStatic() { return false; }
@Override public Access getAccess() { return Access.PUBLIC; }
@Override public boolean isVarargs() { return false; }
@Override public IClass[] getParameterTypes2() { return new IClass[0]; }
@Override public IClass[] getThrownExceptions2() { return new IClass[0]; }
@Override public Java.Annotation[] getAnnotations() { return new Java.Annotation[0]; }
} };
}
IMethod[] result = new IMethod[methods.length];
for (int i = 0; i < result.length; i++) result[i] = new ReflectionIMethod(methods[i]);
return result;
}
@Override protected IField[]
getDeclaredIFields2() {
Field[] fields = this.clazz.getDeclaredFields();
IField[] result = new IField[fields.length];
for (int i = 0; i < fields.length; ++i) {
result[i] = new ReflectionIField(fields[i]);
}
return result;
}
@Override protected IClass[]
getDeclaredIClasses2() { return this.classesToIClasses(this.clazz.getDeclaredClasses()); }
@Override protected IClass
getDeclaringIClass2() {
Class declaringClass = this.clazz.getDeclaringClass();
if (declaringClass == null) return null;
return this.classToIClass(declaringClass);
}
@Override protected IClass
getOuterIClass2() throws CompileException {
if (Modifier.isStatic(this.clazz.getModifiers())) return null;
return this.getDeclaringIClass();
}
@Override protected IClass
getSuperclass2() {
Class superclass = this.clazz.getSuperclass();
return superclass == null ? null : this.classToIClass(superclass);
}
@Override protected IClass[]
getInterfaces2() {
return this.classesToIClasses(this.clazz.getInterfaces());
}
@Override protected String
getDescriptor2() {
return Descriptor.fromClassName(this.clazz.getName());
}
@Override public Access getAccess() { return ReflectionIClass.modifiers2Access(this.clazz.getModifiers()); }
@Override public boolean isFinal() { return Modifier.isFinal(this.clazz.getModifiers()); }
@Override public boolean isInterface() { return this.clazz.isInterface(); }
@Override public boolean isAbstract() { return Modifier.isAbstract(this.clazz.getModifiers()); }
@Override public boolean isArray() { return this.clazz.isArray(); }
@Override protected IClass
getComponentType2() {
Class componentType = this.clazz.getComponentType();
return componentType == null ? null : this.classToIClass(componentType);
}
@Override public boolean
isPrimitive() { return this.clazz.isPrimitive(); }
@Override public boolean
isPrimitiveNumeric() {
return (
this.clazz == byte.class
|| this.clazz == short.class
|| this.clazz == int.class
|| this.clazz == long.class
|| this.clazz == char.class
|| this.clazz == float.class
|| this.clazz == double.class
);
}
/** @return The underlying {@link Class java.lang.Class} */
public Class
getClazz() { return this.clazz; }
/** @return E.g. "int", "int[][]", "pkg1.pkg2.Outer$Inner[]" */
@Override public String
toString() {
int brackets = 0;
Class c = this.clazz;
while (c.isArray()) {
++brackets;
c = c.getComponentType();
}
String s = c.getName();
while (brackets-- > 0) s += "[]";
return s;
}
private
class ReflectionIConstructor extends IConstructor {
public
ReflectionIConstructor(Constructor constructor) { this.constructor = constructor; }
// Implement IMember.
@Override public Access
getAccess() {
int mod = this.constructor.getModifiers();
return ReflectionIClass.modifiers2Access(mod);
}
@Override public Java.Annotation[]
getAnnotations() { return new Java.Annotation[0]; }
@Override public boolean
isVarargs() {
// TRANSIENT is identical with VARARGS.
return Modifier.isTransient(this.constructor.getModifiers());
}
// Implement "IConstructor".
@Override public IClass[]
getParameterTypes2() throws CompileException {
IClass[] parameterTypes = ReflectionIClass.this.classesToIClasses(this.constructor.getParameterTypes());
// The JAVADOC of java.lang.reflect.Constructor does not document it, but
// "getParameterTypes()" includes the synthetic "enclosing instance" parameter.
IClass outerClass = ReflectionIClass.this.getOuterIClass();
if (outerClass != null) {
if (parameterTypes.length < 1) {
throw new CompileException(
"Constructor \"" + this.constructor + "\" lacks synthetic enclosing instance parameter",
null
);
}
if (parameterTypes[0] != outerClass) {
throw new CompileException((
"Enclosing instance parameter of constructor \""
+ this.constructor
+ "\" has wrong type -- \""
+ parameterTypes[0]
+ "\" vs. \""
+ outerClass
+ "\""
), null);
}
IClass[] tmp = new IClass[parameterTypes.length - 1];
System.arraycopy(parameterTypes, 1, tmp, 0, tmp.length);
parameterTypes = tmp;
}
return parameterTypes;
}
@Override public String
getDescriptor2() {
Class[] parameterTypes = this.constructor.getParameterTypes();
String[] parameterDescriptors = new String[parameterTypes.length];
for (int i = 0; i < parameterDescriptors.length; ++i) {
parameterDescriptors[i] = Descriptor.fromClassName(parameterTypes[i].getName());
}
return new MethodDescriptor(parameterDescriptors, Descriptor.VOID).toString();
}
@Override public IClass[]
getThrownExceptions2() {
return ReflectionIClass.this.classesToIClasses(this.constructor.getExceptionTypes());
}
final Constructor constructor;
}
public
class ReflectionIMethod extends IMethod {
public
ReflectionIMethod(Method method) { this.method = method; }
// Implement IMember.
@Override public Access
getAccess() { return ReflectionIClass.modifiers2Access(this.method.getModifiers()); }
@Override public Java.Annotation[]
getAnnotations() { return new Java.Annotation[0]; }
// Implement "IMethod".
@Override public String
getName() { return this.method.getName(); }
@Override public boolean
isVarargs() {
// VARARGS is identical with TRANSIENT.
return Modifier.isTransient(this.method.getModifiers());
}
@Override public IClass[]
getParameterTypes2() { return ReflectionIClass.this.classesToIClasses(this.method.getParameterTypes()); }
@Override public boolean
isStatic() { return Modifier.isStatic(this.method.getModifiers()); }
@Override public boolean
isAbstract() { return Modifier.isAbstract(this.method.getModifiers()); }
@Override public IClass
getReturnType() { return ReflectionIClass.this.classToIClass(this.method.getReturnType()); }
@Override public IClass[]
getThrownExceptions2() { return ReflectionIClass.this.classesToIClasses(this.method.getExceptionTypes()); }
private final Method method;
}
private
class ReflectionIField extends IField {
public
ReflectionIField(Field field) { this.field = field; }
// Implement IMember.
@Override public Access
getAccess() { return ReflectionIClass.modifiers2Access(this.field.getModifiers()); }
@Override public Java.Annotation[]
getAnnotations() { return new Java.Annotation[0]; }
// Implement "IField".
@Override public String
getName() { return this.field.getName(); }
@Override public boolean
isStatic() { return Modifier.isStatic(this.field.getModifiers()); }
@Override public IClass
getType() { return ReflectionIClass.this.classToIClass(this.field.getType()); }
@Override public String
toString() {
return Descriptor.toString(this.getDeclaringIClass().getDescriptor()) + "." + this.getName();
}
/**
* This implementation of {@link IClass.IField#getConstantValue()} is
* not completely correct:
* <ul>
* <li>
* It treats non-static fields as non-constant
* <li>
* Even fields with a <i>non-constant</i> initializer are identified
* as constant. (The value of that field may be different in a
* different JVM instance -- the classical example is
* {@link java.io.File#separator}.)
* </ul>
*/
@Override public Object
getConstantValue() throws CompileException {
int mod = this.field.getModifiers();
Class clazz = this.field.getType();
if (
Modifier.isStatic(mod)
&& Modifier.isFinal(mod)
&& (clazz.isPrimitive() || clazz == String.class)
) {
try {
return this.field.get(null);
} catch (IllegalAccessException ex) {
throw new CompileException( // SUPPRESS CHECKSTYLE AvoidHidingCause
"Field \"" + this.field.getName() + "\" is not accessible",
(Location) null
);
}
}
return IClass.NOT_CONSTANT;
}
final Field field;
}
/** Loads {@link Class} through {@link IClassLoader} to ensure unique {@link IClass}es. */
private IClass
classToIClass(Class c) {
IClass iClass;
try {
iClass = this.iClassLoader.loadIClass(Descriptor.fromClassName(c.getName()));
} catch (ClassNotFoundException ex) {
throw new JaninoRuntimeException("Loading IClass \"" + c.getName() + "\": " + ex);
}
if (iClass == null) {
throw new JaninoRuntimeException("Cannot load class \"" + c.getName() + "\" through the given ClassLoader");
}
return iClass;
}
/** @see #classToIClass(Class) */
private IClass[]
classesToIClasses(Class[] cs) {
IClass[] result = new IClass[cs.length];
for (int i = 0; i < cs.length; ++i) result[i] = this.classToIClass(cs[i]);
return result;
}
private static Access
modifiers2Access(int modifiers) {
return (
Modifier.isPrivate(modifiers) ? Access.PRIVATE :
Modifier.isProtected(modifiers) ? Access.PROTECTED :
Modifier.isPublic(modifiers) ? Access.PUBLIC :
Access.DEFAULT
);
}
}

View File

@ -1,82 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino;
import java.io.IOException;
import java.io.InputStream;
import org.codehaus.janino.util.ClassFile;
import org.codehaus.janino.util.resource.Resource;
import org.codehaus.janino.util.resource.ResourceFinder;
/**
* This {@link org.codehaus.janino.IClassLoader} loads IClasses through a
* a {@link org.codehaus.janino.util.resource.ResourceFinder} that designates
* {@link org.codehaus.janino.util.ClassFile}s.
*/
public
class ResourceFinderIClassLoader extends IClassLoader {
private final ResourceFinder resourceFinder;
public
ResourceFinderIClassLoader(ResourceFinder resourceFinder, IClassLoader optionalParentIClassLoader) {
super(optionalParentIClassLoader);
this.resourceFinder = resourceFinder;
this.postConstruct();
}
@Override protected IClass
findIClass(String descriptor) throws ClassNotFoundException {
String className = Descriptor.toClassName(descriptor);
// Find the class file resource.
Resource classFileResource = this.resourceFinder.findResource(ClassFile.getClassFileResourceName(className));
if (classFileResource == null) return null;
// Open the class file resource.
InputStream is;
try {
is = classFileResource.open();
} catch (IOException ex) {
throw new ClassNotFoundException("Opening resource \"" + classFileResource.getFileName() + "\"", ex);
}
// Load the IClass from the class file.
ClassFile cf;
try {
cf = new ClassFile(is);
} catch (IOException e) {
throw new ClassNotFoundException("Reading resource \"" + classFileResource.getFileName() + "\"", e);
} finally {
try { is.close(); } catch (IOException e) {}
}
IClass iClass = new ClassFileIClass(cf, this);
this.defineIClass(iClass);
return iClass;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,993 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.codehaus.commons.compiler.CompileException;
import org.codehaus.commons.compiler.Cookable;
import org.codehaus.commons.compiler.IExpressionEvaluator;
import org.codehaus.commons.compiler.IScriptEvaluator;
import org.codehaus.commons.compiler.Location;
import org.codehaus.janino.Java.VariableDeclarator;
import org.codehaus.janino.util.Traverser;
/** A number of "convenience constructors" exist that execute the setup steps instantly. Their use is discouraged. */
@SuppressWarnings({ "rawtypes", "unchecked" }) public
class ScriptEvaluator extends ClassBodyEvaluator implements IScriptEvaluator {
/** Whether methods override a method declared by a supertype; {@code null} means "none". */
protected boolean[] optionalOverrideMethod;
/** Whether methods are static; {@code null} means "all". */
protected boolean[] optionalStaticMethod;
/** The methods' return types; {@code null} means "none". */
protected Class[] optionalReturnTypes;
private String[] optionalMethodNames;
private String[][] optionalParameterNames;
private Class[][] optionalParameterTypes;
private Class[][] optionalThrownExceptions;
private Method[] result; // null=uncooked
/**
* Equivalent to<pre>
* ScriptEvaluator se = new ScriptEvaluator();
* se.cook(script);</pre>
*
* @see #ScriptEvaluator()
* @see Cookable#cook(String)
*/
public
ScriptEvaluator(String script) throws CompileException {
this.cook(script);
}
/**
* Equivalent to<pre>
* ScriptEvaluator se = new ScriptEvaluator();
* se.setReturnType(returnType);
* se.cook(script);</pre>
*
* @see #ScriptEvaluator()
* @see #setReturnType(Class)
* @see Cookable#cook(String)
*/
public
ScriptEvaluator(String script, Class returnType) throws CompileException {
this.setReturnType(returnType);
this.cook(script);
}
/**
* Equivalent to<pre>
* ScriptEvaluator se = new ScriptEvaluator();
* se.setReturnType(returnType);
* se.setParameters(parameterNames, parameterTypes);
* se.cook(script);</pre>
*
* @see #ScriptEvaluator()
* @see #setReturnType(Class)
* @see #setParameters(String[], Class[])
* @see Cookable#cook(String)
*/
public
ScriptEvaluator(String script, Class returnType, String[] parameterNames, Class[] parameterTypes)
throws CompileException {
this.setReturnType(returnType);
this.setParameters(parameterNames, parameterTypes);
this.cook(script);
}
/**
* Equivalent to<pre>
* ScriptEvaluator se = new ScriptEvaluator();
* se.setReturnType(returnType);
* se.setParameters(parameterNames, parameterTypes);
* se.setThrownExceptions(thrownExceptions);
* se.cook(script);</pre>
*
* @see #ScriptEvaluator()
* @see #setReturnType(Class)
* @see #setParameters(String[], Class[])
* @see #setThrownExceptions(Class[])
* @see Cookable#cook(String)
*/
public
ScriptEvaluator(
String script,
Class returnType,
String[] parameterNames,
Class[] parameterTypes,
Class[] thrownExceptions
) throws CompileException {
this.setReturnType(returnType);
this.setParameters(parameterNames, parameterTypes);
this.setThrownExceptions(thrownExceptions);
this.cook(script);
}
/**
* Equivalent to<pre>
* ScriptEvaluator se = new ScriptEvaluator();
* se.setReturnType(returnType);
* se.setParameters(parameterNames, parameterTypes);
* se.setThrownExceptions(thrownExceptions);
* se.setParentClassLoader(optionalParentClassLoader);
* se.cook(optionalFileName, is);</pre>
*
* @see #ScriptEvaluator()
* @see #setReturnType(Class)
* @see #setParameters(String[], Class[])
* @see #setThrownExceptions(Class[])
* @see SimpleCompiler#setParentClassLoader(ClassLoader)
* @see Cookable#cook(String, InputStream)
*/
public
ScriptEvaluator(
String optionalFileName,
InputStream is,
Class returnType,
String[] parameterNames,
Class[] parameterTypes,
Class[] thrownExceptions,
ClassLoader optionalParentClassLoader // null = use current thread's context class loader
) throws CompileException, IOException {
this.setReturnType(returnType);
this.setParameters(parameterNames, parameterTypes);
this.setThrownExceptions(thrownExceptions);
this.setParentClassLoader(optionalParentClassLoader);
this.cook(optionalFileName, is);
}
/**
* Equivalent to<pre>
* ScriptEvaluator se = new ScriptEvaluator();
* se.setReturnType(returnType);
* se.setParameters(parameterNames, parameterTypes);
* se.setThrownExceptions(thrownExceptions);
* se.setParentClassLoader(optionalParentClassLoader);
* se.cook(reader);</pre>
*
* @see #ScriptEvaluator()
* @see #setReturnType(Class)
* @see #setParameters(String[], Class[])
* @see #setThrownExceptions(Class[])
* @see SimpleCompiler#setParentClassLoader(ClassLoader)
* @see Cookable#cook(String, Reader)
*/
public
ScriptEvaluator(
String optionalFileName,
Reader reader,
Class returnType,
String[] parameterNames,
Class[] parameterTypes,
Class[] thrownExceptions,
ClassLoader optionalParentClassLoader // null = use current thread's context class loader
) throws CompileException, IOException {
this.setReturnType(returnType);
this.setParameters(parameterNames, parameterTypes);
this.setThrownExceptions(thrownExceptions);
this.setParentClassLoader(optionalParentClassLoader);
this.cook(optionalFileName, reader);
}
/**
* Equivalent to<pre>
* ScriptEvaluator se = new ScriptEvaluator();
* se.setReturnType(returnType);
* se.setParameters(parameterNames, parameterTypes);
* se.setThrownExceptions(thrownExceptions);
* se.setParentClassLoader(optionalParentClassLoader);
* se.cook(scanner);</pre>
*
* @see #ScriptEvaluator()
* @see #setReturnType(Class)
* @see #setParameters(String[], Class[])
* @see #setThrownExceptions(Class[])
* @see SimpleCompiler#setParentClassLoader(ClassLoader)
* @see Cookable#cook(Reader)
*/
public
ScriptEvaluator(
Scanner scanner,
Class returnType,
String[] parameterNames,
Class[] parameterTypes,
Class[] thrownExceptions,
ClassLoader optionalParentClassLoader // null = use current thread's context class loader
) throws CompileException, IOException {
this.setReturnType(returnType);
this.setParameters(parameterNames, parameterTypes);
this.setThrownExceptions(thrownExceptions);
this.setParentClassLoader(optionalParentClassLoader);
this.cook(scanner);
}
/**
* Equivalent to<pre>
* ScriptEvaluator se = new ScriptEvaluator();
* se.setExtendedType(optionalExtendedType);
* se.setImplementedTypes(implementedTypes);
* se.setReturnType(returnType);
* se.setParameters(parameterNames, parameterTypes);
* se.setThrownExceptions(thrownExceptions);
* se.setParentClassLoader(optionalParentClassLoader);
* se.cook(scanner);</pre>
*
* @see #ScriptEvaluator()
* @see ClassBodyEvaluator#setExtendedClass(Class)
* @see ClassBodyEvaluator#setImplementedInterfaces(Class[])
* @see #setReturnType(Class)
* @see #setParameters(String[], Class[])
* @see #setThrownExceptions(Class[])
* @see SimpleCompiler#setParentClassLoader(ClassLoader)
* @see Cookable#cook(Reader)
*/
public
ScriptEvaluator(
Scanner scanner,
Class optionalExtendedType,
Class[] implementedTypes,
Class returnType,
String[] parameterNames,
Class[] parameterTypes,
Class[] thrownExceptions,
ClassLoader optionalParentClassLoader // null = use current thread's context class loader
) throws CompileException, IOException {
this.setExtendedClass(optionalExtendedType);
this.setImplementedInterfaces(implementedTypes);
this.setReturnType(returnType);
this.setParameters(parameterNames, parameterTypes);
this.setThrownExceptions(thrownExceptions);
this.setParentClassLoader(optionalParentClassLoader);
this.cook(scanner);
}
/**
* Equivalent to<pre>
* ScriptEvaluator se = new ScriptEvaluator();
* se.setClassName(className);
* se.setExtendedType(optionalExtendedType);
* se.setImplementedTypes(implementedTypes);
* se.setStaticMethod(staticMethod);
* se.setReturnType(returnType);
* se.setMethodName(methodName);
* se.setParameters(parameterNames, parameterTypes);
* se.setThrownExceptions(thrownExceptions);
* se.setParentClassLoader(optionalParentClassLoader);
* se.cook(scanner);</pre>
*
* @see #ScriptEvaluator()
* @see ClassBodyEvaluator#setClassName(String)
* @see ClassBodyEvaluator#setExtendedClass(Class)
* @see ClassBodyEvaluator#setImplementedInterfaces(Class[])
* @see #setStaticMethod(boolean)
* @see #setReturnType(Class)
* @see #setMethodName(String)
* @see #setParameters(String[], Class[])
* @see #setThrownExceptions(Class[])
* @see SimpleCompiler#setParentClassLoader(ClassLoader)
* @see Cookable#cook(Reader)
*/
public
ScriptEvaluator(
Scanner scanner,
String className,
Class optionalExtendedType,
Class[] implementedTypes,
boolean staticMethod,
Class returnType,
String methodName,
String[] parameterNames,
Class[] parameterTypes,
Class[] thrownExceptions,
ClassLoader optionalParentClassLoader // null = use current thread's context class loader
) throws CompileException, IOException {
this.setClassName(className);
this.setExtendedClass(optionalExtendedType);
this.setImplementedInterfaces(implementedTypes);
this.setStaticMethod(staticMethod);
this.setReturnType(returnType);
this.setMethodName(methodName);
this.setParameters(parameterNames, parameterTypes);
this.setThrownExceptions(thrownExceptions);
this.setParentClassLoader(optionalParentClassLoader);
this.cook(scanner);
}
/**
* Constructs a script evaluator with all the default settings (return type {@code void}
*/
public ScriptEvaluator() {}
@Override public void
setOverrideMethod(boolean overrideMethod) {
this.setOverrideMethod(new boolean[] { overrideMethod });
}
@Override public void
setStaticMethod(boolean staticMethod) {
this.setStaticMethod(new boolean[] { staticMethod });
}
/**
* Defines the return types of the generated methods.
*
* @param returnType The method's return type; {@code null} means the "default return type", which is the type
* returned by {@link #getDefaultReturnType()} ({@code void.class} for {@link ScriptEvaluator}
* and {@code Object.class} for {@link ExpressionEvaluator})
* @see ScriptEvaluator#getDefaultReturnType()
* @see ExpressionEvaluator#getDefaultReturnType()
*/
@Override public void
setReturnType(Class returnType) {
this.setReturnTypes(new Class[] { returnType });
}
@Override public void
setMethodName(String methodName) {
this.setMethodNames(new String[] { methodName });
}
@Override public void
setParameters(String[] parameterNames, Class[] parameterTypes) {
this.setParameters(new String[][] { parameterNames }, new Class[][] { parameterTypes });
}
@Override public void
setThrownExceptions(Class[] thrownExceptions) {
this.setThrownExceptions(new Class[][] { thrownExceptions });
}
@Override public final void
cook(Scanner scanner) throws CompileException, IOException {
this.cook(new Scanner[] { scanner });
}
@Override public Object
evaluate(Object[] arguments) throws InvocationTargetException {
return this.evaluate(0, arguments);
}
@Override public Method
getMethod() { return this.getMethod(0); }
@Override public void
setOverrideMethod(boolean[] overrideMethod) {
this.assertNotCooked();
this.optionalOverrideMethod = overrideMethod.clone();
}
@Override public void
setStaticMethod(boolean[] staticMethod) {
this.assertNotCooked();
this.optionalStaticMethod = staticMethod.clone();
}
/**
* Defines the return types of the generated methods.
*
* @param returnTypes The methods' return types; {@code null} elements mean the "default return type", which is the
* type returned by {@link #getDefaultReturnType()} ({@code void.class} for {@link
* ScriptEvaluator} and {@code Object.class} for {@link ExpressionEvaluator})
* @see ScriptEvaluator#getDefaultReturnType()
* @see ExpressionEvaluator#getDefaultReturnType()
*/
@Override public void
setReturnTypes(Class[] returnTypes) {
this.assertNotCooked();
this.optionalReturnTypes = returnTypes.clone();
}
@Override public void
setMethodNames(String[] methodNames) {
this.assertNotCooked();
this.optionalMethodNames = methodNames.clone();
}
@Override public void
setParameters(String[][] parameterNames, Class[][] parameterTypes) {
this.assertNotCooked();
this.optionalParameterNames = parameterNames.clone();
this.optionalParameterTypes = parameterTypes.clone();
}
@Override public void
setThrownExceptions(Class[][] thrownExceptions) {
this.assertNotCooked();
this.optionalThrownExceptions = thrownExceptions.clone();
}
/**
* Like {@link #cook(Scanner)}, but cooks a <i>set</i> of scripts into one class. Notice that
* if <i>any</i> of the scripts causes trouble, the entire compilation will fail. If you
* need to report <i>which</i> of the scripts causes the exception, you may want to use the
* <code>optionalFileName</code> argument of {@link Scanner#Scanner(String, Reader)} to
* distinguish between the individual token sources.
* <p>
* On a 2 GHz Intel Pentium Core Duo under Windows XP with an IBM 1.4.2 JDK, compiling
* 10000 expressions "a + b" (integer) takes about 4 seconds and 56 MB of main memory.
* The generated class file is 639203 bytes large.
* <p>
* The number and the complexity of the scripts is restricted by the
* <a href="http://java.sun.com/docs/books/vmspec/2nd-edition/html/ClassFile.doc.html#88659">Limitations
* of the Java Virtual Machine</a>, where the most limiting factor is the 64K entries limit
* of the constant pool. Since every method with a distinct name requires one entry there,
* you can define at best 32K (very simple) scripts.
*
* If and only if the number of scanners is one, then that single script may contain leading
* IMPORT directives.
*
* @throws IllegalStateException Any of the preceeding <code>set...()</code> had an array size different from that
* of <code>scanners</code>
*/
public final void
cook(Scanner[] scanners) throws CompileException, IOException {
if (scanners == null) throw new NullPointerException();
Parser[] parsers = new Parser[scanners.length];
for (int i = 0; i < scanners.length; ++i) {
parsers[i] = new Parser(scanners[i]);
}
this.cook(parsers);
}
/** @see #cook(Scanner[]) */
public final void
cook(Parser[] parsers) throws CompileException, IOException {
// The "dimension" of this ScriptEvaluator, i.e. how many scripts are cooked at the same
// time.
int count = parsers.length;
// Check array sizes.
if (this.optionalMethodNames != null && this.optionalMethodNames.length != count) {
throw new IllegalStateException("methodName count");
}
if (this.optionalParameterNames != null && this.optionalParameterNames.length != count) {
throw new IllegalStateException("parameterNames count");
}
if (this.optionalParameterTypes != null && this.optionalParameterTypes.length != count) {
throw new IllegalStateException("parameterTypes count");
}
if (this.optionalOverrideMethod != null && this.optionalOverrideMethod.length != count) {
throw new IllegalStateException("overrideMethod count");
}
if (this.optionalReturnTypes != null && this.optionalReturnTypes.length != count) {
throw new IllegalStateException("returnTypes count");
}
if (this.optionalStaticMethod != null && this.optionalStaticMethod.length != count) {
throw new IllegalStateException("staticMethod count");
}
if (this.optionalThrownExceptions != null && this.optionalThrownExceptions.length != count) {
throw new IllegalStateException("thrownExceptions count");
}
// Create compilation unit.
Java.CompilationUnit compilationUnit = this.makeCompilationUnit(count == 1 ? parsers[0] : null);
// Create class declaration.
Java.ClassDeclaration cd = this.addPackageMemberClassDeclaration(parsers[0].location(), compilationUnit);
// Determine method names.
String[] methodNames;
if (this.optionalMethodNames == null) {
methodNames = new String[count];
for (int i = 0; i < count; ++i) methodNames[i] = "eval" + i;
} else
{
methodNames = this.optionalMethodNames;
}
// Create methods with one block each.
for (int i = 0; i < count; ++i) {
Parser parser = parsers[i];
List<Java.BlockStatement> statements = this.makeStatements(i, parser);
// Determine the following script properties AFTER the call to "makeBlock()",
// because "makeBlock()" may modify these script properties on-the-fly.
boolean staticMethod = this.optionalStaticMethod == null || this.optionalStaticMethod[i];
boolean overrideMethod = this.optionalOverrideMethod != null && this.optionalOverrideMethod[i];
Class returnType = (
this.optionalReturnTypes == null
? this.getDefaultReturnType()
: this.optionalReturnTypes[i]
);
String[] parameterNames = (
this.optionalParameterNames == null
? new String[0]
: this.optionalParameterNames[i]
);
Class[] parameterTypes = (
this.optionalParameterTypes == null
? new Class[0]
: this.optionalParameterTypes[i]
);
Class[] thrownExceptions = (
this.optionalThrownExceptions == null
? new Class[0]
: this.optionalThrownExceptions[i]
);
// If the method is non-static, assume that it overrides a method in a supertype.
Location loc = parser.location();
cd.addDeclaredMethod(this.makeMethodDeclaration(
loc, // location
( // annotations
overrideMethod
? new Java.Annotation[] { new Java.MarkerAnnotation(this.classToType(loc, Override.class)) }
: new Java.Annotation[0]
),
staticMethod, // staticMethod
returnType, // returnType
methodNames[i], // methodName
parameterTypes, // parameterTypes
parameterNames, // parameterNames
thrownExceptions, // thrownExceptions
statements // statements
));
}
// Compile and load the compilation unit.
Class c = this.compileToClass(compilationUnit);
// Find the script methods by name.
this.result = new Method[count];
if (count <= 10) {
for (int i = 0; i < count; ++i) {
try {
this.result[i] = c.getDeclaredMethod(
methodNames[i],
this.optionalParameterTypes == null ? new Class[0] : this.optionalParameterTypes[i]
);
} catch (NoSuchMethodException ex) {
throw new JaninoRuntimeException((
"SNO: Loaded class does not declare method \""
+ methodNames[i]
+ "\""
), ex);
}
}
} else
{
class MethodWrapper {
private final String name;
private final Class[] parameterTypes;
MethodWrapper(String name, Class[] parameterTypes) {
this.name = name;
this.parameterTypes = parameterTypes;
}
@Override public boolean
equals(Object o) {
if (!(o instanceof MethodWrapper)) return false;
MethodWrapper that = (MethodWrapper) o;
if (!this.name.equals(that.name)) return false;
int cnt = this.parameterTypes.length;
if (cnt != that.parameterTypes.length) return false;
for (int i = 0; i < cnt; ++i) {
if (!this.parameterTypes[i].equals(that.parameterTypes[i])) return false;
}
return true;
}
@Override public int
hashCode() {
int hc = this.name.hashCode();
for (Class parameterType : this.parameterTypes) hc ^= parameterType.hashCode();
return hc;
}
}
Method[] ma = c.getDeclaredMethods();
Map<MethodWrapper, Method> dms = new HashMap(2 * count);
for (Method m : ma) dms.put(new MethodWrapper(m.getName(), m.getParameterTypes()), m);
for (int i = 0; i < count; ++i) {
Method m = (Method) dms.get(new MethodWrapper(
methodNames[i],
this.optionalParameterTypes == null ? new Class[0] : this.optionalParameterTypes[i]
));
if (m == null) {
throw new JaninoRuntimeException(
"SNO: Loaded class does not declare method \""
+ methodNames[i]
+ "\""
);
}
this.result[i] = m;
}
}
}
@Override public final void
cook(Reader[] readers) throws CompileException, IOException {
this.cook(new String[readers.length], readers);
}
/**
* On a 2 GHz Intel Pentium Core Duo under Windows XP with an IBM 1.4.2 JDK, compiling
* 10000 expressions "a + b" (integer) takes about 4 seconds and 56 MB of main memory.
* The generated class file is 639203 bytes large.
* <p>
* The number and the complexity of the scripts is restricted by the
* <a href="http://java.sun.com/docs/books/vmspec/2nd-edition/html/ClassFile.doc.html#88659">Limitations
* of the Java Virtual Machine</a>, where the most limiting factor is the 64K entries limit
* of the constant pool. Since every method with a distinct name requires one entry there,
* you can define at best 32K (very simple) scripts.
*/
@Override public final void
cook(String[] optionalFileNames, Reader[] readers) throws CompileException, IOException {
Scanner[] scanners = new Scanner[readers.length];
for (int i = 0; i < readers.length; ++i) {
scanners[i] = new Scanner(optionalFileNames == null ? null : optionalFileNames[i], readers[i]);
}
this.cook(scanners);
}
@Override public final void
cook(String[] strings) throws CompileException { this.cook(null, strings); }
@Override public final void
cook(String[] optionalFileNames, String[] strings) throws CompileException {
Reader[] readers = new Reader[strings.length];
for (int i = 0; i < strings.length; ++i) readers[i] = new StringReader(strings[i]);
try {
this.cook(optionalFileNames, readers);
} catch (IOException ex) {
throw new JaninoRuntimeException("SNO: IOException despite StringReader", ex);
}
}
/**
* @return {@code void.class}
* @see #setReturnTypes(Class[])
*/
protected Class
getDefaultReturnType() { return void.class; }
/** Fills the given <code>block</code> by parsing statements until EOF and adding them to the block. */
protected List<Java.BlockStatement>
makeStatements(int idx, Parser parser) throws CompileException, IOException {
List<Java.BlockStatement> statements = new ArrayList();
while (!parser.peekEof()) {
statements.add(parser.parseBlockStatement());
}
return statements;
}
/**
* To the given {@link Java.ClassDeclaration}, add
* <ul>
* <li>A public method declaration with the given return type, name, parameter
* names and values and thrown exceptions
* <li>A block
* </ul>
*
* @param returnType Return type of the declared method
*/
protected Java.MethodDeclarator
makeMethodDeclaration(
Location location,
Java.Annotation[] annotations,
boolean staticMethod,
Class returnType,
String methodName,
Class[] parameterTypes,
String[] parameterNames,
Class[] thrownExceptions,
List<Java.BlockStatement> statements
) {
if (parameterNames.length != parameterTypes.length) {
throw new JaninoRuntimeException(
"Lengths of \"parameterNames\" ("
+ parameterNames.length
+ ") and \"parameterTypes\" ("
+ parameterTypes.length
+ ") do not match"
);
}
Java.FunctionDeclarator.FormalParameters fps = new Java.FunctionDeclarator.FormalParameters(
location,
new Java.FunctionDeclarator.FormalParameter[parameterNames.length],
false
);
for (int i = 0; i < fps.parameters.length; ++i) {
fps.parameters[i] = new Java.FunctionDeclarator.FormalParameter(
location, // location
true, // finaL
this.classToType(location, parameterTypes[i]), // type
parameterNames[i] // name
);
}
return new Java.MethodDeclarator(
location, // location
null, // optionalDocComment
new Java.Modifiers( // modifiers
staticMethod ? (short) (Mod.PUBLIC | Mod.STATIC) : (short) Mod.PUBLIC,
annotations
),
this.classToType(location, returnType), // type
methodName, // name
fps, // formalParameters
this.classesToTypes(location, thrownExceptions), // thrownExceptions
statements // optionalStatements
);
}
/**
* @deprecated Use {@link #createFastScriptEvaluator(Scanner, String[], String, Class, Class, String[],
* ClassLoader)} instead
*/
@Deprecated public static Object
createFastScriptEvaluator(String script, Class interfaceToImplement, String[] parameterNames)
throws CompileException {
ScriptEvaluator se = new ScriptEvaluator();
return se.createFastEvaluator(script, interfaceToImplement, parameterNames);
}
/**
* @deprecated Use {@link #createFastScriptEvaluator(Scanner, String[], String, Class, Class, String[],
* ClassLoader)} instead
*/
@Deprecated public static Object
createFastScriptEvaluator(
Scanner scanner,
Class interfaceToImplement,
String[] parameterNames,
ClassLoader optionalParentClassLoader
) throws CompileException, IOException {
ScriptEvaluator se = new ScriptEvaluator();
se.setParentClassLoader(optionalParentClassLoader);
return se.createFastEvaluator(scanner, interfaceToImplement, parameterNames);
}
/**
* @deprecated Use {@link #createFastScriptEvaluator(Scanner, String[], String, Class, Class, String[],
* ClassLoader)} instead
*/
@Deprecated public static Object
createFastScriptEvaluator(
Scanner scanner,
String className,
Class optionalExtendedType,
Class interfaceToImplement,
String[] parameterNames,
ClassLoader optionalParentClassLoader
) throws CompileException, IOException {
ScriptEvaluator se = new ScriptEvaluator();
se.setClassName(className);
se.setExtendedClass(optionalExtendedType);
se.setParentClassLoader(optionalParentClassLoader);
return se.createFastEvaluator(scanner, interfaceToImplement, parameterNames);
}
/**
* <pre>
* {@link ScriptEvaluator} se = new {@link ScriptEvaluator#ScriptEvaluator() ScriptEvaluator}();
* se.{@link #setDefaultImports(String[]) setDefaultImports}.(optionalDefaultImports);
* se.{@link #setClassName(String) setClassName}.(className);
* se.{@link #setExtendedClass(Class) setExtendedClass}.(optionalExtendedClass);
* se.{@link #setParentClassLoader(ClassLoader) setParentClassLoader}(optionalParentClassLoader);
* return se.{@link #createFastEvaluator(Scanner, Class, String[]) createFastEvaluator}(scanner,
* interfaceToImplement, parameterNames);
* </pre>
*
* @deprecated Use {@link #createFastEvaluator(Scanner,Class,String[])} instead:
*/
@Deprecated public static Object
createFastScriptEvaluator(
Scanner scanner,
String[] optionalDefaultImports,
String className,
Class optionalExtendedClass,
Class interfaceToImplement,
String[] parameterNames,
ClassLoader optionalParentClassLoader
) throws CompileException, IOException {
ScriptEvaluator se = new ScriptEvaluator();
se.setDefaultImports(optionalDefaultImports);
se.setClassName(className);
se.setExtendedClass(optionalExtendedClass);
se.setParentClassLoader(optionalParentClassLoader);
return se.createFastEvaluator(scanner, interfaceToImplement, parameterNames);
}
/** Don't use. */
@Override public final Object
createInstance(Reader reader) {
throw new UnsupportedOperationException("createInstance");
}
@Override public Object
createFastEvaluator(Reader reader, Class interfaceToImplement, String[] parameterNames)
throws CompileException, IOException {
return this.createFastEvaluator(new Scanner(null, reader), interfaceToImplement, parameterNames);
}
@Override public Object
createFastEvaluator(String script, Class interfaceToImplement, String[] parameterNames) throws CompileException {
try {
return this.createFastEvaluator(
new StringReader(script),
interfaceToImplement,
parameterNames
);
} catch (IOException ex) {
throw new JaninoRuntimeException("IOException despite StringReader", ex);
}
}
/**
* Notice: This method is not declared in {@link IScriptEvaluator}, and is hence only available in <i>this</i>
* implementation of <code>org.codehaus.commons.compiler</code>. To be independent from this particular
* implementation, try to switch to {@link #createFastEvaluator(Reader, Class, String[])}.
*
* @param scanner Source of tokens to read
* @see #createFastEvaluator(Reader, Class, String[])
*/
public Object
createFastEvaluator(Scanner scanner, Class interfaceToImplement, String[] parameterNames)
throws CompileException, IOException {
if (!interfaceToImplement.isInterface()) {
throw new JaninoRuntimeException("\"" + interfaceToImplement + "\" is not an interface");
}
Method methodToImplement;
{
Method[] methods = interfaceToImplement.getDeclaredMethods();
if (methods.length != 1) {
throw new JaninoRuntimeException(
"Interface \""
+ interfaceToImplement
+ "\" must declare exactly one method"
);
}
methodToImplement = methods[0];
}
this.setImplementedInterfaces(new Class[] { interfaceToImplement });
this.setOverrideMethod(true);
this.setStaticMethod(false);
if (this instanceof IExpressionEvaluator) {
// Must not call "IExpressionEvaluator.setReturnType()".
((IExpressionEvaluator) this).setExpressionType(methodToImplement.getReturnType());
} else {
this.setReturnType(methodToImplement.getReturnType());
}
this.setMethodName(methodToImplement.getName());
this.setParameters(parameterNames, methodToImplement.getParameterTypes());
this.setThrownExceptions(methodToImplement.getExceptionTypes());
this.cook(scanner);
Class c = this.getMethod().getDeclaringClass();
try {
return c.newInstance();
} catch (InstantiationException e) {
// SNO - Declared class is always non-abstract.
throw new JaninoRuntimeException(e.toString(), e);
} catch (IllegalAccessException e) {
// SNO - interface methods are always PUBLIC.
throw new JaninoRuntimeException(e.toString(), e);
}
}
/**
* Guess the names of the parameters used in the given expression. The strategy is to look
* at all "ambiguous names" in the expression (e.g. in "a.b.c.d()", the ambiguous name
* is "a.b.c"), and then at the components of the ambiguous name.
* <ul>
* <li>If any component starts with an upper-case letter, then ambiguous name is assumed to
* be a type name.
* <li>Otherwise, if the first component of the ambiguous name matches the name of a
* previously defined local variable, then the first component of the ambiguous name is
* assumed to be a local variable name. (Notice that this strategy does not consider that
* the scope of a local variable declaration may end before the end of the script.)
* <li>Otherwise, the first component of the ambiguous name is assumed to be a parameter name.
* </ul>
*
* @see Scanner#Scanner(String, Reader)
*/
public static String[]
guessParameterNames(Scanner scanner) throws CompileException, IOException {
Parser parser = new Parser(scanner);
// Eat optional leading import declarations.
while (parser.peek("import")) parser.parseImportDeclaration();
// Parse the script statements into a block.
Java.Block block = new Java.Block(scanner.location());
while (!parser.peekEof()) block.addStatement(parser.parseBlockStatement());
// Traverse the block for ambiguous names and guess which of them are parameter names.
final Set<String> localVariableNames = new HashSet();
final Set<String> parameterNames = new HashSet();
new Traverser() {
@Override public void
traverseLocalVariableDeclarationStatement(Java.LocalVariableDeclarationStatement lvds) {
for (VariableDeclarator vd : lvds.variableDeclarators) localVariableNames.add(vd.name);
super.traverseLocalVariableDeclarationStatement(lvds);
}
@Override public void
traverseAmbiguousName(Java.AmbiguousName an) {
// If any of the components starts with an upper-case letter, then the ambiguous
// name is most probably a type name, e.g. "System.out" or "java.lang.System.out".
for (int i = 0; i < an.identifiers.length; ++i) {
if (Character.isUpperCase(an.identifiers[i].charAt(0))) return;
}
// Is it a local variable's name?
if (localVariableNames.contains(an.identifiers[0])) return;
// It's most probably a parameter name (although it could be a field name as well).
parameterNames.add(an.identifiers[0]);
}
}.traverseBlock(block);
return (String[]) parameterNames.toArray(new String[parameterNames.size()]);
}
@Override public Object
evaluate(int idx, Object[] arguments) throws InvocationTargetException {
if (this.result == null) throw new IllegalStateException("Must only be called after \"cook()\"");
try {
return this.result[idx].invoke(null, arguments);
} catch (IllegalAccessException ex) {
throw new JaninoRuntimeException(ex.toString(), ex);
}
}
@Override public Method
getMethod(int idx) {
if (this.result == null) throw new IllegalStateException("Must only be called after \"cook()\"");
return this.result[idx];
}
}

View File

@ -1,425 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.HashMap;
import java.util.Map;
import org.codehaus.commons.compiler.CompileException;
import org.codehaus.commons.compiler.Cookable;
import org.codehaus.commons.compiler.ErrorHandler;
import org.codehaus.commons.compiler.ICookable;
import org.codehaus.commons.compiler.ISimpleCompiler;
import org.codehaus.commons.compiler.Location;
import org.codehaus.commons.compiler.WarningHandler;
import org.codehaus.janino.Java.Type;
import org.codehaus.janino.Visitor.AtomVisitor;
import org.codehaus.janino.Visitor.TypeVisitor;
import org.codehaus.janino.util.ClassFile;
/**
* To set up a {@link SimpleCompiler} object, proceed as described for {@link ISimpleCompiler}.
* Alternatively, a number of "convenience constructors" exist that execute the described steps
* instantly.
*/
@SuppressWarnings({ "rawtypes", "unchecked" }) public
class SimpleCompiler extends Cookable implements ISimpleCompiler {
private static final boolean DEBUG = false;
private ClassLoader parentClassLoader = Thread.currentThread().getContextClassLoader();
// Set when "cook()"ing.
private ClassLoaderIClassLoader classLoaderIClassLoader;
private ClassLoader result;
private ErrorHandler optionalCompileErrorHandler;
private WarningHandler optionalWarningHandler;
private boolean debugSource = Boolean.getBoolean(ICookable.SYSTEM_PROPERTY_SOURCE_DEBUGGING_ENABLE);
private boolean debugLines = this.debugSource;
private boolean debugVars = this.debugSource;
public static void // SUPPRESS CHECKSTYLE JavadocMethod
main(String[] args) throws Exception {
if (args.length >= 1 && "-help".equals(args[0])) {
System.out.println("Usage:");
System.out.println(" org.codehaus.janino.SimpleCompiler <source-file> <class-name> { <argument> }");
System.out.println("Reads a compilation unit from the given <source-file> and invokes method");
System.out.println("\"public static void main(String[])\" of class <class-name>, passing the");
System.out.println("given <argument>s.");
System.exit(1);
}
if (args.length < 2) {
System.err.println("Source file and/or class name missing; try \"-help\".");
System.exit(1);
}
// Get source file.
String sourceFileName = args[0];
// Get class name.
String className = args[1];
// Get arguments.
String[] arguments = new String[args.length - 2];
System.arraycopy(args, 2, arguments, 0, arguments.length);
// Compile the source file.
ClassLoader cl = new SimpleCompiler(sourceFileName, new FileInputStream(sourceFileName)).getClassLoader();
// Load the class.
Class c = cl.loadClass(className);
// Invoke the "public static main(String[])" method.
Method m = c.getMethod("main", new Class[] { String[].class });
m.invoke(null, new Object[] { arguments });
}
/**
* Equivalent to<pre>
* SimpleCompiler sc = new SimpleCompiler();
* sc.cook(optionalFileName, in);</pre>
*
* @see #SimpleCompiler()
* @see Cookable#cook(String, Reader)
*/
public
SimpleCompiler(String optionalFileName, Reader in) throws IOException, CompileException {
this.cook(optionalFileName, in);
}
/**
* Equivalent to<pre>
* SimpleCompiler sc = new SimpleCompiler();
* sc.cook(optionalFileName, is);</pre>
*
* @see #SimpleCompiler()
* @see Cookable#cook(String, InputStream)
*/
public
SimpleCompiler(String optionalFileName, InputStream is) throws IOException, CompileException {
this.cook(optionalFileName, is);
}
/**
* Equivalent to<pre>
* SimpleCompiler sc = new SimpleCompiler();
* sc.cook(fileName);</pre>
*
* @see #SimpleCompiler()
* @see Cookable#cookFile(String)
*/
public
SimpleCompiler(String fileName) throws IOException, CompileException {
this.cookFile(fileName);
}
/**
* Equivalent to<pre>
* SimpleCompiler sc = new SimpleCompiler();
* sc.setParentClassLoader(optionalParentClassLoader);
* sc.cook(scanner);</pre>
*
* @see #SimpleCompiler()
* @see #setParentClassLoader(ClassLoader)
* @see Cookable#cook(Reader)
*/
public
SimpleCompiler(Scanner scanner, ClassLoader optionalParentClassLoader) throws IOException, CompileException {
this.setParentClassLoader(optionalParentClassLoader);
this.cook(scanner);
}
public SimpleCompiler() {}
@Override public void
setParentClassLoader(ClassLoader optionalParentClassLoader) {
this.assertNotCooked();
this.parentClassLoader = (
optionalParentClassLoader != null
? optionalParentClassLoader
: Thread.currentThread().getContextClassLoader()
);
}
@Override public void
setDebuggingInformation(boolean debugSource, boolean debugLines, boolean debugVars) {
this.debugSource = debugSource;
this.debugLines = debugLines;
this.debugVars = debugVars;
}
/**
* Scans, parses and compiles a given compilation unit from the given {@link Reader}. After completion, {@link
* #getClassLoader()} returns a {@link ClassLoader} that allows for access to the compiled classes.
*/
@Override public final void
cook(String optionalFileName, Reader r) throws CompileException, IOException {
this.cook(new Scanner(optionalFileName, r));
}
/**
* Scans, parses and ompiles a given compilation unit from the given scanner. After completion, {@link
* #getClassLoader()} returns a {@link ClassLoader} that allows for access to the compiled classes.
*/
public void
cook(Scanner scanner) throws CompileException, IOException {
this.compileToClassLoader(new Parser(scanner).parseCompilationUnit());
}
/**
* Cooks this compilation unit directly.
*
* @see Cookable#cook(Reader)
*/
public void
cook(Java.CompilationUnit compilationUnit) throws CompileException {
// Compile the classes and load them.
this.compileToClassLoader(compilationUnit);
}
@Override public ClassLoader
getClassLoader() {
if (this.getClass() != SimpleCompiler.class) {
throw new IllegalStateException("Must not be called on derived instances");
}
if (this.result == null) throw new IllegalStateException("Must only be called after \"cook()\"");
return this.result;
}
/**
* Two {@link SimpleCompiler}s are regarded equal iff
* <ul>
* <li>Both are objects of the same class (e.g. both are {@link ScriptEvaluator}s)
* <li>Both generated functionally equal classes as seen by {@link ByteArrayClassLoader#equals(Object)}
* </ul>
*/
@Override public boolean
equals(Object o) {
if (!(o instanceof SimpleCompiler)) return false;
SimpleCompiler that = (SimpleCompiler) o;
if (this.getClass() != that.getClass()) return false;
if (this.result == null || that.result == null) {
throw new IllegalStateException("Equality can only be checked after cooking");
}
return this.result.equals(that.result);
}
@Override public int
hashCode() { return this.parentClassLoader.hashCode(); }
@Override public void
setCompileErrorHandler(ErrorHandler optionalCompileErrorHandler) {
this.optionalCompileErrorHandler = optionalCompileErrorHandler;
}
@Override public void
setWarningHandler(WarningHandler optionalWarningHandler) {
this.optionalWarningHandler = optionalWarningHandler;
}
/** Wraps a reflection {@link Class} in a {@link Java.Type} object. */
protected Java.Type
classToType(final Location location, final Class clazz) {
if (clazz == null) return null;
// IClass iClass;
// synchronized (this.classes) {
// iClass = (IClass) this.classes.get(clazz);
// if (iClass == null) {
// if (clazz.isPrimitive()) {
// if (clazz == byte.class) { iClass = IClass.BYTE; } else
// if (clazz == short.class) { iClass = IClass.SHORT; } else
// if (clazz == int.class) { iClass = IClass.INT; } else
// if (clazz == long.class) { iClass = IClass.LONG; } else
// if (clazz == float.class) { iClass = IClass.FLOAT; } else
// if (clazz == double.class) { iClass = IClass.DOUBLE; } else
// if (clazz == char.class) { iClass = IClass.CHAR; } else
// if (clazz == boolean.class) { iClass = IClass.BOOLEAN; } else
// if (clazz == void.class) { iClass = IClass.VOID; } else
// { throw new AssertionError(clazz); }
// } else {
// iClass = new ReflectionIClass(clazz, null);
// }
// this.classes.put(clazz, iClass);
// }
// }
// return new Java.SimpleType(location, iClass);
// Can't use a SimpleType here because the classLoaderIClassLoader is not yet set up. Instead, create a
// Type that lazily creates a delegate Type at COMPILE TIME.
return new Java.Type(location) {
private Java.SimpleType delegate;
@Override public String toString() { return this.getDelegate().toString(); }
@Override public void accept(AtomVisitor visitor) { this.getDelegate().accept((TypeVisitor) visitor); }
@Override public void accept(TypeVisitor visitor) { this.getDelegate().accept(visitor); }
private Type
getDelegate() {
if (this.delegate == null) {
IClass iClass;
try {
iClass = SimpleCompiler.this.classLoaderIClassLoader.loadIClass(
Descriptor.fromClassName(clazz.getName())
);
} catch (ClassNotFoundException ex) {
throw new JaninoRuntimeException("Loading IClass \"" + clazz.getName() + "\": " + ex);
}
if (iClass == null) {
throw new JaninoRuntimeException(
"Cannot load class '"
+ clazz.getName()
+ "' through the parent loader"
);
}
// Verify that the class loaders match.
IClass iClass2 = iClass;
Class class2 = clazz;
for (;;) {
IClass ct = iClass2.getComponentType();
if (ct == null) {
if (class2.getComponentType() != null) {
throw new JaninoRuntimeException("Array type/class inconsistency");
}
break;
}
iClass2 = ct;
class2 = class2.getComponentType();
if (class2 == null) throw new JaninoRuntimeException("Array type/class inconsistency");
}
if (class2.isPrimitive()) {
if (!iClass2.isPrimitive()) {
throw new JaninoRuntimeException("Primitive type/class inconsistency");
}
} else {
if (iClass2.isPrimitive()) {
throw new JaninoRuntimeException("Primitive type/class inconsistency");
}
if (((ReflectionIClass) iClass2).getClazz() != class2) {
throw new JaninoRuntimeException(
"Class '"
+ class2.getName()
+ "' was loaded through a different loader"
);
}
}
this.delegate = new Java.SimpleType(location, iClass);
}
return this.delegate;
}
};
}
// private final Map<Class, IClass> classes = new HashMap();
/** Converts an array of {@link Class}es into an array of{@link Java.Type}s. */
protected Java.Type[]
classesToTypes(Location location, Class[] classes) {
Java.Type[] types = new Java.Type[classes.length];
for (int i = 0; i < classes.length; ++i) {
types[i] = this.classToType(location, classes[i]);
}
return types;
}
/**
* Compile the given compilation unit. (A "compilation unit" is typically the contents
* of a Java&trade; source file.)
*
* @param compilationUnit The parsed compilation unit
* @return The {@link ClassLoader} into which the compiled classes were defined
* @throws CompileException
*/
protected final ClassLoader
compileToClassLoader(Java.CompilationUnit compilationUnit) throws CompileException {
if (SimpleCompiler.DEBUG) {
UnparseVisitor.unparse(compilationUnit, new OutputStreamWriter(System.out));
}
this.classLoaderIClassLoader = new ClassLoaderIClassLoader(this.parentClassLoader);
// Compile compilation unit to class files.
UnitCompiler unitCompiler = new UnitCompiler(compilationUnit, this.classLoaderIClassLoader);
unitCompiler.setCompileErrorHandler(this.optionalCompileErrorHandler);
unitCompiler.setWarningHandler(this.optionalWarningHandler);
ClassFile[] classFiles = unitCompiler.compileUnit(this.debugSource, this.debugLines, this.debugVars);
// Convert the class files to bytes and store them in a Map.
final Map<String /*className*/, byte[] /*bytecode*/> classes = new HashMap();
for (ClassFile cf : classFiles) {
byte[] contents = cf.toByteArray();
if (SimpleCompiler.DEBUG) {
try {
Class disassemblerClass = Class.forName("de.unkrig.jdisasm.Disassembler");
disassemblerClass.getMethod(
"disasm",
new Class[] { InputStream.class }
).invoke(
disassemblerClass.newInstance(),
new Object[] { new ByteArrayInputStream(contents) }
);
} catch (Exception e) {
e.printStackTrace();
}
}
classes.put(cf.getThisClassName(), contents);
}
// Create a ClassLoader that loads the generated classes.
this.result = (ClassLoader) AccessController.doPrivileged(new PrivilegedAction() {
@Override public Object
run() {
return new ByteArrayClassLoader(
classes, // classes
SimpleCompiler.this.parentClassLoader // parent
);
}
});
return this.result;
}
/** @throws IllegalStateException This {@link Cookable} is already cooked */
protected void
assertNotCooked() {
if (this.classLoaderIClassLoader != null) throw new IllegalStateException("Already cooked");
}
}

View File

@ -1,12 +0,0 @@
The raw, inofficial list of TODOs:
* Implement '@SuppressWarnings'; supersede JANINO's old '-warn:...' feature
* Implement non-SOURCE annotations
* Implement annotation declarations
* Implement ENUMs
* Implement type arguments ('List<String> l;')
* Implement type parameters ('class MyClass<T extends InputStream> { ... }')
* Enhanced FOR loop
Recently implemented:
* ASSERT (simplified, ASSERTions are ALWAYS enabled, as if '-ea' were set)

View File

@ -1,43 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino;
/**
* Represents a problem that occurred while unescaping a unicode escape
* sequence through a {@link org.codehaus.janino.UnicodeUnescapeReader}.
*/
public
class UnicodeUnescapeException extends RuntimeException {
private static final long serialVersionUID = -8965331941165671541L;
public
UnicodeUnescapeException(String message) { super(message); }
public
UnicodeUnescapeException(String message, Throwable cause) { super(message, cause); }
}

View File

@ -1,110 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino;
import java.io.FilterReader;
import java.io.IOException;
import java.io.Reader;
/**
* A {@link FilterReader} that unescapes the "Unicode Escapes" as described in JLS7 3.10.6.
* <p>
* Notice that it is possible to formulate invalid escape sequences, e.g. "&#92;u123g" ("g" is not a valid hex
* character). This is handled by throwing a {@link java.lang.RuntimeException}-derived {@link
* org.codehaus.janino.UnicodeUnescapeException}.
*/
public
class UnicodeUnescapeReader extends FilterReader {
public
UnicodeUnescapeReader(Reader in) { super(in); }
/**
* Override {@link FilterReader#read()}.
*
* @throws UnicodeUnescapeException Invalid escape sequence encountered
*/
@Override public int
read() throws IOException {
int c;
// Read next character.
if (this.unreadChar == -1) {
c = this.in.read();
} else {
c = this.unreadChar;
this.unreadChar = -1;
}
// Check for backslash-u escape sequence, preceeded with an even number
// of backslashes.
if (c != '\\' || this.oddPrecedingBackslashes) {
this.oddPrecedingBackslashes = false;
return c;
}
// Read one character ahead and check if it is a "u".
c = this.in.read();
if (c != 'u') {
this.unreadChar = c;
this.oddPrecedingBackslashes = true;
return '\\';
}
// Skip redundant "u"s.
do {
c = this.in.read();
if (c == -1) throw new UnicodeUnescapeException("Incomplete escape sequence");
} while (c == 'u');
// Decode escape sequence.
char[] ca = new char[4];
ca[0] = (char) c;
if (this.in.read(ca, 1, 3) != 3) throw new UnicodeUnescapeException("Incomplete escape sequence");
try {
return 0xffff & Integer.parseInt(new String(ca), 16);
} catch (NumberFormatException ex) {
throw new UnicodeUnescapeException("Invalid escape sequence \"\\u" + new String(ca) + "\"", ex);
}
}
/** Overrides {@link FilterReader#read(char[], int, int)}. */
@Override public int
read(char[] cbuf, int off, int len) throws IOException {
if (len == 0) return 0;
int res = 0;
do {
int c = this.read();
if (c == -1) break;
cbuf[off++] = (char) c;
} while (++res < len);
return res == 0 ? -1 : res;
}
private int unreadChar = -1; // -1 == none
private boolean oddPrecedingBackslashes;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,274 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino;
/** Basis for the "visitor" pattern as described in "Gamma, Helm, Johnson, Vlissides: Design Patterns". */
public
class Visitor {
/**
* The union of {@link ImportVisitor}, {@link TypeDeclarationVisitor}, {@link TypeBodyDeclarationVisitor} and
* {@link AtomVisitor}.
*/
public
interface ComprehensiveVisitor
extends ImportVisitor, TypeDeclarationVisitor, TypeBodyDeclarationVisitor, BlockStatementVisitor, AtomVisitor,
ElementValueVisitor { // SUPPRESS CHECKSTYLE WrapAndIndent
}
/** The visitor for all kinds of {@link Java.CompilationUnit.ImportDeclaration}s. */
public
interface ImportVisitor {
/** Invoked by {@link Java.CompilationUnit.SingleTypeImportDeclaration#accept(Visitor.ImportVisitor)} */
void visitSingleTypeImportDeclaration(Java.CompilationUnit.SingleTypeImportDeclaration stid);
/** Invoked by {@link Java.CompilationUnit.TypeImportOnDemandDeclaration#accept(Visitor.ImportVisitor)} */
void visitTypeImportOnDemandDeclaration(Java.CompilationUnit.TypeImportOnDemandDeclaration tiodd);
/** Invoked by {@link Java.CompilationUnit.SingleStaticImportDeclaration#accept(Visitor.ImportVisitor)} */
void visitSingleStaticImportDeclaration(Java.CompilationUnit.SingleStaticImportDeclaration ssid);
/** Invoked by {@link Java.CompilationUnit.StaticImportOnDemandDeclaration#accept(Visitor.ImportVisitor)} */
void visitStaticImportOnDemandDeclaration(Java.CompilationUnit.StaticImportOnDemandDeclaration siodd);
}
/** The visitor for all kinds of {@link Java.TypeDeclaration}s. */
public
interface TypeDeclarationVisitor {
/** Invoked by {@link Java.AnonymousClassDeclaration#accept(Visitor.TypeDeclarationVisitor)} */
void visitAnonymousClassDeclaration(Java.AnonymousClassDeclaration acd);
/** Invoked by {@link Java.LocalClassDeclaration#accept(Visitor.TypeDeclarationVisitor)} */
void visitLocalClassDeclaration(Java.LocalClassDeclaration lcd);
/** Invoked by {@link Java.PackageMemberClassDeclaration#accept(Visitor.TypeDeclarationVisitor)} */
void visitPackageMemberClassDeclaration(Java.PackageMemberClassDeclaration pmcd);
/** Invoked by {@link Java.MemberInterfaceDeclaration#accept(Visitor.TypeDeclarationVisitor)} */
void visitMemberInterfaceDeclaration(Java.MemberInterfaceDeclaration mid);
/** Invoked by {@link Java.PackageMemberInterfaceDeclaration#accept(Visitor.TypeDeclarationVisitor)} */
void visitPackageMemberInterfaceDeclaration(Java.PackageMemberInterfaceDeclaration pmid);
/** Invoked by {@link Java.MemberClassDeclaration#accept(Visitor.TypeDeclarationVisitor)} */
void visitMemberClassDeclaration(Java.MemberClassDeclaration mcd);
}
/** The visitor for all kinds of {@link Java.FunctionDeclarator}s. */
public
interface FunctionDeclaratorVisitor {
/** Invoked by {@link Java.ConstructorDeclarator#accept(Visitor.TypeBodyDeclarationVisitor)} */
void visitConstructorDeclarator(Java.ConstructorDeclarator cd);
/** Invoked by {@link Java.MethodDeclarator#accept(Visitor.TypeBodyDeclarationVisitor)} */
void visitMethodDeclarator(Java.MethodDeclarator md);
}
/**
* The visitor for all kinds of {@link Java.TypeBodyDeclaration}s (declarations that may appear in the body of a
* type declaration).
*/
public
interface TypeBodyDeclarationVisitor extends FunctionDeclaratorVisitor {
/** Invoked by {@link Java.MemberInterfaceDeclaration#accept(Visitor.TypeBodyDeclarationVisitor)} */
void visitMemberInterfaceDeclaration(Java.MemberInterfaceDeclaration mid);
/** Invoked by {@link Java.MemberClassDeclaration#accept(Visitor.TypeBodyDeclarationVisitor)} */
void visitMemberClassDeclaration(Java.MemberClassDeclaration mcd);
/** Invoked by {@link Java.Initializer#accept(Visitor.TypeBodyDeclarationVisitor)} */
void visitInitializer(Java.Initializer i);
/** Invoked by {@link Java.FieldDeclaration#accept(Visitor.TypeBodyDeclarationVisitor)} */
void visitFieldDeclaration(Java.FieldDeclaration fd);
}
/** The visitor for all kinds of {@link Java.BlockStatement}s (statements that may appear with a block). */
public
interface BlockStatementVisitor {
/** Invoked by {@link Java.Initializer#accept(Visitor.BlockStatementVisitor)} */
void visitInitializer(Java.Initializer i);
/** Invoked by {@link Java.FieldDeclaration#accept(Visitor.BlockStatementVisitor)} */
void visitFieldDeclaration(Java.FieldDeclaration fd);
/** Invoked by {@link Java.LabeledStatement#accept(Visitor.BlockStatementVisitor)} */
void visitLabeledStatement(Java.LabeledStatement ls);
/** Invoked by {@link Java.Block#accept(Visitor.BlockStatementVisitor)} */
void visitBlock(Java.Block b);
/** Invoked by {@link Java.ExpressionStatement#accept(Visitor.BlockStatementVisitor)} */
void visitExpressionStatement(Java.ExpressionStatement es);
/** Invoked by {@link Java.IfStatement#accept(Visitor.BlockStatementVisitor)} */
void visitIfStatement(Java.IfStatement is);
/** Invoked by {@link Java.ForStatement#accept(Visitor.BlockStatementVisitor)} */
void visitForStatement(Java.ForStatement fs);
/** Invoked by {@link Java.ForEachStatement#accept(Visitor.BlockStatementVisitor)} */
void visitForEachStatement(Java.ForEachStatement forEachStatement);
/** Invoked by {@link Java.WhileStatement#accept(Visitor.BlockStatementVisitor)} */
void visitWhileStatement(Java.WhileStatement ws);
/** Invoked by {@link Java.TryStatement#accept(Visitor.BlockStatementVisitor)} */
void visitTryStatement(Java.TryStatement ts);
/** Invoked by {@link Java.SwitchStatement#accept(Visitor.BlockStatementVisitor)} */
void visitSwitchStatement(Java.SwitchStatement ss);
/** Invoked by {@link Java.SynchronizedStatement#accept(Visitor.BlockStatementVisitor)} */
void visitSynchronizedStatement(Java.SynchronizedStatement ss);
/** Invoked by {@link Java.DoStatement#accept(Visitor.BlockStatementVisitor)} */
void visitDoStatement(Java.DoStatement ds);
/** Invoked by {@link Java.LocalVariableDeclarationStatement#accept(Visitor.BlockStatementVisitor)} */
void visitLocalVariableDeclarationStatement(Java.LocalVariableDeclarationStatement lvds);
/** Invoked by {@link Java.ReturnStatement#accept(Visitor.BlockStatementVisitor)} */
void visitReturnStatement(Java.ReturnStatement rs);
/** Invoked by {@link Java.ThrowStatement#accept(Visitor.BlockStatementVisitor)} */
void visitThrowStatement(Java.ThrowStatement ts);
/** Invoked by {@link Java.BreakStatement#accept(Visitor.BlockStatementVisitor)} */
void visitBreakStatement(Java.BreakStatement bs);
/** Invoked by {@link Java.ContinueStatement#accept(Visitor.BlockStatementVisitor)} */
void visitContinueStatement(Java.ContinueStatement cs);
/** Invoked by {@link Java.AssertStatement#accept(Visitor.BlockStatementVisitor)} */
void visitAssertStatement(Java.AssertStatement as);
/** Invoked by {@link Java.EmptyStatement#accept(Visitor.BlockStatementVisitor)} */
void visitEmptyStatement(Java.EmptyStatement es);
/** Invoked by {@link Java.LocalClassDeclarationStatement#accept(Visitor.BlockStatementVisitor)} */
void visitLocalClassDeclarationStatement(Java.LocalClassDeclarationStatement lcds);
/** Invoked by {@link Java.AlternateConstructorInvocation#accept(Visitor.BlockStatementVisitor)} */
void visitAlternateConstructorInvocation(Java.AlternateConstructorInvocation aci);
/** Invoked by {@link Java.SuperConstructorInvocation#accept(Visitor.BlockStatementVisitor)} */
void visitSuperConstructorInvocation(Java.SuperConstructorInvocation sci);
}
/** The visitor for all kinds of {@link Java.Atom}s. */
public
interface AtomVisitor extends RvalueVisitor, TypeVisitor {
/** Invoked by {@link Java.Package#accept(Visitor.AtomVisitor)}. */
void visitPackage(Java.Package p);
}
/** The visitor for all kinds of {@link Java.Type}s. */
public
interface TypeVisitor {
/** Invoked by {@link Java.ArrayType#accept(Visitor.TypeVisitor)} */
void visitArrayType(Java.ArrayType at);
/** Invoked by {@link Java.BasicType#accept(Visitor.TypeVisitor)} */
void visitBasicType(Java.BasicType bt);
/** Invoked by {@link Java.ReferenceType#accept(Visitor.TypeVisitor)} */
void visitReferenceType(Java.ReferenceType rt);
/** Invoked by {@link Java.RvalueMemberType#accept(Visitor.TypeVisitor)} */
void visitRvalueMemberType(Java.RvalueMemberType rmt);
/** Invoked by {@link Java.SimpleType#accept(Visitor.TypeVisitor)} */
void visitSimpleType(Java.SimpleType st);
}
/** The visitor for all kinds of {@link Java.Rvalue}s. */
public
interface RvalueVisitor extends LvalueVisitor {
/** Invoked by {@link Java.ArrayLength#accept(Visitor.RvalueVisitor)} */
void visitArrayLength(Java.ArrayLength al);
/** Invoked by {@link Java.Assignment#accept(Visitor.RvalueVisitor)} */
void visitAssignment(Java.Assignment a);
/** Invoked by {@link Java.UnaryOperation#accept(Visitor.RvalueVisitor)} */
void visitUnaryOperation(Java.UnaryOperation uo);
/** Invoked by {@link Java.BinaryOperation#accept(Visitor.RvalueVisitor)} */
void visitBinaryOperation(Java.BinaryOperation bo);
/** Invoked by {@link Java.Cast#accept(Visitor.RvalueVisitor)} */
void visitCast(Java.Cast c);
/** Invoked by {@link Java.ClassLiteral#accept(Visitor.RvalueVisitor)} */
void visitClassLiteral(Java.ClassLiteral cl);
/** Invoked by {@link Java.ConditionalExpression#accept(Visitor.RvalueVisitor)} */
void visitConditionalExpression(Java.ConditionalExpression ce);
/** Invoked by {@link Java.Crement#accept(Visitor.RvalueVisitor)} */
void visitCrement(Java.Crement c);
/** Invoked by {@link Java.Instanceof#accept(Visitor.RvalueVisitor)} */
void visitInstanceof(Java.Instanceof io);
/** Invoked by {@link Java.MethodInvocation#accept(Visitor.RvalueVisitor)} */
void visitMethodInvocation(Java.MethodInvocation mi);
/** Invoked by {@link Java.SuperclassMethodInvocation#accept(Visitor.RvalueVisitor)} */
void visitSuperclassMethodInvocation(Java.SuperclassMethodInvocation smi);
/** Invoked by {@link Java.IntegerLiteral#accept(Visitor.RvalueVisitor)} */
void visitIntegerLiteral(Java.IntegerLiteral il);
/** Invoked by {@link Java.FloatingPointLiteral#accept(Visitor.RvalueVisitor)} */
void visitFloatingPointLiteral(Java.FloatingPointLiteral fpl);
/** Invoked by {@link Java.BooleanLiteral#accept(Visitor.RvalueVisitor)} */
void visitBooleanLiteral(Java.BooleanLiteral bl);
/** Invoked by {@link Java.CharacterLiteral#accept(Visitor.RvalueVisitor)} */
void visitCharacterLiteral(Java.CharacterLiteral cl);
/** Invoked by {@link Java.StringLiteral#accept(Visitor.RvalueVisitor)} */
void visitStringLiteral(Java.StringLiteral sl);
/** Invoked by {@link Java.NullLiteral#accept(Visitor.RvalueVisitor)} */
void visitNullLiteral(Java.NullLiteral nl);
/** Invoked by {@link Java.SimpleConstant#accept(Visitor.RvalueVisitor)} */
void visitSimpleConstant(Java.SimpleConstant sl);
/** Invoked by {@link Java.NewAnonymousClassInstance#accept(Visitor.RvalueVisitor)} */
void visitNewAnonymousClassInstance(Java.NewAnonymousClassInstance naci);
/** Invoked by {@link Java.NewArray#accept(Visitor.RvalueVisitor)} */
void visitNewArray(Java.NewArray na);
/** Invoked by {@link Java.NewInitializedArray#accept(Visitor.RvalueVisitor)} */
void visitNewInitializedArray(Java.NewInitializedArray nia);
/** Invoked by {@link Java.NewClassInstance#accept(Visitor.RvalueVisitor)} */
void visitNewClassInstance(Java.NewClassInstance nci);
/** Invoked by {@link Java.ParameterAccess#accept(Visitor.RvalueVisitor)} */
void visitParameterAccess(Java.ParameterAccess pa);
/** Invoked by {@link Java.QualifiedThisReference#accept(Visitor.RvalueVisitor)} */
void visitQualifiedThisReference(Java.QualifiedThisReference qtr);
/** Invoked by {@link Java.ArrayLength#accept(Visitor.RvalueVisitor)} */
void visitThisReference(Java.ThisReference tr);
}
/** The visitor for all kinds of {@link Java.Lvalue}s. */
public
interface LvalueVisitor {
/** Invoked by {@link Java.AmbiguousName#accept(Visitor.LvalueVisitor)} */
void visitAmbiguousName(Java.AmbiguousName an);
/** Invoked by {@link Java.ArrayAccessExpression#accept(Visitor.LvalueVisitor)} */
void visitArrayAccessExpression(Java.ArrayAccessExpression aae);
/** Invoked by {@link Java.FieldAccess#accept(Visitor.LvalueVisitor)} */
void visitFieldAccess(Java.FieldAccess fa);
/** Invoked by {@link Java.FieldAccessExpression#accept(Visitor.LvalueVisitor)} */
void visitFieldAccessExpression(Java.FieldAccessExpression fae);
/** Invoked by {@link Java.SuperclassFieldAccessExpression#accept(Visitor.LvalueVisitor)} */
void visitSuperclassFieldAccessExpression(Java.SuperclassFieldAccessExpression scfae);
/** Invoked by {@link Java.LocalVariableAccess#accept(Visitor.LvalueVisitor)} */
void visitLocalVariableAccess(Java.LocalVariableAccess lva);
/** Invoked by {@link Java.ParenthesizedExpression#accept(Visitor.LvalueVisitor)} */
void visitParenthesizedExpression(Java.ParenthesizedExpression pe);
}
/** The visitor for all kinds of {@link Java.Annotation}s. */
public
interface AnnotationVisitor {
/** Invoked by {@link Java.MarkerAnnotation#accept(Visitor.AnnotationVisitor)} */
void visitMarkerAnnotation(Java.MarkerAnnotation ma);
/** Invoked by {@link Java.NormalAnnotation#accept(Visitor.AnnotationVisitor)} */
void visitNormalAnnotation(Java.NormalAnnotation na);
/** Invoked by {@link Java.SingleElementAnnotation#accept(Visitor.AnnotationVisitor)} */
void visitSingleElementAnnotation(Java.SingleElementAnnotation sea);
}
/** The visitor for all kinds of {@link Java.ElementValue}s. */
public
interface ElementValueVisitor extends RvalueVisitor, AnnotationVisitor {
/** Invoked by {@link Java.ElementValueArrayInitializer#accept(Visitor.ElementValueVisitor)} */
void visitElementValueArrayInitializer(Java.ElementValueArrayInitializer evai);
}
/** The visitor for all kinds of {@link Java.TypeArgument}s. */
public
interface TypeArgumentVisitor {
/** Invoked by {@link Java.Wildcard#accept(Visitor.TypeArgumentVisitor)} */
void visitWildcard(Java.Wildcard w);
/** Invoked by {@link Java.ReferenceType#accept(Visitor.TypeArgumentVisitor)} */
void visitReferenceType(Java.ReferenceType rt);
/** Invoked by {@link Java.ArrayType#accept(Visitor.TypeArgumentVisitor)} */
void visitArrayType(Java.ArrayType arrayType);
}
}

View File

@ -1,35 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2013, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* The classes in this package pose the core of the Janino Java<sup>TM</sup> compiler.
* <p>
* The package comprises a scanner ({@link org.codehaus.janino.Scanner}, a parser ({@link org.codehaus.janino.Parser})
* and a class file library. The parser builds a syntax tree from the "Java.*" classes that represents the parsed code.
* The {@link org.codehaus.janino.UnitCompiler#compileUnit} method compiles this syntax tree into a {@link
* org.codehaus.janino.util.ClassFile} object, which can write Java<sup>TM</sup> bytecode to an "OutputStream".
*/
package org.codehaus.janino;

View File

@ -1,101 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino.samples;
import java.io.FileReader;
import java.io.IOException;
import org.codehaus.commons.compiler.CompileException;
import org.codehaus.janino.Java;
import org.codehaus.janino.Parser;
import org.codehaus.janino.Scanner;
import org.codehaus.janino.util.Traverser;
/**
* An example application for the {@link org.codehaus.janino.util.Traverser}:
* Reads, scans and parses the files named on the command line and counts
* several kinds of declarations.
*/
public
class DeclarationCounter extends Traverser {
public static void // SUPPRESS CHECKSTYLE JavadocMethod
main(String[] args) throws CompileException, IOException {
DeclarationCounter dc = new DeclarationCounter();
for (String fileName : args) {
// Parse each compilation unit.
FileReader r = new FileReader(fileName);
Java.CompilationUnit cu;
try {
cu = new Parser(new Scanner(fileName, r)).parseCompilationUnit();
} finally {
r.close();
}
// Traverse it and count declarations.
dc.traverseCompilationUnit(cu);
}
System.out.println("Class declarations: " + dc.classDeclarationCount);
System.out.println("Interface declarations: " + dc.interfaceDeclarationCount);
System.out.println("Fields: " + dc.fieldCount);
System.out.println("Local variables: " + dc.localVariableCount);
}
// Count class declarations.
@Override public void
traverseClassDeclaration(Java.ClassDeclaration cd) {
++this.classDeclarationCount;
super.traverseClassDeclaration(cd);
}
private int classDeclarationCount;
// Count interface declarations.
@Override public void
traverseInterfaceDeclaration(Java.InterfaceDeclaration id) {
++this.interfaceDeclarationCount;
super.traverseInterfaceDeclaration(id);
}
private int interfaceDeclarationCount;
// Count fields.
@Override public void
traverseFieldDeclaration(Java.FieldDeclaration fd) {
this.fieldCount += fd.variableDeclarators.length;
super.traverseFieldDeclaration(fd);
}
private int fieldCount;
// Count local variables.
@Override public void
traverseLocalVariableDeclarationStatement(Java.LocalVariableDeclarationStatement lvds) {
this.localVariableCount += lvds.variableDeclarators.length;
super.traverseLocalVariableDeclarationStatement(lvds);
}
private int localVariableCount;
}

View File

@ -1,28 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2013, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/** Sample applications for the Janino Java<sup>TM</sup> compiler. */
package org.codehaus.janino.samples;

View File

@ -1,257 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino.tools;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.text.FieldPosition;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
/**
* Example for object allocation statistics:
*
* java -Xrunhprof:heap=sites,monitor=n,cutoff=0,depth=4 MyClass
*/
@SuppressWarnings({ "rawtypes", "unchecked" }) public final
class HprofScrubber {
private HprofScrubber() {}
private static
class Site {
public final int allocatedBytes;
public final int allocatedObjects;
public final int traceNumber;
public final String className;
public
Site(int allocatedBytes, int allocatedObjects, int traceNumber, String className) {
this.allocatedBytes = allocatedBytes;
this.allocatedObjects = allocatedObjects;
this.traceNumber = traceNumber;
this.className = className;
}
}
private static
class Sample {
public final int count;
public final int traceNumber;
public
Sample(int count, int traceNumber) {
this.count = count;
this.traceNumber = traceNumber;
}
}
public static void // SUPPRESS CHECKSTYLE JavadocMethod
main(String[] args) throws Exception {
String fileName = args.length == 0 ? "java.hprof.txt" : args[0];
BufferedReader br = new BufferedReader(new FileReader(fileName));
try {
Map<Integer /*number*/, String[] /*stackFrames*/> traces = new HashMap();
List<Site> sites = new ArrayList();
List<Sample> samples = new ArrayList();
String s = br.readLine();
while (s != null) {
if (s.startsWith("SITES BEGIN")) {
br.readLine();
br.readLine();
for (;;) {
s = br.readLine();
if (s.startsWith("SITES END")) break;
StringTokenizer st = new StringTokenizer(s);
st.nextToken(); // rank
st.nextToken(); // percent self
st.nextToken(); // percent accum
st.nextToken(); // live bytes
st.nextToken(); // live objects
sites.add(new Site(
Integer.parseInt(st.nextToken()), // allocatedBytes
Integer.parseInt(st.nextToken()), // allocatedObjects
Integer.parseInt(st.nextToken()), // traceNumber
st.nextToken() // className
));
}
} else
if (s.startsWith("TRACE ") && s.endsWith(":")) {
int traceNumber = Integer.parseInt(s.substring(6, s.length() - 1));
List<String> l = new ArrayList();
for (;;) {
s = br.readLine();
if (!s.startsWith("\t")) break;
l.add(s.substring(1));
}
traces.put(
new Integer(traceNumber),
(String[]) l.toArray(new String[l.size()])
);
} else
if (s.startsWith("CPU SAMPLES BEGIN")) {
br.readLine();
for (;;) {
s = br.readLine();
if (s.startsWith("CPU SAMPLES END")) break;
StringTokenizer st = new StringTokenizer(s);
st.nextToken(); // rank
st.nextToken(); // percent self
st.nextToken(); // percent accum
int count = Integer.parseInt(st.nextToken());
if (count == 0) continue;
int trace = Integer.parseInt(st.nextToken());
samples.add(new Sample(count, trace));
}
} else {
s = br.readLine();
}
}
HprofScrubber.dumpSites((Site[]) sites.toArray(new Site[sites.size()]), traces);
HprofScrubber.dumpSamples((Sample[]) samples.toArray(new Sample[samples.size()]), traces);
} finally {
try { br.close(); } catch (IOException e) {}
}
}
private static void
dumpSites(Site[] ss, Map<Integer, String[]> traces) {
Arrays.sort(ss, new Comparator() {
@Override public int
compare(Object o1, Object o2) { return ((Site) o2).allocatedBytes - ((Site) o1).allocatedBytes; }
});
int totalAllocatedBytes = 0, totalAllocatedObjects = 0;
for (Site site : ss) {
totalAllocatedBytes += site.allocatedBytes;
totalAllocatedObjects += site.allocatedObjects;
}
System.out.println(" percent alloc'ed");
System.out.println("rank self accum bytes objects class name");
System.out.println("Total: " + totalAllocatedBytes + " " + totalAllocatedObjects);
double accumulatedPercentage = 0.0;
MessageFormat mf = new MessageFormat(
"{0,number,00000} {1,number,00.00}% {2,number,00.00}% {3,number,000000000} {4,number,000000000} {5}"
);
for (int i = 0; i < ss.length; ++i) {
Site site = ss[i];
double selfPercentage = 100.0 * ((double) site.allocatedBytes / (double) totalAllocatedBytes);
accumulatedPercentage += selfPercentage;
// System.out.println(
// (i + 1)
// + " "
// + selfPercentage
// + "% "
// + accumulatedPercentage
// + "% "
// + site.allocatedBytes
// + " "
// + site.allocatedObjects
// + " "
// + site.className
// );
System.out.println(mf.format(
new Object[] {
new Integer(i + 1),
new Double(selfPercentage),
new Double(accumulatedPercentage),
new Integer(site.allocatedBytes),
new Integer(site.allocatedObjects),
site.className
},
new StringBuffer(),
new FieldPosition(0)
));
String[] stackFrames = (String[]) traces.get(new Integer(site.traceNumber));
if (stackFrames != null) {
for (String stackFrame : stackFrames) {
System.out.println(" " + stackFrame);
}
}
}
}
private static void
dumpSamples(Sample[] ss, Map<Integer, String[]> traces) {
int totalCount = 0;
for (Sample s : ss) totalCount += s.count;
System.out.println(" percent");
System.out.println("rank self accum count");
System.out.println("Total: " + totalCount);
double accumulatedPercentage = 0.0;
MessageFormat mf = new MessageFormat(
"{0,number,00000} {1,number,00.00}% {2,number,00.00}% {3,number,000000000}"
);
for (int i = 0; i < ss.length; ++i) {
Sample sample = ss[i];
double selfPercentage = 100.0 * ((double) sample.count / (double) totalCount);
accumulatedPercentage += selfPercentage;
// System.out.println(
// (i + 1)
// + " "
// + selfPercentage
// + "% "
// + accumulatedPercentage
// + "% "
// + sample.count
// + " "
// + sample.traceNumber
// );
System.out.println(mf.format(
new Object[] {
new Integer(i + 1),
new Double(selfPercentage),
new Double(accumulatedPercentage),
new Integer(sample.count)
},
new StringBuffer(),
new FieldPosition(0)
));
String[] stackFrames = (String[]) traces.get(new Integer(sample.traceNumber));
if (stackFrames != null) {
for (String stackFrame : stackFrames) System.out.println(" " + stackFrame);
}
}
}
}

View File

@ -1,714 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino.tools;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.codehaus.commons.compiler.CompileException;
import org.codehaus.commons.compiler.CompilerFactoryFactory;
import org.codehaus.commons.compiler.ICompilerFactory;
import org.codehaus.commons.compiler.IExpressionEvaluator;
import org.codehaus.commons.compiler.UncheckedCompileException;
import org.codehaus.janino.Descriptor;
import org.codehaus.janino.ExpressionEvaluator;
import org.codehaus.janino.IClass;
import org.codehaus.janino.IClassLoader;
import org.codehaus.janino.Java;
import org.codehaus.janino.Java.CompilationUnit;
import org.codehaus.janino.Parser;
import org.codehaus.janino.Scanner;
import org.codehaus.janino.UnitCompiler;
import org.codehaus.janino.util.Benchmark;
import org.codehaus.janino.util.ClassFile;
import org.codehaus.janino.util.StringPattern;
import org.codehaus.janino.util.Traverser;
import org.codehaus.janino.util.enumerator.Enumerator;
import org.codehaus.janino.util.iterator.DirectoryIterator;
import org.codehaus.janino.util.resource.PathResourceFinder;
/**
* Reads a set of compilation units from the file system and searches it for specific
* Java&trade; constructs, e.g. invocations of a particular method.
*
* Usage:
* <pre>
* java org.codehaus.janino.JGrep \
* [ -dirs <i>directory-name-patterns</i> ] \
* [ -files <i>file-name-patterns</i> ] \
* { <i>directory-path</i> } \
* -method-invocation <i>class.method(arg-types)</i>
* java org.codehaus.janino.JGrep -help
* </pre>
*
* If "-dirs" is not given, then all <i>directory-path</i>es are scanned for files.
* The <i>directory-name-patterns</i> work as described in
* {@link org.codehaus.janino.util.StringPattern#parseCombinedPattern(String)}.
* <p>
* If "-files" is not given, then all files ending in ".java" are read. The
* <i>file-name-patterns</i> work as described in
* {@link org.codehaus.janino.util.StringPattern#parseCombinedPattern(String)}.
*/
@SuppressWarnings({ "rawtypes", "unchecked" }) public // SUPPRESS CHECKSTYLE HideUtilityClassConstructor
class JGrep {
private static final boolean DEBUG = false;
private final List<UnitCompiler> parsedCompilationUnits = new ArrayList();
/** Command line interface. */
public static void
main(String[] args) {
int idx = 0;
StringPattern[] directoryNamePatterns = StringPattern.PATTERNS_ALL;
StringPattern[] fileNamePatterns = new StringPattern[] { new StringPattern("*.java") };
File[] classPath = new File[] { new File(".") };
File[] optionalExtDirs = null;
File[] optionalBootClassPath = null;
String optionalCharacterEncoding = null;
boolean verbose = false;
for (; idx < args.length; ++idx) {
String arg = args[idx];
if (arg.charAt(0) != '-') break;
if ("-dirs".equals(arg)) {
directoryNamePatterns = StringPattern.parseCombinedPattern(args[++idx]);
} else
if ("-files".equals(arg)) {
fileNamePatterns = StringPattern.parseCombinedPattern(args[++idx]);
} else
if ("-classpath".equals(arg)) {
classPath = PathResourceFinder.parsePath(args[++idx]);
} else
if ("-extdirs".equals(arg)) {
optionalExtDirs = PathResourceFinder.parsePath(args[++idx]);
} else
if ("-bootclasspath".equals(arg)) {
optionalBootClassPath = PathResourceFinder.parsePath(args[++idx]);
} else
if ("-encoding".equals(arg)) {
optionalCharacterEncoding = args[++idx];
} else
if ("-verbose".equals(arg)) {
verbose = true;
} else
if ("-help".equals(arg)) {
for (String s : JGrep.USAGE) System.out.println(s);
System.exit(1);
} else
{
System.err.println("Unexpected command-line argument \"" + arg + "\", try \"-help\".");
System.exit(1);
return; /* NEVER REACHED */
}
}
// { directory-path }
File[] rootDirectories;
{
int first = idx;
for (; idx < args.length && args[idx].charAt(0) != '-'; ++idx);
if (idx == first) {
System.err.println("No <directory-path>es given, try \"-help\".");
System.exit(1);
return; /* NEVER REACHED */
}
rootDirectories = new File[idx - first];
for (int i = first; i < idx; ++i) rootDirectories[i - first] = new File(args[i]);
}
// Create the JGrep object.
final JGrep jGrep = new JGrep(
classPath,
optionalExtDirs,
optionalBootClassPath,
optionalCharacterEncoding,
verbose
);
List<MethodInvocationTarget> mits = new ArrayList();
for (; idx < args.length; ++idx) {
String arg = args[idx];
if ("-method-invocation".equals(arg)) {
MethodInvocationTarget mit;
try {
mit = JGrep.parseMethodInvocationPattern(args[++idx]);
} catch (Exception ex) {
System.err.println("Parsing method invocation pattern \"" + args[idx] + "\": " + ex.getMessage());
System.exit(1);
return; /* NEVER REACHED */
}
while (idx < args.length - 1) {
arg = args[idx + 1];
if (arg.startsWith("predicate:")) {
String predicateExpression = arg.substring(10);
try {
IExpressionEvaluator ee = new ExpressionEvaluator();
ee.setClassName(JGrep.class.getName() + "PE");
mit.predicates.add((MethodInvocationPredicate) ee.createFastEvaluator(
predicateExpression,
MethodInvocationPredicate.class,
new String[] { "uc", "invocation", "method" }
));
} catch (Exception ex) {
System.err.println(
"Compiling predicate expression \""
+ predicateExpression
+ "\": "
+ ex.getMessage()
);
System.exit(1);
return; /* NEVER REACHED */
}
} else
if (arg.startsWith("action:")) {
String action = arg.substring(7);
try {
mit.actions.add(Action.getMethodInvocationAction(action));
} catch (Exception ex) {
System.err.println(
"Compiling method invocation action \""
+ action
+ "\": "
+ ex.getMessage()
);
System.exit(1);
return; /* NEVER REACHED */
}
} else
{
break;
}
++idx;
}
mits.add(mit);
} else
{
System.err.println("Unexpected command-line argument \"" + arg + "\", try \"-help\".");
System.exit(1);
return; /* NEVER REACHED */
}
}
// JGrep the root directories.
try {
jGrep.jGrep(
rootDirectories,
directoryNamePatterns,
fileNamePatterns,
mits // methodInvocationTargets
);
} catch (Exception e) {
System.err.println(e.toString());
System.exit(1);
}
}
private static final
class Action extends Enumerator {
private Action(String name) { super(name); }
static MethodInvocationAction
getMethodInvocationAction(String action) throws CompileException {
if ("print-location-and-match".equals(action)) {
return new MethodInvocationAction() {
@Override public void
execute(UnitCompiler uc, Java.Invocation invocation, IClass.IMethod method) {
System.out.println(invocation.getLocation() + ": " + method);
}
};
} else
if ("print-location".equals(action)) {
return new MethodInvocationAction() {
@Override public void
execute(UnitCompiler uc, Java.Invocation invocation, IClass.IMethod method) {
System.out.println(invocation.getLocation());
}
};
} else
{
ICompilerFactory cf;
try {
cf = CompilerFactoryFactory.getDefaultCompilerFactory();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e.getMessage()); // SUPPRESS CHECKSTYLE AvoidHidingCause
}
return (MethodInvocationAction) cf.newScriptEvaluator().createFastEvaluator(
action, // script
MethodInvocationAction.class, // interfaceToImplement
new String[] { "uc", "invocation", "method" } // parameterNames
);
}
}
}
private static MethodInvocationTarget
parseMethodInvocationPattern(String mip) throws CompileException, IOException {
MethodInvocationTarget mit = new MethodInvocationTarget();
Scanner scanner = new Scanner(null, new StringReader(mip));
Parser parser = new Parser(scanner);
for (;;) {
String s = JGrep.readIdentifierPattern(parser);
if (parser.peekRead("(")) {
mit.methodNamePattern = s;
List<String> l = new ArrayList();
if (!parser.peekRead(")")) {
for (;;) {
l.add(JGrep.readIdentifierPattern(parser));
if (parser.peek(")")) break;
parser.read(",");
}
}
mit.optionalArgumentTypeNamePatterns = (String[]) l.toArray(new String[l.size()]);
return mit;
} else
if (parser.peekRead(".")) {
if (mit.optionalClassNamePattern == null) {
mit.optionalClassNamePattern = s;
} else
{
mit.optionalClassNamePattern += '.' + s;
}
} else
if (parser.peekEof()) {
mit.methodNamePattern = s;
return mit;
}
}
}
private static String
readIdentifierPattern(Parser p) throws CompileException, IOException {
StringBuilder sb = new StringBuilder();
if (p.peekRead("*")) {
sb.append('*');
} else
{
sb.append(p.readIdentifier());
}
for (;;) {
if (p.peekRead("*")) {
sb.append('*');
} else
if (p.peekIdentifier() != null) {
sb.append(p.readIdentifier());
} else
{
return sb.toString();
}
}
}
private static
class MethodInvocationTarget {
String optionalClassNamePattern;
String methodNamePattern;
String[] optionalArgumentTypeNamePatterns;
List<MethodInvocationPredicate> predicates = new ArrayList();
List<MethodInvocationAction> actions = new ArrayList();
void
apply(UnitCompiler uc, Java.Invocation invocation, IClass.IMethod method) throws CompileException {
// Verify that the class declaring the invoked method matches.
if (this.optionalClassNamePattern != null) {
if (!JGrep.typeMatches(
this.optionalClassNamePattern,
Descriptor.toClassName(method.getDeclaringIClass().getDescriptor())
)) return;
}
// Verify that the name of the invoked method matches.
if (!new StringPattern(this.methodNamePattern).matches(method.getName())) return;
// Verify that the parameter count and types of the invoked method match.
IClass[] fpts = method.getParameterTypes();
if (this.optionalArgumentTypeNamePatterns != null) {
String[] atnps = this.optionalArgumentTypeNamePatterns;
if (atnps.length != fpts.length) return;
for (int i = 0; i < atnps.length; ++i) {
if (!new StringPattern(atnps[i]).matches(Descriptor.toClassName(fpts[i].getDescriptor()))) return;
}
}
// Verify that all predicates (JANINO expressions) return TRUE.
for (MethodInvocationPredicate mip : this.predicates) {
try {
if (!mip.evaluate(uc, invocation, method)) return;
} catch (Exception ex) {
return; // Treat exception as a "false" predicate.
}
}
// Now that all checks were successful, execute all method invocation actions.
for (MethodInvocationAction mia : this.actions) {
try {
mia.execute(uc, invocation, method);
} catch (Exception ex) {
; // Ignore action throwing an exception.
}
}
}
}
/** A predicate that examines a method invocation. */
interface MethodInvocationPredicate {
/** @return Whether the method incovation met some criterion */
boolean evaluate(UnitCompiler uc, Java.Invocation invocation, IClass.IMethod method) throws Exception;
}
/** An entity that does something with a method invocation, e.g. report where it occurred. */
interface MethodInvocationAction {
/** Executes some action for a method invocation. */
void execute(UnitCompiler uc, Java.Invocation invocation, IClass.IMethod method) throws Exception;
}
/**
* @return Whether the fully qualified {@code typeName} matches the {@code pattern}, or, iff the pattern does not
* contain a period, the simple type name of {@code typeName} matches the {@code pattern}
*/
static boolean
typeMatches(String pattern, String typeName) {
return new StringPattern(pattern).matches(
pattern.indexOf('.') == -1
? typeName.substring(typeName.lastIndexOf('.') + 1)
: typeName
);
}
private static final String[] USAGE = {
"Usage:",
"",
" java org.codehaus.janino.tools.JGrep [ <option> ... ] <root-dir> ... <pattern> ...",
" java org.codehaus.janino.tools.JGrep -help",
"",
"Reads a set of compilation units from the files in the <root-dir>s and their",
"subdirectories and searches them for specific Java[TM] constructs, e.g.",
"invocations of a particular method.",
"",
"Supported <option>s are ('cp' is a 'combined pattern, like '*.java-*Generated*'):",
" -dirs <dir-cp> Ignore subdirectories which don't match",
" -files <file-cp> Include only matching files (default is '*.java')",
" -classpath <classpath>",
" -extdirs <classpath>",
" -bootclasspath <classpath>",
" -encoding <encoding>",
" -verbose",
"",
"Supported <pattern>s are:",
" -method-invocation <method-pattern> [ predicate:<predicate-expression> | action:<action-script> ] ...",
"<method-pattern> is ('<ip>' is an 'identifier pattern' like '*foo*'):",
" -method-invocation <method-ip>",
" -method-invocation <simple-class-ip>.<method-ip>",
" -method-invocation <fully-qualified-class-ip>.<method-ip>",
" -method-invocation <method-ip>([<parameter-ip>[,<parameter-ip>]...])",
"",
"<predicate-expression> is a Java[TM] expression with the following signature:",
" boolean evaluate(UnitCompiler uc, Java.Invocation invocation, IClass.IMethod method)",
"",
"<action-script> is either",
" print-location-and-match",
" print-location",
", or a Java[TM] script (method body) with the following signature:",
" void execute(UnitCompiler uc, Java.Invocation invocation, IClass.IMethod method)",
};
private final IClassLoader iClassLoader;
private final String optionalCharacterEncoding;
private final Benchmark benchmark;
public
JGrep(
File[] classPath,
File[] optionalExtDirs,
File[] optionalBootClassPath,
String optionalCharacterEncoding,
boolean verbose
) {
this(
org.codehaus.janino.IClassLoader.createJavacLikePathIClassLoader( // iClassLoader
optionalBootClassPath,
optionalExtDirs,
classPath
),
optionalCharacterEncoding, // optionalCharacterEncoding
verbose // verbose
);
this.benchmark.report("*** JGrep - search Java(TM) source files for specific language constructs");
this.benchmark.report("*** For more information visit http://janino.codehaus.org");
this.benchmark.report("Class path", classPath);
this.benchmark.report("Ext dirs", optionalExtDirs);
this.benchmark.report("Boot class path", optionalBootClassPath);
this.benchmark.report("Character encoding", optionalCharacterEncoding);
}
public
JGrep(IClassLoader iClassLoader, final String optionalCharacterEncoding, boolean verbose) {
this.iClassLoader = new JGrepIClassLoader(iClassLoader);
this.optionalCharacterEncoding = optionalCharacterEncoding;
this.benchmark = new Benchmark(verbose);
}
private void
jGrep(
File[] rootDirectories,
final StringPattern[] directoryNamePatterns,
final StringPattern[] fileNamePatterns,
List<MethodInvocationTarget> methodInvocationTargets
) throws CompileException, IOException {
this.benchmark.report("Root dirs", rootDirectories);
this.benchmark.report("Directory name patterns", directoryNamePatterns);
this.benchmark.report("File name patterns", fileNamePatterns);
this.jGrep(DirectoryIterator.traverseDirectories(
rootDirectories, // rootDirectories
new FilenameFilter() { // directoryNameFilter
@Override public boolean
accept(File dir, String name) { return StringPattern.matches(directoryNamePatterns, name); }
},
new FilenameFilter() { // fileNameFilter
@Override public boolean
accept(File dir, String name) { return StringPattern.matches(fileNamePatterns, name); }
}
), methodInvocationTargets);
}
private void
jGrep(Iterator<File> sourceFilesIterator, final List<MethodInvocationTarget> methodInvocationTargets)
throws CompileException, IOException {
// Parse the given source files.
this.benchmark.beginReporting();
int sourceFileCount = 0;
try {
// Parse all source files.
while (sourceFilesIterator.hasNext()) {
File sourceFile = (File) sourceFilesIterator.next();
UnitCompiler uc = new UnitCompiler(this.parseCompilationUnit(
sourceFile, // sourceFile
this.optionalCharacterEncoding // optionalCharacterEncoding
), this.iClassLoader);
this.parsedCompilationUnits.add(uc);
++sourceFileCount;
}
} finally {
this.benchmark.endReporting("Parsed " + sourceFileCount + " source file(s)");
}
// Traverse the parsed compilation units.
this.benchmark.beginReporting();
try {
for (final UnitCompiler unitCompiler : this.parsedCompilationUnits) {
CompilationUnit compilationUnit = unitCompiler.getCompilationUnit();
this.benchmark.beginReporting("Grepping \"" + compilationUnit.optionalFileName + "\"");
try {
new Traverser() {
// "method(...)", "x.method(...)"
@Override public void
traverseMethodInvocation(Java.MethodInvocation mi) {
try {
this.match(mi, unitCompiler.findIMethod(mi));
} catch (CompileException ex) {
throw new UncheckedCompileException(ex);
}
super.traverseMethodInvocation(mi);
}
// "super.method(...)"
@Override public void
traverseSuperclassMethodInvocation(Java.SuperclassMethodInvocation scmi) {
try {
this.match(scmi, unitCompiler.findIMethod(scmi));
} catch (CompileException ex) {
throw new UncheckedCompileException(ex);
}
super.traverseSuperclassMethodInvocation(scmi);
}
// new Xyz(...)
@Override public void
traverseNewClassInstance(Java.NewClassInstance nci) {
// System.out.println(nci.getLocation() + ": " + nci);
super.traverseNewClassInstance(nci);
}
// new Xyz(...) {}
@Override public void
traverseNewAnonymousClassInstance(Java.NewAnonymousClassInstance naci) {
// System.out.println(naci.getLocation() + ": " + naci);
super.traverseNewAnonymousClassInstance(naci);
}
// Explicit constructor invocation ("this(...)", "super(...)").
@Override public void
traverseConstructorInvocation(Java.ConstructorInvocation ci) {
// System.out.println(ci.getLocation() + ": " + ci);
super.traverseConstructorInvocation(ci);
}
private void
match(Java.Invocation invocation, IClass.IMethod method) throws CompileException {
for (MethodInvocationTarget mit : methodInvocationTargets) {
mit.apply(unitCompiler, invocation, method);
}
}
}.traverseCompilationUnit(compilationUnit);
} catch (UncheckedCompileException uce) {
throw uce.compileException; // SUPPRESS CHECKSTYLE AvoidHidingCause
} finally {
this.benchmark.endReporting();
}
}
} finally {
this.benchmark.endReporting("Traversed " + sourceFileCount + " compilation units");
}
}
/**
* Read one compilation unit from a file and parse it.
* <p>
* The <code>inputStream</code> is closed before the method returns.
* @return the parsed compilation unit
*/
private Java.CompilationUnit
parseCompilationUnit(File sourceFile, String optionalCharacterEncoding) throws CompileException, IOException {
InputStream is = new BufferedInputStream(new FileInputStream(sourceFile));
try {
Parser parser = new Parser(new Scanner(sourceFile.getPath(), is, optionalCharacterEncoding));
this.benchmark.beginReporting("Parsing \"" + sourceFile + "\"");
try {
return parser.parseCompilationUnit();
} finally {
this.benchmark.endReporting();
}
} finally {
try { is.close(); } catch (IOException ex) {}
}
}
/**
* Construct the name of a file that could store the byte code of the class with the given
* name.
* <p>
* If <code>optionalDestinationDirectory</code> is non-null, the returned path is the
* <code>optionalDestinationDirectory</code> plus the package of the class (with dots replaced
* with file separators) plus the class name plus ".class". Example:
* "destdir/pkg1/pkg2/Outer$Inner.class"
* <p>
* If <code>optionalDestinationDirectory</code> is null, the returned path is the
* directory of the <code>sourceFile</code> plus the class name plus ".class". Example:
* "srcdir/Outer$Inner.class"
* @param className E.g. "pkg1.pkg2.Outer$Inner"
* @param sourceFile E.g. "srcdir/Outer.java"
* @param optionalDestinationDirectory E.g. "destdir"
*/
public static File
getClassFile(String className, File sourceFile, File optionalDestinationDirectory) {
if (optionalDestinationDirectory != null) {
return new File(optionalDestinationDirectory, ClassFile.getClassFileResourceName(className));
} else {
int idx = className.lastIndexOf('.');
return new File(
sourceFile.getParentFile(),
ClassFile.getClassFileResourceName(className.substring(idx + 1))
);
}
}
/**
* A specialized {@link IClassLoader} that loads {@link IClass}es from the following
* sources:
* <ol>
* <li>An already-parsed compilation unit
* <li>A class file in the output directory (if existant and younger than source file)
* <li>A source file in any of the source path directories
* <li>The parent class loader
* </ol>
* Notice that the {@link JGrepIClassLoader} is an inner class of {@link JGrep} and
* heavily uses {@link JGrep}'s members.
*/
private
class JGrepIClassLoader extends IClassLoader {
/**
* @param optionalParentIClassLoader The {@link IClassLoader} through which {@link IClass}es are to be loaded
*/
public
JGrepIClassLoader(IClassLoader optionalParentIClassLoader) {
super(optionalParentIClassLoader);
super.postConstruct();
}
/** @param type Field descriptor of the {@IClass} to load, e.g. "Lpkg1/pkg2/Outer$Inner;" */
@Override protected IClass
findIClass(final String type) {
if (JGrep.DEBUG) System.out.println("type = " + type);
// Class type.
String className = Descriptor.toClassName(type); // E.g. "pkg1.pkg2.Outer$Inner"
if (JGrep.DEBUG) System.out.println("2 className = \"" + className + "\"");
// Do not attempt to load classes from package "java".
if (className.startsWith("java.")) return null;
// Check the already-parsed compilation units.
for (int i = 0; i < JGrep.this.parsedCompilationUnits.size(); ++i) {
UnitCompiler uc = (UnitCompiler) JGrep.this.parsedCompilationUnits.get(i);
IClass res = uc.findClass(className);
if (res != null) {
this.defineIClass(res);
return res;
}
}
return null;
}
}
}

View File

@ -1,28 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2013, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/** Auxiliary command line tools related to JANINO. */
package org.codehaus.janino.tools;

View File

@ -1,251 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino.util;
import java.io.FilterWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
/**
* A {@link java.io.FilterWriter} that automatically indents lines by looking at
* trailing opening braces ('{') and leading closing braces ('}').
*/
@SuppressWarnings({ "rawtypes", "unchecked" }) public
class AutoIndentWriter extends FilterWriter {
/** Special character indicating a tabular layout of the following text. */
public static final char TABULATOR = 0xffff;
/** Special character indicating to clear all tabluar layout that was configured through {@link #TABULATOR}. */
public static final char CLEAR_TABULATORS = 0xfffe;
/** Special character that inserts a line break and indents the following text by one position. */
public static final char INDENT = 0xfffd;
/** Special character that inserts a line break and unindents the following text by one position. */
public static final char UNINDENT = 0xfffc;
private final StringBuilder lineBuffer = new StringBuilder();
private int indentation;
private List<StringBuilder> tabulatorBuffer;
private int tabulatorIndentation;
public
AutoIndentWriter(Writer out) { super(out); }
@Override public void
write(char[] cbuf, int off, int len) throws IOException {
for (; len > 0; --len) this.write(cbuf[off++]);
}
@Override public void
write(String str, int off, int len) throws IOException {
for (; len > 0; --len) this.write(str.charAt(off++));
}
@Override public void
write(int c) throws IOException {
if (c == '\n') {
this.lineBuffer.append('\n');
this.line(this.lineBuffer.toString());
this.lineBuffer.setLength(0);
return;
}
if (this.lineBuffer.length() > 0 && this.lineBuffer.charAt(this.lineBuffer.length() - 1) == '\r') {
this.line(this.lineBuffer.toString());
this.lineBuffer.setCharAt(0, (char) c);
this.lineBuffer.setLength(1);
return;
}
this.lineBuffer.append((char) c);
}
private void
line(String line) throws IOException {
if (this.tabulatorBuffer != null) {
this.tabulatorBuffer.add(new StringBuilder(line.length()).append(line));
if (line.charAt(0) == AutoIndentWriter.INDENT) { ++this.indentation; line = line.substring(1); }
if (line.charAt(0) == AutoIndentWriter.UNINDENT && --this.indentation < this.tabulatorIndentation) {
this.flushTabulatorBuffer();
}
} else
if (line.indexOf(AutoIndentWriter.TABULATOR) != -1) {
if (line.charAt(0) == AutoIndentWriter.INDENT) { ++this.indentation; line = line.substring(1); }
if (line.charAt(0) == AutoIndentWriter.UNINDENT) { --this.indentation; line = line.substring(1); }
this.tabulatorBuffer = new ArrayList<StringBuilder>();
this.tabulatorBuffer.add(new StringBuilder(line.length()).append(line));
this.tabulatorIndentation = this.indentation;
} else
{
if (line.charAt(0) == AutoIndentWriter.CLEAR_TABULATORS) line = line.substring(1);
if (line.charAt(0) == AutoIndentWriter.INDENT) { ++this.indentation; line = line.substring(1); }
if (line.charAt(0) == AutoIndentWriter.UNINDENT) { --this.indentation; line = line.substring(1); }
if ("\r\n".indexOf(line.charAt(0)) == -1) {
for (int i = 0; i < this.indentation; ++i) this.out.write(" ");
}
this.out.write(line);
}
}
private void
flushTabulatorBuffer() throws IOException {
List<List<StringBuilder>> lineGroups = new ArrayList();
lineGroups.add(new ArrayList<StringBuilder>());
for (StringBuilder line : this.tabulatorBuffer) {
int idx = 0;
if (line.charAt(0) == AutoIndentWriter.INDENT) {
lineGroups.add(new ArrayList<StringBuilder>());
++idx;
}
if (line.charAt(idx) == AutoIndentWriter.UNINDENT) {
AutoIndentWriter.resolveTabs(lineGroups.remove(lineGroups.size() - 1));
++idx;
}
if (line.charAt(idx) == AutoIndentWriter.CLEAR_TABULATORS) {
List<StringBuilder> lg = lineGroups.get(lineGroups.size() - 1);
AutoIndentWriter.resolveTabs(lg);
lg.clear();
line.deleteCharAt(idx);
}
for (int i = 0; i < line.length(); ++i) {
if (line.charAt(i) == AutoIndentWriter.TABULATOR) {
((List<StringBuilder>) lineGroups.get(lineGroups.size() - 1)).add(line);
}
}
}
for (List<StringBuilder> lg : lineGroups) AutoIndentWriter.resolveTabs(lg);
int ind = this.tabulatorIndentation;
for (StringBuilder sb : this.tabulatorBuffer) {
String line = sb.toString();
if (line.charAt(0) == AutoIndentWriter.INDENT) {
++ind;
line = line.substring(1);
}
if (line.charAt(0) == AutoIndentWriter.UNINDENT) {
--ind;
line = line.substring(1);
}
if ("\r\n".indexOf(line.charAt(0)) == -1) {
for (int i = 0; i < ind; ++i) this.out.write(" ");
}
this.out.write(line.toString());
}
this.tabulatorBuffer = null;
}
/**
* Expands all {@link #TABULATOR}s in the given {@link List} of {@link StringBuilder}s with
* spaces, so that the characters immediately following the {@link #TABULATOR}s are vertically
* aligned, like this:
* <p>
* Input:<pre>
* a @b @c\r\n
* aa @bb @cc\r\n
* aaa @bbb @ccc\r\n</pre>Output:<pre>
* a b c\r\n
* aa bb cc\r\n
* aaa bbb ccc\r\n</pre>
*/
private static void
resolveTabs(List<StringBuilder> lineGroup) {
// Determine the tabulator offsets for this line group.
List<Integer> tabulatorOffsets = new ArrayList<Integer>(); // 4, 4
for (StringBuilder line : lineGroup) {
int previousTab = 0;
if (line.charAt(previousTab) == AutoIndentWriter.INDENT) ++previousTab;
if (line.charAt(previousTab) == AutoIndentWriter.UNINDENT) ++previousTab;
int tabCount = 0;
for (int i = previousTab; i < line.length(); ++i) {
if (line.charAt(i) == AutoIndentWriter.TABULATOR) {
int tabOffset = i - previousTab;
previousTab = i;
if (tabCount >= tabulatorOffsets.size()) {
tabulatorOffsets.add(new Integer(tabOffset));
} else
{
if (tabOffset > ((Integer) tabulatorOffsets.get(tabCount)).intValue()) {
tabulatorOffsets.set(tabCount, new Integer(tabOffset));
}
}
++tabCount;
}
}
}
// Replace tabulators with spaces.
for (Iterator<StringBuilder> it = lineGroup.iterator(); it.hasNext();) {
StringBuilder line = (StringBuilder) it.next();
int tabCount = 0;
int previousTab = 0;
if (line.charAt(previousTab) == AutoIndentWriter.INDENT) ++previousTab;
if (line.charAt(previousTab) == AutoIndentWriter.UNINDENT) ++previousTab;
for (int i = previousTab; i < line.length(); ++i) {
if (line.charAt(i) == AutoIndentWriter.TABULATOR) {
int tabOffset = i - previousTab;
int n = ((Integer) tabulatorOffsets.get(tabCount++)).intValue() - tabOffset;
line.replace(i, i + 1, AutoIndentWriter.spaces(n));
i += n - 1;
previousTab = i;
}
}
}
}
/** @return a {@link String} of <code>n</code> spaces */
private static String
spaces(int n) {
if (n < 30) return " ".substring(0, n);
char[] data = new char[n];
Arrays.fill(data, ' ');
return String.valueOf(data);
}
@Override public void
close() throws IOException {
if (this.tabulatorBuffer != null) this.flushTabulatorBuffer();
if (this.lineBuffer.length() > 0) this.line(this.lineBuffer.toString());
this.out.close();
}
@Override public void
flush() throws IOException {
if (this.tabulatorBuffer != null) this.flushTabulatorBuffer();
if (this.lineBuffer.length() > 0) {
this.line(this.lineBuffer.toString());
this.lineBuffer.setLength(0);
}
this.out.flush();
}
}

View File

@ -1,197 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino.util;
import java.util.Stack;
/**
* Implements a scheme for benchmarking, i.e. for determining and/or reporting the time elapsed
* between the beginning and the end of an activity.
* <p>
* The measurement is done by invoking {@link #begin()} and later calling {@link #end()} whichs
* returns the time elapsed since the call to {@link #begin()}.
* <p>
* Notice that calls to {@link #begin()} and {@link #end()} can be nested, and each call to
* {@link #end()} refers to the matching {@link #begin()} call. To ensure that all calls match,
* the preferred way to write a benchmark is
* <pre>
* ...
* Benchmark b = new Benchmark();
* ...
* b.begin();
* try {
* ....
* } finally {
* long ms = b.end();
* }
* </pre>
* This code layout also makes it visually easy to write correct pairs of {@link #begin()} /
* {@link #end()} pairs.
* <p>
* The pair {@link #beginReporting()} and {@link #endReporting()} do basically the same, but
* report the benchmarking information through an internal {@link Reporter} object. The default
* {@link Reporter} prints its messages by <code>System.out.println()</code>.
* <p>
* Reporting is only enabled if the Benchmark object was created through {@link #Benchmark(boolean)}
* with a <code>true</code> argument.
*/
@SuppressWarnings({ "rawtypes", "unchecked" }) public
class Benchmark {
private final Stack beginTimes = new Stack(); // Long
public
Benchmark() {
this.reportingEnabled = false;
this.reporter = null;
}
/** @see Benchmark */
public void
begin() { this.beginTimes.push(new Long(System.currentTimeMillis())); }
/** @see Benchmark */
public long
end() { return System.currentTimeMillis() - ((Long) this.beginTimes.pop()).longValue(); }
// Reporting-related methods and fields.
/** Sets up a {@link Benchmark} with a default {@link Reporter} that reports to {@code System.out}. */
public
Benchmark(boolean reportingEnabled) {
this.reportingEnabled = reportingEnabled;
this.reporter = new Reporter() {
@Override public void report(String message) { System.out.println(message); }
};
}
/** Set up a {@link Benchmark} with a custom {@link Reporter}. */
public
Benchmark(boolean reportingEnabled, Reporter reporter) {
this.reportingEnabled = reportingEnabled;
this.reporter = reporter;
}
private final boolean reportingEnabled;
private final Reporter reporter;
/** Interface used to report messages. */
public
interface Reporter {
/** Reports the given {@code message}. */
void report(String message);
}
/** Begin a benchmark (see {@link #begin()}) and report the fact. */
public void
beginReporting() {
if (!this.reportingEnabled) return;
this.reportIndented("Beginning...");
this.begin();
}
/** Begin a benchmark (see {@link #begin()}) and report the fact. */
public void
beginReporting(String message) {
if (!this.reportingEnabled) return;
this.reportIndented(message + "...");
this.begin();
}
/** End a benchmark (see {@link #end()}) and report the fact. */
public void
endReporting() {
if (!this.reportingEnabled) return;
this.reportIndented("... took " + this.end() + " ms");
}
/** End a benchmark (see {@link #begin()}) and report the fact. */
public void
endReporting(String message) {
if (!this.reportingEnabled) return;
this.reportIndented("... took " + this.end() + " ms: " + message);
}
/** Report the given message. */
public void
report(String message) {
if (!this.reportingEnabled) return;
this.reportIndented(message);
}
/**
* Report the <code>title</code>, a colon, a space, and the pretty-printed
* {@link Object}.
* @param optionalTitle
* @param o
*/
public void
report(String optionalTitle, Object o) {
if (!this.reportingEnabled) return;
String prefix = optionalTitle == null ? "" : (
optionalTitle
+ ": "
+ (optionalTitle.length() < Benchmark.PAD.length() ? Benchmark.PAD.substring(optionalTitle.length()) : "")
);
if (o == null) {
this.reportIndented(prefix + "(undefined)");
} else
if (o.getClass().isArray()) {
Object[] oa = (Object[]) o;
if (oa.length == 0) {
this.reportIndented(prefix + "(empty)");
} else
if (oa.length == 1) {
this.reportIndented(prefix + oa[0].toString());
} else {
this.reportIndented(optionalTitle == null ? "Array:" : optionalTitle + ':');
this.begin();
try {
for (Object o2 : oa) this.report(null, o2);
} finally {
this.end();
}
}
} else
{
this.reportIndented(prefix + o.toString());
}
}
private static final String PAD = " ";
/** Report a message through {@link #reporter}, indent by N spaces where N is the current benchmark stack depth. */
private void
reportIndented(String message) {
StringBuilder sb = new StringBuilder();
for (int i = this.beginTimes.size(); i > 0; --i) sb.append(" ");
sb.append(message);
this.reporter.report(sb.toString());
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,144 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino.util;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.NoSuchElementException;
import org.codehaus.janino.JaninoRuntimeException;
/**
* An {@link java.util.Iterator} that traverses a {@link java.util.Collection} of {@link java.util.Iterator}s.
*
* @param <T> The element type of the iterator
*/
@SuppressWarnings("unchecked") public
class MultiIterator<T> implements Iterator<T> {
private static final Iterator<?> AT_END = new Iterator<Object>() {
@Override public boolean hasNext() { return false; }
@Override public Object next() { throw new NoSuchElementException(); }
@Override public void remove() { throw new UnsupportedOperationException(); }
};
private final Iterator<?> outer; // Over Iterators, Collections or arrays
private Iterator<T> inner = (Iterator<T>) MultiIterator.AT_END;
/** @param iterators An array of {@link Iterator}s */
public
MultiIterator(Iterator<T>[] iterators) { this.outer = Arrays.asList(iterators).iterator(); }
/** @param collections An array of {@link Collection}s */
public
MultiIterator(Collection<T>[] collections) { this.outer = Arrays.asList(collections).iterator(); }
/** @param arrays An array of arrays */
public
MultiIterator(Object/*T*/[][] arrays) { this.outer = Arrays.asList(arrays).iterator(); }
/** @param collection A {@link Collection} of {@link Collection}s, {@link Iterator}s and/or arrays */
public
MultiIterator(Collection<?> collection) { this.outer = collection.iterator(); }
/** @param iterator An iterator over {@link Collection}s, {@link Iterator}s and/or arrays */
public
MultiIterator(Iterator<?> iterator) { this.outer = iterator; }
/** @param array An array of {@link Collection}s, {@link Iterator}s and/or arrays */
public
MultiIterator(Object[] array) { this.outer = Arrays.asList(array).iterator(); }
/** Iterates over the given {@link Collection}, prepended with the given {@link Object}. */
public
MultiIterator(Object/*T*/ object, Collection<T> collection) {
this.outer = Arrays.asList(new Object[] {
new Object[] { object },
collection
}).iterator();
}
/** Iterates over the given {@link Collection}, appended with the given {@link Object}. */
public
MultiIterator(Collection<T> collection, Object/*T*/ object) {
this.outer = Arrays.asList(new Object[] {
collection,
new Object[] { object }
}).iterator();
}
/** Iterates over the given {@link Iterator}, prepended with the given {@code prefix}. */
public
MultiIterator(Object/*T*/ prefix, Iterator<T> iterator) {
this.outer = Arrays.asList(new Object[] {
new Object[] { prefix },
iterator
}).iterator();
}
/** Iterates over the given {@link Iterator}, appended with the given <code>suffix</code>. */
public
MultiIterator(Iterator<T> iterator, Object/*T*/ suffix) {
this.outer = Arrays.asList(new Object[] {
iterator,
new Object[] { suffix }
}).iterator();
}
@Override public boolean
hasNext() {
for (;;) {
if (this.inner.hasNext()) return true;
if (!this.outer.hasNext()) return false;
Object o = this.outer.next();
if (o instanceof Iterator) {
this.inner = (Iterator<T>) o;
} else
if (o instanceof Collection) {
this.inner = ((Collection<T>) o).iterator();
} else
if (o instanceof Object[]) {
this.inner = Arrays.asList((T[]) o).iterator();
} else
{
throw new JaninoRuntimeException("Unexpected element type \"" + o.getClass().getName() + "\"");
}
}
}
@Override public T
next() {
if (this.hasNext()) return this.inner.next();
throw new NoSuchElementException();
}
@Override public void
remove() {
this.inner.remove();
}
}

View File

@ -1,51 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino.util;
/**
* An object that produces some {@link java.lang.Object} each time the
* {@link #produce()} method is invoked. This behavior is similar to the
* {@link java.util.Iterator}, but is represented by one single
* {@link #produce()} method as opposed to {@link java.util.Iterator}'s
* two methods {@link java.util.Iterator#hasNext()} and
* {@link java.util.Iterator#next()}. This simplifies the implementation of
* certain complex iterations.
*
* @param <T> The type of the products
* @see org.codehaus.janino.util.iterator.DirectoryIterator
* @see org.codehaus.janino.util.iterator.ProducerIterator
*/
public
interface Producer<T> {
/**
* Produce the next object.
*
* @return the next object or <code>null</code> to indicate that no more objects can be produced
*/
T produce();
}

View File

@ -1,107 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino.util;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import org.codehaus.janino.JaninoRuntimeException;
import org.codehaus.janino.util.resource.Resource;
import org.codehaus.janino.util.resource.ResourceFinder;
/**
* A {@link ClassLoader} that uses a {@link org.codehaus.janino.util.resource.ResourceFinder} to find ".class" files.
*/
@SuppressWarnings({ "rawtypes", "unchecked" }) public
class ResourceFinderClassLoader extends ClassLoader {
private final ResourceFinder resourceFinder;
public
ResourceFinderClassLoader(ResourceFinder resourceFinder, ClassLoader parent) {
super(parent);
this.resourceFinder = resourceFinder;
}
/** @return The underlying {@link ResourceFinder} */
public ResourceFinder
getResourceFinder() { return this.resourceFinder; }
@Override protected Class
findClass(String className) throws ClassNotFoundException {
// Find the resource containing the class bytecode.
Resource classFileResource = this.resourceFinder.findResource(ClassFile.getClassFileResourceName(className));
if (classFileResource == null) throw new ClassNotFoundException(className);
// Open the class file resource.
InputStream is;
try {
is = classFileResource.open();
} catch (IOException ex) {
throw new JaninoRuntimeException((
"Opening class file resource \""
+ classFileResource.getFileName()
+ "\": "
+ ex.getMessage()
), ex);
}
// Read bytecode from the resource into a byte array.
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
byte[] buffer = new byte[4096];
for (;;) {
int bytesRead = is.read(buffer);
if (bytesRead == -1) break;
baos.write(buffer, 0, bytesRead);
}
} catch (IOException ex) {
throw new ClassNotFoundException("Reading class file from \"" + classFileResource + "\"", ex);
} finally {
try { is.close(); } catch (IOException ex) {}
}
byte[] ba = baos.toByteArray();
// Define the class in this ClassLoader.
Class clazz = super.defineClass(null, ba, 0, ba.length);
if (!clazz.getName().equals(className)) {
// This is a really complicated case: We may find a class file on
// the class path that seemingly defines the class we are looking
// for, but doesn't. This is possible if the underlying file system
// has case-insensitive file names and/or file names that are
// limited in length (e.g. DOS 8.3).
throw new ClassNotFoundException(className);
}
return clazz;
}
}

View File

@ -1,195 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino.util;
import java.util.ArrayList;
import java.util.List;
/**
* Implementation of a UNIX shell-like string pattern algorithm.
* <p>
* Additionally, the concept of the "combined pattern" is supported (see
* {@link #matches(StringPattern[], String)}.
*/
@SuppressWarnings({ "rawtypes", "unchecked" }) public
class StringPattern {
/** @see #matches(StringPattern[], String) */
public static final int INCLUDE = 0;
/** @see #matches(StringPattern[], String) */
public static final int EXCLUDE = 1;
private final int mode;
private final String pattern;
/** @param mode {@link #INCLUDE} or {@link #EXCLUDE} */
public
StringPattern(int mode, String pattern) {
this.mode = mode;
this.pattern = pattern;
}
public
StringPattern(String pattern) {
this.mode = StringPattern.INCLUDE;
this.pattern = pattern;
}
/**
* @return Whether this {@link StringPattern} represents <i>inclusion</i> ({@link #INCLUDE}) or <i>exclusion</i>
* exclusion ({@link #EXCLUDE}) of subjects
*/
public int
getMode() { return this.mode; }
/**
* Match the given <code>text</code> against the pattern represented by the current instance,
* as follows:
* <ul>
* <li>
* A <code>*</code> in the pattern matches any sequence of zero or more characters in the
* <code>text</code>
* </li>
* <li>
* A <code>?</code> in the pattern matches exactly one character in the <code>text</code>
* </li>
* <li>
* Any other character in the pattern must appear exactly as it is in the <code>text</code>
* </ul>
* Notice: The <code>mode</code> flag of the current instance does not take any effect here.
*/
public boolean
matches(String text) { return StringPattern.wildmatch(this.pattern, text); }
/**
* Parse a "combined pattern" into an array of {@link StringPattern}s. A combined pattern
* string is structured as follows:
* <pre>
* combined-pattern :=
* [ '+' | '-' ] pattern
* { ( '+' | '-' ) pattern }
* </pre>
* If a pattern is preceeded with a '-', then the {@link StringPattern} is created with mode
* {@link #EXCLUDE}, otherwise with mode {@link #INCLUDE}.
*/
public static StringPattern[]
parseCombinedPattern(String combinedPattern) {
List<StringPattern> al = new ArrayList();
for (int k = 0, l; k < combinedPattern.length(); k = l) {
int patternMode;
char c = combinedPattern.charAt(k);
if (c == '+') {
patternMode = StringPattern.INCLUDE;
++k;
} else
if (c == '-') {
patternMode = StringPattern.EXCLUDE;
++k;
} else {
patternMode = StringPattern.INCLUDE;
}
for (l = k; l < combinedPattern.length(); ++l) {
c = combinedPattern.charAt(l);
if (c == '+' || c == '-') break;
}
al.add(new StringPattern(patternMode, combinedPattern.substring(k, l)));
}
return (StringPattern[]) al.toArray(new StringPattern[al.size()]);
}
/**
* Match a given <code>text</code> against an array of {@link StringPattern}s (which was
* typically created by {@link #parseCombinedPattern(String)}.
* <p>
* The last matching pattern takes effect; if its mode is {@link #INCLUDE}, then
* <code>true</code> is returned, if its mode is {@link #EXCLUDE}, then <code>false</code> is
* returned.
* <p>
* If <code>patterns</code> is {@link #PATTERNS_NONE}, or empty, or none of its patterns
* matches, then <code>false</code> is returned.
* <p>
* If <code>patterns</code> is {@link #PATTERNS_ALL}, then <code>true</code> is
* returned.
* <p>
* For backwards compatibility, <code>null</code> patterns are treated like
* {@link #PATTERNS_NONE}.
*/
public static boolean
matches(StringPattern[] patterns, String text) {
if (patterns == null) return false; // Backwards compatibility -- previously, "null" was officially documented.
for (int i = patterns.length - 1; i >= 0; --i) {
if (patterns[i].matches(text)) {
return patterns[i].getMode() == StringPattern.INCLUDE;
}
}
return false; // No patterns defined or no pattern matches.
}
/** A {@link StringPattern} that matches any subject. */
public static final StringPattern[] PATTERNS_ALL = new StringPattern[] { new StringPattern("*") };
/** A {@link StringPattern} that matches no subject whatsoever. */
public static final StringPattern[] PATTERNS_NONE = new StringPattern[0];
@Override public String
toString() {
return (
this.mode == StringPattern.INCLUDE ? '+' :
this.mode == StringPattern.EXCLUDE ? '-' :
'?'
) + this.pattern;
}
private static boolean
wildmatch(String pattern, String text) {
int i;
for (i = 0; i < pattern.length(); ++i) {
char c = pattern.charAt(i);
switch (c) {
case '?':
if (i == text.length()) return false;
break;
case '*':
if (pattern.length() == i + 1) return true; // Optimization for trailing '*'.
pattern = pattern.substring(i + 1);
for (; i <= text.length(); ++i) {
if (StringPattern.wildmatch(pattern, text.substring(i))) return true;
}
return false;
default:
if (i == text.length()) return false;
if (text.charAt(i) != c) return false;
break;
}
}
return text.length() == i;
}
}

View File

@ -1,85 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino.util;
import java.io.FilterReader;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
/**
* A {@link java.io.FilterReader} that copies the bytes being passed through
* to a given {@link java.io.Writer}. This is in analogy with the UNIX "tee" command.
*/
public
class TeeReader extends FilterReader {
private final Writer out;
private final boolean closeWriterOnEOF;
public
TeeReader(Reader in, Writer out, boolean closeWriterOnEof) {
super(in);
this.out = out;
this.closeWriterOnEOF = closeWriterOnEof;
}
@Override public void
close() throws IOException {
this.in.close();
this.out.close();
}
@Override public int
read() throws IOException {
int c = this.in.read();
if (c == -1) {
if (this.closeWriterOnEOF) {
this.out.close();
} else {
this.out.flush();
}
} else {
this.out.write(c);
}
return c;
}
@Override public int
read(char[] cbuf, int off, int len) throws IOException {
int bytesRead = this.in.read(cbuf, off, len);
if (bytesRead == -1) {
if (this.closeWriterOnEOF) {
this.out.close();
} else {
this.out.flush();
}
} else {
this.out.write(cbuf, off, bytesRead);
}
return bytesRead;
}
}

View File

@ -1,798 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino.util;
import org.codehaus.janino.JaninoRuntimeException;
import org.codehaus.janino.Java;
import org.codehaus.janino.Java.Rvalue;
import org.codehaus.janino.Visitor;
import org.codehaus.janino.Visitor.ComprehensiveVisitor;
/**
* This class traverses the subnodes of an AST. Derived classes may override
* individual methods to process specific nodes, e.g.:<pre>
* LocalClassDeclaration lcd = ...;
* lcd.accept(new Traverser() {
* int n = 0;
* public void traverseMethodDeclarator(Java.MethodDeclarator md) {
* ++this.n;
* super.traverseMethodDeclarator(md);
* }
* }.comprehensiveVisitor());</pre>
*/
public
class Traverser {
private final Visitor.ComprehensiveVisitor cv = new Visitor.ComprehensiveVisitor() {
// CHECKSTYLE LineLengthCheck:OFF
@Override public void visitSingleTypeImportDeclaration(Java.CompilationUnit.SingleTypeImportDeclaration stid) { Traverser.this.traverseSingleTypeImportDeclaration(stid); }
@Override public void visitTypeImportOnDemandDeclaration(Java.CompilationUnit.TypeImportOnDemandDeclaration tiodd) { Traverser.this.traverseTypeImportOnDemandDeclaration(tiodd); }
@Override public void visitSingleStaticImportDeclaration(Java.CompilationUnit.SingleStaticImportDeclaration ssid) { Traverser.this.traverseSingleStaticImportDeclaration(ssid); }
@Override public void visitStaticImportOnDemandDeclaration(Java.CompilationUnit.StaticImportOnDemandDeclaration siodd) { Traverser.this.traverseStaticImportOnDemandDeclaration(siodd); }
@Override public void visitAnonymousClassDeclaration(Java.AnonymousClassDeclaration acd) { Traverser.this.traverseAnonymousClassDeclaration(acd); }
@Override public void visitLocalClassDeclaration(Java.LocalClassDeclaration lcd) { Traverser.this.traverseLocalClassDeclaration(lcd); }
@Override public void visitPackageMemberClassDeclaration(Java.PackageMemberClassDeclaration pmcd) { Traverser.this.traversePackageMemberClassDeclaration(pmcd); }
@Override public void visitMemberInterfaceDeclaration(Java.MemberInterfaceDeclaration mid) { Traverser.this.traverseMemberInterfaceDeclaration(mid); }
@Override public void visitPackageMemberInterfaceDeclaration(Java.PackageMemberInterfaceDeclaration pmid) { Traverser.this.traversePackageMemberInterfaceDeclaration(pmid); }
@Override public void visitMemberClassDeclaration(Java.MemberClassDeclaration mcd) { Traverser.this.traverseMemberClassDeclaration(mcd); }
@Override public void visitConstructorDeclarator(Java.ConstructorDeclarator cd) { Traverser.this.traverseConstructorDeclarator(cd); }
@Override public void visitInitializer(Java.Initializer i) { Traverser.this.traverseInitializer(i); }
@Override public void visitMethodDeclarator(Java.MethodDeclarator md) { Traverser.this.traverseMethodDeclarator(md); }
@Override public void visitFieldDeclaration(Java.FieldDeclaration fd) { Traverser.this.traverseFieldDeclaration(fd); }
@Override public void visitLabeledStatement(Java.LabeledStatement ls) { Traverser.this.traverseLabeledStatement(ls); }
@Override public void visitBlock(Java.Block b) { Traverser.this.traverseBlock(b); }
@Override public void visitExpressionStatement(Java.ExpressionStatement es) { Traverser.this.traverseExpressionStatement(es); }
@Override public void visitIfStatement(Java.IfStatement is) { Traverser.this.traverseIfStatement(is); }
@Override public void visitForStatement(Java.ForStatement fs) { Traverser.this.traverseForStatement(fs); }
@Override public void visitForEachStatement(Java.ForEachStatement fes) { Traverser.this.traverseForEachStatement(fes); }
@Override public void visitWhileStatement(Java.WhileStatement ws) { Traverser.this.traverseWhileStatement(ws); }
@Override public void visitTryStatement(Java.TryStatement ts) { Traverser.this.traverseTryStatement(ts); }
@Override public void visitSwitchStatement(Java.SwitchStatement ss) { Traverser.this.traverseSwitchStatement(ss); }
@Override public void visitSynchronizedStatement(Java.SynchronizedStatement ss) { Traverser.this.traverseSynchronizedStatement(ss); }
@Override public void visitDoStatement(Java.DoStatement ds) { Traverser.this.traverseDoStatement(ds); }
@Override public void visitLocalVariableDeclarationStatement(Java.LocalVariableDeclarationStatement lvds) { Traverser.this.traverseLocalVariableDeclarationStatement(lvds); }
@Override public void visitReturnStatement(Java.ReturnStatement rs) { Traverser.this.traverseReturnStatement(rs); }
@Override public void visitThrowStatement(Java.ThrowStatement ts) { Traverser.this.traverseThrowStatement(ts); }
@Override public void visitBreakStatement(Java.BreakStatement bs) { Traverser.this.traverseBreakStatement(bs); }
@Override public void visitContinueStatement(Java.ContinueStatement cs) { Traverser.this.traverseContinueStatement(cs); }
@Override public void visitAssertStatement(Java.AssertStatement as) { Traverser.this.traverseAssertStatement(as); }
@Override public void visitEmptyStatement(Java.EmptyStatement es) { Traverser.this.traverseEmptyStatement(es); }
@Override public void visitLocalClassDeclarationStatement(Java.LocalClassDeclarationStatement lcds) { Traverser.this.traverseLocalClassDeclarationStatement(lcds); }
@Override public void visitPackage(Java.Package p) { Traverser.this.traversePackage(p); }
@Override public void visitArrayLength(Java.ArrayLength al) { Traverser.this.traverseArrayLength(al); }
@Override public void visitAssignment(Java.Assignment a) { Traverser.this.traverseAssignment(a); }
@Override public void visitUnaryOperation(Java.UnaryOperation uo) { Traverser.this.traverseUnaryOperation(uo); }
@Override public void visitBinaryOperation(Java.BinaryOperation bo) { Traverser.this.traverseBinaryOperation(bo); }
@Override public void visitCast(Java.Cast c) { Traverser.this.traverseCast(c); }
@Override public void visitClassLiteral(Java.ClassLiteral cl) { Traverser.this.traverseClassLiteral(cl); }
@Override public void visitConditionalExpression(Java.ConditionalExpression ce) { Traverser.this.traverseConditionalExpression(ce); }
@Override public void visitCrement(Java.Crement c) { Traverser.this.traverseCrement(c); }
@Override public void visitInstanceof(Java.Instanceof io) { Traverser.this.traverseInstanceof(io); }
@Override public void visitMethodInvocation(Java.MethodInvocation mi) { Traverser.this.traverseMethodInvocation(mi); }
@Override public void visitSuperclassMethodInvocation(Java.SuperclassMethodInvocation smi) { Traverser.this.traverseSuperclassMethodInvocation(smi); }
@Override public void visitIntegerLiteral(Java.IntegerLiteral il) { Traverser.this.traverseIntegerLiteral(il); }
@Override public void visitFloatingPointLiteral(Java.FloatingPointLiteral fpl) { Traverser.this.traverseFloatingPointLiteral(fpl); }
@Override public void visitBooleanLiteral(Java.BooleanLiteral bl) { Traverser.this.traverseBooleanLiteral(bl); }
@Override public void visitCharacterLiteral(Java.CharacterLiteral cl) { Traverser.this.traverseCharacterLiteral(cl); }
@Override public void visitStringLiteral(Java.StringLiteral sl) { Traverser.this.traverseStringLiteral(sl); }
@Override public void visitNullLiteral(Java.NullLiteral nl) { Traverser.this.traverseNullLiteral(nl); }
@Override public void visitSimpleConstant(Java.SimpleConstant sl) { Traverser.this.traverseSimpleLiteral(sl); }
@Override public void visitNewAnonymousClassInstance(Java.NewAnonymousClassInstance naci) { Traverser.this.traverseNewAnonymousClassInstance(naci); }
@Override public void visitNewArray(Java.NewArray na) { Traverser.this.traverseNewArray(na); }
@Override public void visitNewInitializedArray(Java.NewInitializedArray nia) { Traverser.this.traverseNewInitializedArray(nia); }
@Override public void visitNewClassInstance(Java.NewClassInstance nci) { Traverser.this.traverseNewClassInstance(nci); }
@Override public void visitParameterAccess(Java.ParameterAccess pa) { Traverser.this.traverseParameterAccess(pa); }
@Override public void visitQualifiedThisReference(Java.QualifiedThisReference qtr) { Traverser.this.traverseQualifiedThisReference(qtr); }
@Override public void visitThisReference(Java.ThisReference tr) { Traverser.this.traverseThisReference(tr); }
@Override public void visitArrayType(Java.ArrayType at) { Traverser.this.traverseArrayType(at); }
@Override public void visitBasicType(Java.BasicType bt) { Traverser.this.traverseBasicType(bt); }
@Override public void visitReferenceType(Java.ReferenceType rt) { Traverser.this.traverseReferenceType(rt); }
@Override public void visitRvalueMemberType(Java.RvalueMemberType rmt) { Traverser.this.traverseRvalueMemberType(rmt); }
@Override public void visitSimpleType(Java.SimpleType st) { Traverser.this.traverseSimpleType(st); }
@Override public void visitAlternateConstructorInvocation(Java.AlternateConstructorInvocation aci) { Traverser.this.traverseAlternateConstructorInvocation(aci); }
@Override public void visitSuperConstructorInvocation(Java.SuperConstructorInvocation sci) { Traverser.this.traverseSuperConstructorInvocation(sci); }
@Override public void visitAmbiguousName(Java.AmbiguousName an) { Traverser.this.traverseAmbiguousName(an); }
@Override public void visitArrayAccessExpression(Java.ArrayAccessExpression aae) { Traverser.this.traverseArrayAccessExpression(aae); }
@Override public void visitFieldAccess(Java.FieldAccess fa) { Traverser.this.traverseFieldAccess(fa); }
@Override public void visitFieldAccessExpression(Java.FieldAccessExpression fae) { Traverser.this.traverseFieldAccessExpression(fae); }
@Override public void visitSuperclassFieldAccessExpression(Java.SuperclassFieldAccessExpression scfae) { Traverser.this.traverseSuperclassFieldAccessExpression(scfae); }
@Override public void visitLocalVariableAccess(Java.LocalVariableAccess lva) { Traverser.this.traverseLocalVariableAccess(lva); }
@Override public void visitParenthesizedExpression(Java.ParenthesizedExpression pe) { Traverser.this.traverseParenthesizedExpression(pe); }
@Override public void visitMarkerAnnotation(Java.MarkerAnnotation ma) { Traverser.this.traverseMarkerAnnotation(ma); }
@Override public void visitNormalAnnotation(Java.NormalAnnotation na) { Traverser.this.traverseNormalAnnotation(na); }
@Override public void visitSingleElementAnnotation(Java.SingleElementAnnotation sea) { Traverser.this.traverseSingleElementAnnotation(sea); }
@Override public void visitElementValueArrayInitializer(Java.ElementValueArrayInitializer evai) { Traverser.this.traverseElementValueArrayInitializer(evai); }
// CHECKSTYLE LineLengthCheck:ON
};
/** @see Traverser */
public ComprehensiveVisitor
comprehensiveVisitor() { return this.cv; }
// These may be overridden by derived classes.
/** @see Traverser */
public void
traverseCompilationUnit(Java.CompilationUnit cu) {
// The optionalPackageDeclaration is considered an integral part of
// the compilation unit and is thus not traversed.
for (Java.CompilationUnit.ImportDeclaration id : cu.importDeclarations) id.accept(this.cv);
for (Java.PackageMemberTypeDeclaration pmtd : cu.packageMemberTypeDeclarations) pmtd.accept(this.cv);
}
/** @see Traverser */
public void
traverseSingleTypeImportDeclaration(Java.CompilationUnit.SingleTypeImportDeclaration stid) {
this.traverseImportDeclaration(stid);
}
/** @see Traverser */
public void
traverseTypeImportOnDemandDeclaration(Java.CompilationUnit.TypeImportOnDemandDeclaration tiodd) {
this.traverseImportDeclaration(tiodd);
}
/** @see Traverser */
public void
traverseSingleStaticImportDeclaration(Java.CompilationUnit.SingleStaticImportDeclaration stid) {
this.traverseImportDeclaration(stid);
}
/** @see Traverser */
public void
traverseStaticImportOnDemandDeclaration(Java.CompilationUnit.StaticImportOnDemandDeclaration siodd) {
this.traverseImportDeclaration(siodd);
}
/** @see Traverser */
public void
traverseImportDeclaration(Java.CompilationUnit.ImportDeclaration id) { this.traverseLocated(id); }
/** @see Traverser */
public void
traverseAnonymousClassDeclaration(Java.AnonymousClassDeclaration acd) {
acd.baseType.accept((Visitor.TypeVisitor) this.cv);
this.traverseClassDeclaration(acd);
}
/** @see Traverser */
public void
traverseLocalClassDeclaration(Java.LocalClassDeclaration lcd) { this.traverseNamedClassDeclaration(lcd); }
/** @see Traverser */
public void
traversePackageMemberClassDeclaration(Java.PackageMemberClassDeclaration pmcd) {
this.traverseNamedClassDeclaration(pmcd);
}
/** @see Traverser */
public void
traverseMemberInterfaceDeclaration(Java.MemberInterfaceDeclaration mid) { this.traverseInterfaceDeclaration(mid); }
/** @see Traverser */
public void
traversePackageMemberInterfaceDeclaration(Java.PackageMemberInterfaceDeclaration pmid) {
this.traverseInterfaceDeclaration(pmid);
}
/** @see Traverser */
public void
traverseMemberClassDeclaration(Java.MemberClassDeclaration mcd) { this.traverseNamedClassDeclaration(mcd); }
/** @see Traverser */
public void
traverseConstructorDeclarator(Java.ConstructorDeclarator cd) {
if (cd.optionalConstructorInvocation != null) {
cd.optionalConstructorInvocation.accept((Visitor.BlockStatementVisitor) this.cv);
}
this.traverseFunctionDeclarator(cd);
}
/** @see Traverser */
public void
traverseInitializer(Java.Initializer i) {
i.block.accept(this.cv);
this.traverseAbstractTypeBodyDeclaration(i);
}
/** @see Traverser */
public void
traverseMethodDeclarator(Java.MethodDeclarator md) { this.traverseFunctionDeclarator(md); }
/** @see Traverser */
public void
traverseFieldDeclaration(Java.FieldDeclaration fd) {
fd.type.accept((Visitor.TypeVisitor) this.cv);
for (Java.VariableDeclarator vd : fd.variableDeclarators) {
Java.ArrayInitializerOrRvalue optionalInitializer = vd.optionalInitializer;
if (optionalInitializer != null) this.traverseArrayInitializerOrRvalue(optionalInitializer);
}
this.traverseStatement(fd);
}
/** @see Traverser */
public void
traverseLabeledStatement(Java.LabeledStatement ls) {
ls.body.accept(this.cv);
this.traverseBreakableStatement(ls);
}
/** @see Traverser */
public void
traverseBlock(Java.Block b) {
for (Java.BlockStatement bs : b.statements) bs.accept(this.cv);
this.traverseStatement(b);
}
/** @see Traverser */
public void
traverseExpressionStatement(Java.ExpressionStatement es) {
es.rvalue.accept((Visitor.RvalueVisitor) this.cv);
this.traverseStatement(es);
}
/** @see Traverser */
public void
traverseIfStatement(Java.IfStatement is) {
is.condition.accept((Visitor.RvalueVisitor) this.cv);
is.thenStatement.accept(this.cv);
if (is.optionalElseStatement != null) is.optionalElseStatement.accept(this.cv);
this.traverseStatement(is);
}
/** @see Traverser */
public void
traverseForStatement(Java.ForStatement fs) {
if (fs.optionalInit != null) fs.optionalInit.accept(this.cv);
if (fs.optionalCondition != null) fs.optionalCondition.accept((Visitor.RvalueVisitor) this.cv);
if (fs.optionalUpdate != null) {
for (Java.Rvalue rv : fs.optionalUpdate) rv.accept((Visitor.RvalueVisitor) this.cv);
}
fs.body.accept(this.cv);
this.traverseContinuableStatement(fs);
}
/** @see Traverser */
public void
traverseForEachStatement(Java.ForEachStatement fes) {
this.traverseFormalParameter(fes.currentElement);
fes.expression.accept((Visitor.RvalueVisitor) this.cv);
fes.body.accept(this.cv);
this.traverseContinuableStatement(fes);
}
/** @see Traverser */
public void
traverseWhileStatement(Java.WhileStatement ws) {
ws.condition.accept((Visitor.RvalueVisitor) this.cv);
ws.body.accept(this.cv);
this.traverseContinuableStatement(ws);
}
/** @see Traverser */
public void
traverseTryStatement(Java.TryStatement ts) {
ts.body.accept(this.cv);
for (Java.CatchClause cc : ts.catchClauses) cc.body.accept(this.cv);
if (ts.optionalFinally != null) ts.optionalFinally.accept(this.cv);
this.traverseStatement(ts);
}
/** @see Traverser */
public void
traverseSwitchStatement(Java.SwitchStatement ss) {
ss.condition.accept((Visitor.RvalueVisitor) this.cv);
for (Java.SwitchStatement.SwitchBlockStatementGroup sbsg : ss.sbsgs) {
for (Java.Rvalue cl : sbsg.caseLabels) cl.accept((Visitor.RvalueVisitor) this.cv);
for (Java.BlockStatement bs : sbsg.blockStatements) bs.accept(this.cv);
this.traverseLocated(sbsg);
}
this.traverseBreakableStatement(ss);
}
/** @see Traverser */
public void
traverseSynchronizedStatement(Java.SynchronizedStatement ss) {
ss.expression.accept((Visitor.RvalueVisitor) this.cv);
ss.body.accept(this.cv);
this.traverseStatement(ss);
}
/** @see Traverser */
public void
traverseDoStatement(Java.DoStatement ds) {
ds.body.accept(this.cv);
ds.condition.accept((Visitor.RvalueVisitor) this.cv);
this.traverseContinuableStatement(ds);
}
/** @see Traverser */
public void
traverseLocalVariableDeclarationStatement(Java.LocalVariableDeclarationStatement lvds) {
lvds.type.accept((Visitor.TypeVisitor) this.cv);
for (Java.VariableDeclarator vd : lvds.variableDeclarators) {
Java.ArrayInitializerOrRvalue optionalInitializer = vd.optionalInitializer;
if (optionalInitializer != null) this.traverseArrayInitializerOrRvalue(optionalInitializer);
}
this.traverseStatement(lvds);
}
/** @see Traverser */
public void
traverseReturnStatement(Java.ReturnStatement rs) {
if (rs.optionalReturnValue != null) rs.optionalReturnValue.accept((Visitor.RvalueVisitor) this.cv);
this.traverseStatement(rs);
}
/** @see Traverser */
public void
traverseThrowStatement(Java.ThrowStatement ts) {
ts.expression.accept((Visitor.RvalueVisitor) this.cv);
this.traverseStatement(ts);
}
/** @see Traverser */
public void
traverseBreakStatement(Java.BreakStatement bs) { this.traverseStatement(bs); }
/** @see Traverser */
public void
traverseContinueStatement(Java.ContinueStatement cs) { this.traverseStatement(cs); }
/** @see Traverser */
public void
traverseAssertStatement(Java.AssertStatement as) {
as.expression1.accept((Visitor.RvalueVisitor) this.cv);
if (as.optionalExpression2 != null) as.optionalExpression2.accept((Visitor.RvalueVisitor) this.cv);
this.traverseStatement(as);
}
/** @see Traverser */
public void
traverseEmptyStatement(Java.EmptyStatement es) { this.traverseStatement(es); }
/** @see Traverser */
public void
traverseLocalClassDeclarationStatement(Java.LocalClassDeclarationStatement lcds) {
lcds.lcd.accept(this.cv);
this.traverseStatement(lcds);
}
/** @see Traverser */
public void
traversePackage(Java.Package p) { this.traverseAtom(p); }
/** @see Traverser */
public void
traverseArrayLength(Java.ArrayLength al) {
al.lhs.accept((Visitor.RvalueVisitor) this.cv);
this.traverseRvalue(al);
}
/** @see Traverser */
public void
traverseAssignment(Java.Assignment a) {
a.lhs.accept((Visitor.LvalueVisitor) this.cv);
a.rhs.accept((Visitor.RvalueVisitor) this.cv);
this.traverseRvalue(a);
}
/** @see Traverser */
public void
traverseUnaryOperation(Java.UnaryOperation uo) {
uo.operand.accept((Visitor.RvalueVisitor) this.cv);
this.traverseBooleanRvalue(uo);
}
/** @see Traverser */
public void
traverseBinaryOperation(Java.BinaryOperation bo) {
bo.lhs.accept((Visitor.RvalueVisitor) this.cv);
bo.rhs.accept((Visitor.RvalueVisitor) this.cv);
this.traverseBooleanRvalue(bo);
}
/** @see Traverser */
public void
traverseCast(Java.Cast c) {
c.targetType.accept((Visitor.TypeVisitor) this.cv);
c.value.accept((Visitor.RvalueVisitor) this.cv);
this.traverseRvalue(c);
}
/** @see Traverser */
public void
traverseClassLiteral(Java.ClassLiteral cl) {
cl.type.accept((Visitor.TypeVisitor) this.cv);
this.traverseRvalue(cl);
}
/** @see Traverser */
public void
traverseConditionalExpression(Java.ConditionalExpression ce) {
ce.lhs.accept((Visitor.RvalueVisitor) this.cv);
ce.mhs.accept((Visitor.RvalueVisitor) this.cv);
ce.rhs.accept((Visitor.RvalueVisitor) this.cv);
this.traverseRvalue(ce);
}
/** @see Traverser */
public void
traverseCrement(Java.Crement c) {
c.operand.accept((Visitor.LvalueVisitor) this.cv);
this.traverseRvalue(c);
}
/** @see Traverser */
public void
traverseInstanceof(Java.Instanceof io) {
io.lhs.accept((Visitor.RvalueVisitor) this.cv);
io.rhs.accept((Visitor.TypeVisitor) this.cv);
this.traverseRvalue(io);
}
/** @see Traverser */
public void
traverseMethodInvocation(Java.MethodInvocation mi) {
if (mi.optionalTarget != null) mi.optionalTarget.accept(this.cv);
this.traverseInvocation(mi);
}
/** @see Traverser */
public void
traverseSuperclassMethodInvocation(Java.SuperclassMethodInvocation smi) { this.traverseInvocation(smi); }
/** @see Traverser */
public void
traverseLiteral(Java.Literal l) { this.traverseRvalue(l); }
/** @see Traverser */
public void
traverseIntegerLiteral(Java.IntegerLiteral il) { this.traverseLiteral(il); }
/** @see Traverser */
public void
traverseFloatingPointLiteral(Java.FloatingPointLiteral fpl) { this.traverseLiteral(fpl); }
/** @see Traverser */
public void
traverseBooleanLiteral(Java.BooleanLiteral bl) { this.traverseLiteral(bl); }
/** @see Traverser */
public void
traverseCharacterLiteral(Java.CharacterLiteral cl) { this.traverseLiteral(cl); }
/** @see Traverser */
public void
traverseStringLiteral(Java.StringLiteral sl) { this.traverseLiteral(sl); }
/** @see Traverser */
public void
traverseNullLiteral(Java.NullLiteral nl) { this.traverseLiteral(nl); }
/** @see Traverser */
public void
traverseSimpleLiteral(Java.SimpleConstant sl) { this.traverseRvalue(sl); }
/** @see Traverser */
public void
traverseNewAnonymousClassInstance(Java.NewAnonymousClassInstance naci) {
if (naci.optionalQualification != null) naci.optionalQualification.accept((Visitor.RvalueVisitor) this.cv);
naci.anonymousClassDeclaration.accept(this.cv);
for (Java.Rvalue argument : naci.arguments) argument.accept((Visitor.RvalueVisitor) this.cv);
this.traverseRvalue(naci);
}
/** @see Traverser */
public void
traverseNewArray(Java.NewArray na) {
na.type.accept((Visitor.TypeVisitor) this.cv);
for (Rvalue dimExpr : na.dimExprs) dimExpr.accept((Visitor.RvalueVisitor) this.cv);
this.traverseRvalue(na);
}
/** @see Traverser */
public void
traverseNewInitializedArray(Java.NewInitializedArray nia) {
nia.arrayType.accept((Visitor.TypeVisitor) this.cv);
this.traverseArrayInitializerOrRvalue(nia.arrayInitializer);
}
/** @see Traverser */
public void
traverseArrayInitializerOrRvalue(Java.ArrayInitializerOrRvalue aiorv) {
if (aiorv instanceof Java.Rvalue) {
((Java.Atom) aiorv).accept(this.cv);
} else
if (aiorv instanceof Java.ArrayInitializer) {
Java.ArrayInitializerOrRvalue[] values = ((Java.ArrayInitializer) aiorv).values;
for (Java.ArrayInitializerOrRvalue value : values) this.traverseArrayInitializerOrRvalue(value);
} else
{
throw new JaninoRuntimeException(
"Unexpected array initializer or rvalue class "
+ aiorv.getClass().getName()
);
}
}
/** @see Traverser */
public void
traverseNewClassInstance(Java.NewClassInstance nci) {
if (nci.optionalQualification != null) nci.optionalQualification.accept((Visitor.RvalueVisitor) this.cv);
if (nci.type != null) nci.type.accept((Visitor.TypeVisitor) this.cv);
for (Java.Rvalue argument : nci.arguments) argument.accept((Visitor.RvalueVisitor) this.cv);
this.traverseRvalue(nci);
}
/** @see Traverser */
public void
traverseParameterAccess(Java.ParameterAccess pa) { this.traverseRvalue(pa); }
/** @see Traverser */
public void
traverseQualifiedThisReference(Java.QualifiedThisReference qtr) {
qtr.qualification.accept((Visitor.TypeVisitor) this.cv);
this.traverseRvalue(qtr);
}
/** @see Traverser */
public void
traverseThisReference(Java.ThisReference tr) { this.traverseRvalue(tr); }
/** @see Traverser */
public void
traverseArrayType(Java.ArrayType at) {
at.componentType.accept((Visitor.TypeVisitor) this.cv);
this.traverseType(at);
}
/** @see Traverser */
public void
traverseBasicType(Java.BasicType bt) { this.traverseType(bt); }
/** @see Traverser */
public void
traverseReferenceType(Java.ReferenceType rt) { this.traverseType(rt); }
/** @see Traverser */
public void
traverseRvalueMemberType(Java.RvalueMemberType rmt) {
rmt.rvalue.accept((Visitor.RvalueVisitor) this.cv);
this.traverseType(rmt);
}
/** @see Traverser */
public void
traverseSimpleType(Java.SimpleType st) { this.traverseType(st); }
/** @see Traverser */
public void
traverseAlternateConstructorInvocation(Java.AlternateConstructorInvocation aci) {
this.traverseConstructorInvocation(aci);
}
/** @see Traverser */
public void
traverseSuperConstructorInvocation(Java.SuperConstructorInvocation sci) {
if (sci.optionalQualification != null) sci.optionalQualification.accept((Visitor.RvalueVisitor) this.cv);
this.traverseConstructorInvocation(sci);
}
/** @see Traverser */
public void
traverseAmbiguousName(Java.AmbiguousName an) { this.traverseLvalue(an); }
/** @see Traverser */
public void
traverseArrayAccessExpression(Java.ArrayAccessExpression aae) {
aae.lhs.accept((Visitor.RvalueVisitor) this.cv);
((Java.Atom) aae.index).accept(this.cv);
this.traverseLvalue(aae);
}
/** @see Traverser */
public void
traverseFieldAccess(Java.FieldAccess fa) {
fa.lhs.accept(this.cv);
this.traverseLvalue(fa);
}
/** @see Traverser */
public void
traverseFieldAccessExpression(Java.FieldAccessExpression fae) {
fae.lhs.accept(this.cv);
this.traverseLvalue(fae);
}
/** @see Traverser */
public void
traverseSuperclassFieldAccessExpression(Java.SuperclassFieldAccessExpression scfae) {
if (scfae.optionalQualification != null) scfae.optionalQualification.accept((Visitor.TypeVisitor) this.cv);
this.traverseLvalue(scfae);
}
/** @see Traverser */
public void
traverseLocalVariableAccess(Java.LocalVariableAccess lva) { this.traverseLvalue(lva); }
/** @see Traverser */
public void
traverseParenthesizedExpression(Java.ParenthesizedExpression pe) {
pe.value.accept((Visitor.RvalueVisitor) this.cv);
this.traverseLvalue(pe);
}
/** @see Traverser */
public void
traverseElementValueArrayInitializer(Java.ElementValueArrayInitializer evai) {
for (Java.ElementValue elementValue : evai.elementValues) elementValue.accept(this.cv);
this.traverseElementValue(evai);
}
/** @see Traverser */
public void
traverseElementValue(Java.ElementValue ev) {}
/** @see Traverser */
public void
traverseSingleElementAnnotation(Java.SingleElementAnnotation sea) {
sea.type.accept(this.cv);
sea.elementValue.accept(this.cv);
this.traverseAnnotation(sea);
}
/** @see Traverser */
public void
traverseAnnotation(Java.Annotation a) {}
/** @see Traverser */
public void
traverseNormalAnnotation(Java.NormalAnnotation na) {
na.type.accept(this.cv);
for (Java.ElementValuePair elementValuePair : na.elementValuePairs) {
elementValuePair.elementValue.accept(this.cv);
}
this.traverseAnnotation(na);
}
/** @see Traverser */
public void
traverseMarkerAnnotation(Java.MarkerAnnotation ma) {
ma.type.accept(this.cv);
this.traverseAnnotation(ma);
}
/** @see Traverser */
public void
traverseClassDeclaration(Java.ClassDeclaration cd) {
for (Java.ConstructorDeclarator ctord : cd.constructors) ctord.accept(this.cv);
for (Java.BlockStatement vdoi : cd.variableDeclaratorsAndInitializers) vdoi.accept(this.cv);
this.traverseAbstractTypeDeclaration(cd);
}
/** @see Traverser */
public void
traverseAbstractTypeDeclaration(Java.AbstractTypeDeclaration atd) {
for (Java.NamedTypeDeclaration mtd : atd.getMemberTypeDeclarations()) mtd.accept(this.cv);
for (Java.MethodDeclarator md : atd.getMethodDeclarations()) this.traverseMethodDeclarator(md);
}
/** @see Traverser */
public void
traverseNamedClassDeclaration(Java.NamedClassDeclaration ncd) {
for (Java.Type implementedType : ncd.implementedTypes) implementedType.accept((Visitor.TypeVisitor) this.cv);
if (ncd.optionalExtendedType != null) ncd.optionalExtendedType.accept((Visitor.TypeVisitor) this.cv);
this.traverseClassDeclaration(ncd);
}
/** @see Traverser */
public void
traverseInterfaceDeclaration(Java.InterfaceDeclaration id) {
for (Java.TypeBodyDeclaration cd : id.constantDeclarations) cd.accept(this.cv);
for (Java.Type extendedType : id.extendedTypes) extendedType.accept((Visitor.TypeVisitor) this.cv);
this.traverseAbstractTypeDeclaration(id);
}
/** @see Traverser */
public void
traverseFunctionDeclarator(Java.FunctionDeclarator fd) {
this.traverseFormalParameters(fd.formalParameters);
if (fd.optionalStatements != null) {
for (Java.BlockStatement bs : fd.optionalStatements) bs.accept(this.cv);
}
}
/** @see Traverser */
public void
traverseFormalParameters(Java.FunctionDeclarator.FormalParameters formalParameters) {
for (Java.FunctionDeclarator.FormalParameter formalParameter : formalParameters.parameters) {
this.traverseFormalParameter(formalParameter);
}
}
/** @see Traverser */
public void
traverseFormalParameter(Java.FunctionDeclarator.FormalParameter formalParameter) {
formalParameter.type.accept((Visitor.TypeVisitor) this.cv);
}
/** @see Traverser */
public void
traverseAbstractTypeBodyDeclaration(Java.AbstractTypeBodyDeclaration atbd) { this.traverseLocated(atbd); }
/** @see Traverser */
public void
traverseStatement(Java.Statement s) { this.traverseLocated(s); }
/** @see Traverser */
public void
traverseBreakableStatement(Java.BreakableStatement bs) { this.traverseStatement(bs); }
/** @see Traverser */
public void
traverseContinuableStatement(Java.ContinuableStatement cs) { this.traverseBreakableStatement(cs); }
/** @see Traverser */
public void
traverseRvalue(Java.Rvalue rv) { this.traverseAtom(rv); }
/** @see Traverser */
public void
traverseBooleanRvalue(Java.BooleanRvalue brv) { this.traverseRvalue(brv); }
/** @see Traverser */
public void
traverseInvocation(Java.Invocation i) {
for (Java.Rvalue argument : i.arguments) argument.accept((Visitor.RvalueVisitor) this.cv);
this.traverseRvalue(i);
}
/** @see Traverser */
public void
traverseConstructorInvocation(Java.ConstructorInvocation ci) {
for (Java.Rvalue argument : ci.arguments) argument.accept((Visitor.RvalueVisitor) this.cv);
this.traverseAtom(ci);
}
/** @see Traverser */
public void
traverseLvalue(Java.Lvalue lv) { this.traverseRvalue(lv); }
/** @see Traverser */
public void
traverseType(Java.Type t) { this.traverseAtom(t); }
/** @see Traverser */
public void
traverseAtom(Java.Atom a) { this.traverseLocated(a); }
/** @see Traverser */
public void
traverseLocated(Java.Located l) {}
}

View File

@ -1,126 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino.util.enumerator;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/**
* A class that represents an enumerated value. Its main features are its {@link #toString()} and
* {@link #fromString(String, Class)} method, which map names to values and vice versa.
* <p>
* To use this class, derive from it and define one or more
* <code>public static final</code> fields, as follows:
* <pre>
* public final class Suit extends Enumerator {
*
* // Exactly N instances of "Suit" exist to represent the N possible values.
* public static final Suit CLUBS = new Suit("clubs");
* public static final Suit DIAMONDS = new Suit("diamonds");
* public static final Suit HEARTS = new Suit("hearts");
* public static final Suit SPADES = new Suit("spades");
*
* // Optional, if you want to use EumeratorSet arithmetics.
* public static final EnumeratorSet NONE = new EnumeratorSet(Suit.class ).setName("none");
* public static final EnumeratorSet ALL = new EnumeratorSet(Suit.class, true).setName("all");
*
* // These MUST be declared exactly like this:
* private Suit(String name) { super(name); }
* public static Suit fromString(String name) throws EnumeratorFormatException {
* return (Suit) Enumerator.fromString(name, Suit.class);
* }
* }
* </pre>
*
* @see <a href="http://java.sun.com/developer/Books/effectivejava/Chapter5.pdf">Effective Java, Item 21</a>
*/
@SuppressWarnings({ "rawtypes", "unchecked" }) public abstract
class Enumerator {
private final String name;
private static final Map<Class /*enumeratorClass*/, Map<String /*name*/, Enumerator>>
INSTANCES = Collections.synchronizedMap(new HashMap());
/** Initialize the enumerator to the given value. */
protected
Enumerator(String name) {
if (name == null) throw new NullPointerException();
this.name = name;
((Map<String /*name*/, Enumerator>) Enumerator.getInstances(this.getClass())).put(name, this);
}
/** Equality is reference identity. */
@Override public final boolean
equals(Object that) { return this == that; }
/** Enforce {@link Object}'s notion of {@link Object#hashCode()}. */
@Override public final int
hashCode() { return super.hashCode(); }
/** Returns a mapping of name to Enumerator for the given enumeratorClass. */
static Map<String /*name*/, Enumerator>
getInstances(Class enumeratorClass) {
Map<String /*name*/, Enumerator> m = (Map) Enumerator.INSTANCES.get(enumeratorClass);
if (m != null) return m;
// The map need not be synchronized because it is modified only during initialization
// of the Enumerator.
m = new HashMap();
Enumerator.INSTANCES.put(enumeratorClass, m);
return m;
}
/**
* Initialize an {@link Enumerator} from a string.
* <p>
* The given string is converted into a value by looking at all instances of the given type
* created so far.
* <p>
* Derived classes should invoke this method as follows:<pre>
* public class Suit extends Enumerator {
* ...
* public static Suit fromString(String name) throws EnumeratorFormatException {
* return (Suit) Enumerator.fromString(name, Suit.class);
* }
* }</pre>
*
* @throws EnumeratorFormatException if the string cannot be identified
*/
protected static final Enumerator
fromString(String name, Class enumeratorClass) throws EnumeratorFormatException {
Enumerator value = (Enumerator) Enumerator.getInstances(enumeratorClass).get(name);
if (value == null) throw new EnumeratorFormatException(name);
return value;
}
/** Returns the <code>name</code> passed to {@link #Enumerator(String)}. */
@Override public String
toString() { return this.name; }
}

View File

@ -1,36 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino.util.enumerator;
/** Represents a problem related to parsing {@link Enumerator}s. */
public
class EnumeratorFormatException extends Exception {
private static final long serialVersionUID = -8883639721818527892L;
public EnumeratorFormatException() {}
public EnumeratorFormatException(String message) { super(message); }
}

View File

@ -1,28 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2013, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/** {@link org.codehaus.janino.util.enumerator.Enumerator}-related utility classes. */
package org.codehaus.janino.util.enumerator;

View File

@ -1,133 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino.util.iterator;
import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.codehaus.janino.JaninoRuntimeException;
import org.codehaus.janino.util.Producer;
/**
* An {@link Iterator} that finds the normal {@link File}s who's names are
* {@link FilenameFilter#accept(java.io.File, java.lang.String) accepted} by the
* <code>fileNameFilter</code> and
* <ul>
* <li>
* that exist in the given <code>rootDirectory</code>,
* </li>
* <li>
* and those that exist in all subdirectories of the
* <code>rootDirectory</code> who's names are
* {@link FilenameFilter#accept(java.io.File, java.lang.String)}ed by the
* <code>directoryNameFilter</code>
* </li>
* </ul>
*/
@SuppressWarnings({ "rawtypes", "unchecked" }) public
class DirectoryIterator extends ProducerIterator<File> {
public
DirectoryIterator(
final File rootDirectory,
final FilenameFilter directoryNameFilter,
final FilenameFilter fileNameFilter
) {
super(new Producer() {
private final List<State> stateStack = DirectoryIterator.newArrayList(new State(rootDirectory));
@Override public Object
produce() {
while (!this.stateStack.isEmpty()) {
State state = (State) this.stateStack.get(this.stateStack.size() - 1);
if (state.directories.hasNext()) {
this.stateStack.add(new State((File) state.directories.next()));
} else
if (state.files.hasNext()) {
File file = (File) state.files.next();
return file;
} else
{
this.stateStack.remove(this.stateStack.size() - 1);
}
}
return null;
}
class State {
State(File dir) {
File[] entries = dir.listFiles();
if (entries == null) {
throw new JaninoRuntimeException("Directory \"" + dir + "\" could not be read");
}
List<File> directoryList = new ArrayList();
List<File> fileList = new ArrayList();
for (File entry : entries) {
if (entry.isDirectory()) {
if (directoryNameFilter.accept(dir, entry.getName())) directoryList.add(entry);
} else
if (entry.isFile()) {
if (fileNameFilter.accept(dir, entry.getName())) fileList.add(entry);
}
}
this.directories = directoryList.iterator();
this.files = fileList.iterator();
}
final Iterator<File> directories;
final Iterator<File> files;
}
});
}
/**
* Create an {@link Iterator} that returns all matching {@link File}s locatable in a <i>set</i> of root
* directories.
*
* @see #DirectoryIterator(File, FilenameFilter, FilenameFilter)
*/
public static Iterator<File>
traverseDirectories(
File[] rootDirectories,
FilenameFilter directoryNameFilter,
FilenameFilter fileNameFilter
) {
List<Iterator<File>> result = new ArrayList();
for (File rootDirectory : rootDirectories) {
result.add(new DirectoryIterator(rootDirectory, directoryNameFilter, fileNameFilter));
}
return new MultiDimensionalIterator(result.iterator(), 2);
}
private static ArrayList
newArrayList(Object initialElement) {
ArrayList result = new ArrayList();
result.add(initialElement);
return result;
}
}

View File

@ -1,54 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino.util.iterator;
import java.util.Enumeration;
import java.util.Iterator;
/**
* An {@link java.util.Iterator} that iterates over the elements of an {@link java.util.Enumeration}.
*
* @param <T> The element type of the enumeration and the iterator
*/
public
class EnumerationIterator<T> implements Iterator<T> {
private final Enumeration<T> e;
public EnumerationIterator(Enumeration<T> e) { this.e = e; }
@Override public boolean hasNext() { return this.e.hasMoreElements(); }
@Override public T next() { return this.e.nextElement(); }
/**
* Since {@link Enumeration}s don't support element removal, this method always throws
* an {@link UnsupportedOperationException}.
*
* @see Iterator#remove()
*/
@Override public void remove() { throw new UnsupportedOperationException("remove"); }
}

View File

@ -1,48 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino.util.iterator;
import java.util.Iterator;
/**
* An {@link java.util.Iterator} that retrieves its elements from a delegate {@link java.util.Iterator}. The default
* implementation simply passes all method invocations to the delegate.
*
* @param <T> The element type of the iterator
*/
public abstract
class FilterIterator<T> implements Iterator<T> {
/** @see FilterIterator */
protected final Iterator<T> delegate;
public FilterIterator(Iterator<T> delegate) { this.delegate = delegate; }
@Override public boolean hasNext() { return this.delegate.hasNext(); }
@Override public T next() { return this.delegate.next(); }
@Override public void remove() { this.delegate.remove(); }
}

View File

@ -1,83 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino.util.iterator;
import java.util.ListIterator;
/**
* An {@link java.util.ListIterator} that retrieves its elements from a delegate {@link java.util.ListIterator}. The
* default implementation simply passes all method invocations to the delegate.
*
* @param <T> The element type of the list iterator
*/
public abstract
class FilterListIterator<T> implements ListIterator<T> {
/** @see FilterListIterator */
protected final ListIterator<T> delegate;
public
FilterListIterator(ListIterator<T> delegate) {
this.delegate = delegate;
}
/** Calls {@link #delegate}.{@link java.util.ListIterator#hasNext()} */
@Override public boolean
hasNext() { return this.delegate.hasNext(); }
/** Calls {@link #delegate}.{@link java.util.ListIterator#next()} */
@Override public T
next() { return this.delegate.next(); }
/** Calls {@link #delegate}.{@link java.util.ListIterator#hasPrevious()} */
@Override public boolean
hasPrevious() { return this.delegate.hasPrevious(); }
/** Calls {@link #delegate}.{@link java.util.ListIterator#previous()} */
@Override public T
previous() { return this.delegate.previous(); }
/** Calls {@link #delegate}.{@link java.util.ListIterator#nextIndex()} */
@Override public int
nextIndex() { return this.delegate.nextIndex(); }
/** Calls {@link #delegate}.{@link java.util.ListIterator#previousIndex()} */
@Override public int
previousIndex() { return this.delegate.previousIndex(); }
/** Calls {@link #delegate}.{@link java.util.ListIterator#remove()} */
@Override public void
remove() { this.delegate.remove(); }
/** Calls {@link #delegate}.{@link java.util.ListIterator#set(java.lang.Object)} */
@Override public void
set(T o) { this.delegate.set(o); }
/** Calls {@link #delegate}.{@link java.util.ListIterator#add(java.lang.Object)} */
@Override public void
add(T o) { this.delegate.add(o); }
}

View File

@ -1,91 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino.util.iterator;
import java.util.AbstractCollection;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* A {@link java.util.Collection} that lazily reads its elements from an
* {@link java.util.Iterator}.
* <p>
* In other words, you can call {@link #iterator()} as often as you want, but the
* {@link IteratorCollection} will iterate over its delegate only once.
*
* @param <T> The element type of the iterator and the collection
*/
@SuppressWarnings({ "rawtypes", "unchecked" }) public
class IteratorCollection<T> extends AbstractCollection<T> {
/** The delegate. */
private final Iterator<T> iterator;
/** Lazily-filled collection of the elements delivered by the delegate. */
private final List/*<T>*/ elements = new ArrayList();
public
IteratorCollection(Iterator iterator) { this.iterator = iterator; }
@Override public Iterator<T>
iterator() {
return new Iterator/*<T>*/() {
private Iterator/*<T>*/ elementsIterator = IteratorCollection.this.elements.iterator();
@Override public Object
next() {
if (this.elementsIterator != null) {
if (this.elementsIterator.hasNext()) return this.elementsIterator.next();
this.elementsIterator = null;
}
Object o = IteratorCollection.this.iterator.next();
IteratorCollection.this.elements.add(o);
return o;
}
@Override public boolean
hasNext() {
return (
(this.elementsIterator != null && this.elementsIterator.hasNext())
|| IteratorCollection.this.iterator.hasNext()
);
}
@Override public void
remove() { throw new UnsupportedOperationException(); }
};
}
@Override public int
size() {
int size = 0;
for (@SuppressWarnings("unused") Object o : this) ++size;
return size;
}
}

View File

@ -1,105 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino.util.iterator;
import java.util.Arrays;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* An {@link java.util.Iterator} that iterates over a delegate, which produces
* arrays, {@link java.util.Collection}s, {@link java.util.Enumeration}s or
* {@link java.util.Iterator}s. This {@link java.util.Iterator} returns the
* elements of these objects.
* <p>
* The count of dimensions is declared at construction. Count "1" produces an
* {@link java.util.Iterator} that adds no functionality to its delegate, count
* "2" produces an {@link Iterator} that behaves as explained above, and so
* forth.
*/
@SuppressWarnings("rawtypes") public
class MultiDimensionalIterator implements Iterator {
private final Iterator[] nest;
private static final Iterator EMPTY_ITERATOR = new Iterator() {
@Override public boolean hasNext() { return false; }
@Override public Object next() { throw new NoSuchElementException(); }
@Override public void remove() { throw new UnsupportedOperationException("remove"); }
};
public
MultiDimensionalIterator(Iterator delegate, int dimensionCount) {
this.nest = new Iterator[dimensionCount];
this.nest[0] = delegate;
for (int i = 1; i < dimensionCount; ++i) this.nest[i] = MultiDimensionalIterator.EMPTY_ITERATOR;
}
/** @throws UniterableElementException */
@SuppressWarnings("unchecked") @Override public boolean
hasNext() {
// Unroll this check because it is so performance critical:
if (this.nest[this.nest.length - 1].hasNext()) return true;
int i = this.nest.length - 2;
if (i < 0) return false;
for (;;) {
if (!this.nest[i].hasNext()) {
if (i == 0) return false;
--i;
} else {
if (i == this.nest.length - 1) return true;
Object o = this.nest[i].next();
if (o instanceof Iterator) {
this.nest[++i] = (Iterator) o;
} else
if (o instanceof Object[]) {
this.nest[++i] = Arrays.asList((Object[]) o).iterator();
} else
if (o instanceof Collection) {
this.nest[++i] = ((Collection) o).iterator();
} else
if (o instanceof Enumeration) {
this.nest[++i] = new EnumerationIterator<Object>((Enumeration) o);
} else
{
throw new UniterableElementException();
}
}
}
}
@Override public Object
next() {
if (!this.hasNext()) throw new NoSuchElementException();
return this.nest[this.nest.length - 1].next();
}
@Override public void remove() { throw new UnsupportedOperationException("remove"); }
}

View File

@ -1,69 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino.util.iterator;
import java.util.Iterator;
import java.util.NoSuchElementException;
import org.codehaus.janino.util.Producer;
/**
* An {@link Iterator} that iterates over all the objects produced by a delegate {@link Producer}.
*
* @param <T> The type of the products and the iterator elements
* @see Producer
*/
public
class ProducerIterator<T> implements Iterator<T> {
private final Producer<T> producer;
private static final Object UNKNOWN = new Object();
private static final Object AT_END = null;
private Object nextElement = ProducerIterator.UNKNOWN;
public
ProducerIterator(Producer<T> producer) { this.producer = producer; }
@Override public boolean
hasNext() {
if (this.nextElement == ProducerIterator.UNKNOWN) this.nextElement = this.producer.produce();
return this.nextElement != ProducerIterator.AT_END;
}
@Override public T
next() {
if (this.nextElement == ProducerIterator.UNKNOWN) this.nextElement = this.producer.produce();
if (this.nextElement == ProducerIterator.AT_END) throw new NoSuchElementException();
@SuppressWarnings("unchecked") T result = (T) this.nextElement;
this.nextElement = ProducerIterator.UNKNOWN;
return result;
}
@Override public void
remove() { throw new UnsupportedOperationException("remove"); }
}

View File

@ -1,66 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino.util.iterator;
import java.util.ListIterator;
/**
* A {@link java.util.ListIterator} that reverses the direction of all operations
* of a delegate {@link java.util.ListIterator}.
*
* @param <T> The element type of the list iterator
*/
public
class ReverseListIterator<T> extends FilterListIterator<T> {
public
ReverseListIterator(ListIterator<T> delegate) { super(delegate); }
/** Calls {@link #delegate}.{@link java.util.ListIterator#hasPrevious()} */
@Override public boolean
hasNext() { return super.hasPrevious(); }
/** Calls {@link #delegate}.{@link java.util.ListIterator#hasNext()} */
@Override public boolean
hasPrevious() { return super.hasNext(); }
/** Calls {@link #delegate}.{@link java.util.ListIterator#previous()} */
@Override public T
next() { return super.previous(); }
/** Calls {@link #delegate}.{@link java.util.ListIterator#next()} */
@Override public T
previous() { return super.next(); }
/** Throws an {@link UnsupportedOperationException}. */
@Override public int
nextIndex() { throw new UnsupportedOperationException(); }
/** Throws an {@link UnsupportedOperationException}. */
@Override public int
previousIndex() { throw new UnsupportedOperationException(); }
}

View File

@ -1,56 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino.util.iterator;
import java.util.Iterator;
/**
* An {@link java.util.Iterator} that transforms its elements on-the-fly.
*
* @param <T1> The element type of the delegate iterator
* @param <T2> The element type of this iterator
*/
public abstract
class TransformingIterator<T1, T2> implements Iterator<T2> {
private final Iterator<T1> delegate;
public
TransformingIterator(Iterator<T1> delegate) { this.delegate = delegate; }
@Override public boolean
hasNext() { return this.delegate.hasNext(); }
@Override public final T2
next() { return this.transform(this.delegate.next()); }
@Override public void
remove() { this.delegate.remove(); }
/** Derived classes must implement this method such that it does the desired transformation. */
protected abstract T2 transform(T1 o);
}

View File

@ -1,103 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino.util.iterator;
import java.util.Arrays;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Stack;
/**
* An {@link java.util.Iterator} that iterates over a delegate, and while it encounters an array, a {@link
* java.util.Collection}, an {@link java.util.Enumeration} or a {@link java.util.Iterator} element, it iterates over it
* recursively.
* <p>
* Be aware that {@link #hasNext()} must read ahead one element.
*/
@SuppressWarnings({ "rawtypes", "unchecked" }) public
class TraversingIterator implements Iterator {
private final Stack nest = new Stack(); // Iterator
private Object nextElement;
private boolean nextElementRead; // Have we read ahead?
public
TraversingIterator(Iterator delegate) { this.nest.push(delegate); }
@Override public boolean
hasNext() { return this.nextElementRead || this.readNext(); }
@Override public Object
next() {
if (!this.nextElementRead && !this.readNext()) throw new NoSuchElementException();
this.nextElementRead = false;
return this.nextElement;
}
/**
* Reads the next element and stores it in {@link #nextElement}.
* @return <code>false</code> if no more element can be read.
*/
private boolean
readNext() {
while (!this.nest.empty()) {
Iterator it = (Iterator) this.nest.peek();
if (!it.hasNext()) {
this.nest.pop();
continue;
}
Object o = it.next();
if (o instanceof Iterator) {
this.nest.push(o);
} else
if (o instanceof Object[]) {
this.nest.push(Arrays.asList((Object[]) o).iterator());
} else
if (o instanceof Collection) {
this.nest.push(((Collection) o).iterator());
} else
if (o instanceof Enumeration) {
this.nest.push(new EnumerationIterator((Enumeration) o));
} else
{
this.nextElement = o;
this.nextElementRead = true;
return true;
}
}
return false;
}
/**
* @throws UnsupportedOperationException iff the {@link Iterator} currently being
* traversed doesn't support element removal
* @see Iterator#remove()
*/
@Override public void
remove() { ((Iterator) this.nest.peek()).remove(); }
}

View File

@ -1,39 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino.util.iterator;
/**
* Thrown by {@link org.codehaus.janino.util.iterator.MultiDimensionalIterator} to indicate that it has encountered an
* element that cannot be iterated.
*/
public
class UniterableElementException extends RuntimeException {
private static final long serialVersionUID = 4822728738007842244L;
public UniterableElementException() {}
}

View File

@ -1,28 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2013, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/** Some generic {@link java.util.Iterator}-related helper classes. */
package org.codehaus.janino.util.iterator;

View File

@ -1,28 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2013, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/** Application-independent helper classes. */
package org.codehaus.janino.util;

View File

@ -1,46 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino.util.resource;
import java.io.File;
/**
* Creates a resource in a given directory:<pre>
* <i>destinationDirectory</i>/<i>resourceName</i></pre>
*/
public
class DirectoryResourceCreator extends FileResourceCreator {
private final File destinationDirectory;
public
DirectoryResourceCreator(File destinationDirectory) { this.destinationDirectory = destinationDirectory; }
@Override protected final File
getFile(String resourceName) {
return new File(this.destinationDirectory, resourceName.replace('/', File.separatorChar));
}
}

View File

@ -1,85 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino.util.resource;
import java.io.File;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* A {@link org.codehaus.janino.util.resource.FileResourceFinder} that finds file resources in
* a directory. The name of the file is constructed by concatenating a dirctory name
* with the resource name such that slashes in the resource name map to file
* separators.
*/
@SuppressWarnings({ "rawtypes", "unchecked" }) public
class DirectoryResourceFinder extends FileResourceFinder {
private final File directory;
private final Map<String /*directoryName*/, Set<File>> subdirectoryNameToFiles = new HashMap();
/** @param directory the directory to use as the search base */
public
DirectoryResourceFinder(File directory) { this.directory = directory; }
@Override public final String toString() { return "dir:" + this.directory; }
// Implement FileResourceFinder.
@Override protected final File
findResourceAsFile(String resourceName) {
// Determine the subdirectory name (null for no subdirectory).
int idx = resourceName.lastIndexOf('/');
String subdirectoryName = (
idx == -1 ? null :
resourceName.substring(0, idx).replace('/', File.separatorChar)
);
// Determine files existing in this subdirectory.
Set<File> files = (Set) this.subdirectoryNameToFiles.get(subdirectoryName);
if (files == null) {
File subDirectory = (
subdirectoryName == null
? this.directory
: new File(this.directory, subdirectoryName)
);
File[] fa = subDirectory.listFiles();
files = (fa == null) ? Collections.EMPTY_SET : new HashSet(Arrays.asList(fa));
this.subdirectoryNameToFiles.put(subdirectoryName, files);
}
// Notice that "File.equals()" performs all the file-system dependent
// magic like case conversion.
File file = new File(this.directory, resourceName.replace('/', File.separatorChar));
if (!files.contains(file)) return null;
return file;
}
}

View File

@ -1,50 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino.util.resource;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
/** Representation of a resource that is a {@link java.io.File}. */
public
class FileResource implements Resource {
public FileResource(File file) { this.file = file; }
// Implement "Resource".
@Override public final String getFileName() { return this.file.toString(); }
@Override public final InputStream open() throws IOException { return new FileInputStream(this.file); }
@Override public final long lastModified() { return this.file.lastModified(); }
/** @return The file containing the contents of this resource */
public final File getFile() { return this.file; }
@Override public final String toString() { return this.getFileName(); }
private final File file;
}

View File

@ -1,57 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino.util.resource;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
/** Stores a stream of bytes in a named resource. */
public abstract
class FileResourceCreator implements ResourceCreator {
@Override public final OutputStream
createResource(String resourceName) throws IOException {
File file = this.getFile(resourceName);
// Create directory for class file if it does not exist.
File dir = file.getParentFile();
if (dir != null && !dir.isDirectory()) {
if (!dir.mkdirs()) throw new IOException("Cannot create directory for class file \"" + file + "\"");
}
// Create the file.
return new FileOutputStream(file);
}
@Override public final boolean
deleteResource(String resourceName) { return this.getFile(resourceName).delete(); }
/** @return The file into which the contents is written */
protected abstract File getFile(String resourceName);
}

View File

@ -1,50 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino.util.resource;
import java.io.File;
/**
* This class specializes the {@link org.codehaus.janino.util.resource.ResourceFinder}
* for finding resources in {@link java.io.File}s.
* <p>
* It finds {@link FileResource}s instead of simple
* {@link Resource}s.
*/
public abstract
class FileResourceFinder extends ResourceFinder {
@Override public final Resource
findResource(String resourceName) {
File file = this.findResourceAsFile(resourceName);
if (file == null) return null;
return new FileResource(file);
}
/** Converts a given resource resource name into a {@link File}. */
protected abstract File findResourceAsFile(String resourceName);
}

View File

@ -1,78 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino.util.resource;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.zip.ZipFile;
import org.codehaus.janino.util.iterator.MultiDimensionalIterator;
import org.codehaus.janino.util.iterator.TransformingIterator;
/** Finds resources in any of the "*.jar" files that exist in a given set of directories. */
public
class JarDirectoriesResourceFinder extends LazyMultiResourceFinder {
/** @param directories The set of directories to search for JAR files. */
@SuppressWarnings({ "unchecked", "rawtypes" }) public
JarDirectoriesResourceFinder(final File[] directories) {
super(new MultiDimensionalIterator(
// Iterate over directories.
new TransformingIterator(Arrays.asList(directories).iterator()) {
@Override protected Object/*Iterator<ResourceFinder>*/
transform(Object/*File*/ o) {
File directory = (File) o;
if (!directory.exists()) return Collections.EMPTY_LIST.iterator();
// Iterate over the JAR files in the given directory.
File[] jarFiles = directory.listFiles(new FilenameFilter() {
@Override public boolean accept(File dir, String name) { return name.endsWith(".jar"); }
});
return new TransformingIterator(Arrays.asList(jarFiles).iterator()) {
@Override protected Object/*ResourceFinder*/
transform(Object/*File*/ o) {
File jarFile = (File) o;
try {
return new ZipFileResourceFinder(new ZipFile(jarFile));
} catch (IOException e) {
return ResourceFinder.EMPTY_RESOURCE_FINDER;
}
}
};
}
},
2
));
}
}

View File

@ -1,48 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino.util.resource;
import java.util.Iterator;
import org.codehaus.janino.util.iterator.IteratorCollection;
/**
* A {@link org.codehaus.janino.util.resource.ResourceFinder} that examines a set of {@link
* org.codehaus.janino.util.resource.ResourceFinder}s lazily as it searches for resources.
*
* @see IteratorCollection
*/
@SuppressWarnings("unchecked") public
class LazyMultiResourceFinder extends MultiResourceFinder {
/** @param resourceFinders delegate {@link ResourceFinder}s */
@SuppressWarnings("rawtypes") public
LazyMultiResourceFinder(Iterator<ResourceFinder> resourceFinders) {
super(new IteratorCollection(resourceFinders));
}
}

View File

@ -1,65 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino.util.resource;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
/** Creates resources as byte arrays in a delegate {@link java.util.Map}. */
@SuppressWarnings({ "rawtypes", "unchecked" }) public
class MapResourceCreator implements ResourceCreator {
private final Map<String, byte[]> map;
/** Auto-create the delegate {@link Map}. */
public
MapResourceCreator() { this.map = new HashMap(); }
public
MapResourceCreator(Map<String, byte[]> map) { this.map = map; }
/** @return The {@link String}-to-{@code byte[]} map of the resources created */
public final Map<String, byte[]>
getMap() { return this.map; }
@Override public final OutputStream
createResource(final String resourceName) {
return new ByteArrayOutputStream() {
@Override public void
close() throws IOException {
super.close();
MapResourceCreator.this.map.put(resourceName, this.toByteArray());
}
};
}
@Override public final boolean
deleteResource(String resourceName) { return this.map.remove(resourceName) != null; }
}

View File

@ -1,60 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino.util.resource;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.Map;
/**
* A {@link org.codehaus.janino.util.resource.ResourceFinder} that provides access
* to resource stored as byte arrays in a {@link java.util.Map}.
*/
public
class MapResourceFinder extends ResourceFinder {
private final Map<String, byte[]> map;
private long lastModified;
public
MapResourceFinder(Map<String, byte[]> map) { this.map = map; }
/** @param lastModified The return value of {@link Resource#lastModified()} for the next resources found */
public final void
setLastModified(long lastModified) { this.lastModified = lastModified; }
@Override public final Resource
findResource(final String resourceName) {
final byte[] ba = (byte[]) this.map.get(resourceName);
if (ba == null) return null;
return new Resource() {
@Override public InputStream open() { return new ByteArrayInputStream(ba); }
@Override public String getFileName() { return resourceName; }
@Override public long lastModified() { return MapResourceFinder.this.lastModified; }
};
}
}

View File

@ -1,55 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino.util.resource;
import java.util.Collection;
/**
* A {@link org.codehaus.janino.util.resource.ResourceFinder} that finds its resources through a collection of
* other {@link org.codehaus.janino.util.resource.ResourceFinder}s.
*/
public
class MultiResourceFinder extends ResourceFinder {
private final Collection<ResourceFinder> resourceFinders; // One for each entry
/** @param resourceFinders The entries of the "path" */
public
MultiResourceFinder(Collection<ResourceFinder> resourceFinders) { this.resourceFinders = resourceFinders; }
// Implement ResourceFinder.
@Override public final Resource
findResource(String resourceName) {
for (ResourceFinder rf : this.resourceFinders) {
Resource resource = rf.findResource(resourceName);
//System.err.println("*** " + resourceName + " in " + rf + "? => " + url);
if (resource != null) return resource;
}
return null;
}
}

View File

@ -1,136 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino.util.resource;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.zip.ZipFile;
import org.codehaus.janino.util.iterator.TransformingIterator;
/**
* A {@link org.codehaus.janino.util.resource.ResourceFinder} that finds its resources along a "path"
* consisting of JAR file names, ZIP file names, and directory names.
* @see org.codehaus.janino.util.resource.ZipFileResourceFinder
* @see org.codehaus.janino.util.resource.DirectoryResourceFinder
*/
@SuppressWarnings({ "rawtypes", "unchecked" }) public
class PathResourceFinder extends LazyMultiResourceFinder {
/** @param entries The entries of the "path" */
public
PathResourceFinder(final File[] entries) {
super(PathResourceFinder.createIterator(Arrays.asList(entries).iterator()));
}
/** @param entries The entries of the "path" (type must be {@link File}) */
public
PathResourceFinder(Iterator<ResourceFinder> entries) { super(entries); }
/** @param path A java-like path, i.e. a "path separator"-separated list of entries. */
public
PathResourceFinder(String path) { this(PathResourceFinder.parsePath(path)); }
private static Iterator<ResourceFinder>
createIterator(final Iterator<File> entries) {
return new TransformingIterator/*<File, ResourceFinder>*/(entries) {
@Override protected Object transform(Object o) { return PathResourceFinder.createResourceFinder((File) o); }
};
}
/**
* Break a given string up by the system-dependent path-separator character (on UNIX systems,
* this character is ':'; on Microsoft Windows systems it is ';'). Empty components are
* ignored.
* <p>
* UNIX Examples:
* <dl>
* <dt>A:B:C <dd>A, B, C
* <dt>::B: <dd>B
* <dt>:A <dd>A
* <dt>(Empty string) <dd>(Zero components)
* </dl>
*
* @see File#pathSeparatorChar
*/
public static File[]
parsePath(String s) {
int from = 0;
List<File> l = new ArrayList();
for (;;) {
int to = s.indexOf(File.pathSeparatorChar, from);
if (to == -1) {
if (from != s.length()) l.add(new File(s.substring(from)));
break;
}
if (to != from) l.add(new File(s.substring(from, to)));
from = to + 1;
}
return (File[]) l.toArray(new File[l.size()]);
}
/**
* A factory method that creates a Java classpath-style ResourceFinder as
* follows:
* <table>
* <tr><th><code>entry</code></th><th>Returned {@link ResourceFinder}</th></tr>
* <tr><td>"*.jar" file</td><td>{@link ZipFileResourceFinder}</td></tr>
* <tr><td>"*.zip" file</td><td>{@link ZipFileResourceFinder}</td></tr>
* <tr><td>directory</td><td>{@link DirectoryResourceFinder}</td></tr>
* <tr><td>any other</td><td>A {@link ResourceFinder} that never finds a resource</td></tr>
* </table>
* @return a valid {@link ResourceFinder}
*/
private static ResourceFinder
createResourceFinder(final File entry) {
// ZIP file or JAR file.
if (
(entry.getName().endsWith(".jar") || entry.getName().endsWith(".zip"))
&& entry.isFile()
) {
try {
return new ZipFileResourceFinder(new ZipFile(entry));
} catch (IOException e) {
return ResourceFinder.EMPTY_RESOURCE_FINDER;
}
}
// Directory.
if (entry.isDirectory()) {
return new DirectoryResourceFinder(entry);
}
// Invalid entry.
return ResourceFinder.EMPTY_RESOURCE_FINDER;
}
}

View File

@ -1,64 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino.util.resource;
import java.io.IOException;
import java.io.InputStream;
/**
* A {@link Resource} is "something" that is typically found by a
* {@link org.codehaus.janino.util.resource.ResourceFinder}, can be {@link #open()}ed for
* reading, and optionally has a {@link #lastModified()} property.
* <p>
* There also exists a {@link org.codehaus.janino.util.resource.ResourceCreator} concept which
* opens a resource for writing, but that happens directly and not through an intermediate
* {@link Resource} object.
*
* @see org.codehaus.janino.util.resource.ResourceFinder
* @see org.codehaus.janino.util.resource.ResourceCreator
*/
public
interface Resource {
/** Opens the resource. The caller is responsible for closing the {@link java.io.InputStream}. */
InputStream open() throws IOException;
/**
* Returns a decorative "file name" that can be used for reporting
* errors and the like. It does not necessarily map to a file in the
* local file system!
*/
String getFileName();
/**
* Returns the time of the last modification, in milliseconds since
* 1970, or <code>0L</code> if the time of the last modification cannot
* be determined.
*/
long lastModified();
}

View File

@ -1,59 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino.util.resource;
import java.io.IOException;
import java.io.OutputStream;
/**
* Opens a resource, characterized by a name, for writing.
* <p>
* There also exists a concept {@link org.codehaus.janino.util.resource.ResourceFinder} that
* finds {@link org.codehaus.janino.util.resource.Resource}s for reading.
*
* @see org.codehaus.janino.util.resource.ResourceFinder
*/
public
interface ResourceCreator {
/**
* Create the designated resource.
*
* @param resourceName Designates the resource; typically structured by slashes ("/") like
* "<code>com/foo/pkg/Bar.class</code>"
* @return Bytes written to this {@link OutputStream} are stored in the resource
* @throws IOException Problems creating the resource
*/
OutputStream createResource(String resourceName) throws IOException;
/**
* Deletes the resource with the given name.
*
* @return <code>false</code> if the resource could not be deleted
*/
boolean deleteResource(String resourceName);
}

View File

@ -1,73 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino.util.resource;
import java.io.IOException;
import java.io.InputStream;
/**
* Finds a resource by name.
* <p>
* Notice that there is a symmetrical concept
* {@link org.codehaus.janino.util.resource.ResourceCreator} that creates resources for
* writing.
*
* @see org.codehaus.janino.util.resource.ResourceCreator
*/
public abstract
class ResourceFinder {
/**
* Find a resource by name and open it for reading.
*
* @param resourceName Designates the resource; typically structured by slashes ("/") like
* "<code>com/foo/pkg/Bar.class</code>"
* @return <code>null</code> if the resource could not be found
* @throws IOException The resource was found, but there are problems opening it
*/
public final InputStream
findResourceAsStream(String resourceName) throws IOException {
Resource resource = this.findResource(resourceName);
if (resource == null) return null;
return resource.open();
}
/**
* Find a resource by name and return it as a {@link Resource} object.
*
* @param resourceName Designates the resource; typically structured by slashes ("/") like
* "<code>com/foo/pkg/Bar.class</code>"
* @return <code>null</code> if the resource could not be found
*/
public abstract Resource findResource(String resourceName);
/** This one's useful when a resource finder is required, but cannot be created for some reason. */
public static final ResourceFinder EMPTY_RESOURCE_FINDER = new ResourceFinder() {
@Override public Resource findResource(String resourceName) { return null; }
@Override public String toString() { return "invalid entry"; }
};
}

View File

@ -1,71 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.codehaus.janino.util.resource;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
/** A {@link org.codehaus.janino.util.resource.ResourceFinder} that finds resources in a ZIP file. */
public
class ZipFileResourceFinder extends ResourceFinder {
private final ZipFile zipFile;
public
ZipFileResourceFinder(ZipFile zipFile) {
this.zipFile = zipFile;
}
@Override public final String toString() { return "zip:" + this.zipFile.getName(); }
// Implement ResourceFinder.
@Override public final Resource
findResource(final String resourceName) {
final ZipEntry ze = this.zipFile.getEntry(resourceName);
if (ze == null) return null;
return new Resource() {
@Override public InputStream
open() throws IOException {
return ZipFileResourceFinder.this.zipFile.getInputStream(ze);
}
@Override public String
getFileName() {
return ZipFileResourceFinder.this.zipFile.getName() + ':' + resourceName;
}
@Override public long
lastModified() { long l = ze.getTime(); return l == -1L ? 0L : l; }
@Override public String
toString() { return this.getFileName(); }
};
}
}

View File

@ -1,31 +0,0 @@
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2013, Arno Unkrig
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* Classes related to loading "resources" ({@link org.codehaus.janino.util.resource.ResourceFinder}) and creating
* resources ({@link org.codehaus.janino.util.resource.ResourceCreator}).
*/
package org.codehaus.janino.util.resource;

View File

@ -90,10 +90,11 @@ import the.bytecode.club.bytecodeviewer.plugin.PluginManager;
* add stackmapframes to bytecode decompiler
* add stackmapframes remover?
* make ez-injection plugin console show all sys.out calls
* add JEB decompiler optionally, requires them to add jeb library jar externally and disable update check
* add JEB decompiler optionally, requires them to add jeb library jar externally and disable update check ?
* add decompile as zip for krakatau-bytecode, jd-gui and smali for CLI
* fix hook inject for EZ-Injection
* fix classfile searcher
* make the decompilers launch in a separate process?
*
* -----2.9.8-----:
* 07/19/2015 - Fixed enjarify.
@ -117,6 +118,13 @@ import the.bytecode.club.bytecodeviewer.plugin.PluginManager;
* 07/22/2015 - The Quick file search now opens the files again.
* 07/23/2015 - Fixed opening single files and file folders into BCV
* 07/24/2015 - Added File>Reload Resources.
* 07/26/2015 - Fixed the view pane refresh after toggling a viewer, it's now flawless.
* 07/26/2015 - Fixed Krakatau Disassembler.
* 07/26/2015 - Mibbzz is gay once again.
* 07/30/2015 - Removed Janino Compiler & moved to Javac, it can now compile decompiled classes again.
* 07/30/2015 - Affssdd fixed the File Navigator Pane's Quick Class Search.
* 07/30/2015 - Fixed a process leak in KrakatauDisassembler.
* 07/30/2015 - Started working on converting all the decompilers to launch in their own process in an effort to reduce BCV resources (only for non-fatjar version).
*
* @author Konloch
*
@ -126,7 +134,7 @@ public class BytecodeViewer {
/*per version*/
public static String version = "2.9.8";
public static boolean previewCopy = true;
public static boolean previewCopy = false;
public static boolean fatJar = false;
/*the rest*/
public static boolean verify = false; //eventually may be a setting
@ -138,6 +146,8 @@ public class BytecodeViewer {
public static String python3 = "";
public static String rt = "";
public static String library = "";
public static String javac = "";
public static String java = "";
public static ArrayList<FileContainer> files = new ArrayList<FileContainer>(); //all of BCV's loaded files/classes/etc
private static int maxRecentFiles = 25;
public static String fs = System.getProperty("file.separator");
@ -568,7 +578,33 @@ public class BytecodeViewer {
public static void exit(int i) {
}
/**
* Returns the java command it can use to launch the decompilers
* @return
*/
public static String getJavaCommand() {
try {
sm.stopBlocking();
ProcessBuilder pb = new ProcessBuilder("java", "-version");
Process p = pb.start();
sm.setBlocking();
if(p != null)
return "java"; //java is set
} catch(Exception e) { //ignore
sm.setBlocking();
boolean empty = java.isEmpty();
while(empty) {
showMessage("You need to set your Java path, this requires the JRE to be downloaded."+BytecodeViewer.nl+
"(C:/programfiles/Java/JRE_xx/bin/javac.exe)");
viewer.java();
if(!java.isEmpty())
empty = false;
}
}
return java;
}
/**
* Returns the currently opened ClassNode
* @return the currently opened ClassNode
@ -639,6 +675,7 @@ public class BytecodeViewer {
* @return true if no errors, false if it failed to compile.
*/
public static boolean compile(boolean message) {
BytecodeViewer.viewer.setIcon(true);
boolean actuallyTried = false;
for(java.awt.Component c : BytecodeViewer.viewer.workPane.getLoadedViewers()) {
@ -659,6 +696,7 @@ public class BytecodeViewer {
BytecodeViewer.updateNode(origNode, newNode);
} else {
BytecodeViewer.showMessage("There has been an error with assembling your Smali code, please check this. Class: " + origNode.name);
BytecodeViewer.viewer.setIcon(false);
return false;
}
}
@ -680,6 +718,7 @@ public class BytecodeViewer {
BytecodeViewer.updateNode(origNode, newNode);
} else {
BytecodeViewer.showMessage("There has been an error with assembling your Krakatau Bytecode, please check this. Class: " + origNode.name);
BytecodeViewer.viewer.setIcon(false);
return false;
}
}
@ -694,10 +733,10 @@ public class BytecodeViewer {
if(java != null) {
ClassNode origNode = (ClassNode) java[0];
String javaText = (String) java[1];
SystemErrConsole errConsole = new SystemErrConsole("Java Compile Issues");
errConsole.setText("Error compiling class: " + origNode.name + nl + "Keep in mind most decompilers cannot produce compilable classes"+nl+nl);
byte[] javaCompiled = the.bytecode.club.bytecodeviewer.compilers.Compiler.java.compile(javaText, origNode.name);
if(javaCompiled != null) {
ClassNode newNode = JarUtils.getNode(javaCompiled);
@ -707,6 +746,7 @@ public class BytecodeViewer {
errConsole.pretty();
errConsole.setVisible(true);
errConsole.finished();
BytecodeViewer.viewer.setIcon(false);
return false;
}
}
@ -720,6 +760,7 @@ public class BytecodeViewer {
else
BytecodeViewer.showMessage("You have no editable panes opened, make one editable and try again.");
BytecodeViewer.viewer.setIcon(false);
return true;
}
@ -1181,7 +1222,12 @@ public class BytecodeViewer {
BytecodeViewer.resetWorkSpace(true);
} else if ((e.getKeyCode() == KeyEvent.VK_T) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) {
last = System.currentTimeMillis();
BytecodeViewer.compile(true);
Thread t = new Thread() {
public void run() {
BytecodeViewer.compile(true);
}
};
t.start();
} else if ((e.getKeyCode() == KeyEvent.VK_R) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) {
last = System.currentTimeMillis();
if(BytecodeViewer.getLoadedClasses().isEmpty()) {
@ -1196,62 +1242,68 @@ public class BytecodeViewer {
BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file.");
return;
}
if(viewer.autoCompileSmali.isSelected() && !BytecodeViewer.compile(false))
return;
JFileChooser fc = new JFileChooser();
fc.setFileFilter(new FileFilter() {
@Override
public boolean accept(File f) {
return f.isDirectory() || MiscUtils.extension(f.getAbsolutePath()).equals("zip");
}
@Override
public String getDescription() {
return "Zip Archives";
}
});
fc.setFileHidingEnabled(false);
fc.setAcceptAllFileFilterUsed(false);
int returnVal = fc.showSaveDialog(viewer);
if (returnVal == JFileChooser.APPROVE_OPTION) {
File file = fc.getSelectedFile();
if(!file.getAbsolutePath().endsWith(".zip"))
file = new File(file.getAbsolutePath()+".zip");
if(file.exists()) {
JOptionPane pane = new JOptionPane(
"Are you sure you wish to overwrite this existing file?");
Object[] options = new String[] { "Yes", "No" };
pane.setOptions(options);
JDialog dialog = pane.createDialog(BytecodeViewer.viewer,
"Bytecode Viewer - Overwrite File");
dialog.setVisible(true);
Object obj = pane.getValue();
int result = -1;
for (int k = 0; k < options.length; k++)
if (options[k].equals(obj))
result = k;
if (result == 0) {
file.delete();
} else {
Thread t = new Thread() {
public void run() {
if(viewer.autoCompileSmali.isSelected() && !BytecodeViewer.compile(false))
return;
JFileChooser fc = new JFileChooser();
fc.setFileFilter(new FileFilter() {
@Override
public boolean accept(File f) {
return f.isDirectory() || MiscUtils.extension(f.getAbsolutePath()).equals("zip");
}
@Override
public String getDescription() {
return "Zip Archives";
}
});
fc.setFileHidingEnabled(false);
fc.setAcceptAllFileFilterUsed(false);
int returnVal = fc.showSaveDialog(viewer);
if (returnVal == JFileChooser.APPROVE_OPTION) {
File file = fc.getSelectedFile();
if(!file.getAbsolutePath().endsWith(".zip"))
file = new File(file.getAbsolutePath()+".zip");
if(file.exists()) {
JOptionPane pane = new JOptionPane(
"Are you sure you wish to overwrite this existing file?");
Object[] options = new String[] { "Yes", "No" };
pane.setOptions(options);
JDialog dialog = pane.createDialog(BytecodeViewer.viewer,
"Bytecode Viewer - Overwrite File");
dialog.setVisible(true);
Object obj = pane.getValue();
int result = -1;
for (int k = 0; k < options.length; k++)
if (options[k].equals(obj))
result = k;
if (result == 0) {
file.delete();
} else {
return;
}
}
final File file2 = file;
BytecodeViewer.viewer.setIcon(true);
Thread t = new Thread() {
@Override
public void run() {
JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(),
file2.getAbsolutePath());
BytecodeViewer.viewer.setIcon(false);
}
};
t.start();
}
}
final File file2 = file;
BytecodeViewer.viewer.setIcon(true);
Thread t = new Thread() {
@Override
public void run() {
JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(),
file2.getAbsolutePath());
BytecodeViewer.viewer.setIcon(false);
}
};
t.start();
}
};
t.start();
} else if ((e.getKeyCode() == KeyEvent.VK_W) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) {
last = System.currentTimeMillis();
if(viewer.workPane.getCurrentViewer() != null)

View File

@ -1,9 +1,6 @@
package the.bytecode.club.bytecodeviewer;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
/**
* A simple wrapper for Enjarify.
@ -25,6 +22,11 @@ public class Enjarify {
BytecodeViewer.viewer.pythonC3();
}
if(BytecodeViewer.python3.equals("")) {
BytecodeViewer.showMessage("You need to set Python!");
return;
}
BytecodeViewer.sm.stopBlocking();
try {
ProcessBuilder pb = new ProcessBuilder(
@ -38,35 +40,14 @@ public class Enjarify {
);
pb.directory(new File(BytecodeViewer.enjarifyWorkingDirectory));
Process process = pb.start();
BytecodeViewer.createdProcesses.add(process);
process.waitFor();
//Read out dir output
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
br.close();
is = process.getErrorStream();
isr = new InputStreamReader(is);
br = new BufferedReader(isr);
while ((line = br.readLine()) != null) {
System.out.println(line);
}
br.close();
int exitValue = process.waitFor();
System.out.println("Exit Value is " + exitValue);
} catch(Exception e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
} finally {
BytecodeViewer.sm.setBlocking();
}
BytecodeViewer.sm.setBlocking();
}
}

View File

@ -13,6 +13,8 @@ import java.util.jar.JarOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import me.konloch.kontainer.io.DiskWriter;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.tree.ClassNode;
@ -42,11 +44,11 @@ public class JarUtils {
while ((entry = jis.getNextEntry()) != null) {
try {
final String name = entry.getName();
final byte[] bytes = getBytes(jis);
if (!name.endsWith(".class")) {
if(!entry.isDirectory())
files.put(name, getBytes(jis));
files.put(name, bytes);
} else {
byte[] bytes = getBytes(jis);
String cafebabe = String.format("%02X", bytes[0])
+ String.format("%02X", bytes[1])
+ String.format("%02X", bytes[2])
@ -232,7 +234,6 @@ public class JarUtils {
*/
public static void saveAsJarClassesOnly(ArrayList<ClassNode> nodeList, String path) {
try {
System.out.println("zipping");
JarOutputStream out = new JarOutputStream(new FileOutputStream(path));
ArrayList<String> noDupe = new ArrayList<String>();
for (ClassNode cn : nodeList) {
@ -256,6 +257,28 @@ public class JarUtils {
}
}
/**
* Saves a jar without the manifest
* @param nodeList The loaded ClassNodes
* @param path the exact jar output path
*/
public static void saveAsJarClassesOnlyToDir(ArrayList<ClassNode> nodeList, String dir) {
try {
for (ClassNode cn : nodeList) {
ClassWriter cw = new ClassWriter(0);
cn.accept(cw);
String name = dir + BytecodeViewer.fs + cn.name + ".class";
File f = new File(name);
f.mkdirs();
DiskWriter.replaceFile(name, cw.toByteArray(), false);
}
} catch (Exception e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
}
}
/**
* Saves a jar without the manifest
* @param nodeList The loaded ClassNodes

View File

@ -15,39 +15,39 @@ public class NewlineOutputStream extends FilterOutputStream {
private static byte[] newline;
public NewlineOutputStream(OutputStream os) {
super(os);
if (newline == null) {
String s = System.getProperty("line.separator");
if (s == null || s.length() <= 0)
s = "\n";
try {
newline = s.getBytes("iso-8859-1"); // really us-ascii
} catch (UnsupportedEncodingException ex) {
// should never happen
newline = new byte[] { (byte)'\n' };
}
}
super(os);
if (newline == null) {
String s = System.getProperty("line.separator");
if (s == null || s.length() <= 0)
s = "\n";
try {
newline = s.getBytes("iso-8859-1"); // really us-ascii
} catch (UnsupportedEncodingException ex) {
// should never happen
newline = new byte[] { (byte)'\n' };
}
}
}
public void write(int b) throws IOException {
if (b == '\r') {
out.write(newline);
} else if (b == '\n') {
if (lastb != '\r')
out.write(newline);
} else {
out.write(b);
}
lastb = b;
if (b == '\r') {
out.write(newline);
} else if (b == '\n') {
if (lastb != '\r')
out.write(newline);
} else {
out.write(b);
}
lastb = b;
}
public void write(byte b[]) throws IOException {
write(b, 0, b.length);
write(b, 0, b.length);
}
public void write(byte b[], int off, int len) throws IOException {
for (int i = 0 ; i < len ; i++) {
write(b[off + i]);
}
for (int i = 0 ; i < len ; i++) {
write(b[off + i]);
}
}
}

View File

@ -2,6 +2,7 @@ package the.bytecode.club.bytecodeviewer;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.util.ArrayList;
import javax.imageio.ImageIO;
@ -98,4 +99,13 @@ public class Resources {
return image;
}
public static String findLibrary(String nameContains) {
for(File f : new File(BytecodeViewer.libsDirectory).listFiles()) {
if(f.getName().contains(nameContains))
return f.getAbsolutePath();
}
return null;
}
}

View File

@ -20,10 +20,15 @@ public class SecurityMan extends SecurityManager {
public void stopBlocking() { //slightly safer security system than just a public static boolean being toggled
String executedClass = Thread.currentThread().getStackTrace()[2].getClassName();
if( executedClass.equals("the.bytecode.club.bytecodeviewer.decompilers.KrakatauDecompiler") ||
executedClass.equals("the.bytecode.club.bytecodeviewer.decompilers.KrakatauDisassambler") ||
executedClass.equals("the.bytecode.club.bytecodeviewer.decompilers.KrakatauDisassembler") ||
executedClass.equals("the.bytecode.club.bytecodeviewer.decompilers.CFRDecompiler") ||
executedClass.equals("the.bytecode.club.bytecodeviewer.decompilers.ProcyonDecompiler") ||
executedClass.equals("the.bytecode.club.bytecodeviewer.decompilers.FernFlowerDecompiler") ||
executedClass.equals("the.bytecode.club.bytecodeviewer.decompilers.JDGUIDecompiler") ||
executedClass.equals("the.bytecode.club.bytecodeviewer.compilers.KrakatauAssembler") ||
executedClass.equals("the.bytecode.club.bytecodeviewer.Enjarify") ||
executedClass.equals("the.bytecode.club.bytecodeviewer.BytecodeViewer"))
executedClass.equals("the.bytecode.club.bytecodeviewer.BytecodeViewer") ||
executedClass.equals("the.bytecode.club.bytecodeviewer.compilers.JavaCompiler"))
{
blocking = false;
} else for(StackTraceElement stackTraceElements : Thread.currentThread().getStackTrace()) {
@ -38,7 +43,8 @@ public class SecurityMan extends SecurityManager {
String[] whitelist = {
"attrib",
"python",
"pypy"
"pypy",
"java"
};
boolean allow = false;

View File

@ -195,6 +195,8 @@ public class Settings {
else if(BytecodeViewer.viewer.apkConversionGroup.isSelected(BytecodeViewer.viewer.apkConversionEnjarify.getModel()))
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "1", false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, BytecodeViewer.python3, false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, BytecodeViewer.javac, false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, BytecodeViewer.java, false);
} catch(Exception e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
}
@ -389,6 +391,8 @@ public class Settings {
else if(decompiler == 1)
BytecodeViewer.viewer.apkConversionGroup.setSelected(BytecodeViewer.viewer.apkConversionEnjarify.getModel(), true);
BytecodeViewer.python3 = DiskReader.loadString(BytecodeViewer.settingsName, 115, false);
BytecodeViewer.javac = DiskReader.loadString(BytecodeViewer.settingsName, 116, false);
BytecodeViewer.java = DiskReader.loadString(BytecodeViewer.settingsName, 117, false);
} catch(Exception e) {
//ignore because errors are expected, first start up and outdated settings.
//e.printStackTrace();

View File

@ -98,6 +98,7 @@ public class ExceptionUI extends JFrame {
getContentPane().add(new JScrollPane(txtrBytecodeViewerIs),
"name_140466576080695");
txtrBytecodeViewerIs.setText(e);
System.err.println(e);
this.setLocationRelativeTo(null);
this.setVisible(true);
}

View File

@ -1,7 +1,10 @@
package the.bytecode.club.bytecodeviewer.compilers;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import me.konloch.kontainer.io.DiskWriter;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
@ -26,21 +29,77 @@ public class JavaCompiler extends Compiler {
File cp = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + "cpath_"+MiscUtils.randomString(12)+".jar");
File tempD = new File(fileStart + BytecodeViewer.fs + name.substring(0,name.length() - name.split("/")[name.split("/").length-1].length()));
tempD.mkdirs();
new File(fileStart2).mkdirs();
if(BytecodeViewer.javac.equals("")) {
BytecodeViewer.showMessage("You need to set your Javac path, this requires the JDK to be downloaded."+BytecodeViewer.nl+"(C:/programfiles/Java/JRE_xx/bin/javac.exe)");
BytecodeViewer.viewer.javac();
}
if(BytecodeViewer.javac.equals("")) {
BytecodeViewer.showMessage("You need to set Javac!");
return null;
}
DiskWriter.replaceFile(java.getAbsolutePath(), contents, false);
JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(), cp.getAbsolutePath());
boolean cont = true;
BytecodeViewer.sm.stopBlocking();
try {
org.codehaus.janino.Compiler.BCV(new String[]{
"-d", fileStart2,
"-classpath", cp.getAbsolutePath(),
java.getAbsolutePath()
});
String log = "";
ProcessBuilder pb;
if(BytecodeViewer.library.isEmpty()) {
pb = new ProcessBuilder(
BytecodeViewer.javac,
"-d", fileStart2,
"-classpath", cp.getAbsolutePath(),
java.getAbsolutePath()
);
} else {
pb = new ProcessBuilder(
BytecodeViewer.javac,
"-d", fileStart2,
"-classpath", cp.getAbsolutePath()+";"+BytecodeViewer.library,
java.getAbsolutePath()
);
}
Process process = pb.start();
BytecodeViewer.createdProcesses.add(process);
//Read out dir output
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null) {
log += BytecodeViewer.nl + line;
}
br.close();
log += BytecodeViewer.nl+BytecodeViewer.nl+"Error:"+BytecodeViewer.nl+BytecodeViewer.nl;
is = process.getErrorStream();
isr = new InputStreamReader(is);
br = new BufferedReader(isr);
while ((line = br.readLine()) != null) {
log += BytecodeViewer.nl + line;
}
br.close();
int exitValue = process.waitFor();
log += BytecodeViewer.nl+BytecodeViewer.nl+"Exit Value is " + exitValue;
System.out.println(log);
if(!clazz.exists())
throw new Exception(log);
} catch(Exception e) {
cont = false;
e.printStackTrace();
}
BytecodeViewer.sm.setBlocking();
cp.delete();

View File

@ -24,17 +24,20 @@ public class KrakatauAssembler extends Compiler {
BytecodeViewer.showMessage("You need to set your Python (or PyPy for speed) 2.7 executable path.");
BytecodeViewer.viewer.pythonC();
}
if(BytecodeViewer.python.equals("")) {
BytecodeViewer.showMessage("You need to set Python!");
return null;
}
String origName = name;
name = MiscUtils.randomString(20);
System.out.println("run");
File tempD = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + MiscUtils.randomString(32) + BytecodeViewer.fs);
tempD.mkdir();
File tempJ = new File(tempD.getAbsolutePath() + BytecodeViewer.fs+name+".j");
DiskWriter.replaceFile(tempJ.getAbsolutePath(), contents, true);
System.out.println("ran");
final File tempDirectory = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + MiscUtils.randomString(32) + BytecodeViewer.fs);
tempDirectory.mkdir();
@ -77,7 +80,7 @@ public class KrakatauAssembler extends Compiler {
int exitValue = process.waitFor();
log += BytecodeViewer.nl+BytecodeViewer.nl+"Exit Value is " + exitValue;
System.out.println(log);
//System.out.println(log);
byte[] b = org.apache.commons.io.FileUtils.readFileToByteArray(new File(tempDirectory.getAbsolutePath() + BytecodeViewer.fs + origName + ".class"));
tempDirectory.delete();

View File

@ -16,11 +16,14 @@ import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import me.konloch.kontainer.io.DiskReader;
import org.apache.commons.lang3.ArrayUtils;
import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.JarUtils;
import the.bytecode.club.bytecodeviewer.MiscUtils;
import the.bytecode.club.bytecodeviewer.Resources;
/**
* CFR Java Wrapper
@ -48,8 +51,24 @@ public class CFRDecompiler extends Decompiler {
}
String fuckery = fuckery(fileStart);
org.benf.cfr.reader.Main.main(generateMainMethod(
tempClass.getAbsolutePath(), fuckery));
/*if(!BytecodeViewer.fatJar) {
try {
ProcessBuilder pb = new ProcessBuilder(ArrayUtils.addAll(
new String[]{BytecodeViewer.getJavaCommand(),"-jar",Resources.findLibrary("cfr")},
generateMainMethod(tempClass.getAbsolutePath(), fuckery)
));
BytecodeViewer.sm.stopBlocking();
Process p = pb.start();
BytecodeViewer.createdProcesses.add(p);
p.waitFor();
} catch(Exception e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
} finally {
BytecodeViewer.sm.setBlocking();
}
} else {*/
org.benf.cfr.reader.Main.main(generateMainMethod(tempClass.getAbsolutePath(), fuckery));
//}
tempClass.delete();

View File

@ -42,6 +42,17 @@ public class KrakatauDecompiler extends Decompiler {
BytecodeViewer.showMessage("You need to set your JRE RT Library.\r\n(C:\\Program Files (x86)\\Java\\jre7\\lib\\rt.jar)");
BytecodeViewer.viewer.rtC();
}
if(BytecodeViewer.python.equals("")) {
BytecodeViewer.showMessage("You need to set Python!");
return "Set your paths";
}
if(BytecodeViewer.rt.equals("")) {
BytecodeViewer.showMessage("You need to set RT.jar!");
return "Set your paths";
}
String s = "Bytecode Viewer Version: " + BytecodeViewer.version + BytecodeViewer.nl + BytecodeViewer.nl + "Please send this to konloch@gmail.com. " + BytecodeViewer.nl + BytecodeViewer.nl;
final File tempDirectory = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + MiscUtils.randomString(32) + BytecodeViewer.fs);
@ -139,27 +150,7 @@ public class KrakatauDecompiler extends Decompiler {
Process process = pb.start();
BytecodeViewer.createdProcesses.add(process);
//Read out dir output
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
br.close();
is = process.getErrorStream();
isr = new InputStreamReader(is);
br = new BufferedReader(isr);
while ((line = br.readLine()) != null) {
System.out.println(line);
}
br.close();
int exitValue = process.waitFor();
System.out.println("Exit Value is " + exitValue);
process.waitFor();
// ZipUtils.zipDirectory(tempDirectory, new File(zipName));
ZipUtils.zipFolder(tempDirectory.getAbsolutePath(), zipName, ran);
@ -173,67 +164,4 @@ public class KrakatauDecompiler extends Decompiler {
}
}
public void decompileToClass(String className, String classNameSaved) {
if(BytecodeViewer.python.equals("")) {
BytecodeViewer.showMessage("You need to set your Python (or PyPy for speed) 2.7 executable path.");
BytecodeViewer.viewer.pythonC();
}
if(BytecodeViewer.rt.equals("")) {
BytecodeViewer.showMessage("You need to set your JRE RT Library.\r\n(C:\\Program Files (x86)\\Java\\jre7\\lib\\rt.jar)");
BytecodeViewer.viewer.rtC();
}
final File tempDirectory = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + MiscUtils.randomString(32) + BytecodeViewer.fs);
tempDirectory.mkdir();
final File tempJar = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp.jar");
JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(), tempJar.getAbsolutePath());
BytecodeViewer.sm.stopBlocking();
try {
ProcessBuilder pb = new ProcessBuilder(
BytecodeViewer.python,
"-O", //love you storyyeller <3
BytecodeViewer.krakatauWorkingDirectory + BytecodeViewer.fs + "decompile.py",
"-nauto",
"-path",
BytecodeViewer.rt+";"+tempJar.getAbsolutePath(),
"-out",
tempDirectory.getAbsolutePath(),
className+".class"
);
Process process = pb.start();
//Read out dir output
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
br.close();
is = process.getErrorStream();
isr = new InputStreamReader(is);
br = new BufferedReader(isr);
while ((line = br.readLine()) != null) {
System.out.println(line);
}
br.close();
int exitValue = process.waitFor();
System.out.println("Exit Value is " + exitValue);
File f = new File(tempDirectory.getAbsolutePath() + BytecodeViewer.fs + className + ".java");
f.renameTo(new File(classNameSaved));
tempDirectory.delete();
tempJar.delete();
} catch(Exception e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
} finally {
BytecodeViewer.sm.setBlocking();
}
}
}

Some files were not shown because too many files have changed in this diff Show More