pax_global_header00006660000000000000000000000064122226406230014511gustar00rootroot0000000000000052 comment=2c27618650dc03a426f70007a552a1952dae7c47 janino-2.7.0/000077500000000000000000000000001222264062300127755ustar00rootroot00000000000000janino-2.7.0/commons-compiler-jdk/000077500000000000000000000000001222264062300170265ustar00rootroot00000000000000janino-2.7.0/commons-compiler-jdk/.checkstyle000066400000000000000000000010171222264062300211640ustar00rootroot00000000000000 janino-2.7.0/commons-compiler-jdk/pom.xml000066400000000000000000000017271222264062300203520ustar00rootroot00000000000000 4.0.0 org.codehaus.janino janino-parent 2.6.2-SNAPSHOT commons-compiler-jdk Commons Compiler Jdk org.codehaus.janino commons-compiler org.apache.maven.plugins maven-compiler-plugin 1.6 1.6 janino-2.7.0/commons-compiler-jdk/src/000077500000000000000000000000001222264062300176155ustar00rootroot00000000000000janino-2.7.0/commons-compiler-jdk/src/org.codehaus.commons.compiler.properties000066400000000000000000000001031222264062300275710ustar00rootroot00000000000000compilerFactory=org.codehaus.commons.compiler.jdk.CompilerFactory janino-2.7.0/commons-compiler-jdk/src/org/000077500000000000000000000000001222264062300204045ustar00rootroot00000000000000janino-2.7.0/commons-compiler-jdk/src/org/codehaus/000077500000000000000000000000001222264062300221775ustar00rootroot00000000000000janino-2.7.0/commons-compiler-jdk/src/org/codehaus/commons/000077500000000000000000000000001222264062300236525ustar00rootroot00000000000000janino-2.7.0/commons-compiler-jdk/src/org/codehaus/commons/compiler/000077500000000000000000000000001222264062300254645ustar00rootroot00000000000000janino-2.7.0/commons-compiler-jdk/src/org/codehaus/commons/compiler/jdk/000077500000000000000000000000001222264062300262345ustar00rootroot00000000000000ByteArrayJavaFileManager.java000066400000000000000000000170101222264062300336160ustar00rootroot00000000000000janino-2.7.0/commons-compiler-jdk/src/org/codehaus/commons/compiler/jdk /* * 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.commons.compiler.jdk; import java.io.*; import java.net.URI; import java.util.*; import java.util.Map.Entry; import javax.tools.*; import javax.tools.JavaFileObject.Kind; /** * A {@link ForwardingJavaFileManager} that stores {@link JavaFileObject}s in byte arrays, i.e. in * memory (as opposed to the {@link StandardJavaFileManager}, which stores them in files). */ public class ByteArrayJavaFileManager extends ForwardingJavaFileManager { /** location => kind => className => JavaFileObject */ Map>> javaFiles = ( new HashMap>>() ); public ByteArrayJavaFileManager(M delegate) { super(delegate); } @Override public FileObject getFileForInput(Location location, String packageName, String relativeName) { throw new UnsupportedOperationException("getFileForInput"); } @Override public FileObject getFileForOutput( Location location, String packageName, String relativeName, FileObject sibling ) { throw new UnsupportedOperationException("getFileForInput"); } @Override public JavaFileObject getJavaFileForInput(Location location, String className, Kind kind) throws IOException { Map> locationJavaFiles = this.javaFiles.get(location); if (locationJavaFiles == null) return null; Map kindJavaFiles = locationJavaFiles.get(kind); if (kindJavaFiles == null) return null; return kindJavaFiles.get(className); } @Override public JavaFileObject getJavaFileForOutput( Location location, final String className, Kind kind, FileObject sibling ) throws IOException { /** * {@link StringWriter}-based implementation of {@link JavaFileObject}. *

* Notice that {@link #getCharContent(boolean)} is much more efficient than {@link * ByteArrayJavaFileObject#getCharContent(boolean)}. However, memory consumption is * roughly double, and {@link #openInputStream()} and {@link #openOutputStream()} are * not available. */ class StringWriterJavaFileObject extends SimpleJavaFileObject { final StringWriter buffer = new StringWriter(); public StringWriterJavaFileObject(Kind kind) { super( URI.create("stringbuffer:///" + className.replace('.', '/') + kind.extension), kind ); } @Override public Writer openWriter() throws IOException { return this.buffer; } @Override public Reader openReader(boolean ignoreEncodingErrors) throws IOException { return new StringReader(this.buffer.toString()); } @Override public CharSequence getCharContent(boolean ignoreEncodingErrors) { return this.buffer.getBuffer(); } } JavaFileObject fileObject = ( kind == Kind.SOURCE ? new StringWriterJavaFileObject(kind) : new ByteArrayJavaFileObject(className, kind) ); Map> locationJavaFiles = this.javaFiles.get(location); if (locationJavaFiles == null) { locationJavaFiles = new HashMap>(); this.javaFiles.put(location, locationJavaFiles); } Map kindJavaFiles = locationJavaFiles.get(kind); if (kindJavaFiles == null) { kindJavaFiles = new HashMap(); locationJavaFiles.put(kind, kindJavaFiles); } kindJavaFiles.put(className, fileObject); return fileObject; } @Override public Iterable list( Location location, String packageName, Set kinds, boolean recurse ) throws IOException { Map> locationFiles = this.javaFiles.get(location); if (locationFiles == null) return super.list(location, packageName, kinds, recurse); String prefix = packageName.length() == 0 ? "" : packageName + "."; int pl = prefix.length(); List result = new ArrayList(); for (Kind kind : kinds) { Map kindFiles = locationFiles.get(kind); if (kindFiles == null) continue; for (Entry e : kindFiles.entrySet()) { String className = e.getKey(); if (!className.startsWith(prefix)) continue; if (!recurse && className.indexOf('.', pl) != -1) continue; result.add(e.getValue()); } } return result; } /** * Byte array-based implementation of {@link JavaFileObject}. */ public static class ByteArrayJavaFileObject extends SimpleJavaFileObject { final ByteArrayOutputStream buffer = new ByteArrayOutputStream(); public ByteArrayJavaFileObject(String className, Kind kind) { super( URI.create("bytearray:///" + className.replace('.', '/') + kind.extension), kind ); } @Override public OutputStream openOutputStream() throws IOException { return this.buffer; } public byte[] toByteArray() { return this.buffer.toByteArray(); } @Override public InputStream openInputStream() throws IOException { return new ByteArrayInputStream(this.toByteArray()); } } } janino-2.7.0/commons-compiler-jdk/src/org/codehaus/commons/compiler/jdk/ClassBodyEvaluator.java000066400000000000000000000253361222264062300326560ustar00rootroot00000000000000 /* * 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.commons.compiler.jdk; import java.io.BufferedReader; import java.io.IOException; import java.io.PrintWriter; import java.io.Reader; import java.io.StringReader; import java.io.StringWriter; import java.nio.CharBuffer; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.codehaus.commons.compiler.CompileException; import org.codehaus.commons.compiler.IClassBodyEvaluator; import org.codehaus.commons.io.MultiReader; /** * To set up a {@link ClassBodyEvaluator} object, proceed as described for {@link * IClassBodyEvaluator}. Alternatively, a number of "convenience constructors" exist that execute * the described steps instantly. *

* Notice that this implementation of {@link IClassBodyEvaluator} is prone to "Java * injection", i.e. an application could get more than one class body compiled by passing a * bogus input document. *

* Also notice that the parsing of leading IMPORT declarations is heuristic and has certain * limitations; see {@link #parseImportDeclarations(Reader)}. * * @see IClassBodyEvaluator */ public class ClassBodyEvaluator extends SimpleCompiler implements IClassBodyEvaluator { private String[] optionalDefaultImports; private String className = IClassBodyEvaluator.DEFAULT_CLASS_NAME; private Class optionalExtendedType; private Class[] implementedTypes = new Class[0]; private Class result; @Override public void setClassName(String className) { assertNotCooked(); this.className = className; } @Override public void setDefaultImports(String[] optionalDefaultImports) { assertNotCooked(); this.optionalDefaultImports = optionalDefaultImports; } @Override public void setExtendedClass(@SuppressWarnings("rawtypes") Class optionalExtendedType) { assertNotCooked(); this.optionalExtendedType = optionalExtendedType; } /** @deprecated */ @Deprecated @Override public void setExtendedType(@SuppressWarnings("rawtypes") Class optionalExtendedClass) { this.setExtendedClass(optionalExtendedClass); } @Override public void setImplementedInterfaces(@SuppressWarnings("rawtypes") Class[] implementedTypes) { assertNotCooked(); this.implementedTypes = implementedTypes; } /** @deprecated */ @Deprecated @Override public void setImplementedTypes(@SuppressWarnings("rawtypes") Class[] implementedInterfaces) { this.setImplementedInterfaces(implementedInterfaces); } @Override public void cook(String optionalFileName, Reader r) throws CompileException, IOException { if (!r.markSupported()) r = new BufferedReader(r); this.cook(optionalFileName, ClassBodyEvaluator.parseImportDeclarations(r), r); } /** * @param imports E.g. "java.io.*" or "static java.util.Arrays.asList" * @param r The class body to cook, without leading IMPORT declarations */ protected void cook(String optionalFileName, String[] imports, Reader r) throws CompileException, IOException { // Wrap the class body in a compilation unit. { StringWriter sw1 = new StringWriter(); { PrintWriter pw = new PrintWriter(sw1); // Break the class name up into package name and simple class name. String packageName; // null means default package. String simpleClassName; { int idx = this.className.lastIndexOf('.'); if (idx == -1) { packageName = ""; simpleClassName = this.className; } else { packageName = this.className.substring(0, idx); simpleClassName = this.className.substring(idx + 1); } } // Print PACKAGE directive. if (!packageName.isEmpty()) { pw.print("package "); pw.print(packageName); pw.println(";"); } // Print default imports. if (this.optionalDefaultImports != null) { for (String defaultImport : this.optionalDefaultImports) { pw.print("import "); pw.print(defaultImport); pw.println(";"); } } // Print imports as declared in the document. if (!r.markSupported()) r = new BufferedReader(r); for (String imporT : imports) { pw.print("import "); pw.print(imporT); pw.println(";"); } // Print the class declaration. pw.print("public class "); pw.print(simpleClassName); if (this.optionalExtendedType != null) { pw.print(" extends "); pw.print(this.optionalExtendedType.getCanonicalName()); } if (this.implementedTypes.length > 0) { pw.print(" implements "); pw.print(this.implementedTypes[0].getName()); for (int i = 1; i < this.implementedTypes.length; ++i) { pw.print(", "); pw.print(this.implementedTypes[i].getName()); } } pw.println(" {"); pw.close(); } StringWriter sw2 = new StringWriter(); { PrintWriter pw = new PrintWriter(sw2); pw.println("}"); pw.close(); } r = new MultiReader(new Reader[] { new StringReader(sw1.toString()), r, new StringReader(sw2.toString()), }); } /** * Compile the generated compilation unit. */ super.cook(optionalFileName, r); try { // Load the "main" class through the ClassLoader that was created by // "SimpleCompiler.cook()". More classes (e.g. member types will be loaded // automatically by the JVM. this.result = this.getClassLoader().loadClass(this.className); } catch (ClassNotFoundException cnfe) { throw new IOException(cnfe); } } /** * @return The {@link Class} created by the preceding call to {@link #cook(Reader)} */ @Override public Class getClazz() { return this.result; } /** * Heuristically parse IMPORT declarations at the beginning of the character stream produced * by the given {@link Reader}. After this method returns, all characters up to and including * that last IMPORT declaration have been read from the {@link Reader}. *

* This method does not handle comments and string literals correctly, i.e. if a pattern that * looks like an IMPORT declaration appears within a comment or a string literal, it will be * taken as an IMPORT declaration. * * @param r A {@link Reader} that supports MARK, e.g. a {@link BufferedReader} * @return The parsed imports, e.g. {@code { "java.util.*", "static java.util.Map.Entry" }} */ protected static String[] parseImportDeclarations(Reader r) throws IOException { final CharBuffer cb = CharBuffer.allocate(10000); r.mark(cb.limit()); r.read(cb); cb.rewind(); List imports = new ArrayList(); int afterLastImport = 0; for (Matcher matcher = IMPORT_STATEMENT_PATTERN.matcher(cb); matcher.find();) { imports.add(matcher.group(1)); afterLastImport = matcher.end(); } r.reset(); r.skip(afterLastImport); return imports.toArray(new String[imports.size()]); } private static final Pattern IMPORT_STATEMENT_PATTERN = Pattern.compile( "\\bimport\\s+" + "(" + "(?:static\\s+)?" + "[\\p{javaLowerCase}\\p{javaUpperCase}_\\$][\\p{javaLowerCase}\\p{javaUpperCase}\\d_\\$]*" + "(?:\\.[\\p{javaLowerCase}\\p{javaUpperCase}_\\$][\\p{javaLowerCase}\\p{javaUpperCase}\\d_\\$]*)*" + "(?:\\.\\*)?" + ");" ); @Override public Object createInstance(Reader reader) throws CompileException, IOException { this.cook(reader); try { return this.getClazz().newInstance(); } catch (InstantiationException ie) { throw new CompileException(( "Class is abstract, an interface, an array class, a primitive type, or void; " + "or has no zero-parameter constructor" ), null, ie); } catch (IllegalAccessException iae) { throw new CompileException("The class or its zero-parameter constructor is not accessible", null, iae); } } } janino-2.7.0/commons-compiler-jdk/src/org/codehaus/commons/compiler/jdk/CompilerFactory.java000066400000000000000000000060211222264062300322000ustar00rootroot00000000000000 /* * 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.commons.compiler.jdk; import java.security.AccessController; import java.security.PrivilegedAction; import org.codehaus.commons.compiler.*; public class CompilerFactory extends AbstractCompilerFactory { @Override public String getId() { return "org.codehaus.commons.compiler.jdk"; } @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 AccessController.doPrivileged(new PrivilegedAction() { @Override public JavaSourceClassLoader run() { return new JavaSourceClassLoader(); } }); } @Override public AbstractJavaSourceClassLoader newJavaSourceClassLoader(final ClassLoader parentClassLoader) { return AccessController.doPrivileged(new PrivilegedAction() { @Override public JavaSourceClassLoader run() { return new JavaSourceClassLoader(parentClassLoader); } }); } } janino-2.7.0/commons-compiler-jdk/src/org/codehaus/commons/compiler/jdk/ExpressionEvaluator.java000066400000000000000000000244171222264062300331310ustar00rootroot00000000000000 /* * 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.commons.compiler.jdk; import java.io.BufferedReader; import java.io.IOException; import java.io.PrintWriter; import java.io.Reader; import java.io.StringReader; import java.io.StringWriter; import org.codehaus.commons.compiler.CompileException; import org.codehaus.commons.compiler.Cookable; import org.codehaus.commons.compiler.IExpressionEvaluator; /** * This {@link IExpressionEvaluator} is implemented by creating and compiling a temporary compilation unit defining one * class with one static method with one RETURN statement. *

* A number of "convenience constructors" exist that execute the set-up steps described for {@link * IExpressionEvaluator} instantly. *

* If the parameter and return types of the expression are known at compile time, then a "fast" expression evaluator can * be instantiated through {@link #createFastEvaluator(String, Class, String[])}. Expression evaluation is faster than * through {@link #evaluate(Object[])}, because it is not done through reflection but through direct method invocation. *

* Example: *

 * 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
 * 
* Notice: The {@code interfaceToImplement} must either be declared {@code public}, * or with package scope in the root package (i.e. "no" package). *

* On my system (Intel P4, 2 GHz, MS Windows XP, JDK 1.4.1), expression "x + 1" * evaluates as follows: * * * * *
Server JVMClient JVM
Normal EE23.7 ns64.0 ns
Fast EE31.2 ns42.2 ns
* (How can it be that interface method invocation is slower than reflection for * the server JVM?) */ public class ExpressionEvaluator extends ScriptEvaluator implements IExpressionEvaluator { private Class[] optionalExpressionTypes; /** * Equivalent to

     * ExpressionEvaluator ee = new ExpressionEvaluator();
     * ee.setExpressionType(expressionType);
     * ee.setParameters(parameterNames, parameterTypes);
     * ee.cook(expression);
* * @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
     * ExpressionEvaluator ee = new ExpressionEvaluator();
     * ee.setExpressionType(expressionType);
     * ee.setParameters(parameterNames, parameterTypes);
     * ee.setThrownExceptions(thrownExceptions);
     * ee.setParentClassLoader(optionalParentClassLoader);
     * ee.cook(expression);
* * @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
     * 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);
* * @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); } public ExpressionEvaluator() {} @Override public void setExpressionType(@SuppressWarnings("rawtypes") Class expressionType) { this.setExpressionTypes(new Class[] { expressionType }); } @Override public void setExpressionTypes(@SuppressWarnings("rawtypes") Class[] expressionTypes) { 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 == ANY_TYPE ? Object.class : et; } super.setReturnTypes(returnTypes); } @Override @Deprecated public final void setReturnType(@SuppressWarnings("rawtypes") Class returnType) { throw new AssertionError("Must not be used on an ExpressionEvaluator; use 'setExpressionType()' instead"); } @Override @Deprecated public final void setReturnTypes(@SuppressWarnings("rawtypes") Class[] returnTypes) { throw new AssertionError("Must not be used on an ExpressionEvaluator; use 'setExpressionTypes()' instead"); } @Override protected Class getDefaultReturnType() { return Object.class; } @Override public void cook(String[] optionalFileNames, Reader[] readers) throws CompileException, IOException { readers = readers.clone(); // Don't modify the argument array. String[] imports; if (readers.length == 1) { if (!readers[0].markSupported()) readers[0] = new BufferedReader(readers[0]); imports = parseImportDeclarations(readers[0]); } else { imports = new String[0]; } Class[] returnTypes = new Class[readers.length]; for (int i = 0; i < readers.length; ++i) { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); if (this.optionalExpressionTypes == null || this.optionalExpressionTypes[i] == ANY_TYPE) { returnTypes[i] = Object.class; pw.print("return org.codehaus.commons.compiler.PrimitiveWrapper.wrap("); pw.write(readString(readers[i])); pw.println(");"); } else { returnTypes[i] = this.optionalExpressionTypes[i]; if (returnTypes[i] != void.class && returnTypes[i] != Void.class) { pw.print("return "); } pw.write(readString(readers[i])); pw.println(";"); } pw.close(); readers[i] = new StringReader(sw.toString()); } super.setReturnTypes(returnTypes); this.cook(optionalFileNames, readers, imports); } } FileInputJavaFileManager.java000066400000000000000000000165161222264062300336250ustar00rootroot00000000000000janino-2.7.0/commons-compiler-jdk/src/org/codehaus/commons/compiler/jdk /* * 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.commons.compiler.jdk; import java.io.*; import java.util.*; import javax.tools.*; import javax.tools.JavaFileManager.Location; import javax.tools.JavaFileObject.Kind; import org.codehaus.commons.compiler.Cookable; /** * A {@link ForwardingJavaFileManager} that maps accesses to a particular {@link Location} and {@link Kind} to * a path-based search in the file system. */ final class FileInputJavaFileManager extends ForwardingJavaFileManager { private final Location location; private final Kind kind; private final File[] path; private final String optionalCharacterEncoding; /** * @param path List of directories to look through * @param optionalCharacterEncoding Encoding of the files being read */ FileInputJavaFileManager( JavaFileManager delegate, Location location, Kind kind, File[] path, String optionalCharacterEncoding ) { super(delegate); this.location = location; this.kind = kind; this.path = path; this.optionalCharacterEncoding = optionalCharacterEncoding; } @Override public Iterable list(Location location, String packageName, Set kinds, boolean recurse) throws IOException { if (location == this.location && kinds.contains(this.kind)) { Collection result = new ArrayList(); String rel = packageName.replace('.', File.separatorChar); for (File directory : this.path) { File packageDirectory = new File(directory, rel); result.addAll(this.list( packageDirectory, packageName.isEmpty() ? "" : packageName + ".", this.kind, recurse )); } return result; } return super.list(location, packageName, kinds, recurse); } /** * @param qualification E.g. "", or "pkg1.pkg2." * @return All {@link JavaFileObject}s of the given {@code kind} in the given {@code directory} */ private Collection list(File directory, String qualification, Kind kind, boolean recurse) throws IOException { if (!directory.isDirectory()) return Collections.emptyList(); Collection result = new ArrayList(); for (String name : directory.list()) { File file = new File(directory, name); if (name.endsWith(kind.extension)) { result.add(new InputFileJavaFileObject( file, qualification + name.substring(0, name.length() - kind.extension.length()) )); } else if (recurse && file.isDirectory()) { result.addAll(this.list(file, qualification + name + ".", kind, true)); } } return result; } @Override public String inferBinaryName(Location location, JavaFileObject file) { if (location == this.location) return ((InputFileJavaFileObject) file).getBinaryName(); return super.inferBinaryName(location, file); } @Override public boolean hasLocation(Location location) { return location == this.location || super.hasLocation(location); } @Override public JavaFileObject getJavaFileForInput(Location location, String className, Kind kind) throws IOException { if (location == this.location && kind == this.kind) { // Find the source file through the source path. final File sourceFile; FIND_SOURCE: { String rel = className.replace('.', File.separatorChar) + kind.extension; for (File sourceDirectory : this.path) { File f = new File(sourceDirectory, rel); if (f.exists()) { sourceFile = f.getCanonicalFile(); break FIND_SOURCE; } } return null; } // Create and return a JavaFileObject. return new InputFileJavaFileObject(sourceFile, className); } return super.getJavaFileForInput(location, className, kind); } /** * A {@link JavaFileObject} that reads from a {@link File}. */ private class InputFileJavaFileObject extends SimpleJavaFileObject { private final File file; private final String binaryName; public InputFileJavaFileObject(File file, String binaryName) { super(file.toURI(), FileInputJavaFileManager.this.kind); this.file = file; this.binaryName = binaryName; } @SuppressWarnings("resource") @Override public Reader openReader(boolean ignoreEncodingErrors) throws IOException { return ( FileInputJavaFileManager.this.optionalCharacterEncoding == null ? new FileReader(this.file) : new InputStreamReader( new FileInputStream(this.file), FileInputJavaFileManager.this.optionalCharacterEncoding ) ); } @Override public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException { Reader r = this.openReader(true); try { return Cookable.readString(r); } finally { r.close(); } } String getBinaryName() { return this.binaryName; } } } JavaFileManagerClassLoader.java000066400000000000000000000066541222264062300341240ustar00rootroot00000000000000janino-2.7.0/commons-compiler-jdk/src/org/codehaus/commons/compiler/jdk /* * 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.commons.compiler.jdk; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import javax.tools.JavaFileManager; import javax.tools.JavaFileObject; import javax.tools.StandardLocation; import javax.tools.JavaFileObject.Kind; public class JavaFileManagerClassLoader extends ClassLoader { private final JavaFileManager javaFileManager; public JavaFileManagerClassLoader(JavaFileManager javaFileManager) { this.javaFileManager = javaFileManager; } public JavaFileManagerClassLoader(JavaFileManager javaFileManager, ClassLoader parentClassLoader) { super(parentClassLoader); this.javaFileManager = javaFileManager; } @Override protected Class findClass(String className) throws ClassNotFoundException { byte[] ba; try { JavaFileObject classFile = this.javaFileManager.getJavaFileForInput( StandardLocation.CLASS_OUTPUT, className, Kind.CLASS ); if (classFile == null) throw new ClassNotFoundException(className); ByteArrayOutputStream baos = new ByteArrayOutputStream(); { InputStream is = classFile.openInputStream(); try { byte[] buffer = new byte[8192]; for (;;) { int count = is.read(buffer); if (count == -1) break; baos.write(buffer, 0, count); } } finally { try { is.close(); } catch (Exception e) {} } } ba = baos.toByteArray(); } catch (IOException ioe) { throw new ClassNotFoundException(className, ioe); } return this.defineClass(className, ba, 0, ba.length); } } janino-2.7.0/commons-compiler-jdk/src/org/codehaus/commons/compiler/jdk/JavaSourceClassLoader.java000066400000000000000000000253501222264062300332630ustar00rootroot00000000000000 /* * 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.commons.compiler.jdk; import java.io.*; import java.util.*; import javax.tools.*; import javax.tools.JavaFileObject.Kind; import org.codehaus.commons.compiler.*; import org.codehaus.commons.compiler.jdk.ByteArrayJavaFileManager.ByteArrayJavaFileObject; public class JavaSourceClassLoader extends AbstractJavaSourceClassLoader { private File[] sourcePath; private String optionalCharacterEncoding; private boolean debuggingInfoLines; private boolean debuggingInfoVars; private boolean debuggingInfoSource; private Collection compilerOptions = new ArrayList(); private JavaCompiler compiler; private JavaFileManager fileManager; /** * @see ICompilerFactory#newJavaSourceClassLoader() */ public JavaSourceClassLoader() { this.init(); } /** * @see ICompilerFactory#newJavaSourceClassLoader(ClassLoader) */ public JavaSourceClassLoader(ClassLoader parentClassLoader) { super(parentClassLoader); this.init(); } private void init() { this.compiler = ToolProvider.getSystemJavaCompiler(); if (this.compiler == null) { throw new UnsupportedOperationException( "JDK Java compiler not available - probably you're running a JRE, not a JDK" ); } } /** * Creates the underlying {@link JavaFileManager} lazily, because {@link #setSourcePath(File[])} and consorts * are called after initialization. */ JavaFileManager getJavaFileManager() { if (this.fileManager == null) { // Get the original FM, which reads class files through this JVM's BOOTCLASSPATH and // CLASSPATH. JavaFileManager jfm = this.compiler.getStandardFileManager(null, null, null); // Wrap it so that the output files (in our case class files) are stored in memory rather // than in files. jfm = new ByteArrayJavaFileManager(jfm); // Wrap it in a file manager that finds source files through the source path. jfm = new FileInputJavaFileManager( jfm, StandardLocation.SOURCE_PATH, Kind.SOURCE, this.sourcePath, this.optionalCharacterEncoding ); this.fileManager = jfm; } return this.fileManager; } @Override public void setSourcePath(File[] sourcePath) { this.sourcePath = sourcePath; } @Override public void setSourceFileCharacterEncoding(String optionalCharacterEncoding) { this.optionalCharacterEncoding = optionalCharacterEncoding; } @Override public void setDebuggingInfo(boolean lines, boolean vars, boolean source) { this.debuggingInfoLines = lines; this.debuggingInfoVars = vars; this.debuggingInfoSource = source; } /** * Notice: Don't use the '-g' options - these are controlled through {@link #setDebuggingInfo(boolean, boolean, * boolean)}. * * @param compilerOptions All command line options supported by the JDK JAVAC tool */ public void setCompilerOptions(String[] compilerOptions) { this.compilerOptions = Arrays.asList(compilerOptions); } /** * Implementation of {@link ClassLoader#findClass(String)}. * * @throws ClassNotFoundException */ @Override protected Class findClass(String className) throws ClassNotFoundException { byte[] ba; int size; try { // Maybe the bytecode is already there, because the class was compiled as a side effect of a preceding // compilation. JavaFileObject classFileObject = this.getJavaFileManager().getJavaFileForInput( StandardLocation.CLASS_OUTPUT, className, Kind.CLASS ); if (classFileObject == null) { // Get the sourceFile. JavaFileObject sourceFileObject = this.getJavaFileManager().getJavaFileForInput( StandardLocation.SOURCE_PATH, className, Kind.SOURCE ); if (sourceFileObject == null) { throw new DiagnosticException("Source for '" + className + "' not found"); } // Compose the effective compiler options. List options = new ArrayList(this.compilerOptions); options.add(this.debuggingInfoLines ? ( this.debuggingInfoSource ? ( this.debuggingInfoVars ? "-g" : "-g:lines,source" ) : this.debuggingInfoVars ? "-g:lines,vars" : "-g:lines" ) : this.debuggingInfoSource ? ( this.debuggingInfoVars ? "-g:source,vars" : "-g:source" ) : this.debuggingInfoVars ? "-g:vars" : "-g:none"); // Run the compiler. if (!this.compiler.getTask( null, // out this.getJavaFileManager(), // fileManager new DiagnosticListener() { // diagnosticListener @Override public void report(final Diagnostic diagnostic) { if (diagnostic.getKind() == Diagnostic.Kind.ERROR) { throw new DiagnosticException(diagnostic); } } }, options, // options null, // classes Collections.singleton(sourceFileObject) // compilationUnits ).call()) { throw new ClassNotFoundException(className + ": Compilation failed"); } classFileObject = this.getJavaFileManager().getJavaFileForInput( StandardLocation.CLASS_OUTPUT, className, Kind.CLASS ); if (classFileObject == null) { throw new ClassNotFoundException(className + ": Class file not created by compilation"); } } if (classFileObject instanceof ByteArrayJavaFileObject) { ByteArrayJavaFileObject bajfo = (ByteArrayJavaFileObject) classFileObject; ba = bajfo.toByteArray(); size = ba.length; } else { ba = new byte[4096]; size = 0; InputStream is = classFileObject.openInputStream(); try { for (;;) { int res = is.read(ba, size, ba.length - size); if (res == -1) break; size += res; if (size == ba.length) { byte[] tmp = new byte[2 * size]; System.arraycopy(ba, 0, tmp, 0, size); ba = tmp; } } } finally { is.close(); } } } catch (IOException ioe) { throw new DiagnosticException(ioe); } return this.defineClass(className, ba, 0, size, ( this.optionalProtectionDomainFactory == null ? null : this.optionalProtectionDomainFactory.getProtectionDomain(getSourceResourceName(className)) )); } /** * Construct the name of a resource that could contain the source code of * the class with the given name. *

* Notice that member types are declared inside a different type, so the relevant source file * is that of the outermost declaring class. * * @param className Fully qualified class name, e.g. "pkg1.pkg2.Outer$Inner" * @return the name of the resource, e.g. "pkg1/pkg2/Outer.java" */ private static String getSourceResourceName(String className) { // Strip nested type suffixes. { int idx = className.lastIndexOf('.') + 1; idx = className.indexOf('$', idx); if (idx != -1) className = className.substring(0, idx); } return className.replace('.', '/') + ".java"; } public static class DiagnosticException extends RuntimeException { private static final long serialVersionUID = 5589635876875819926L; public DiagnosticException(String message) { super(message); } public DiagnosticException(Throwable cause) { super(cause); } public DiagnosticException(Diagnostic diagnostic) { super(diagnostic.toString()); } } } janino-2.7.0/commons-compiler-jdk/src/org/codehaus/commons/compiler/jdk/ScriptEvaluator.java000066400000000000000000000543271222264062300322410ustar00rootroot00000000000000 /* * 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.commons.compiler.jdk; import java.io.*; import java.lang.reflect.*; import java.util.*; import org.codehaus.commons.compiler.*; import org.codehaus.commons.io.MultiReader; /** * To set up a {@link ScriptEvaluator} object, proceed as described for {@link IScriptEvaluator}. * Alternatively, a number of "convenience constructors" exist that execute the described steps * instantly. *

* Alternatively, a number of "convenience constructors" exist that execute the steps described * above instantly. Their use is discouraged. *

* Notice that this implementation of {@link IClassBodyEvaluator} is prone to "Java * injection", i.e. an application could get more than one class body compiled by passing a * bogus input document. *

* Also notice that the parsing of leading IMPORT declarations is heuristic and has certain * limitations; see {@link #parseImportDeclarations(Reader)}. */ 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; protected Class[] optionalReturnTypes; protected String[] optionalMethodNames; protected String[][] optionalParameterNames; protected Class[][] optionalParameterTypes; protected Class[][] optionalThrownExceptions; /** null=uncooked */ private Method[] result; /** * Equivalent to

     * ScriptEvaluator se = new ScriptEvaluator();
     * se.cook(script);
* * @see #ScriptEvaluator() * @see Cookable#cook(String) */ public ScriptEvaluator(String script) throws CompileException { this.cook(script); } /** * Equivalent to
     * ScriptEvaluator se = new ScriptEvaluator();
     * se.setReturnType(returnType);
     * se.cook(script);
* * @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
     * ScriptEvaluator se = new ScriptEvaluator();
     * se.setReturnType(returnType);
     * se.setParameters(parameterNames, parameterTypes);
     * se.cook(script);
* * @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
     * ScriptEvaluator se = new ScriptEvaluator();
     * se.setReturnType(returnType);
     * se.setParameters(parameterNames, parameterTypes);
     * se.setThrownExceptions(thrownExceptions);
     * se.cook(script);
* * @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
     * ScriptEvaluator se = new ScriptEvaluator();
     * se.setReturnType(returnType);
     * se.setParameters(parameterNames, parameterTypes);
     * se.setThrownExceptions(thrownExceptions);
     * se.setParentClassLoader(optionalParentClassLoader);
     * se.cook(optionalFileName, is);
* * @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
     * ScriptEvaluator se = new ScriptEvaluator();
     * se.setReturnType(returnType);
     * se.setParameters(parameterNames, parameterTypes);
     * se.setThrownExceptions(thrownExceptions);
     * se.setParentClassLoader(optionalParentClassLoader);
     * se.cook(reader);
* * @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); } public ScriptEvaluator() {} @Override public void setOverrideMethod(boolean overrideMethod) { this.setOverrideMethod(new boolean[] { overrideMethod }); } @Override public void setStaticMethod(final boolean staticMethod) { this.setStaticMethod(new boolean[] { staticMethod }); } @Override public void setReturnType(@SuppressWarnings("rawtypes") Class returnType) { this.setReturnTypes(new Class[] { returnType }); } @Override public void setMethodName(String methodName) { this.setMethodNames(new String[] { methodName }); } @Override public void setParameters(String[] names, @SuppressWarnings("rawtypes") Class[] types) { this.setParameters(new String[][] { names }, new Class[][] { types }); } @Override public void setThrownExceptions(@SuppressWarnings("rawtypes") Class[] thrownExceptions) { this.setThrownExceptions(new Class[][] { thrownExceptions }); } @Override public void cook(String optionalFileName, Reader r) throws CompileException, IOException { this.cook(new String[] { optionalFileName }, new Reader[] { r }); } @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) { assertNotCooked(); this.optionalOverrideMethod = overrideMethod.clone(); } @Override public void setStaticMethod(boolean[] staticMethod) { assertNotCooked(); this.optionalStaticMethod = staticMethod.clone(); } @Override public void setReturnTypes(@SuppressWarnings("rawtypes") Class[] returnTypes) { assertNotCooked(); this.optionalReturnTypes = returnTypes.clone(); } @Override public void setMethodNames(String[] methodNames) { assertNotCooked(); this.optionalMethodNames = methodNames.clone(); } @Override public void setParameters(String[][] names, @SuppressWarnings("rawtypes") Class[][] types) { assertNotCooked(); this.optionalParameterNames = names.clone(); this.optionalParameterTypes = types.clone(); } @Override public void setThrownExceptions(@SuppressWarnings("rawtypes") Class[][] thrownExceptions) { assertNotCooked(); this.optionalThrownExceptions = thrownExceptions.clone(); } @Override public final void cook(Reader[] readers) throws CompileException, IOException { this.cook(null, readers); } @Override public void cook(String[] optionalFileNames, Reader[] readers) throws CompileException, IOException { String[] imports; if (readers.length == 1) { if (!readers[0].markSupported()) { readers = new Reader[] { new BufferedReader(readers[0]) }; } imports = parseImportDeclarations(readers[0]); } else { imports = new String[0]; } this.cook(optionalFileNames, readers, imports); } @Override public final void cook(String[] strings) throws CompileException { this.cook(null, strings); } @Override public 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 ioe) { throw new RuntimeException("SNO: IOException despite StringReader", ioe); } } /** * @param readers The scripts to cook */ protected final void cook(String[] optionalFileNames, Reader[] readers, String[] imports) throws CompileException, IOException { // The "dimension" of this ScriptEvaluator, i.e. how many scripts are cooked at the same // time. int count = readers.length; // Check array sizes. if (this.optionalMethodNames != null && this.optionalMethodNames.length != count) { throw new IllegalStateException("methodName"); } if (this.optionalParameterNames != null && this.optionalParameterNames.length != count) { throw new IllegalStateException("parameterNames"); } if (this.optionalParameterTypes != null && this.optionalParameterTypes.length != count) { throw new IllegalStateException("parameterTypes"); } if (this.optionalReturnTypes != null && this.optionalReturnTypes.length != count) { throw new IllegalStateException("returnTypes"); } if (this.optionalOverrideMethod != null && this.optionalOverrideMethod.length != count) { throw new IllegalStateException("overrideMethod"); } if (this.optionalStaticMethod != null && this.optionalStaticMethod.length != count) { throw new IllegalStateException("staticMethod"); } if (this.optionalThrownExceptions != null && this.optionalThrownExceptions.length != count) { throw new IllegalStateException("thrownExceptions"); } // 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 compilation unit. List classBody = new ArrayList(); // Create methods with one block each. for (int i = 0; i < count; ++i) { boolean overrideMethod = this.optionalOverrideMethod != null && this.optionalOverrideMethod[i]; boolean staticMethod = this.optionalStaticMethod == null || this.optionalStaticMethod[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] ); { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); if (overrideMethod) pw.print("@Override "); pw.print("public "); if (staticMethod) pw.print("static "); pw.print(returnType.getName()); pw.print(" "); pw.print(methodNames[i]); pw.print("("); for (int j = 0; j < parameterNames.length; ++j) { if (j > 0) pw.print(", "); pw.print(parameterTypes[j].getName()); pw.print(" "); pw.print(parameterNames[j]); } pw.print(")"); for (int j = 0; j < thrownExceptions.length; ++j) { pw.print(j == 0 ? " throws " : ", "); pw.print(thrownExceptions[j].getName()); } pw.println(" {"); pw.close(); classBody.add(new StringReader(sw.toString())); } classBody.add(readers[i]); { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); pw.println("}"); pw.close(); classBody.add(new StringReader(sw.toString())); } } super.cook(optionalFileNames == null ? null : optionalFileNames[0], imports, new MultiReader(classBody)); Class c = this.getClazz(); // 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 RuntimeException( "SNO: Loaded class does not declare method \"" + methodNames[i] + "\"", ex ); } } } else { // "getDeclaredMethod()" implements a linear search which is inefficient like hell for // classes with MANY methods (like an ExpressionEvaluator with a 10000 methods). Thus // we se "getDeclaredMethods()" and sort things out ourselves with a HashMap. 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; return ( this.name.equals(that.name) && Arrays.equals(this.parameterTypes, that.parameterTypes) ); } @Override public int hashCode() { return this.name.hashCode() ^ Arrays.hashCode(this.parameterTypes); } } Method[] ma = c.getDeclaredMethods(); Map dms = new HashMap(2 * count); for (int i = 0; i < ma.length; ++i) { Method m = ma[i]; dms.put(new MethodWrapper(m.getName(), m.getParameterTypes()), m); } for (int i = 0; i < count; ++i) { Method m = dms.get(new MethodWrapper( methodNames[i], this.optionalParameterTypes == null ? new Class[0] : this.optionalParameterTypes[i] )); if (m == null) { throw new RuntimeException("SNO: Loaded class does not declare method \"" + methodNames[i] + "\""); } this.result[i] = m; } } } protected Class getDefaultReturnType() { return void.class; } /** * @param script Contains the sequence of script tokens * @see #createFastEvaluator(String, Class, String[]) */ @Override public Object createFastEvaluator( String script, @SuppressWarnings("rawtypes") Class interfaceToImplement, String[] parameterNames ) throws CompileException { try { return this.createFastEvaluator(new StringReader(script), interfaceToImplement, parameterNames); } catch (IOException ioe) { throw new RuntimeException("SNO: IOException despite StringReader", ioe); } } /** * Don't use. */ @Override public final Object createInstance(Reader reader) { throw new UnsupportedOperationException("createInstance"); } @Override public Object createFastEvaluator( Reader r, @SuppressWarnings("rawtypes") Class interfaceToImplement, String[] parameterNames ) throws CompileException, IOException { if (!interfaceToImplement.isInterface()) { throw new RuntimeException("\"" + interfaceToImplement + "\" is not an interface"); } Method[] methods = interfaceToImplement.getDeclaredMethods(); if (methods.length != 1) { throw new RuntimeException("Interface \"" + interfaceToImplement + "\" must declare exactly one method"); } Method methodToImplement = methods[0]; this.setImplementedInterfaces(new Class[] { interfaceToImplement }); 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(r); Class c = this.getMethod().getDeclaringClass(); try { return c.newInstance(); } catch (InstantiationException e) { throw new RuntimeException("SNO - Declared class is always non-abstract", e); } catch (IllegalAccessException e) { throw new RuntimeException("SNO - interface methods are always PUBLIC", e); } } @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 RuntimeException(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]; } } janino-2.7.0/commons-compiler-jdk/src/org/codehaus/commons/compiler/jdk/SimpleCompiler.java000066400000000000000000000271451222264062300320340ustar00rootroot00000000000000 /* * 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.commons.compiler.jdk; import java.io.*; import java.net.*; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.*; import javax.tools.*; import javax.tools.JavaFileObject.Kind; import org.codehaus.commons.compiler.*; public class SimpleCompiler extends Cookable implements ISimpleCompiler { private ClassLoader parentClassLoader = Thread.currentThread().getContextClassLoader(); private ClassLoader result; private boolean debugSource; private boolean debugLines; private boolean debugVars; @Override public ClassLoader getClassLoader() { assertCooked(); return this.result; } @Override public void cook(String optionalFileName, final Reader r) throws CompileException, IOException { assertNotCooked(); // Create one Java source file in memory, which will be compiled later. JavaFileObject compilationUnit; { URI uri; try { uri = new URI("simplecompiler"); } catch (URISyntaxException use) { throw new RuntimeException(use); } compilationUnit = new SimpleJavaFileObject(uri, Kind.SOURCE) { @Override public boolean isNameCompatible(String simpleName, Kind kind) { return true; } @Override public Reader openReader(boolean ignoreEncodingErrors) throws IOException { return r; } @Override public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException { return readString(this.openReader(ignoreEncodingErrors)); } }; } // Find the JDK Java compiler. JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); if (compiler == null) { throw new CompileException( "JDK Java compiler not available - probably you're running a JRE, not a JDK", null ); } // Get the original FM, which reads class files through this JVM's BOOTCLASSPATH and // CLASSPATH. final JavaFileManager fm = compiler.getStandardFileManager(null, null, null); // Wrap it so that the output files (in our case class files) are stored in memory rather // than in files. final JavaFileManager fileManager = new ByteArrayJavaFileManager(fm); // Run the compiler. try { if (!compiler.getTask( null, // out fileManager, // fileManager new DiagnosticListener() { // diagnosticListener @Override public void report(Diagnostic diagnostic) { //System.err.println("*** " + diagnostic.toString() + " *** " + diagnostic.getCode()); Location loc = new Location( diagnostic.getSource().toString(), (short) diagnostic.getLineNumber(), (short) diagnostic.getColumnNumber() ); String code = diagnostic.getCode(); String message = diagnostic.getMessage(null) + " (" + code + ")"; // Wrap the exception in a RuntimeException, because "report()" does not declare checked // exceptions. throw new RuntimeException(new CompileException(message, loc)); } }, Collections.singletonList( // options this.debugSource ? "-g:source" + (this.debugLines ? ",lines" : "") + (this.debugVars ? ",vars" : "") : this.debugLines ? "-g:lines" + (this.debugVars ? ",vars" : "") : this.debugVars ? "-g:vars" : "-g:none" ), null, // classes Collections.singleton(compilationUnit) // compilationUnits ).call()) { throw new CompileException("Compilation failed", null); } } catch (RuntimeException rte) { // Unwrap the compilation exception and throw it. Throwable cause = rte.getCause(); if (cause != null) { cause = cause.getCause(); if (cause instanceof CompileException) { throw (CompileException) cause; // SUPPRESS CHECKSTYLE AvoidHidingCause } if (cause instanceof IOException) { throw (IOException) cause; // SUPPRESS CHECKSTYLE AvoidHidingCause } } throw rte; } // Create a ClassLoader that reads class files from our FM. this.result = AccessController.doPrivileged(new PrivilegedAction() { @Override public JavaFileManagerClassLoader run() { return new JavaFileManagerClassLoader(fileManager, SimpleCompiler.this.parentClassLoader); } }); } protected void cook(JavaFileObject compilationUnit) throws CompileException, IOException { // Find the JDK Java compiler. JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); if (compiler == null) { throw new CompileException( "JDK Java compiler not available - probably you're running a JRE, not a JDK", null ); } // Get the original FM, which reads class files through this JVM's BOOTCLASSPATH and // CLASSPATH. final JavaFileManager fm = compiler.getStandardFileManager(null, null, null); // Wrap it so that the output files (in our case class files) are stored in memory rather // than in files. final JavaFileManager fileManager = new ByteArrayJavaFileManager(fm); // Run the compiler. try { if (!compiler.getTask( null, // out fileManager, // fileManager new DiagnosticListener() { // diagnosticListener @Override public void report(Diagnostic diagnostic) { System.err.println("*** " + diagnostic.toString() + " *** " + diagnostic.getCode()); Location loc = new Location( diagnostic.getSource().toString(), (short) diagnostic.getLineNumber(), (short) diagnostic.getColumnNumber() ); String code = diagnostic.getCode(); String message = diagnostic.getMessage(null) + " (" + code + ")"; // Wrap the exception in a RuntimeException, because "report()" does not declare checked // exceptions. throw new RuntimeException(new CompileException(message, loc)); } }, null, // options null, // classes Collections.singleton(compilationUnit) // compilationUnits ).call()) { throw new CompileException("Compilation failed", null); } } catch (RuntimeException rte) { // Unwrap the compilation exception and throw it. Throwable cause = rte.getCause(); if (cause != null) { cause = cause.getCause(); if (cause instanceof CompileException) { throw (CompileException) cause; // SUPPRESS CHECKSTYLE AvoidHidingCause } if (cause instanceof IOException) { throw (IOException) cause; // SUPPRESS CHECKSTYLE AvoidHidingCause } } throw rte; } // Create a ClassLoader that reads class files from our FM. this.result = AccessController.doPrivileged(new PrivilegedAction() { @Override public JavaFileManagerClassLoader run() { return new JavaFileManagerClassLoader(fileManager, SimpleCompiler.this.parentClassLoader); } }); } @Override public void setDebuggingInformation(boolean debugSource, boolean debugLines, boolean debugVars) { this.debugSource = debugSource; this.debugLines = debugLines; this.debugVars = debugVars; } @Override public void setParentClassLoader(ClassLoader optionalParentClassLoader) { assertNotCooked(); this.parentClassLoader = ( optionalParentClassLoader != null ? optionalParentClassLoader : Thread.currentThread().getContextClassLoader() ); } /** * Auxiliary classes never really worked... don't use them. * * @param optionalParentClassLoader * @param auxiliaryClasses * @deprecated */ @Deprecated public void setParentClassLoader(ClassLoader optionalParentClassLoader, Class[] auxiliaryClasses) { this.setParentClassLoader(optionalParentClassLoader); } /** * Throw an {@link IllegalStateException} if this {@link Cookable} is not yet cooked. */ protected void assertCooked() { if (this.result == null) throw new IllegalStateException("Not yet cooked"); } /** * Throw an {@link IllegalStateException} if this {@link Cookable} is already cooked. */ protected void assertNotCooked() { if (this.result != null) throw new IllegalStateException("Already cooked"); } } janino-2.7.0/commons-compiler-jdk/src/org/codehaus/commons/compiler/jdk/package-info.java000066400000000000000000000032771222264062300314340ustar00rootroot00000000000000 /* * cs-contrib - Additional checks, filters and quickfixes for CheckStyle and Eclipse-CS * * 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. */ /** * Main package of the plugin. */ @de.unkrig.commons.nullanalysis.NotNullByDefault package org.codehaus.commons.compiler.jdk; janino-2.7.0/commons-compiler-jdk/src/org/codehaus/commons/io/000077500000000000000000000000001222264062300242615ustar00rootroot00000000000000janino-2.7.0/commons-compiler-jdk/src/org/codehaus/commons/io/MultiReader.java000066400000000000000000000074501222264062300273470ustar00rootroot00000000000000 /* * 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.commons.io; import java.io.*; import java.util.*; /** * Similar to {@link FilterReader}, but when the first delegate is at end-of-input, it continues * with reading from the next delegate. *

* This {@link Reader} does not support MARK. */ public class MultiReader extends Reader { private static final Reader EMPTY_READER = new StringReader(""); private final List delegates; private final Iterator delegateIterator; private Reader currentDelegate = EMPTY_READER; public MultiReader(List delegates) { this.delegates = delegates; this.delegateIterator = delegates.iterator(); } public MultiReader(Reader[] delegates) { this(Arrays.asList(delegates)); } /** * Closes all delegates. */ public void close() throws IOException { for (Reader delegate : this.delegates) delegate.close(); } public int read() throws IOException { for (;;) { int result = this.currentDelegate.read(); if (result != -1) return result; if (!this.delegateIterator.hasNext()) return -1; this.currentDelegate = this.delegateIterator.next(); } } public long skip(long n) throws IOException { long skipped = 0L; for (;;) { long result = this.currentDelegate.skip(n - skipped); if (result != -1L) { skipped += result; if (skipped == n) return skipped; continue; } if (!this.delegateIterator.hasNext()) return skipped; this.currentDelegate = this.delegateIterator.next(); } } public int read(final char[] cbuf, final int off, final int len) throws IOException { int read = 0; for (;;) { long result = this.currentDelegate.read(cbuf, off + read, len - read); if (result != -1L) { read += result; if (read == len) return read; continue; } if (!this.delegateIterator.hasNext()) return read == 0 ? -1 : read; this.currentDelegate = this.delegateIterator.next(); } } } janino-2.7.0/commons-compiler-tests/000077500000000000000000000000001222264062300174205ustar00rootroot00000000000000janino-2.7.0/commons-compiler-tests/.checkstyle000066400000000000000000000012531222264062300215600ustar00rootroot00000000000000 janino-2.7.0/commons-compiler-tests/aux-files/000077500000000000000000000000001222264062300213155ustar00rootroot00000000000000janino-2.7.0/commons-compiler-tests/aux-files/Bug 106/000077500000000000000000000000001222264062300223215ustar00rootroot00000000000000janino-2.7.0/commons-compiler-tests/aux-files/Bug 106/a/000077500000000000000000000000001222264062300225415ustar00rootroot00000000000000janino-2.7.0/commons-compiler-tests/aux-files/Bug 106/a/C2.java000066400000000000000000000001341222264062300236460ustar00rootroot00000000000000 package a; public class C2 { private static int A = 0; public static int B = 0; } janino-2.7.0/commons-compiler-tests/aux-files/Bug 106/b/000077500000000000000000000000001222264062300225425ustar00rootroot00000000000000janino-2.7.0/commons-compiler-tests/aux-files/Bug 106/b/C1.java000066400000000000000000000001041222264062300236430ustar00rootroot00000000000000 package b; public class C1 { public static int A = 0; } janino-2.7.0/commons-compiler-tests/aux-files/Bug 106/b/C3.java000066400000000000000000000002571222264062300236560ustar00rootroot00000000000000 package b; import static a.C2.*; import static b.C1.*; public class C3 { public static void main(String[] args) { System.out.println(A + B); } } janino-2.7.0/commons-compiler-tests/aux-files/testCircularSingleTypeImports/000077500000000000000000000000001222264062300273435ustar00rootroot00000000000000janino-2.7.0/commons-compiler-tests/aux-files/testCircularSingleTypeImports/test/000077500000000000000000000000001222264062300303225ustar00rootroot00000000000000janino-2.7.0/commons-compiler-tests/aux-files/testCircularSingleTypeImports/test/Func1.java000066400000000000000000000002361222264062300321420ustar00rootroot00000000000000 package test; import test.Func2; public class Func1 { public static boolean func1() throws Exception { return Func2.func2(); } } janino-2.7.0/commons-compiler-tests/aux-files/testCircularSingleTypeImports/test/Func2.java000066400000000000000000000002361222264062300321430ustar00rootroot00000000000000 package test; import test.Func1; public class Func2 { public static boolean func2() throws Exception { return Func1.func1(); } } janino-2.7.0/commons-compiler-tests/aux-files/testCircularStaticImports/000077500000000000000000000000001222264062300265075ustar00rootroot00000000000000janino-2.7.0/commons-compiler-tests/aux-files/testCircularStaticImports/test/000077500000000000000000000000001222264062300274665ustar00rootroot00000000000000janino-2.7.0/commons-compiler-tests/aux-files/testCircularStaticImports/test/Func1.java000066400000000000000000000002421222264062300313030ustar00rootroot00000000000000 package test; import static test.Func2.func2; public class Func1 { public static boolean func1() throws Exception { return true; } } janino-2.7.0/commons-compiler-tests/aux-files/testCircularStaticImports/test/Func2.java000066400000000000000000000002421222264062300313040ustar00rootroot00000000000000 package test; import static test.Func1.func1; public class Func2 { public static boolean func2() throws Exception { return true; } } janino-2.7.0/commons-compiler-tests/janino common-tests.launch000066400000000000000000000054721222264062300245130ustar00rootroot00000000000000 janino-2.7.0/commons-compiler-tests/janino+jdk common-tests.launch000066400000000000000000000054011222264062300252470ustar00rootroot00000000000000 janino-2.7.0/commons-compiler-tests/jdk common-tests.launch000066400000000000000000000050431222264062300237770ustar00rootroot00000000000000 janino-2.7.0/commons-compiler-tests/src/000077500000000000000000000000001222264062300202075ustar00rootroot00000000000000janino-2.7.0/commons-compiler-tests/src/EvaluatorTests.java000066400000000000000000001022311222264062300240360ustar00rootroot00000000000000 /* * 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. */ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.text.MessageFormat; import java.util.Collection; import java.util.Properties; import org.codehaus.commons.compiler.CompileException; 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; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; import util.TestUtil; import for_sandbox_tests.OverridesWithDifferingVisibility; @RunWith(Parameterized.class) public class EvaluatorTests { private final ICompilerFactory compilerFactory; @Parameters public static Collection compilerFactories() throws Exception { return TestUtil.getCompilerFactoriesForParameters(); } public EvaluatorTests(ICompilerFactory compilerFactory) { this.compilerFactory = compilerFactory; } @Test public void testMultiScriptEvaluator() throws Exception { IScriptEvaluator se = this.compilerFactory.newScriptEvaluator(); se.setOverrideMethod(new boolean[] { false, false }); se.setReturnTypes(new Class[] { double.class, double.class }); se.setMethodNames(new String[] { "funct2", "funct3" }); se.setParameters(new String[][] { { "a", "b" }, {} }, new Class[][] { { double.class, double.class }, {} }); se.setStaticMethod(new boolean[] { true, true }); se.cook(new String[] { "return a + b;", "return 0;" }); assertEquals(se.getMethod(0).invoke(null, new Object[] { new Double(3.0), new Double(4.0) }), new Double(7.0)); assertEquals(se.getMethod(1).invoke(null, new Object[0]), new Double(0.0)); } @Test public void testExpressionEvaluator() throws Exception { IExpressionEvaluator ee = this.compilerFactory.newExpressionEvaluator(); ee.setClassName("Foo"); ee.setDefaultImports(new String[] { "java.io.*", "for_sandbox_tests.*", }); ee.setOverrideMethod(new boolean[] { false, false, true, }); ee.setStaticMethod(new boolean[] { false, true, false, }); ee.setExpressionTypes(new Class[] { IExpressionEvaluator.ANY_TYPE, InputStream.class, void.class, }); ee.setExtendedClass(Properties.class); ee.setImplementedInterfaces(new Class[] { Runnable.class, }); ee.setMethodNames(new String[] { "a", "b", "run", }); ee.setParameters(new String[][] { { "a", "b" }, {}, {}, }, new Class[][] { { int.class, int.class }, {}, {}, }); // ee.setParentClassLoader(BOOT_CLASS_LOADER, new Class[] { for_sandbox_tests.ExternalClass.class }); ee.setThrownExceptions(new Class[][] { {}, { IOException.class }, {}, }); ee.cook(new String[] { "a + b", "new FileInputStream(\"xyz\")", "ExternalClass.m1()", }); { Method m = ee.getMethod(0); Object instance = m.getDeclaringClass().newInstance(); assertEquals(5, m.invoke(instance, new Object[] { 2, 3 })); } try { ee.evaluate(1, new Object[0]); fail("Should have thrown an InvocationTargetException"); } catch (InvocationTargetException ex) { assertTrue("FileNotFoundException", ex.getTargetException() instanceof FileNotFoundException); } try { Method m = ee.getMethod(2); Object instance = m.getDeclaringClass().newInstance(); m.invoke(instance, new Object[0]); } catch (Exception e) { fail(e.getMessage()); } } @Test public void testFastClassBodyEvaluator1() throws Exception { IClassBodyEvaluator cbe = this.compilerFactory.newClassBodyEvaluator(); cbe.setImplementedInterfaces(new Class[] { Runnable.class }); cbe.cook( "" + "import java.util.*;\n" + "@Override public void run() {\n" + " new ArrayList();\n" + " new other_package.Foo(7);\n" + "}\n" ); ((Runnable) cbe.getClazz().newInstance()).run(); } @Test public void testFastClassBodyEvaluator2() throws Exception { try { IClassBodyEvaluator cbe = this.compilerFactory.newClassBodyEvaluator(); cbe.setImplementedInterfaces(new Class[] { Runnable.class }); cbe.cook( "" + "public void m() { // Implement \"m()\" instead of \"run()\".\n" + " System.out.println(\"Got here\");\n" + "}" ); fail("CompileException expected"); } catch (CompileException ex) { ; } } @Test @SuppressWarnings("unchecked") public void testFastExpressionEvaluator() throws Exception { IExpressionEvaluator ee = this.compilerFactory.newExpressionEvaluator(); ee.setImplementedInterfaces(new Class[] { Comparable.class }); ee.setExpressionTypes(new Class[] { int.class }); ((Comparable) ee.createFastEvaluator( "o == null ? 3 : 4", Comparable.class, new String[] { "o" } )).compareTo(""); } private static final int COUNT = 10000; @Test public void testManyEEs() throws Exception { IExpressionEvaluator ee = this.compilerFactory.newExpressionEvaluator(); String[] expressions = new String[COUNT]; String[][] parameterNames = new String[COUNT][2]; Class[][] parameterTypes = new Class[COUNT][2]; for (int i = 0; i < expressions.length; ++i) { expressions[i] = "a + b"; parameterNames[i][0] = "a"; parameterNames[i][1] = "b"; parameterTypes[i][0] = int.class; parameterTypes[i][1] = int.class; } ee.setParameters(parameterNames, parameterTypes); ee.cook(expressions); assertEquals(165, ee.evaluate(3 * COUNT / 4, new Object[] { 77, 88 })); } @Test public void testAssertNotCooked() throws Exception { IClassBodyEvaluator temp = this.compilerFactory.newClassBodyEvaluator(); temp.cook(""); try { temp.setExtendedClass(String.class); // Must throw an ISE because the CBE is already cooked. } catch (IllegalStateException ex) { return; } fail(); } @Test public void testAccessingCompilingClass() throws Exception { ISimpleCompiler sc = this.compilerFactory.newSimpleCompiler(); sc.cook( "" + "package test.simple;\n" + "public class L0 {\n" + " public static class L1 {\n" + " public static class L2 { }\n" + " } \n" + " public Class getL0_1() {\n" + " return L0.class;\n" + " }\n" + " public Class getL0_2() {\n" + " return test.simple.L0.class;\n" + " }\n" + " public Class getL1_1() {\n" + " return L1.class;\n" + " }\n" + " public Class getL1_2() {\n" + " return L0.L1.class;\n" + " }\n" + " public Class getL1_3() {\n" + " return test.simple.L0.L1.class;\n" + " }\n" + " public Class getL2_1() {\n" + " return L1.L2.class;\n" + " }\n" + " public Class getL2_2() {\n" + " return L0.L1.L2.class;\n" + " }\n" + " public Class getL2_3() {\n" + " return test.simple.L0.L1.L2.class;\n" + " }\n" + "}" ); Class[] exp = new Class[] { sc.getClassLoader().loadClass("test.simple.L0"), sc.getClassLoader().loadClass("test.simple.L0$L1"), sc.getClassLoader().loadClass("test.simple.L0$L1$L2"), }; Method[] m = exp[0].getMethods(); Object inst = exp[0].newInstance(); int numTests = 0; for (int i = 0; i < m.length; ++i) { for (int j = 0; j < exp.length; ++j) { if (m[i].getName().startsWith("getL" + j)) { Class res = (Class) m[i].invoke(inst, new Object[0]); assertEquals(exp[j], res); ++numTests; } } } //we count tests just to make sure things didn't go horrifically wrong and //the above loops become empty assertEquals(8, numTests); } @Test public void testDivByZero() throws Exception { ISimpleCompiler sc = this.compilerFactory.newSimpleCompiler(); sc.cook( "" + "package test;\n" + "public class Test {\n" + " public int runIntDiv() {\n" + " return 1 / 0;\n" + " }\n" + " public int runIntMod() {\n" + " return 1 % 0;\n" + " }\n" + " public long runLongDiv() {\n" + " return 1L / 0;\n" + " }\n" + " public long runLongMod() {\n" + " return 1L % 0;\n" + " }\n" + "}" ); Class c = sc.getClassLoader().loadClass("test.Test"); Object o = c.newInstance(); Method[] m = c.getMethods(); for (int i = 0; i < m.length; ++i) { if (m[i].getName().startsWith("run")) { try { Object res = m[i].invoke(o, new Object[0]); fail("Method " + m[i] + " should have failed, but got " + res); } catch (InvocationTargetException ae) { assertTrue(ae.getTargetException() instanceof ArithmeticException); } } } } @Test public void testTrinaryOptimize() throws Exception { ISimpleCompiler sc = this.compilerFactory.newSimpleCompiler(); sc.cook( "" + "package test;\n" + "public class Test {\n" + " public int runTrue() {\n" + " return true ? -1 : 1;\n" + " }\n" + " public int runFalse() {\n" + " return false ? -1 : 1;\n" + " }\n" + "}" ); Class c = sc.getClassLoader().loadClass("test.Test"); Method trueMeth = c.getMethod("runTrue"); Method falseMeth = c.getMethod("runFalse"); Object o = c.newInstance(); assertEquals(-1, trueMeth.invoke(o, new Object[0])); assertEquals(1, falseMeth.invoke(o, new Object[0])); } public static boolean compare(double lhs, double rhs, String comp) { // CHECKSTYLE StringLiteralEquality:OFF if (comp == "==") { return lhs == rhs; } if (comp == "!=") { return lhs != rhs; } if (comp == "<") { return lhs < rhs; } if (comp == "<=") { return lhs <= rhs; } if (comp == ">") { return lhs < rhs; } if (comp == ">=") { return lhs <= rhs; } // CHECKSTYLE StringLiteralEquality:ON throw new RuntimeException("Unsupported comparison"); } public static boolean compare(float lhs, float rhs, String comp) { // CHECKSTYLE StringLiteralEquality:OFF if (comp == "==") { return lhs == rhs; } if (comp == "!=") { return lhs != rhs; } if (comp == "<") { return lhs < rhs; } if (comp == "<=") { return lhs <= rhs; } if (comp == ">") { return lhs < rhs; } if (comp == ">=") { return lhs <= rhs; } // CHECKSTYLE StringLiteralEquality:ON throw new RuntimeException("Unsupported comparison"); } @Test public void testHandlingNaN() throws Exception { String prog = ( "" + "package test;\n" + "public class Test {\n" + " public static boolean compare(double lhs, double rhs, String comp) {" + " if (comp == \"==\") { return lhs == rhs; }" + " if (comp == \"!=\") { return lhs != rhs; }" + " if (comp == \"<\" ) { return lhs < rhs; }" + " if (comp == \"<=\") { return lhs <= rhs; }" + " if (comp == \">\" ) { return lhs < rhs; }" + " if (comp == \">=\") { return lhs <= rhs; }" + " throw new RuntimeException(\"Unsupported comparison\");" + " }" + " public static boolean compare(float lhs, float rhs, String comp) {" + " if (comp == \"==\") { return lhs == rhs; }" + " if (comp == \"!=\") { return lhs != rhs; }" + " if (comp == \"<\" ) { return lhs < rhs; }" + " if (comp == \"<=\") { return lhs <= rhs; }" + " if (comp == \">\" ) { return lhs < rhs; }" + " if (comp == \">=\") { return lhs <= rhs; }" + " throw new RuntimeException(\"Unsupported comparison\");" + " }" + "}" ); ISimpleCompiler sc = this.compilerFactory.newSimpleCompiler(); sc.cook(prog); Class c = sc.getClassLoader().loadClass("test.Test"); Method dm = c.getMethod("compare", new Class[] { double.class, double.class, String.class }); Method fm = c.getMethod("compare", new Class[] { float.class, float.class, String.class }); Double[][] args = new Double[][] { { new Double(Double.NaN), new Double(Double.NaN) }, { new Double(Double.NaN), new Double(1.0) }, { new Double(1.0), new Double(Double.NaN) }, { new Double(1.0), new Double(2.0) }, { new Double(2.0), new Double(1.0) }, { new Double(1.0), new Double(1.0) }, }; String[] opcode = new String[] { "==", "!=", "<", "<=", ">", ">=" }; for (int opIdx = 0; opIdx < opcode.length; ++opIdx) { for (int argIdx = 0; argIdx < args.length; ++argIdx) { String msg = "\"" + args[argIdx][0] + " " + opcode[opIdx] + " " + args[argIdx][1] + "\""; { boolean exp = compare( args[argIdx][0].doubleValue(), args[argIdx][1].doubleValue(), opcode[opIdx] ); Object[] objs = new Object[] { args[argIdx][0], args[argIdx][1], opcode[opIdx] }; Object actual = dm.invoke(null, objs); assertEquals(msg, exp, actual); } { msg = "float: " + msg; boolean exp = compare(args[argIdx][0].floatValue(), args[argIdx][1].floatValue(), opcode[opIdx]); Object[] objs = new Object[] { new Float(args[argIdx][0].floatValue()), new Float(args[argIdx][1].floatValue()), opcode[opIdx] }; Object actual = fm.invoke(null, objs); assertEquals(msg, exp, actual); } } } } @Test public void test32kBranchLimit() throws Exception { String preamble = ( "" + "package test;\n" + "public class Test {\n" + " public int run() {\n" + " int res = 0;\n" + " for(int i = 0; i < 2; ++i) {\n" ); String middle = ( "" + " ++res;\n" ); String postamble = ( "" + " }\n" + " return res;\n" + " }\n" + "}" ); int[] tests = new int[] { 1, 10, 100, Short.MAX_VALUE / 5, Short.MAX_VALUE / 4, Short.MAX_VALUE / 2 }; for (int i = 0; i < tests.length; ++i) { int repititions = tests[i]; StringBuilder sb = new StringBuilder(); sb.append(preamble); for (int j = 0; j < repititions; ++j) { sb.append(middle); } sb.append(postamble); ISimpleCompiler sc = this.compilerFactory.newSimpleCompiler(); sc.cook(sb.toString()); Class c = sc.getClassLoader().loadClass("test.Test"); Method m = c.getDeclaredMethod("run", new Class[0]); Object o = c.newInstance(); Object res = m.invoke(o, new Object[0]); assertEquals(2 * repititions, res); } } @Test public void test32kConstantPool() throws Exception { String preamble = ( "" + "package test;\n" + "public class Test {\n" ); String postamble = ( "}" ); int[] tests = new int[] { 1, 100, 13020 }; for (int i = 0; i < tests.length; ++i) { int repititions = tests[i]; StringBuilder sb = new StringBuilder(); sb.append(preamble); for (int j = 0; j < repititions; ++j) { sb.append("boolean _v").append(Integer.toString(j)).append(" = false;\n"); } sb.append(postamble); ISimpleCompiler sc = this.compilerFactory.newSimpleCompiler(); sc.cook(sb.toString()); Class c = sc.getClassLoader().loadClass("test.Test"); Object o = c.newInstance(); assertNotNull(o); } } @Test public void testHugeIntArray() throws Exception { String preamble = ( "" + "package test;\n" + "public class Test {\n" + " public int[] run() {\n" + " return 1.0 > 2.0 ? null : new int[] {" ); String middle = ( "" + " 123," ); String postamble = ( "" + " };\n" + " }\n" + "}" ); int[] tests = new int[] { 1, 10, 8192 }; for (int i = 0; i < tests.length; ++i) { int repititions = tests[i]; StringBuilder sb = new StringBuilder(); sb.append(preamble); for (int j = 0; j < repititions; ++j) { sb.append(middle); } sb.append(postamble); ISimpleCompiler sc = this.compilerFactory.newSimpleCompiler(); sc.cook(sb.toString()); Class c = sc.getClassLoader().loadClass("test.Test"); Object o = c.newInstance(); assertNotNull(o); } } @Test public void testStaticFieldAccess() throws Exception { assertCompiles(true, ( "" + "package test;\n" + "public class Test {\n" + " public static class Inner {\n" + " public static int i = 0;\n" + " }\n" + " public int runTest(Inner in) {\n" + " return in.i;\n" + " }\n" + "}" )); } @Test public void testWideInstructions() throws Exception { String preamble = ( "" + "package test;\n" + "public class Test {\n" + " public static String run() {\n" ); String middle = ( "" + " Object o_{0,number,#}; int i_{0,number,#};\n" ); String postamble = ( "" + " int i = (int)0; ++i; i = (int)(i*i);\n" + " double d = (double)0.0; ++d; d = (double)(d*d);\n" + " float f = (float)0.0; ++f; f = (float)(f*f);\n" + " short s = (short)0; ++s; s = (short)(s*s);\n" + " long l = (long)0; ++l; l = (long)(l*l);\n" + " boolean b = false; b = !b;\n" + " Object o = \"hi\"; o = o.toString();\n" + " String res = o.toString() +\" \"+ i +\" \"+ d +\" \"+ f +\" \"+ s +\" \"+ l +\" \"+ b;\n" + " try { res = res + \" try\"; } finally { res = res + \" finally\"; }\n" + " return res;\n" + " };\n" + "}" ); int[] tests = new int[] { 1, 128, }; for (int i = 0; i < tests.length; ++i) { int repititions = tests[i]; StringBuilder sb = new StringBuilder(); sb.append(preamble); for (int j = 0; j < repititions; ++j) { sb.append(MessageFormat.format(middle, new Object[] { j })); } sb.append(postamble); ISimpleCompiler sc = this.compilerFactory.newSimpleCompiler(); sc.cook(sb.toString()); Class c = sc.getClassLoader().loadClass("test.Test"); Method m = c.getDeclaredMethod("run", new Class[0]); Object o = m.invoke(null, new Object[0]); assertEquals("hi 1 1.0 1.0 1 1 true try finally", o); } } @Test public void testInstanceOf() throws Exception { String test = ( "" + "package test;\n" + "public class Test {\n" + " public static boolean run(String o) {\n" + " return o instanceof String;" + " };\n" + " public static boolean run(Object o) {\n" + " return o instanceof String;" + " };\n" + " public static boolean run() {\n" + " return null instanceof String;" + " };\n" + "}" ); ISimpleCompiler sc = this.compilerFactory.newSimpleCompiler(); sc.cook(test); Class c = sc.getClassLoader().loadClass("test.Test"); Method m0 = c.getDeclaredMethod("run", new Class[] {}); assertEquals(false, m0.invoke(null, new Object[0])); Method mStr = c.getDeclaredMethod("run", new Class[] { String.class }); Method mObj = c.getDeclaredMethod("run", new Class[] { Object.class }); assertEquals(true, mObj.invoke(null, new Object[] { "" })); assertEquals(false, mObj.invoke(null, new Object[] { 1 })); assertEquals(false, mObj.invoke(null, new Object[] { null })); assertEquals(true, mStr.invoke(null, new Object[] { "" })); assertEquals(false, mStr.invoke(null, new Object[] { null })); } @Test public void testOverrideVisibility() throws Exception { // note that this compiles without problem OverridesWithDifferingVisibility.test(new Object[] { "asdf" }); // so should this assertCompiles(true, ( "" + "package test;\n" + "public class Test {\n" + " public void runTest() {\n" + " for_sandbox_tests.OverridesWithDifferingVisibility.test(new Object[] { \"asdf\"} );\n" + " }\n" + "}\n" )); } @Test public void testCovariantReturns() throws Exception { assertCompiles(true, ( "" + "package test;\n" + "public class Test extends for_sandbox_tests.CovariantReturns {\n" + " @Override public Test overrideMe() { return this; }\n" + "}" )); assertCompiles(false, ( "" + "package test;\n" + "public class Test2 extends for_sandbox_tests.CovariantReturns {\n" + " public Integer overrideMe() { return null; }\n" + "}" )); } @Test public void testNonExistentImport() throws Exception { assertCompiles(false, "import does.not.Exist; public class Test { private final Exist e = null; }"); assertCompiles(false, "import does.not.Exist; public class Test { }"); } @Test public void testAnonymousFieldInitializedByCapture() throws Exception { ISimpleCompiler sc = this.compilerFactory.newSimpleCompiler(); sc.cook( "" + "public class Top {\n" + " public Runnable get() {\n" + " final String foo = \"foo\";\n" + " final String cow = \"cow\";\n" + " final String moo = \"moo\";\n" + " return new Runnable() {\n" + " @Override public void run() {\n" + " if (bar == null) {\n" + " throw new RuntimeException();\n" + " }\n" + " }\n" + " private String bar = foo;\n" + " private String[] cowparts = { moo, cow };\n" + " };\n" + " }\n" + "}\n" ); Class topClass = sc.getClassLoader().loadClass("Top"); Method get = topClass.getDeclaredMethod("get", new Class[0]); Object t = topClass.newInstance(); Object res = get.invoke(t, new Object[0]); ((Runnable) res).run(); } @Test public void testNamedFieldInitializedByCapture() throws Exception { ISimpleCompiler sc = this.compilerFactory.newSimpleCompiler(); sc.cook( "" + "public class Top {\n" + " public Runnable get() {\n" + " final String foo = \"foo\";\n" + " final String cow = \"cow\";\n" + " final String moo = \"moo\";\n" + " class R implements Runnable {\n" + " @Override public void run() {\n" + " if (bar == null) {\n" + " throw new RuntimeException();\n" + " }\n" + " }\n" + " private String bar = foo;\n" + " private String[] cowparts = { moo, cow };\n" + " }\n" + " return new R();" + " }\n" + "}\n" ); Class topClass = sc.getClassLoader().loadClass("Top"); Method get = topClass.getDeclaredMethod("get", new Class[0]); Object t = topClass.newInstance(); Object res = get.invoke(t, new Object[0]); ((Runnable) res).run(); } @Test public void testAbstractGrandParentsWithCovariantReturns() throws Exception { assertCompiles(true, ( "" + "public class Top {\n" + " private static class IndentPrintWriter extends java.io.PrintWriter { " + " public IndentPrintWriter(java.io.OutputStream os) { super(os); }" + " }" + "}" )); } @Test public void testStringBuilderLength() throws Exception { ISimpleCompiler sc = this.compilerFactory.newSimpleCompiler(); sc.cook( "" + "public class Top {\n" + " public int len(StringBuilder sb) { return sb.length(); }\n" + "}\n" ); Class topClass = sc.getClassLoader().loadClass("Top"); Method get = topClass.getDeclaredMethod("len", new Class[] { StringBuilder.class }); Object t = topClass.newInstance(); StringBuilder sb = new StringBuilder(); assertEquals(sb.length(), get.invoke(t, new Object[] { sb })); sb.append("asdf"); assertEquals(sb.length(), get.invoke(t, new Object[] { sb })); sb.append("qwer"); assertEquals(sb.length(), get.invoke(t, new Object[] { sb })); } @Test public void testCovariantClone() throws Exception { ISimpleCompiler sc = this.compilerFactory.newSimpleCompiler(); sc.cook( "" + "package covariant_clone;\n" + "public class Child extends Middle implements java.lang.Cloneable {\n" + " @Override public Child clone() throws java.lang.CloneNotSupportedException {\n" + " return new Child();\n" + " }\n" + " @Override public Child other(long i, Object o) {\n" + " return this;\n" + " }\n" + "}\n" ); // calling clone directly here would work, we need to trigger a call into the // covariant version of clone from a less described version of it. Class topClass = sc.getClassLoader().loadClass("covariant_clone.Child"); Method foo = topClass.getMethod("cloneWithArguments"); Method bar = topClass.getMethod("cloneWithOutArguments"); Object t = topClass.newInstance(); assertNotNull(foo.invoke(t, new Object[0])); assertNotNull(bar.invoke(t, new Object[0])); } @Test public void testBaseClassAccess() throws Exception { assertCompiles(true, ( "" + "class top extends other_package.ScopingRules {\n" + " class Inner extends other_package.ScopingRules.ProtectedInner {\n" + " public void test() {\n" + " publicMethod();\n" + " }\n" + " }\n" + "\n" + " public void test() {\n" + " Inner i = new Inner();\n" + " i.publicMethod();\n" + " }\n" + "}\n" )); } @Test public void testNullComparator() throws Exception { assertCompiles(true, ( "" + "class Test {\n" + " public void test() {\n" + " if (null == null) {\n" + " // success\n" + " } else if (null != null) {\n" + " throw new RuntimeException();\n" + " }\n" + " }\n" + "}\n" )); } public ISimpleCompiler assertCompiles(boolean shouldCompile, CharSequence prog) throws Exception { try { ISimpleCompiler sc = this.compilerFactory.newSimpleCompiler(); sc.cook(prog.toString()); assertTrue("Compilation should have failed for:\n" + prog, shouldCompile); return sc; } catch (CompileException ce) { if (shouldCompile) throw ce; } return null; } } janino-2.7.0/commons-compiler-tests/src/IPred.java000066400000000000000000000031231222264062300220540ustar00rootroot00000000000000 /* * 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. */ public interface IPred { boolean filter() throws Exception; } janino-2.7.0/commons-compiler-tests/src/JLS2Tests.java000066400000000000000000000675171222264062300226270ustar00rootroot00000000000000 /* * 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. */ import java.util.Arrays; import java.util.List; import org.codehaus.commons.compiler.ICompilerFactory; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; import util.JaninoTestSuite; import util.TestUtil; // CHECKSTYLE MethodName:OFF /** * Tests against the \"Java Language Specification\"; 2nd edition */ @RunWith(Parameterized.class) public class JLS2Tests extends JaninoTestSuite { @Parameters public static List compilerFactories() throws Exception { return TestUtil.getCompilerFactoriesForParameters(); } public JLS2Tests(ICompilerFactory compilerFactory) throws Exception { super(compilerFactory); } @Test public void test_3__LexicalStructure() throws Exception { // 3.1. Lexical Structure -- Unicode exp(TRUE, "'\\u00e4' == '\u00e4'"); // 3.2. Lexical Structure -- Translations scr(COMP, "3--4"); // 3.3. Lexical Structure -- Unicode Escapes exp(COMP, "aaa\\u123gbbb"); exp(TRUE, "\"\\u0041\".equals(\"A\")"); exp(TRUE, "\"\\uu0041\".equals(\"A\")"); exp(TRUE, "\"\\uuu0041\".equals(\"A\")"); exp(TRUE, "\"\\\\u0041\".equals(\"\\\\\" + \"u0041\")"); exp(TRUE, "\"\\\\\\u0041\".equals(\"\\\\\" + \"A\")"); // 3.3. Lexical Structure -- Line Terminators exp(TRUE, "1//\r+//\r\n2//\n==//\n\r3"); // 3.6. Lexical Structure -- White Space exp(TRUE, "3\t\r \n==3"); // 3.7. Lexical Structure -- Comments exp(TRUE, "7/* */==7"); exp(TRUE, "7/**/==7"); exp(TRUE, "7/***/==7"); exp(COMP, "7/*/==7"); exp(TRUE, "7/*\r*/==7"); exp(TRUE, "7//\r==7"); exp(TRUE, "7//\n==7"); exp(TRUE, "7//\r\n==7"); exp(TRUE, "7//\n\r==7"); scr(COMP, "7// /*\n\rXXX*/==7"); // 3.8. Lexical Structure -- Identifiers scr(EXEC, "int a;"); scr(EXEC, "int \u00e4\u00e4\u00e4;"); scr(EXEC, "int \\u0391;"); // Greek alpha scr(EXEC, "int _aaa;"); scr(EXEC, "int $aaa;"); scr(COMP, "int 9aaa;"); scr(COMP, "int const;"); } @Test public void test_3_10_1__Literals_Integer() throws Exception { exp(TRUE, "17 == 17L"); exp(TRUE, "255 == 0xFFl"); exp(TRUE, "17 == 021L"); exp(COMP, "17 == 029"); // Digit "9" not allowed in octal literal. exp(TRUE, "2 * 2147483647 == -2"); exp(TRUE, "2 * -2147483648 == 0"); exp(COMP, "2147483648"); exp(EXEC, "-2147483648"); exp(TRUE, "-1 == 0xffffffff"); exp(TRUE, "1 == -0xffffffff"); exp(TRUE, "-0xf == -15"); exp(EXEC, "9223372036854775807L"); exp(COMP, "9223372036854775808L"); exp(COMP, "9223372036854775809L"); exp(COMP, "99999999999999999999999999999L"); exp(EXEC, "-9223372036854775808L"); exp(COMP, "-9223372036854775809L"); } @Test public void test_3_10_2__Literals_FloatingPoint() throws Exception { exp(TRUE, "1e1f == 10f"); exp(TRUE, "1E1F == 10f"); exp(TRUE, ".3f == 0.3f"); exp(TRUE, "0f == (float) 0"); exp(EXEC, "3.14f"); exp(EXEC, "3.40282347e+38f"); exp(COMP, "3.40282357e+38f"); exp(EXEC, "1.40239846e-45f"); exp(COMP, "7.0e-46f"); exp(EXEC, "1.79769313486231570e+308D"); exp(COMP, "1.79769313486231581e+308d"); exp(EXEC, "4.94065645841246544e-324D"); exp(COMP, "2e-324D"); } @Test public void test_3_10_3__Literals_Boolean() throws Exception { exp(TRUE, "true"); exp(TRUE, "! false"); } @Test public void test_3_10_4__Literals_Character() throws Exception { exp(TRUE, "'a' == 97"); exp(COMP, "'''"); exp(COMP, "'\\'"); exp(COMP, "'\n'"); exp(COMP, "'ax'"); exp(COMP, "'a\n'"); exp(TRUE, "'\"' == 34"); // Unescaped double quote is allowed! } @Test public void test_3_10_5__Literals_String() throws Exception { exp(TRUE, "\"'\".charAt(0) == 39"); // Unescaped single quote is allowed! // Escape sequences already tested above for character literals. exp(TRUE, "\"\\b\".charAt(0) == 8"); exp(COMP, "\"aaa\nbbb\""); exp(COMP, "\"aaa\rbbb\""); exp(TRUE, "\"aaa\" == \"aaa\""); exp(TRUE, "\"aaa\" != \"bbb\""); } @Test public void test_3_10_6__Literals_EscapeSequences() throws Exception { exp(COMP, "'\\u000a'"); // 0x000a is LF exp(TRUE, "'\\b' == 8"); exp(TRUE, "'\\t' == 9"); exp(TRUE, "'\\n' == 10"); exp(TRUE, "'\\f' == 12"); exp(TRUE, "'\\r' == 13"); exp(TRUE, "'\\\"' == 34"); exp(TRUE, "'\\'' == 39"); exp(TRUE, "'\\\\' == 92"); exp(TRUE, "'\\0' == 0"); exp(TRUE, "'\\07' == 7"); exp(TRUE, "'\\377' == 255"); exp(COMP, "'\\400'"); exp(COMP, "'\\1234'"); } @Test public void test_3_10_7__Literals_Null() throws Exception { exp(EXEC, "null"); } @Test public void test_3_11__Separators() throws Exception { scr(EXEC, ";"); } @Test public void test_3_12__Operators() throws Exception { scr(TRUE, "int a = -11; a >>>= 2; return a == 1073741821;"); } @Test public void test_5_1_7__Conversion_Boxing() throws Exception { scr(TRUE, "Boolean b = true; return b.booleanValue();"); scr(TRUE, "Boolean b = false; return !b.booleanValue();"); scr(TRUE, "Byte b = (byte) 7; return b.equals(new Byte((byte) 7));"); scr(TRUE, "Character c = 'X'; return c.equals(new Character('X'));"); scr(TRUE, "Short s = (short) 322; return s.equals(new Short((short) 322));"); scr(TRUE, "Integer i = 99; return i.equals(new Integer(99));"); scr(TRUE, "Long l = 733L; return l.equals(new Long(733L));"); scr(TRUE, "Float f = 12.5F; return f.equals(new Float(12.5F));"); scr(TRUE, "Double d = 14.3D; return d.equals(new Double(14.3D));"); } @Test public void test_5_1_8__Conversion_UnBoxing() throws Exception { exp(TRUE, "Boolean.TRUE"); exp(TRUE, "!Boolean.FALSE"); exp(TRUE, "new Byte((byte) 9) == (byte) 9"); exp(TRUE, "new Character('Y') == 'Y'"); exp(TRUE, "new Short((short) 33) == (short) 33"); exp(TRUE, "new Integer(-444) == -444"); exp(TRUE, "new Long(987654321L) == 987654321L"); exp(TRUE, "new Float(33.3F) == 33.3F"); exp(TRUE, "new Double(939.939D) == 939.939D"); } @Test public void test_5_2__Conversion_Assignment() throws Exception { scr(TRUE, "int i = 7; return i == 7;"); scr(TRUE, "String s = \"S\"; return s.equals(\"S\");"); scr(TRUE, "long l = 7; return l == 7L;"); scr(TRUE, "Object o = \"A\"; return o.equals(\"A\");"); scr(TRUE, "Integer i = 7; return i.intValue() == 7;"); scr(TRUE, "Object o = 7; return o.equals(new Integer(7));"); scr(TRUE, "int i = new Integer(7); return i == 7;"); scr(TRUE, "long l = new Integer(7); return l == 7L;"); scr(EXEC, "byte b = -128;"); scr(COMP, "byte b = 128;"); scr(EXEC, "short s = -32768;"); scr(COMP, "short s = 32768;"); scr(COMP, "char c = -1;"); scr(EXEC, "char c = 0;"); scr(EXEC, "char c = 65535;"); scr(COMP, "char c = 65536;"); scr(EXEC, "Byte b = -128;"); scr(COMP, "Byte b = 128;"); scr(EXEC, "Short s = -32768;"); scr(COMP, "Short s = 32768;"); scr(COMP, "Character c = -1;"); scr(EXEC, "Character c = 0;"); scr(EXEC, "Character c = 65535;"); scr(COMP, "Character c = 65536;"); } @Test public void test_5_5__Conversion_Casting() throws Exception { exp(TRUE, "7 == (int) 7"); exp(TRUE, "(int) 'a' == 97"); exp(TRUE, "(int) 10000000000L == 1410065408"); exp(TRUE, "((Object) \"SS\").equals(\"SS\")"); scr(TRUE, "Object o = \"SS\"; return ((String) o).length() == 2;"); exp(TRUE, "((Integer) 7).intValue() == 7"); exp(TRUE, "(int) new Integer(7) == 7"); // Boxing conversion followed by widening reference conversion - not described in the JLS3, but supported // by JAVAC. See JLS3 5.5, and JANINO-153. exp(TRUE, "null != (Comparable) 5.0"); // Unboxing conversion followed by widening primitive conversion - not described in the JLS3, but supported // by JAVAC. See JLS3 5.5, and JANINO-153. exp(TRUE, "0L != (long) new Integer(8)"); } @Test public void test_5_6__Conversion_NumberPromotions() throws Exception { // 5.6.1 Unary Numeric Promotion exp(TRUE, "-new Byte((byte) 7) == -7"); exp(TRUE, "-new Double(10.0D) == -10.0D"); scr(TRUE, "char c = 'a'; return -c == -97;"); // 5.6.2 Binary Numeric Promotion exp(TRUE, "2.5D * new Integer(4) == 10D"); exp(TRUE, "7 % new Float(2.5F) == 2F"); exp(TRUE, "2000000000 + 2000000000L == 4000000000L"); exp(TRUE, "(short) 32767 + (byte) 100 == 32867"); } @Test public void test_7_5__ImportDeclarations() throws Exception { // Default imports exp( TRUE, "new ArrayList().getClass().getName().equals(\"java.util.ArrayList\")", new String[] { "java.util.*" } ); scr(COMP, "xxx", new String[] { "java.util#" }); scr(COMP, "xxx", new String[] { "java.util.9" }); scr(COMP, "xxx", new String[] { "java.util.*;" }); clb( TRUE, "public static boolean main() { return new ArrayList() instanceof List; }", new String[] { "java.util.*" } ); exp(COMP, "new ArrayList()", new String[] { "java.io.*" }); // 7.5.1 Import Declarations -- Single-Type-Import exp(EXEC, "import java.util.ArrayList; new ArrayList()"); exp(EXEC, "import java.util.ArrayList; import java.util.ArrayList; new ArrayList()"); scr(COMP, "import java.util.List; import java.awt.List;"); // 7.5.2 Import Declarations -- Import-on-Demand exp(EXEC, "import java.util.*; new ArrayList()"); exp(EXEC, "import java.util.*; import java.util.*; new ArrayList()"); // 7.5.3 Import Declarations -- Single Static Import exp(TRUE, "import static java.util.Collections.EMPTY_SET; EMPTY_SET instanceof java.util.Set"); exp(TRUE, ( "import static java.util.Collections.EMPTY_SET;" + "import static java.util.Collections.EMPTY_SET;" + "EMPTY_SET instanceof java.util.Set" )); scr(EXEC, "import static java.util.Map.Entry; Entry e;"); scr(EXEC, ( "import static java.util.Map.Entry;" + "import static java.util.Map.Entry;" + "Entry e;" )); scr(COMP, ( "import static java.util.Map.Entry;" + "import static java.security.KeyStore.Entry;" + "Entry e;" )); exp(TRUE, ( "import static java.util.Arrays.asList;" + "asList(new String[] { \"HELLO\", \"WORLD\" }).size() == 2" )); exp(TRUE, ( "import static java.util.Arrays.asList;" + "import static java.util.Arrays.asList;" + "asList(new String[] { \"HELLO\", \"WORLD\" }).size() == 2" )); scr(COMP, ( "import static java.lang.Integer.decode;" + "import static java.lang.Long.decode;" + "decode(\"4000000000\");" )); // 7.5.4 Import Declarations -- Static-Import-on-Demand exp(TRUE, "import static java.util.Collections.*; EMPTY_SET instanceof java.util.Set"); scr(EXEC, "import static java.util.Map.*; Entry e;"); exp(TRUE, ( "import static java.util.Arrays.*;" + "asList(new String[] { \"HELLO\", \"WORLD\" }).size() == 2" )); } @Test public void test_9_7__Annotations() throws Exception { clb(COOK, "class C { @Override public String toString() { return \"foo!\"; } }"); clb(COMP, "class C { public String toString() { return \"foo!\"; } }"); clb(COMP, "class C { @Override public String meth1() { return \"foo!\"; } }"); clb(COOK, "class C { public String meth1() { return \"foo!\"; } }"); clb(COOK, "interface I extends Runnable { @Override void run(); }"); clb(COOK, "interface I extends Runnable { void run(); }"); } @Test public void test_14_3__LocalClassDeclarations() throws Exception { scr(TRUE, "class S2 extends SC { public int foo() { return 37; } }; return new S2().foo() == 37;"); } @Test public void test_14_8__ExpressionStatements() throws Exception { scr(TRUE, "int a; a = 8; ++a; a++; if (a != 10) return false; --a; a--; return a == 8;"); scr(EXEC, "System.currentTimeMillis();"); scr(EXEC, "new Object();"); scr(COMP, "new Object[3];"); scr(COMP, "int a; a;"); } @Test public void test_14_10a__TheAssertStatement() throws Exception { // CHECKSTYLE LineLength:OFF scr(EXEC, "assert true;"); scr(TRUE, "try { assert false; } catch (AssertionError ae) { return ae.getMessage() == null; } return false;"); scr(TRUE, "try { assert false : \"x\"; } catch (AssertionError ae) { return \"x\".equals(ae.getMessage()); } return false;"); scr(TRUE, "try { assert false : 3; } catch (AssertionError ae) { return \"3\".equals(ae.getMessage()); } return false;"); scr(TRUE, "try { assert false : new Integer(8); } catch (AssertionError ae) { return \"8\".equals(ae.getMessage()); } return false;"); // CHECKSTYLE LineLength:ON } @Test public void test_14_10__TheSwitchStatement() throws Exception { scr(TRUE, "int x = 37; switch (x) {} return x == 37;"); scr(TRUE, "int x = 37; switch (x) { default: ++x; break; } return x == 38;"); scr(TRUE, "int x = 37; switch (x) { case 36: case 37: case 38: x += x; break; } return x == 74;"); scr(TRUE, "int x = 37; switch (x) { case 36: case 37: case 1000: x += x; break; } return x == 74;"); scr(TRUE, "int x = 37; switch (x) { case -10000: break; case 10000: break; } return x == 37;"); scr(TRUE, "int x = 37; switch (x) { case -2000000000: break; case 2000000000: break; } return x == 37;"); } @Test public void test_14_20__UnreachableStatements() throws Exception { clb(COMP, ( "" + "public void test() throws Exception {}\n" + "public void test2() {\n" + " try {\n" + " test();\n" + " } catch (Exception e) {\n" + " ;\n" + " } catch (java.io.IOException e) {\n" + " // This CATCH clause is unreachable.\n" + " }\n" + "}\n" )); } @Test public void test_15_9__Expressions__ClassInstanceCreationExpressions() throws Exception { // 15.9.1 Determining the class being Instantiated exp(TRUE, "new Object() instanceof Object"); exp(COMP, "new java.util.List()"); exp(COMP, "new other_package.PackageClass()"); exp(COMP, "new java.util.AbstractList()"); exp(TRUE, ( "new other_package.Foo(3).new PublicMemberClass() instanceof other_package.Foo.PublicMemberClass" )); exp(COMP, "new other_package.Foo(3).new Foo.PublicMemberClass()"); exp(COMP, "new other_package.Foo(3).new other_package.Foo.PublicMemberClass()"); exp(COMP, "new other_package.Foo(3).new PackageMemberClass()"); exp(COMP, "new other_package.Foo(3).new PublicAbstractMemberClass()"); exp(COMP, "new other_package.Foo(3).new PublicStaticMemberClass()"); exp(COMP, "new other_package.Foo(3).new PublicMemberInterface()"); exp(COMP, "new java.util.ArrayList().new PublicMemberClass()"); // The following one is tricky: A Java 6 JRE declares // public int File.compareTo(File) // public abstract int Comparable.compareTo(Object) // , and yet "File" is not abstract! sim(TRUE, ( "class MyFile extends java.io.File {\n" + " public MyFile() { super(\"/my/file\"); }\n" + "}\n" + "public class Main {\n" + " public static boolean test() {\n" + " return 0 == new MyFile().compareTo(new MyFile());\n" + " }\n" + "}" ), "Main"); // 15.9.3 Choosing the Constructor and its Arguments exp(EXEC, "new Integer(3)"); exp(EXEC, "new Integer(new Integer(3))"); exp(EXEC, "new Integer(new Byte((byte) 3))"); exp(COMP, "new Integer(new Object())"); // 15.9.5 Anonymous Class Declarations sim(EXEC, ( "" + "public class Foo {\n" + " public static void test() { new Foo().meth(); }\n" + " private Object meth() {\n" + " return new Object() {};\n" + " }\n" + "}\n" ), "Foo"); sim(EXEC, ( "" + "public class A {\n" + " public static void test() { new A(); }\n" + " public A(Object o) {}\n" + " public A() {\n" + " this(new Object() {});\n" + " }\n" + "}\n" ), "A"); } @Test public void test_15_11__FieldAccessExpressions() throws Exception { // 15.11.2 Accessing Superclass Members using super sim(TRUE, ( "" + "public class T1 { int x = 1; }\n" + "public class T2 extends T1 { int x = 2; }\n" + "public class T3 extends T2 {\n" + " int x = 3;\n" + " public static boolean test() {\n" + " return new T3().test2();\n" + " }\n" + " public boolean test2() {\n" + " return (\n" + " x == 3\n" + " && super.x == 2\n" + " && T3.super.x == 2\n" + "// && T2.super.x == 1\n" // <= Does not work with the SUN JDK 1.6 compiler + " && ((T2) this).x == 2\n" + " && ((T1) this).x == 1\n" + " );\n" + " }\n" + "}\n" ), "T3"); } @Test public void test_15_12__MethodInvocationExpressions() throws Exception { // 15.12.2.2 Choose the Most Specific Method sim(COMP, ( "" + "public class Main { public static boolean test() { return new A().meth(\"x\", \"y\"); } }\n" + "public class A {\n" + " public boolean meth(String s, Object o) { return true; }\n" + " public boolean meth(Object o, String s) { return false; }\n" + "}\n" ), "Main"); // The following case is tricky: JLS2 says that the invocation is AMBIGUOUS, but only // JAVAC 1.2 issues an error; JAVAC 1.4.1, 1.5.0 and 1.6.0 obviously ignore the declaring // type and invoke "A.meth(String)". // JLS3 is not clear about this. For compatibility with JAVA 1.4.1, 1.5.0 and 1.6.0, // JANINO also ignores the declaring type. // // See also JANINO-79 and "IClass.IInvocable.isMoreSpecificThan()". sim(TRUE, ( "" + "public class Main { public static boolean test() { return new B().meth(\"x\"); } }\n" + "public class A { public boolean meth(String s) { return true; } }\n" + "public class B extends A { public boolean meth(Object o) { return false; } }\n" ), "Main"); } @Test public void test_15_14__PostfixExpressions() throws Exception { // "15.14.2 Postfix Increment Operator ++ scr(TRUE, "int i = 7; i++; return i == 8;"); scr(TRUE, "Integer i = new Integer(7); i++; return i.intValue() == 8;"); scr(TRUE, "int i = 7; return i == 7 && i++ == 7 && i == 8;"); scr(TRUE, ( "Integer i = new Integer(7);" + "return i.intValue() == 7 && (i++).intValue() == 7 && i.intValue() == 8;" )); // 15.14.3 Postfix Decrement Operator -- scr(TRUE, "int i = 7; i--; return i == 6;"); scr(TRUE, "Integer i = new Integer(7); i--; return i.intValue() == 6;"); scr(TRUE, "int i = 7; return i == 7 && i-- == 7 && i == 6;"); scr(TRUE, ( "Integer i = new Integer(7);" + "return i.intValue() == 7 && (i--).intValue() == 7 && i.intValue() == 6;" )); } @Test public void test_15_15__UnaryOperators() throws Exception { // 15.15.1 Prefix Increment Operator ++ scr(TRUE, "int i = 7; ++i; return i == 8;"); scr(TRUE, "Integer i = new Integer(7); ++i; return i.intValue() == 8;"); scr(TRUE, "int i = 7; return i == 7 && ++i == 8 && i == 8;"); scr(TRUE, ( "Integer i = new Integer(7);" + "return i.intValue() == 7 && (++i).intValue() == 8 && i.intValue() == 8;" )); // 15.15.2 Prefix Decrement Operator -- scr(TRUE, "int i = 7; --i; return i == 6;"); scr(TRUE, "Integer i = new Integer(7); --i; return i.intValue() == 6;"); scr(TRUE, "int i = 7; return i == 7 && --i == 6 && i == 6;"); scr(TRUE, ( "Integer i = new Integer(7);" + "return i.intValue() == 7 && (--i).intValue() == 6 && i.intValue() == 6;" )); // 15.15.3 Unary Plus Operator + exp(TRUE, "new Integer(+new Integer(7)).intValue() == 7"); // 15.15.4 Unary Minus Operator - exp(TRUE, "new Integer(-new Integer(7)).intValue() == -7"); } @Test public void test_15_17__MultiplicativeOperators() throws Exception { exp(TRUE, "new Integer(new Byte((byte) 2) * new Short((short) 3)).intValue() == 6"); } @Test public void test_15_18__AdditiveOperators() throws Exception { // 15.18 Additive Operators -- Numeric exp(TRUE, "(new Byte((byte) 7) - new Double(1.5D) + \"x\").equals(\"5.5x\")"); // 15.18.1.3 Additive Operators -- String Concatentation exp(TRUE, ( "(\"The square root of 6.25 is \" + Math.sqrt(6.25)).equals(\"The square root of 6.25 is 2.5\")" )); exp(TRUE, "1 + 2 + \" fiddlers\" == \"3 fiddlers\""); exp(TRUE, "\"fiddlers \" + 1 + 2 == \"fiddlers 12\""); for (int i = 65530; i <= 65537; ++i) { char[] ca = new char[i]; Arrays.fill(ca, 'x'); String s1 = new String(ca); exp(TRUE, "\"" + s1 + "\".length() == " + i); exp(TRUE, "(\"" + s1 + "\" + \"XXX\").length() == " + (i + 3)); } } @Test public void test_15_20__RelationOperators() throws Exception { // 15.20.1 Numerical Comparison Operators <, <=, > and >= exp(TRUE, "new Integer(7) > new Byte((byte) 5)"); } @Test public void test_15_21__EqualityOperators() throws Exception { // 15.21.1 Numerical Equality Operators == and != exp(COMP, "new Integer(7) != new Byte((byte) 5)"); exp(TRUE, "new Integer(7) == 7"); exp(TRUE, "new Byte((byte) -7) == -7"); exp(TRUE, "5 == new Byte((byte) 5)"); // 15.21.2 Boolean Equality Operators == and != exp(TRUE, "new Boolean(true) != new Boolean(true)"); exp(TRUE, "new Boolean(true) == true"); exp(TRUE, "false == new Boolean(false)"); exp(TRUE, "false != true"); // 15.21.3 Reference Equality Operators == and != exp(TRUE, "new Object() != new Object()"); exp(TRUE, "new Object() != null"); exp(TRUE, "new Object() != \"foo\""); exp(COMP, "new Integer(3) == \"foo\""); } @Test public void test_15_22__BitwiseAndLogicalOperators() throws Exception { // 15.22.2 Boolean Logical Operators &, ^, and | exp(TRUE, "new Boolean(true) & new Boolean(true)"); exp(TRUE, "new Boolean(true) ^ false"); exp(TRUE, "false | new Boolean(true)"); } @Test public void test_15_23__ConditionalAndOperator() throws Exception { // 15.23 Conditional-And Operator && exp(TRUE, "new Boolean(true) && new Boolean(true)"); exp(TRUE, "new Boolean(true) && true"); exp(TRUE, "true && new Boolean(true)"); } @Test public void test_15_24__ConditionalOrOperator() throws Exception { // 15.24 Conditional-Or Operator || exp(TRUE, "new Boolean(true) || new Boolean(false)"); exp(TRUE, "new Boolean(false) || true"); exp(TRUE, "true || new Boolean(true)"); } @Test public void test_15_26__ConditionalOrOperator() throws Exception { // 15.26.2 Compound Assignment Operators scr(TRUE, "int a = 7; a += 3; return a == 10;"); scr(TRUE, "int a = 7; a %= 3; return a == 1;"); scr(COMP, "Object a = \"foo\"; a += 3;"); scr(COMP, "int a = 7; a += \"foo\";"); scr(TRUE, "String a = \"foo\"; a += 3; return a.equals(\"foo3\");"); scr(TRUE, "String a = \"foo\"; a += 'o'; return a.equals(\"fooo\");"); scr(TRUE, "String a = \"foo\"; a += 1.0; return a.equals(\"foo1.0\");"); scr(TRUE, "String[] a = { \"foo\" }; a[0] += 1.0; return a[0].equals(\"foo1.0\");"); scr(TRUE, "Integer a = 7; a += 3; return a == 10;"); scr(TRUE, "int a = 7; a += new Integer(3); return a == 10;"); // JANINO-155: Compound assignment does not implement boxing conversion scr(TRUE, "Double[] a = { 1.0, 2.0 }; a[0] += 1.0; return a[0] == 2.0;"); } } janino-2.7.0/commons-compiler-tests/src/JavaSourceClassLoaderTests.java000066400000000000000000000100701222264062300262520ustar00rootroot00000000000000 /* * 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. */ import static org.junit.Assert.fail; import java.io.File; import java.util.Collection; import org.codehaus.commons.compiler.AbstractJavaSourceClassLoader; import org.codehaus.commons.compiler.ICompilerFactory; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; import util.TestUtil; @RunWith(Parameterized.class) public class JavaSourceClassLoaderTests { private static final File[] SOURCE_PATH = new File[] { new File("../janino/src"), new File("../commons-compiler/src"), }; private final ICompilerFactory compilerFactory; @Parameters public static Collection compilerFactories() throws Exception { return TestUtil.getCompilerFactoriesForParameters(); } public JavaSourceClassLoaderTests(ICompilerFactory compilerFactory) { this.compilerFactory = compilerFactory; } @Test public void testJSCL() throws Exception { ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); systemClassLoader.loadClass(this.getClass().getName()); ClassLoader extensionsClassLoader = systemClassLoader.getParent(); try { extensionsClassLoader.loadClass(this.getClass().getName()); fail("extensionsClassLoader should be separate from the current classloader"); } catch (ClassNotFoundException cnfe) { // as we had intended } extensionsClassLoader.loadClass("java.lang.String"); AbstractJavaSourceClassLoader jscl = this.compilerFactory.newJavaSourceClassLoader(extensionsClassLoader); jscl.setSourcePath(SOURCE_PATH); jscl.loadClass("org.codehaus.janino.Compiler"); } @Test public void testCircularSingleTypeImports() throws Exception { AbstractJavaSourceClassLoader jscl = this.compilerFactory.newJavaSourceClassLoader( ClassLoader.getSystemClassLoader().getParent() ); jscl.setSourcePath(new File[] { new File("aux-files/testCircularSingleTypeImports/") }); jscl.loadClass("test.Func1"); } @Test public void testCircularStaticImports() throws Exception { AbstractJavaSourceClassLoader jscl = this.compilerFactory.newJavaSourceClassLoader( ClassLoader.getSystemClassLoader().getParent() ); jscl.setSourcePath(new File[] { new File("aux-files/testCircularStaticImports/") }); jscl.loadClass("test.Func1"); } } janino-2.7.0/commons-compiler-tests/src/ReportedBugs.java000066400000000000000000000441541222264062300234670ustar00rootroot00000000000000 /* * 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. */ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import java.io.File; import java.io.StringReader; import java.util.Collection; import org.codehaus.commons.compiler.CompilerFactoryFactory; import org.codehaus.commons.compiler.ICompilerFactory; import org.codehaus.commons.compiler.IExpressionEvaluator; import org.codehaus.commons.compiler.ISimpleCompiler; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; import util.JaninoTestSuite; import util.TestUtil; // CHECKSTYLE MethodName:OFF @RunWith(Parameterized.class) public class ReportedBugs extends JaninoTestSuite { @Parameters public static Collection compilerFactories() throws Exception { return TestUtil.getCompilerFactoriesForParameters(); } public ReportedBugs(ICompilerFactory compilerFactory) throws Exception { super(compilerFactory); } @Test public void testBug48() throws Exception { sim(EXEC, ( "" + "package demo;\n" + "public class Service {\n" + " public static void test() {\n" + " Broken[] dummy = new Broken[5];\n" + " }\n" + " class Broken {\n" + " }\n" + "}" ), "demo.Service"); sim(EXEC, ( "" + "package demo;\n" + "public class Service {\n" + " public static Broken[] test() {\n" + " return null;\n" + " }\n" + "}\n" + "class Broken {\n" + "}" ), "demo.Service"); } @Test public void testBug54() throws Exception { scr(TRUE, ( "" + "String s = \"\";\n" + "try {\n" + " {\n" + " s += \"set1\";\n" + " }\n" + " {\n" + " boolean tmp4 = false;\n" + " if (tmp4) {\n" + " {\n" + " s += \"if true\";\n" + " if (true) return false;\n" + " }\n" + " }\n" + " }\n" + " {\n" + " s += \"return\";\n" + " }\n" + "} catch (Exception e) {\n" + " s += \"exception\";\n" + "} finally {\n" + " s +=\"finally\";\n" + "}\n" + "return \"set1returnfinally\".equals(s);" )); clb(COOK, ( "" + "void foo() {\n" + " while (true) {\n" + " if (true) {\n" + " break;\n" + " }\n" + " return;\n" + " }\n" + "}\n" + "void bar() {\n" + " while (true) {\n" + " {\n" + " if (true) {\n" + " break;\n" + " }\n" + " }\n" + " return;\n" + " }\n" + "}\n" )); clb(COOK, ( "" + "void baz1() {\n" + " for (int i = 0; i < 100;) {\n" + " {\n" + " if (true) {\n" + " break;\n" + " }\n" + " }\n" + " i += 2;\n" + " }\n" + "}\n" )); clb(COOK, ( "" + "void baz2() {\n" + " for (int i = 0; i < 100; i++) {\n" + " {\n" + " if (true) {\n" + " break;\n" + " }\n" + " }\n" + " i += 2;\n" + " }\n" + "}\n" )); clb(COOK, ( "" + "public void foo() throws Exception {\n" + " for (int i = 0 ; true; i++) {\n" + " break;\n" + " }\n" + "}\n" )); clb(COOK, ( "" + "public void foo() throws Exception {\n" + " for (int i = 0 ; true; i++) {\n" + " if (true) { break; }\n" + " }\n" + "}\n" )); clb(COOK, ( "" + "public void foo() throws Exception {\n" + " {\n" + " try {\n" + " int i = 0;\n" + " for (; true;) {\n" + " try {\n" + " {\n" + " {\n" // Invoke: break + " if (true) { break; }\n" + " }\n" // End Invoke: break + " }\n" + " i++;\n" + " } finally {}\n" + " i++;\n" + " }\n" + " return;\n" + " } finally {}\n" + " }\n" + "}\n" )); scr(EXEC, ( "" + "int c = 5;\n" + "if (c == 5) {\n" + " if (true) return;\n" + "} else {\n" + " return;\n" + "}\n" + "int b = 3;\n" // Physically unreachable, but logically reachable, hence not a compile error. )); } @Test public void testBug55() throws Exception { sim(COOK, ( "" + "class Junk {" + "\n" + " double[][] x = { { 123.4 } };" + "\n" + "}" ), null); } @Test public void testBug56() throws Exception { scr(COOK, ( "" + "int dummy3 = 3;\n" + "try {\n" + " // 3 vars must be declared in try block\n" + " int dummy5 = 5;\n" + " int dummy4 = 4;\n" + " boolean b = true;\n" + "\n" + " while (b) {\n" + " try {\n" + " ++dummy5;\n" // Optional + " return;\n" // <= Required + " } catch (Exception ex) {\n" + " ++dummy5;\n" + " }\n" + " }\n" + "} finally {\n" + " ++dummy3;\n" + "}\n" )); } @Test public void testBug63() throws Exception { clb(COMP, ( "" + "public static boolean main() {\n" + " IPred p = new Pred();\n" + " return !p.filter();\n" + "}\n" )); clb(TRUE, ( "" + "public static boolean main() {\n" + " Pred p = new Pred();\n" + " return !p.filter();\n" + "}\n" )); } @Test public void testBug69() throws Exception { sim(EXEC, ( "" + "public class Test {\n" + " public static void test() {\n" + " Object foo = baz();\n" + " System.out.println(\"hello\");\n" + " }\n" + " public static Object baz() {\n" + " final Test test = new Test();\n" + " return new Foo() {\n" + " private final void bar() {\n" + " try {\n" + " whee();\n" + " } catch (Throwable ex) {\n" + " throw test.choke();\n" + " }\n" + " }\n" + " private void whee() {\n" + " }\n" + " };\n" + " }\n" + " public RuntimeException choke() {\n" + " return new RuntimeException(\"ack\");\n" + " }\n" + " private static abstract class Foo {\n" + " }\n" + "}\n" ), "Test"); } @Test public void testBug70() throws Exception { clb(COOK, ( "" + "public String result = \"allow\", email = null, anno = null, cnd = null, transactionID = null;\n" + "public String treeCode(String root) {\n" + " try {\n" + " return null;\n" + " } catch (Exception treeEx) {\n" + " treeEx.printStackTrace();\n" + " result = \"allow\";\n" + " }\n" + " return result;\n" + "}\n" )); } @Test public void testBug71() throws Exception { sim(TRUE, ( "" + "public class ACI {\n" + " public static boolean test() {\n" + " Sub s = new ACI().new Sub(new int[] { 1, 2 });\n" + " return s.x == 1 && s.y == 2;\n" + " }\n" + " class Sub {\n" + " int x, y;\n" + " public Sub(int[] a) {\n" + " this(a[0], a[1]);\n" + " }\n" + " public Sub(int x, int y) {\n" + " this.x = x;\n" + " this.y = y;\n" + " }\n" + " }\n" + "}\n" ), "ACI"); sim(TRUE, ( "" + "public class SCI {\n" + " public static boolean test() {\n" + " Sub s = new SCI().new Sub(1, 2);\n" + " return s.x == 1 && s.y == 2;\n" + " }\n" + " class Sub extends Foo.Subb {\n" + " public Sub(int x, int y) {\n" + " new Foo().super(x, y);\n" + " }\n" + " }\n" + "}\n" + "class Foo {\n" + " class Subb {\n" + " int x, y;\n" + " public Subb(int x, int y) {\n" + " this.x = x;\n" + " this.y = y;\n" + " }\n" + " }\n" + "}\n" ), "SCI"); } @Test public void testBug80() throws Exception { // Expression compilation is said to throw StackOverflowError!? exp(COMP, "(10).total >= 100.0 ? 0.0 : 7.95"); } @Test public void testBug81() throws Exception { // IncompatibleClassChangeError when invoking getClass() on interface references scr(EXEC, ( "" + "import java.util.ArrayList;\n" + "import java.util.List;\n" + "\n" + "List list = new ArrayList();\n" + "System.out.println(list.getClass());\n" )); } @Test public void testBug99() throws Exception { // ConcurrentModificationException due to instance variable of Class type initialized using a class literal sim(COOK, "class Test{Class c = String.class;}", "Test"); } @Test public void testBug102() throws Exception { // Static initializers are not executed sim(TRUE, ( "" + "public class Test{\n" + " static String x = \"\";\n" + " static { x += 0; }\n" + " static int a = 7;\n" + " static { x += a; }\n" + " static { System.out.println(\"HELLO\");\n }\n" + " public static boolean test() {\n" + " System.out.println(\">>>\" + x + \"<<<\");\n" + " return x.equals(\"07\");\n" + " }\n" + "}" ), "Test"); ISimpleCompiler compiler = CompilerFactoryFactory.getDefaultCompilerFactory().newSimpleCompiler(); compiler.cook(new StringReader("public class Test{static{System.setProperty(\"foo\", \"bar\");}}")); Class testClass = compiler.getClassLoader().loadClass("Test"); // Only loads the class (JLS2 12.2) assertNull(System.getProperty("foo")); testClass.newInstance(); // Initializes the class (JLS2 12.4) assertEquals("bar", System.getProperty("foo")); System.getProperties().remove("foo"); assertNull(System.getProperty("foo")); } @Test public void testBug105() throws Exception { // Possible to call a method of an enclosing class as if it was a member of an inner class clb(COMP, ( "" + "class Price {\n" + " public int getPriceA() {\n" + " return 1;\n" + " }\n" + "\n" + " public int getPriceB() {\n" + " return 2;\n" + " }\n" + "}\n" + "\n" + "Price price;\n" + "\n" + "public int assign() {\n" + " return price.rate();\n" // This should not compile. + "}\n" + "\n" + "int rate() {\n" + " return 17;\n" + "}\n" )); } @Test public void testBug106() throws Exception { jscl("Bug 106", new File("aux-files/Bug 106"), "b.C3"); sim(TRUE, ( "class MyFile extends java.io.File {\n" + " public MyFile() { super(\"/my/file\"); }\n" + "}\n" + "public class Main {\n" + " public static boolean test() {\n" + " return 0 == new MyFile().compareTo(new MyFile());\n" + " }\n" + "}" ), "Main"); scr(TRUE, ( "StringBuffer sb = new StringBuffer();\n" + "sb.append('(');\n" + "return sb.length() == 1;\n" )); } @Test public void testBug147() throws Exception { sim(COOK, ( "public class Foo {\n" + " public static void main(String[] args) {\n" + " new Object() {\n" + " Object bar = new Object() {\n" + " public Object getObject(int i8) {\n" + " switch (i8) { case 0: return \"sss\"; }\n" + " return null;\n" + " }\n" + " };\n" + " };\n" + " }\n" + "}" ), "Foo"); } @Test public void testBug149() throws Exception { // JLS3 3.10.6: "aaa\/bbb" contains an invalid escape sequence: "\/". exp(COMP, "\"aaa\\/bbb\""); } @SuppressWarnings("deprecation") @Test(expected = AssertionError.class) public void testBug157() throws Exception { IExpressionEvaluator evaluator = CompilerFactoryFactory.getDefaultCompilerFactory().newExpressionEvaluator(); evaluator.setReturnType(Long.class); } @Test public void testBug153_1() throws Exception { scr(EXEC, "Comparable x = 5.0;"); } @Test public void testBug153_2() throws Exception { // JLS3 says about casting conversion // (http://java.sun.com/docs/books/jls/third_edition/html/conversions.html#5.5): // // Casting contexts allow the use of: // ... // * a boxing conversion (�5.1.7) // // , but obviously (JAVAC) a boxing conversion followed by a widening reference conversion is also // permitted (as for assignment conversion). scr(EXEC, "Comparable x = (Comparable) 5.0;"); } @Test public void testBug153_3() throws Exception { scr(EXEC, "long x = new Integer(8);"); } @Test public void testBug153_4() throws Exception { // JLS3 says about casting conversion // (http://java.sun.com/docs/books/jls/third_edition/html/conversions.html#5.5): // // Casting contexts allow the use of: // ... // * an unboxing conversion (�5.1.8) // // , but obviously (JAVAC) an unboxing conversion followed by a widening primitive conversion is also // permitted (as for assignment conversion). scr(EXEC, "long x = (long) new Integer(8);"); } } janino-2.7.0/commons-compiler-tests/src/SandboxTests.java000066400000000000000000000075661222264062300235110ustar00rootroot00000000000000 /* * 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. */ import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import java.util.Collection; import org.codehaus.commons.compiler.CompileException; import org.codehaus.commons.compiler.ICompilerFactory; import org.codehaus.commons.compiler.ICookable; import org.codehaus.commons.compiler.IExpressionEvaluator; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; import util.TestUtil; import for_sandbox_tests.ExternalClass; @RunWith(Parameterized.class) public class SandboxTests { private final ICompilerFactory compilerFactory; @Parameters public static Collection compilerFactories() throws Exception { return TestUtil.getCompilerFactoriesForParameters(); } public SandboxTests(ICompilerFactory compilerFactory) { this.compilerFactory = compilerFactory; } @Test public void testForbiddenClass() throws Exception { // Invoke method of a class that is on the CLASSPATH of this JVM, but not on the BOOTCLASSPATH. try { IExpressionEvaluator ee = this.compilerFactory.newExpressionEvaluator(); ee.setParentClassLoader(ICookable.BOOT_CLASS_LOADER); ee.cook("for_sandbox_tests.ExternalClass.m1()"); fail("Should have thrown a CompileException"); } catch (CompileException ex) { ; } } @Test public void testAuxiliaryClass() throws Exception { // Invoke method of allowed external class. IExpressionEvaluator ee = this.compilerFactory.newExpressionEvaluator(); // ee.setParentClassLoader(null, new Class[] { ExternalClass.class }); ee.cook("for_sandbox_tests.ExternalClass.m1()"); assertEquals(7, ((Integer) ee.evaluate(new Object[0])).intValue()); } @Test public void testExternalBaseClass() throws Exception { // Invoke method of base class. IExpressionEvaluator ee = this.compilerFactory.newExpressionEvaluator(); // ee.setParentClassLoader(SimpleCompiler.BOOT_CLASS_LOADER, new Class[] { OtherExternalClass.class }); ee.setExtendedClass(ExternalClass.class); ee.cook("m1()"); assertEquals(7, ((Integer) ee.evaluate(new Object[0])).intValue()); } } janino-2.7.0/commons-compiler-tests/src/ScopingTests.java000066400000000000000000000221541222264062300235030ustar00rootroot00000000000000 /* * 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. */ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import java.lang.reflect.Method; import java.util.Collection; import org.codehaus.commons.compiler.ICompilerFactory; import org.codehaus.commons.compiler.ISimpleCompiler; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; import util.TestUtil; @RunWith(Parameterized.class) public class ScopingTests { private final ICompilerFactory compilerFactory; @Parameters public static Collection compilerFactories() throws Exception { return TestUtil.getCompilerFactoriesForParameters(); } public ScopingTests(ICompilerFactory compilerFactory) { this.compilerFactory = compilerFactory; } private void setParentClassLoader(ISimpleCompiler sc) { // sc.setParentClassLoader(BOOT_CLASS_LOADER /*, new Class[] { for_sandbox_tests.ProtectedVariable.class }*/); } @Test public void testProtectedAccessAcrossPackages() throws Exception { ISimpleCompiler sc = this.compilerFactory.newSimpleCompiler(); this.setParentClassLoader(sc); sc.cook( "" + "package test;\n" + "public class Top extends for_sandbox_tests.ProtectedVariable {\n" + " public class Inner {\n" + " public int get() {\n" + " return var;\n" + " }\n" + " } \n" + "}" ); } @Test @Ignore("Known failure - JANINO-113") public void testProtectedAccessWithinPackage() throws Exception { ISimpleCompiler sc = this.compilerFactory.newSimpleCompiler(); this.setParentClassLoader(sc); sc.cook( "" + "package for_sandbox_tests;\n" + "public class Top extends for_sandbox_tests.ProtectedVariable {\n" + " public class Inner {\n" + " public int get() {\n" + " return var;\n" + " }\n" + " public void set() {\n" + " var += 10;\n" + " }\n" + " public int getS() {\n" + " return svar;\n" + " }\n" + " public void setS() {\n" + " svar += 10;\n" + " }\n" + " } \n" + " public Inner createInner() {\n" + " return new Inner();\n" + " }\n" + "}" ); Class topClass = sc.getClassLoader().loadClass("for_sandbox_tests.Top"); Method createInner = topClass.getDeclaredMethod("createInner", new Class[0]); Object t = topClass.newInstance(); Object i = createInner.invoke(t, new Object[0]); Class innerClass = sc.getClassLoader().loadClass("for_sandbox_tests.Top$Inner"); Method get = innerClass.getDeclaredMethod("get", new Class[0]); Method getS = innerClass.getDeclaredMethod("getS", new Class[0]); Method set = innerClass.getDeclaredMethod("set", new Class[0]); Method setS = innerClass.getDeclaredMethod("setS", new Class[0]); Object res; { // non-static res = get.invoke(i, new Object[0]); assertEquals(1, res); set.invoke(i, new Object[0]); res = get.invoke(i, new Object[0]); assertEquals(11, res); } { //static res = getS.invoke(i, new Object[0]); assertEquals(2, res); setS.invoke(i, new Object[0]); res = getS.invoke(i, new Object[0]); assertEquals(12, res); } } @Test @Ignore("Known failure - JANINO-113") public void testComplicatedSyntheticAccess() throws Exception { ISimpleCompiler sc = this.compilerFactory.newSimpleCompiler(); this.setParentClassLoader(sc); sc.cook( "" + "package for_sandbox_tests;\n" + "public class L0 extends for_sandbox_tests.ProtectedVariable {\n" + " public class L1 extends for_sandbox_tests.ProtectedVariable {\n" + " public class L2 extends for_sandbox_tests.ProtectedVariable {\n" + " public class Inner {\n" + " public int getL2() { return L0.L1.L2.this.var; }\n" + " public int getL1() { return L0.L1.this.var; }\n" + " public int getL0() { return L0.this.var; }\n" + " public int setL2() { return L2.this.var = 2; }\n" + " public int setL1() { return L1.this.var = 1; }\n" + " public int setL0() { return L0.this.var = 0; }\n" + " }\n" + " }\n" + " }\n" + " public L0.L1.L2.Inner createInner() {\n" + " return new L0().new L1().new L2().new Inner();\n" + " }\n" + "}" ); Class topClass = sc.getClassLoader().loadClass("for_sandbox_tests.L0"); Method createInner = topClass.getDeclaredMethod("createInner", new Class[0]); Object t = topClass.newInstance(); Object inner = createInner.invoke(t, new Object[0]); Class innerClass = inner.getClass(); Method[] gets = new Method[] { innerClass.getMethod("getL0", new Class[0]), innerClass.getMethod("getL1", new Class[0]), innerClass.getMethod("getL2", new Class[0]), }; Method[] sets = new Method[] { innerClass.getMethod("setL0", new Class[0]), innerClass.getMethod("setL1", new Class[0]), innerClass.getMethod("setL2", new Class[0]), }; for (int i = 0; i < 3; ++i) { Object g1 = gets[i].invoke(inner, new Object[0]); assertEquals(1, g1); Object s1 = sets[i].invoke(inner, new Object[0]); assertEquals(i, s1); Object g2 = gets[i].invoke(inner, new Object[0]); assertEquals(i, g2); } } @Test @Ignore("Known failure - JANINO-113") public void testStaticInitAccessProtected() throws Exception { ISimpleCompiler sc = this.compilerFactory.newSimpleCompiler(); sc.cook( "" + "package test;\n" + "public class Outer extends for_sandbox_tests.ProtectedVariable {\n" + " public class Inner {\n" + " {\n" + " int t = var;\n" + " var = svar;\n" + " svar = t;\n" + " }\n" + " private final int i = var;\n" + " private final int j = svar;\n" + " {\n" + " int t = var;\n" + " var = svar;\n" + " svar = t;\n" + " }\n" + " private final int[] a = new int[] { i, j };\n" + " }\n" + " public Inner createInner() {\n" + " return new Inner();\n" + " }\n" + "}" ); Class topClass = sc.getClassLoader().loadClass("test.Outer"); Method createInner = topClass.getDeclaredMethod("createInner", new Class[0]); Object t = topClass.newInstance(); assertNotNull(t); Object inner = createInner.invoke(t, new Object[0]); assertNotNull(inner); } } janino-2.7.0/commons-compiler-tests/src/SerializationTests.java000066400000000000000000000056731222264062300247250ustar00rootroot00000000000000 /* * 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. */ import static org.junit.Assert.fail; import java.io.ByteArrayOutputStream; import java.io.ObjectOutputStream; import java.util.Collection; import org.codehaus.commons.compiler.ICompilerFactory; import org.codehaus.commons.compiler.ISimpleCompiler; import org.codehaus.commons.compiler.LocatedException; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; import util.TestUtil; @RunWith(Parameterized.class) public class SerializationTests { private final ICompilerFactory compilerFactory; @Parameters public static Collection compilerFactories() throws Exception { return TestUtil.getCompilerFactoriesForParameters(); } public SerializationTests(ICompilerFactory compilerFactory) { this.compilerFactory = compilerFactory; } @Test public void testExceptionSerializable() throws Exception { ISimpleCompiler compiler = this.compilerFactory.newSimpleCompiler(); try { compiler.cook("this is not valid Java"); fail("Cook should have thrown an exception"); } catch (LocatedException e) { ObjectOutputStream oos = new ObjectOutputStream(new ByteArrayOutputStream()); oos.writeObject(e); oos.close(); } } } janino-2.7.0/commons-compiler-tests/src/util/000077500000000000000000000000001222264062300211645ustar00rootroot00000000000000janino-2.7.0/commons-compiler-tests/src/util/JaninoTestSuite.java000066400000000000000000000337111222264062300251240ustar00rootroot00000000000000 /* * 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 util; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.fail; import java.io.File; import java.lang.reflect.Method; import org.codehaus.commons.compiler.AbstractJavaSourceClassLoader; import org.codehaus.commons.compiler.CompileException; 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; import org.codehaus.commons.compiler.LocatedException; public class JaninoTestSuite { /** The test is expected to throw a CompileException */ public static final CompileAndExecuteTest.Mode COMP = new CompileAndExecuteTest.Mode(); /** The test is expected to compile successfully, but is not executed */ public static final CompileAndExecuteTest.Mode COOK = new CompileAndExecuteTest.Mode(); /** The test is expected to compile and execute successfully */ public static final CompileAndExecuteTest.Mode EXEC = new CompileAndExecuteTest.Mode(); /** The test is expected to compile and execute successfully, and return {@code true} */ public static final CompileAndExecuteTest.Mode TRUE = new CompileAndExecuteTest.Mode(); protected final ICompilerFactory compilerFactory; public JaninoTestSuite(ICompilerFactory compilerFactory) { this.compilerFactory = compilerFactory; } /** * Add a test case that scans, parses and compiles an expression, and verifies that it * evaluates to {@code true}. * * * * * * * *
{@code mode}Meaning
COMPThe test is expected to throw a CompileException
COOKThe test is expected to compile successfully, but is not executed
EXECThe test is expected to compile and execute successfully
TRUEThe test is expected to compile and execute successfully, and return {@code true}
*/ protected void exp(ExpressionTest.Mode mode, String expression) throws Exception { ExpressionTest et = new ExpressionTest(mode, expression); et.runTest(); } protected void exp(ExpressionTest.Mode mode, String expression, String[] defaultImports) throws Exception { ExpressionTest et = new ExpressionTest(mode, expression); et.setDefaultImports(defaultImports); et.runTest(); } protected class ExpressionTest extends CompileAndExecuteTest { private final String expression; private final IExpressionEvaluator expressionEvaluator; public ExpressionTest(Mode mode, String expression) throws Exception { super(mode); this.expression = expression; this.expressionEvaluator = JaninoTestSuite.this.compilerFactory.newExpressionEvaluator(); this.expressionEvaluator.setExpressionType(mode == TRUE ? boolean.class : IExpressionEvaluator.ANY_TYPE); } public ExpressionTest setDefaultImports(String[] defaultImports) { this.expressionEvaluator.setDefaultImports(defaultImports); return this; } protected void compile() throws Exception { this.expressionEvaluator.cook(this.expression); } protected Object execute() throws Exception { return this.expressionEvaluator.evaluate(new Object[0]); } } /** * Add a test case that scans, parses, compiles and executes a Janino script, and verifies * that it returns {@code true}. * * * * * * * *
{@code mode}Meaning
COMPThe test is expected to throw a CompileException
COOKThe test is expected to compile successfully, but is not executed
EXECThe test is expected to compile and execute successfully
TRUEThe test is expected to compile and execute successfully, and return {@code true}
*/ protected void scr(ScriptTest.Mode mode, String script) throws Exception { ScriptTest st = new ScriptTest(mode, script); st.runTest(); } protected void scr(ScriptTest.Mode mode, String script, String[] defaultImports) throws Exception { ScriptTest st = new ScriptTest(mode, script); st.setDefaultImports(defaultImports); st.runTest(); } protected class ScriptTest extends CompileAndExecuteTest { private final String script; private final IScriptEvaluator scriptEvaluator; public ScriptTest(Mode mode, String script) throws Exception { super(mode); this.script = script; this.scriptEvaluator = JaninoTestSuite.this.compilerFactory.newScriptEvaluator(); this.scriptEvaluator.setReturnType(mode == TRUE ? boolean.class : void.class); } public ScriptTest setDefaultImports(String[] defaultImports) { this.scriptEvaluator.setDefaultImports(defaultImports); return this; } protected void compile() throws Exception { this.scriptEvaluator.cook(this.script); } protected Object execute() throws Exception { return this.scriptEvaluator.evaluate(new Object[0]); } } /** * Add a test case that scans, parses and compiles a class body, invokes its {@code public static boolean main()} * method and verifies that it returns {@code true}. * * * * * * * *
{@code mode}Meaning
COMPThe test is expected to throw a CompileException
COOKThe test is expected to compile successfully, but is not executed
EXECThe test is expected to compile and execute successfully
TRUEThe test is expected to compile and execute successfully, and return {@code true}
*/ protected void clb(ClassBodyTest.Mode mode, String classBody) throws Exception { ClassBodyTest cbt = new ClassBodyTest(mode, classBody); cbt.runTest(); } protected void clb(ClassBodyTest.Mode mode, String classBody, String[] defaultImports) throws Exception { ClassBodyTest cbt = new ClassBodyTest(mode, classBody); cbt.setDefaultImports(defaultImports); cbt.runTest(); } protected class ClassBodyTest extends CompileAndExecuteTest { private final String classBody; private final IClassBodyEvaluator classBodyEvaluator; public ClassBodyTest(Mode mode, String classBody) throws Exception { super(mode); this.classBody = classBody; this.classBodyEvaluator = JaninoTestSuite.this.compilerFactory.newClassBodyEvaluator(); } public ClassBodyTest setDefaultImports(String[] defaultImports) { this.classBodyEvaluator.setDefaultImports(defaultImports); return this; } protected void compile() throws Exception { this.classBodyEvaluator.cook(this.classBody); } protected Object execute() throws Exception { @SuppressWarnings("unchecked") Method method = this.classBodyEvaluator.getClazz().getMethod( "main", new Class[0] ); return method.invoke(null, new Object[0]); } } /** * Add a test case that scans, parses and compiles a compilation unit, then calls the {@code public static boolean * test()} method of the named class, and verifies that it returns {@code true}. * * * * * * * *
{@code mode}Meaning
COMPThe test is expected to throw a CompileException
COOKThe test is expected to compile successfully, but is not executed
EXECThe test is expected to compile and execute successfully
TRUEThe test is expected to compile and execute successfully, and return {@code true}
* @param className The name of the class with the {@code public static boolean test()} method */ protected void sim(SimpleCompilerTest.Mode mode, String compilationUnit, String className) throws Exception { SimpleCompilerTest sct = new SimpleCompilerTest(mode, compilationUnit, className); sct.runTest(); } protected class SimpleCompilerTest extends CompileAndExecuteTest { private final String compilationUnit; private final String className; private final ISimpleCompiler simpleCompiler; public SimpleCompilerTest(Mode mode, String compilationUnit, String className) throws Exception { super(mode); this.compilationUnit = compilationUnit; this.className = className; this.simpleCompiler = JaninoTestSuite.this.compilerFactory.newSimpleCompiler(); } protected void compile() throws Exception { this.simpleCompiler.cook(this.compilationUnit); } protected Object execute() throws Exception { return ( this.simpleCompiler.getClassLoader() .loadClass(this.className) .getMethod("test", new Class[0]) .invoke(null, new Object[0]) ); } } /** * Create and return a test case that sets up a {@link JavaSourceClassLoader} that reads sources from a given * directory, and then loads the named class. * * @param className The name of the class to be loaded from the {@link JavaSourceClassLoader} */ protected void jscl(String testCaseName, final File sourceDirectory, final String className) throws Exception { AbstractJavaSourceClassLoader loader = this.compilerFactory.newJavaSourceClassLoader(); loader.setSourcePath(new File[] { sourceDirectory }); loader.loadClass(className); } /** * A test case that calls its abstract methods {@link #compile()}, then {@link #execute()}, and * verifies that they throw exceptions and return results as expected. */ abstract static class CompileAndExecuteTest { protected final Mode mode; public static final class Mode { private Mode() {} } public CompileAndExecuteTest(Mode mode) { this.mode = mode; } protected abstract void compile() throws Exception; protected abstract Object execute() throws Exception; /** * Invoke {@link #compile()}, then {@link #execute()}, and verify that they throw exceptions and return * results as expected. */ protected void runTest() throws Exception { if (this.mode == COMP) { try { this.compile(); } catch (CompileException ex) { return; } catch (LocatedException le) { assertEquals("CompileException", le); } fail("Should have thrown CompileException, but compiled successfully"); } else if (this.mode == COOK) { this.compile(); } else if (this.mode == EXEC) { this.compile(); this.execute(); } else if (this.mode == TRUE) { this.compile(); Object result = this.execute(); assertNotNull("Test result", result); assertSame("Test return type", Boolean.class, result.getClass()); assertEquals("Test result", true, ((Boolean) result).booleanValue()); } else { fail("Invalid mode \"" + this.mode + "\""); } } } } janino-2.7.0/commons-compiler-tests/src/util/TestUtil.java000066400000000000000000000015321222264062300236050ustar00rootroot00000000000000package util; import java.util.ArrayList; import java.util.List; import org.codehaus.commons.compiler.CompilerFactoryFactory; import org.codehaus.commons.compiler.ICompilerFactory; import org.junit.runners.Parameterized.Parameters; public final class TestUtil { /** * Return the available compiler factories in a format suitable for JUnit {@link Parameters} */ public static List getCompilerFactoriesForParameters() throws Exception { ArrayList f = new ArrayList(); for (ICompilerFactory fact : CompilerFactoryFactory.getAllCompilerFactories()) { f.add(new Object[] { fact }); } if (f.isEmpty()) { throw new RuntimeException("Could not find any Compiler Factories on the classpath"); } return f; } private TestUtil() {} } janino-2.7.0/commons-compiler-tests/test-src/000077500000000000000000000000001222264062300211645ustar00rootroot00000000000000janino-2.7.0/commons-compiler-tests/test-src/Pred.java000066400000000000000000000031551222264062300227250ustar00rootroot00000000000000 /* * 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. */ public class Pred implements IPred { public boolean filter() { return false; } } janino-2.7.0/commons-compiler-tests/test-src/covariant_clone/000077500000000000000000000000001222264062300243325ustar00rootroot00000000000000janino-2.7.0/commons-compiler-tests/test-src/covariant_clone/Base.java000066400000000000000000000007711222264062300260540ustar00rootroot00000000000000 package covariant_clone; public abstract class Base implements Cloneable, CloneableData { /** * Clone this tuple, the new tuple will not share any buffers or data with the original * @return A copy of this Tuple */ public Base clone() throws CloneNotSupportedException { //subclasses must implement throw new CloneNotSupportedException(); } public Base other(long i, Object o) { throw new RuntimeException("Base.other() called"); } } janino-2.7.0/commons-compiler-tests/test-src/covariant_clone/CloneableData.java000066400000000000000000000002141222264062300276500ustar00rootroot00000000000000package covariant_clone; public interface CloneableData extends Cloneable { CloneableData clone() throws CloneNotSupportedException; } janino-2.7.0/commons-compiler-tests/test-src/covariant_clone/Middle.java000066400000000000000000000007771222264062300264060ustar00rootroot00000000000000 package covariant_clone; public class Middle extends Base { public Base cloneWithOutArguments() { try { return clone(); } catch (CloneNotSupportedException e) { throw new RuntimeException("Clone not supported on class: " + getClass().getName(), e); } } public Middle cloneWithArguments() { return other(1, null); } public Middle other(long i, Object o) { throw new RuntimeException("Middle() called"); } } janino-2.7.0/commons-compiler-tests/test-src/for_sandbox_tests/000077500000000000000000000000001222264062300247125ustar00rootroot00000000000000janino-2.7.0/commons-compiler-tests/test-src/for_sandbox_tests/BaseOfBaseOfExternalClass.java000066400000000000000000000001161222264062300324630ustar00rootroot00000000000000 package for_sandbox_tests; public class BaseOfBaseOfExternalClass { } janino-2.7.0/commons-compiler-tests/test-src/for_sandbox_tests/BaseOfExternalClass.java000066400000000000000000000002241222264062300314030ustar00rootroot00000000000000 package for_sandbox_tests; public class BaseOfExternalClass extends BaseOfBaseOfExternalClass implements InterfaceOfBaseOfExternalClass { } janino-2.7.0/commons-compiler-tests/test-src/for_sandbox_tests/CovariantReturns.java000066400000000000000000000002021222264062300310600ustar00rootroot00000000000000 package for_sandbox_tests; public abstract class CovariantReturns { public abstract CovariantReturns overrideMe(); } janino-2.7.0/commons-compiler-tests/test-src/for_sandbox_tests/ExternalClass.java000066400000000000000000000006521222264062300303300ustar00rootroot00000000000000 package for_sandbox_tests; public class ExternalClass extends BaseOfExternalClass implements InterfaceOfExternalClass { public final OtherExternalClass x = new OtherExternalClass(); public static int m1() { return OtherExternalClass.m1(); } public OtherExternalClass m2() { return null; } public void m2(OtherExternalClass fc) {} } janino-2.7.0/commons-compiler-tests/test-src/for_sandbox_tests/InterfaceOfBaseOfExternalClass.java000066400000000000000000000001271222264062300335130ustar00rootroot00000000000000 package for_sandbox_tests; public interface InterfaceOfBaseOfExternalClass { } janino-2.7.0/commons-compiler-tests/test-src/for_sandbox_tests/InterfaceOfExternalClass.java000066400000000000000000000001211222264062300324250ustar00rootroot00000000000000 package for_sandbox_tests; public interface InterfaceOfExternalClass { } janino-2.7.0/commons-compiler-tests/test-src/for_sandbox_tests/OtherExternalClass.java000066400000000000000000000001611222264062300313250ustar00rootroot00000000000000 package for_sandbox_tests; public class OtherExternalClass { public static int m1() { return 7; } } janino-2.7.0/commons-compiler-tests/test-src/for_sandbox_tests/OverridesWithDifferingVisibility.java000066400000000000000000000004001222264062300342330ustar00rootroot00000000000000 package for_sandbox_tests; public class OverridesWithDifferingVisibility { public static void test(Object o) {} private static void test(Object[] arr) {} // squish a compiler warning static { test(new Object[] {}); } } janino-2.7.0/commons-compiler-tests/test-src/for_sandbox_tests/ProtectedVariable.java000066400000000000000000000002161222264062300311530ustar00rootroot00000000000000 package for_sandbox_tests; public class ProtectedVariable { protected int var = 1; protected static int svar = 2; } janino-2.7.0/commons-compiler-tests/test-src/other_package/000077500000000000000000000000001222264062300237605ustar00rootroot00000000000000janino-2.7.0/commons-compiler-tests/test-src/other_package/Base.java000066400000000000000000000001371222264062300254760ustar00rootroot00000000000000 package other_package; public abstract class Base { public abstract void run(); } janino-2.7.0/commons-compiler-tests/test-src/other_package/Foo.java000066400000000000000000000044731222264062300253560ustar00rootroot00000000000000 package other_package; /** * Helper class for {@link JLS2Tests} -- used to define accessibility tests. */ public class Foo { public Foo(int i) {} /*package*/ Foo(String s) {} protected Foo(boolean b) {} private Foo(char c) {} private static void privateStaticMethod() {} private void privateMethod() {} static void packageStaticMethod() {} void packageMethod() {} protected static void protectedStaticMethod() {} protected void protectedMethod() {} public static void publicStaticMethod() {} public void publicMethod() {} private static class PrivateStaticMemberClass {} private class PrivateMemberClass {} static class PackageStaticMemberClass {} class PackageMemberClass {} protected static class ProtectedStaticMemberClass {} protected class ProtectedMemberClass {} public static class PublicStaticMemberClass {} public class PublicMemberClass {} public abstract static class PublicAbstractStaticMemberClass {} public abstract class PublicAbstractMemberClass {} private static interface PrivateStaticMemberInterface {} // SUPPRESS CHECKSTYLE RedundantModifier private interface PrivateMemberInterface {} static interface PackageStaticMemberInterface {} // SUPPRESS CHECKSTYLE RedundantModifier interface PackageMemberInterface {} protected static interface ProtectedStaticMemberInterface {} // SUPPRESS CHECKSTYLE RedundantModifier protected interface ProtectedMemberInterface {} public static interface PublicStaticMemberInterface {} // SUPPRESS CHECKSTYLE RedundantModifier public interface PublicMemberInterface {} void useMembersToSuppressWarnings() { new Foo('c'); privateStaticMethod(); this.privateMethod(); new PrivateStaticMemberClass(); new PrivateMemberClass(); new PrivateStaticMemberInterface() {}; new PrivateMemberInterface() {}; } } class PackageClass {} interface PackageInterface {} janino-2.7.0/commons-compiler-tests/test-src/other_package/ScopingRules.java000066400000000000000000000003221222264062300272350ustar00rootroot00000000000000 package other_package; public class ScopingRules { protected class ProtectedInner { public void publicMethod() {} } public static double publicStaticDouble = Math.PI; } janino-2.7.0/commons-compiler/000077500000000000000000000000001222264062300162605ustar00rootroot00000000000000janino-2.7.0/commons-compiler/.checkstyle000066400000000000000000000010171222264062300204160ustar00rootroot00000000000000 janino-2.7.0/commons-compiler/janino-checkstyle-configuration.xml000066400000000000000000000072511222264062300252660ustar00rootroot00000000000000 janino-2.7.0/commons-compiler/pom.xml000066400000000000000000000012441222264062300175760ustar00rootroot00000000000000 4.0.0 org.codehaus.janino janino-parent 2.6.2-SNAPSHOT commons-compiler Commons Compiler junit junit test janino-2.7.0/commons-compiler/src/000077500000000000000000000000001222264062300170475ustar00rootroot00000000000000janino-2.7.0/commons-compiler/src/org/000077500000000000000000000000001222264062300176365ustar00rootroot00000000000000janino-2.7.0/commons-compiler/src/org/codehaus/000077500000000000000000000000001222264062300214315ustar00rootroot00000000000000janino-2.7.0/commons-compiler/src/org/codehaus/commons/000077500000000000000000000000001222264062300231045ustar00rootroot00000000000000janino-2.7.0/commons-compiler/src/org/codehaus/commons/compiler/000077500000000000000000000000001222264062300247165ustar00rootroot00000000000000janino-2.7.0/commons-compiler/src/org/codehaus/commons/compiler/AbstractCompilerFactory.java000066400000000000000000000056041222264062300323540ustar00rootroot00000000000000 /* * Janino - An embedded Java[TM] compiler * * Copyright (c) 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.commons.compiler; /** * Base class for a simple {@link ICompilerFactory}. */ public abstract class AbstractCompilerFactory implements ICompilerFactory { @Override public abstract String getId(); @Override public abstract String getImplementationVersion(); @Override public IExpressionEvaluator newExpressionEvaluator() { throw new UnsupportedOperationException(this.getId() + ": newExpressionEvaluator"); } @Override public IScriptEvaluator newScriptEvaluator() { throw new UnsupportedOperationException(this.getId() + ": newScriptEvaluator"); } @Override public IClassBodyEvaluator newClassBodyEvaluator() { throw new UnsupportedOperationException(this.getId() + ": newClassBodyEvaluator"); } @Override public ISimpleCompiler newSimpleCompiler() { throw new UnsupportedOperationException(this.getId() + ": newSimpleCompiler"); } @Override public AbstractJavaSourceClassLoader newJavaSourceClassLoader() { throw new UnsupportedOperationException(this.getId() + ": newJavaSourceClassLoader"); } @Override public AbstractJavaSourceClassLoader newJavaSourceClassLoader(ClassLoader parentClassLoader) { throw new UnsupportedOperationException(this.getId() + ": newJavaSourceClassLoader(ClassLoader)"); } } janino-2.7.0/commons-compiler/src/org/codehaus/commons/compiler/AbstractJavaSourceClassLoader.java000066400000000000000000000222501222264062300334250ustar00rootroot00000000000000 /* * 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.commons.compiler; import java.io.File; import java.lang.reflect.*; import java.security.ProtectionDomain; import java.util.*; /** * A {@link ClassLoader} that, unlike usual {@link ClassLoader}s, does not load byte code, but reads Java™ source * code and then scans, parses, compiles and loads it into the virtual machine. *

* 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 AbstractJavaSourceClassLoader} and create a new one. */ @SuppressWarnings({ "rawtypes", "unchecked" }) public abstract class AbstractJavaSourceClassLoader extends ClassLoader { /** @see ClassLoader#defineClass(String, byte[], int, int, ProtectionDomain) */ protected ProtectionDomainFactory optionalProtectionDomainFactory; public AbstractJavaSourceClassLoader() {} public AbstractJavaSourceClassLoader(ClassLoader parentClassLoader) { super(parentClassLoader); } /** * @param sourcePath The sequence of directories to search for Java™ source files */ public abstract void setSourcePath(File[] sourcePath); /** * @param optionalCharacterEncoding if {@code null}, use platform default encoding */ public abstract void setSourceFileCharacterEncoding(String optionalCharacterEncoding); /** * @param lines Whether line number debugging information should be generated * @param vars Whether variables debugging information should be generated * @param source Whether source file debugging information should be generated */ public abstract void setDebuggingInfo(boolean lines, boolean vars, boolean source); /** @see ClassLoader#defineClass(String, byte[], int, int, ProtectionDomain) */ public final void setProtectionDomainFactory(ProtectionDomainFactory optionalProtectionDomainFactory) { this.optionalProtectionDomainFactory = optionalProtectionDomainFactory; } /** * @see AbstractJavaSourceClassLoader#setProtectionDomainFactory */ public interface ProtectionDomainFactory { /** * @param sourceResourceName E.g. 'pkg1/pkg2/Outer.java' */ ProtectionDomain getProtectionDomain(String sourceResourceName); } /** * Read Java™ source code for a given class name, scan, parse, compile and load it into the virtual machine, * and invoke its "main()" method with the given arguments. *

* Usage is as follows: *

     *   java {@link AbstractJavaSourceClassLoader} [ option ] ... class-name [ argument ] ...
     *
     *   option:
     *     -sourcepath colon-separated-list-of-source-directories
     *     -encoding character-encoding
     *     -g                           Generate all debugging info
     *     -g:none                      Generate no debugging info
     *     -g:{source,lines,vars}       Generate only some debugging info
     * 
*/ public static void main(String[] args) throws Exception { File[] optionalSourcePath = null; String optionalCharacterEncoding = null; boolean debuggingInfoLines = false; boolean debuggingInfoVars = false; boolean debuggingInfoSource = false; boolean haveDebuggingInfo = false; // Scan command line options. int i; for (i = 0; i < args.length; ++i) { String arg = args[i]; if (!arg.startsWith("-")) break; if ("-sourcepath".equals(arg)) { optionalSourcePath = splitPath(args[++i]); } else if ("-encoding".equals(arg)) { optionalCharacterEncoding = args[++i]; } else if ("-g".equals(arg)) { debuggingInfoLines = true; debuggingInfoVars = true; debuggingInfoSource = true; haveDebuggingInfo = true; } else if ("-g:none".equals(arg)) { debuggingInfoLines = false; debuggingInfoVars = false; debuggingInfoSource = false; haveDebuggingInfo = true; } else if ("-g:".startsWith(arg)) { debuggingInfoLines = arg.indexOf("lines") != -1; debuggingInfoVars = arg.indexOf("vars") != -1; debuggingInfoSource = arg.indexOf("source") != -1; haveDebuggingInfo = true; } else if ("-help".equals(arg)) { System.out.println("Usage:"); System.out.println( " java " + AbstractJavaSourceClassLoader.class.getName() + " {