[janino] 02/05: Imported Upstream version 2.6.1
Damien Raude-Morvan
drazzib at alioth.debian.org
Sat Aug 17 13:16:12 UTC 2013
This is an automated email from the git hooks/post-receive script.
drazzib pushed a commit to annotated tag debian/2.6.1-1
in repository janino.
commit 3938a2a06b78dac2a6b55ae4406b7af51f8e97c7
Author: Damien Raude-Morvan <drazzib at drazzib.com>
Date: Fri Aug 16 10:24:13 2013 +0200
Imported Upstream version 2.6.1
---
README.txt | 19 +
build.properties | 60 -
build.xml | 99 -
commons-compiler-jdk-src.zip | Bin 0 -> 27640 bytes
commons-compiler-jdk.jar | Bin 0 -> 43330 bytes
commons-compiler-src.zip | Bin 0 -> 42676 bytes
commons-compiler.jar | Bin 0 -> 29924 bytes
janino-src.zip | Bin 0 -> 317584 bytes
janino.jar | Bin 0 -> 602320 bytes
.../new_bsd_license.txt => new_bsd_license.txt | 2 +-
src/org/codehaus/janino/Access.java | 55 -
src/org/codehaus/janino/AntCompilerAdapter.java | 186 -
.../janino/AstCompilationUnitGenerator.java | 42 -
src/org/codehaus/janino/ByteArrayClassLoader.java | 143 -
.../janino/CachingJavaSourceClassLoader.java | 225 -
src/org/codehaus/janino/ClassBodyEvaluator.java | 495 --
src/org/codehaus/janino/ClassFileIClass.java | 449 --
.../codehaus/janino/ClassLoaderIClassLoader.java | 108 -
src/org/codehaus/janino/CodeContext.java | 1103 ---
src/org/codehaus/janino/CompileException.java | 50 -
src/org/codehaus/janino/Compiler.java | 846 --
src/org/codehaus/janino/Cookable.java | 150 -
src/org/codehaus/janino/DebuggingInformation.java | 59 -
src/org/codehaus/janino/Descriptor.java | 270 -
src/org/codehaus/janino/ExpressionEvaluator.java | 525 --
src/org/codehaus/janino/FilterWarningHandler.java | 57 -
src/org/codehaus/janino/IClass.java | 819 --
src/org/codehaus/janino/IClassLoader.java | 227 -
src/org/codehaus/janino/Java.java | 2924 -------
src/org/codehaus/janino/JavaSourceClassLoader.java | 412 -
.../codehaus/janino/JavaSourceIClassLoader.java | 173 -
src/org/codehaus/janino/Location.java | 69 -
src/org/codehaus/janino/MethodDescriptor.java | 98 -
src/org/codehaus/janino/Mod.java | 104 -
src/org/codehaus/janino/Opcode.java | 612 --
src/org/codehaus/janino/Parser.java | 2540 ------
src/org/codehaus/janino/ReflectionIClass.java | 314 -
.../janino/ResourceFinderIClassLoader.java | 89 -
src/org/codehaus/janino/Scanner.java | 1276 ---
src/org/codehaus/janino/ScriptEvaluator.java | 1045 ---
src/org/codehaus/janino/SimpleCompiler.java | 462 --
.../codehaus/janino/UnicodeUnescapeException.java | 45 -
src/org/codehaus/janino/UnicodeUnescapeReader.java | 136 -
src/org/codehaus/janino/UnitCompiler.java | 8378 --------------------
src/org/codehaus/janino/UnparseVisitor.java | 775 --
src/org/codehaus/janino/Visitor.java | 138 -
src/org/codehaus/janino/WarningHandler.java | 42 -
src/org/codehaus/janino/package.html | 11 -
src/org/codehaus/janino/samples/ClassBodyDemo.java | 96 -
.../janino/samples/DeclarationCounter.java | 99 -
src/org/codehaus/janino/samples/DemoBase.java | 154 -
.../codehaus/janino/samples/ExpressionDemo.java | 129 -
src/org/codehaus/janino/samples/ScriptDemo.java | 126 -
src/org/codehaus/janino/samples/ShippingCost.java | 72 -
src/org/codehaus/janino/samples/package.html | 3 -
src/org/codehaus/janino/tools/Disassembler.java | 1425 ----
src/org/codehaus/janino/tools/HprofScrubber.java | 220 -
src/org/codehaus/janino/tools/JGrep.java | 692 --
src/org/codehaus/janino/tools/package.html | 3 -
src/org/codehaus/janino/util/AutoIndentWriter.java | 92 -
src/org/codehaus/janino/util/Benchmark.java | 220 -
src/org/codehaus/janino/util/CausedException.java | 107 -
src/org/codehaus/janino/util/ClassFile.java | 1514 ----
src/org/codehaus/janino/util/LocatedException.java | 70 -
src/org/codehaus/janino/util/MultiIterator.java | 163 -
src/org/codehaus/janino/util/PrimitiveWrapper.java | 50 -
src/org/codehaus/janino/util/Producer.java | 57 -
.../janino/util/ResourceFinderClassLoader.java | 120 -
src/org/codehaus/janino/util/StringPattern.java | 191 -
src/org/codehaus/janino/util/TeeReader.java | 82 -
src/org/codehaus/janino/util/Traverser.java | 599 --
.../janino/util/enumerator/Enumerator.java | 143 -
.../util/enumerator/EnumeratorFormatException.java | 45 -
.../janino/util/enumerator/EnumeratorSet.java | 324 -
.../enumerator/EnumeratorSetTypeException.java | 44 -
.../codehaus/janino/util/enumerator/package.html | 3 -
.../janino/util/iterator/DirectoryIterator.java | 132 -
.../janino/util/iterator/EnumerationIterator.java | 51 -
.../janino/util/iterator/FilterIterator.java | 52 -
.../janino/util/iterator/FilterListIterator.java | 71 -
.../janino/util/iterator/IteratorCollection.java | 82 -
.../util/iterator/MultiDimensionalIterator.java | 107 -
.../janino/util/iterator/ProducerIterator.java | 75 -
.../janino/util/iterator/ReverseListIterator.java | 61 -
.../janino/util/iterator/TransformingIterator.java | 56 -
.../janino/util/iterator/TraversingIterator.java | 100 -
.../util/iterator/UniterableElementException.java | 44 -
src/org/codehaus/janino/util/iterator/package.html | 3 -
src/org/codehaus/janino/util/package.html | 3 -
.../util/resource/DirectoryResourceCreator.java | 53 -
.../util/resource/DirectoryResourceFinder.java | 85 -
.../janino/util/resource/FileResource.java | 55 -
.../janino/util/resource/FileResourceCreator.java | 62 -
.../janino/util/resource/FileResourceFinder.java | 57 -
.../resource/JarDirectoriesResourceFinder.java | 80 -
.../util/resource/LazyMultiResourceFinder.java | 57 -
.../janino/util/resource/MapResourceCreator.java | 71 -
.../janino/util/resource/MapResourceFinder.java | 65 -
.../janino/util/resource/MultiResourceFinder.java | 64 -
.../janino/util/resource/PathResourceFinder.java | 145 -
.../codehaus/janino/util/resource/Resource.java | 73 -
.../janino/util/resource/ResourceCreator.java | 64 -
.../janino/util/resource/ResourceFinder.java | 79 -
.../util/resource/ZipFileResourceFinder.java | 71 -
src/org/codehaus/janino/util/resource/package.html | 6 -
src/overview.html | 9 -
106 files changed, 20 insertions(+), 34388 deletions(-)
diff --git a/README.txt b/README.txt
new file mode 100644
index 0000000..09c1939
--- /dev/null
+++ b/README.txt
@@ -0,0 +1,19 @@
+Quick start for JANINO users:
+
+(1) Put "commons-compiler.jar" and "janino.jar" on your class path.
+
+(2) If you're using an IDE like ECLIPSE, you can optionally have
+ "commons-compiler-src.zip" as the source attachment of
+ "commons-compiler.jar", and "janino-src.zip" as the source attachment of
+ "janino.jar". That'll get you tooltip JAVADOC and source level debugging
+ into the JANINO libraries.
+
+(3) Use one of the features, e.g. the "expression evaluator", in your program:
+
+ import org.codehaus.janino.*;
+
+ ExpressionEvaluator ee = new ExpressionEvaluator();
+ ee.cook("3 + 4");
+ System.out.println(ee.evaluate(null));
+
+(4) Compile, run, ... be happy!
diff --git a/build.properties b/build.properties
deleted file mode 100644
index 30aa8e5..0000000
--- a/build.properties
+++ /dev/null
@@ -1,60 +0,0 @@
-
-#
-# Janino - An embedded Java[TM] compiler
-#
-# Copyright (c) 2001-2007, 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.
-#
-
-# misc
-version = 2.5.15
-
-# directories
-src = src
-build = build
-javadoc = javadoc
-jdk_1_2_2_home = c:/jdk-1.2.2
-
-# files
-ant_jar = c:/Programme/eclipse-3.3.2/plugins/org.apache.ant_1.7.0.v200706080842/lib/ant.jar
-janino_zip = janino-${version}.zip
-
-# javadoc-related
-jdk_javadoc_local = c:/j2sdk-1.4.1-doc/docs/api
-jdk_javadoc_remote = http://java.sun.com/j2se/1.4.1/docs/api
-ant_javadoc_local = ant
-ant_javadoc_remote = http://www.cs.bris.ac.uk/Teaching/Resources/General/ant/docs/manual/api
-javadoc_packages = \
- org.codehaus.janino,\
- org.codehaus.janino.samples,\
- org.codehaus.janino.tools,\
- org.codehaus.janino.util,\
- org.codehaus.janino.util.enumerator,\
- org.codehaus.janino.util.iterator,\
- org.codehaus.janino.util.resource
diff --git a/build.xml b/build.xml
deleted file mode 100644
index 5c65f61..0000000
--- a/build.xml
+++ /dev/null
@@ -1,99 +0,0 @@
-<!--
-
- Janino - An embedded Java[TM] compiler
-
- Copyright (c) 2001-2007, 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.
-//-->
-
-<project name="Janino" default="compile" basedir=".">
- <description>
- Build file for the Janino project
- </description>
-
- <property file="build.properties"/>
-
- <target name="compile" description="Compile the source">
- <mkdir dir="build/classes"/>
-
- <javac
- fork="yes"
- executable="${jdk_1_2_2_home}/bin/javac"
- srcdir="src" excludes="org/codehaus/janino/AstGeneratorVisitor.java"
- destdir="build/classes"
- debug="true"
- debuglevel="source"
- />
- </target>
-
- <target name="javadoc" description="Build JAVADOC" depends="compile">
- <mkdir dir="build/javadoc"/>
- <javadoc
- header="<a href="http://janino.codehaus.org/">Web Site</a>"
- splitindex="true"
- doctitle="Janino ${version}"
- windowtitle="Janino ${version}"
- overview="src/overview.html"
- sourcepath="src"
- classpath="build/classes;${ant_jar}"
- destdir="build/javadoc"
- packagenames="${javadoc_packages}"
- >
- <link offline="true" href="${jdk_javadoc_remote}" packagelistloc="${jdk_javadoc_local}"/>
- <link offline="true" href="${ant_javadoc_remote}" packagelistloc="${ant_javadoc_local}"/>
- </javadoc>
- </target>
-
- <target name="jar" description="Create the janino jar." depends="compile">
- <mkdir dir="build/lib"/>
- <jar jarfile="build/lib/janino.jar" basedir="build/classes"/>
- </target>
-
- <target name="dist" description="Generate the distribution" depends="jar, javadoc">
- <echo level="info">Signing jar: build/lib/janino.jar</echo>
- <exec executable="jarsigner">
- <arg value="-keystore"/><arg value="dummy-keystore"/>
- <arg value="-storepass"/><arg value="storepass"/>
- <arg value="-keypass"/><arg value="keypass"/>
- <arg value="build/lib/janino.jar"/>
- <arg value="dummy"/>
- </exec>
-
- <zip destfile="${janino_zip}">
- <zipfileset file="build/lib/janino.jar" prefix="janino-${version}/lib"/>
- <zipfileset dir="build/javadoc" prefix="janino-${version}/javadoc"/>
- <zipfileset dir="src" prefix="janino-${version}/src"/>
- <zipfileset file="build.*" prefix="janino-${version}"/>
- </zip>
- </target>
-
- <target name="clean" description="Clean built files.">
- <delete dir="build"/>
- </target>
-</project>
diff --git a/commons-compiler-jdk-src.zip b/commons-compiler-jdk-src.zip
new file mode 100644
index 0000000..1b583f3
Binary files /dev/null and b/commons-compiler-jdk-src.zip differ
diff --git a/commons-compiler-jdk.jar b/commons-compiler-jdk.jar
new file mode 100644
index 0000000..bb8cbfc
Binary files /dev/null and b/commons-compiler-jdk.jar differ
diff --git a/commons-compiler-src.zip b/commons-compiler-src.zip
new file mode 100644
index 0000000..5f283e8
Binary files /dev/null and b/commons-compiler-src.zip differ
diff --git a/commons-compiler.jar b/commons-compiler.jar
new file mode 100644
index 0000000..39ec753
Binary files /dev/null and b/commons-compiler.jar differ
diff --git a/janino-src.zip b/janino-src.zip
new file mode 100644
index 0000000..a023f67
Binary files /dev/null and b/janino-src.zip differ
diff --git a/janino.jar b/janino.jar
new file mode 100644
index 0000000..c92f477
Binary files /dev/null and b/janino.jar differ
diff --git a/src/org/codehaus/janino/doc-files/new_bsd_license.txt b/new_bsd_license.txt
similarity index 97%
rename from src/org/codehaus/janino/doc-files/new_bsd_license.txt
rename to new_bsd_license.txt
index c39b618..f906e86 100644
--- a/src/org/codehaus/janino/doc-files/new_bsd_license.txt
+++ b/new_bsd_license.txt
@@ -1,6 +1,6 @@
Janino - An embedded Java[TM] compiler
-Copyright (c) 2001-2007, Arno Unkrig
+Copyright (c) 2001-2010, Arno Unkrig
All rights reserved.
Redistribution and use in source and binary forms, with or without
diff --git a/src/org/codehaus/janino/Access.java b/src/org/codehaus/janino/Access.java
deleted file mode 100644
index d88d9b7..0000000
--- a/src/org/codehaus/janino/Access.java
+++ /dev/null
@@ -1,55 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino;
-
-import org.codehaus.janino.util.enumerator.Enumerator;
-import org.codehaus.janino.util.enumerator.EnumeratorFormatException;
-
-/**
- * Return value for {@link IClass.IMember#getAccess}.
- * JLS2 6.6
- */
-public final class Access extends Enumerator {
- public static final Access PRIVATE = new Access("private");
- public static final Access PROTECTED = new Access("protected");
- public static final Access DEFAULT = new Access("/*default*/");
- public static final Access PUBLIC = new Access("public");
-
- // These MUST be declared exactly like this:
- private Access(String name) { super(name); }
- public static Access fromString(String name) throws EnumeratorFormatException {
- return (Access) Enumerator.fromString(name, Access.class);
- }
-}
diff --git a/src/org/codehaus/janino/AntCompilerAdapter.java b/src/org/codehaus/janino/AntCompilerAdapter.java
deleted file mode 100644
index f5a6b25..0000000
--- a/src/org/codehaus/janino/AntCompilerAdapter.java
+++ /dev/null
@@ -1,186 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino;
-
-import java.io.*;
-
-import org.apache.tools.ant.taskdefs.compilers.*;
-import org.apache.tools.ant.types.Path;
-import org.codehaus.janino.util.enumerator.*;
-
-/**
- * A simple {@link org.apache.tools.ant.taskdefs.compilers.CompilerAdapter} for the "ant" tool
- * that silently ignores most of the configuration parameters and attempts to compile all given
- * source files into class files.
- */
-public class AntCompilerAdapter extends DefaultCompilerAdapter {
-
- /**
- * Compile all source files in <code>DefaultCompilerAdapter.compileList</code> individually and
- * write class files in directory <code>DefaultCompilerAdapter.destDir</code>.
- * <p>
- * The following fields of {@link DefaultCompilerAdapter} are honored:
- * <ul>
- * <li><code>DefaultCompilerAdapter.compileList</code> - the set of Java<sup>TM</sup> source files to compile
- * <li><code>DefaultCompilerAdapter.destDir</code> - where to store the class files
- * <li><code>DefaultCompilerAdapter.compileSourcepath</code> - where to look for more Java<sup>TM</sup> source files
- * <li><code>DefaultCompilerAdapter.compileClasspath</code> - where to look for required classes
- * <li><code>DefaultCompilerAdapter.extdirs</code>
- * <li><code>DefaultCompilerAdapter.bootclasspath</code>
- * <li><code>DefaultCompilerAdapter.encoding</code> - how the Java<sup>TM</sup> source files are encoded
- * <li><code>DefaultCompilerAdapter.verbose</code>
- * <li><code>DefaultCompilerAdapter.debug</code>
- * <li><code>org.apache.tools.ant.taskdefs.Javac.getDebugLevel()</code>
- * <li><code>DefaultCompilerAdapter.src</code>
- * </ul>
- * The following fields of {@link DefaultCompilerAdapter} are not honored at this time:
- * <ul>
- * <li><code>DefaultCompilerAdapter.depend</code>
- * <li><code>DefaultCompilerAdapter.deprecation</code>
- * <li><code>DefaultCompilerAdapter.includeAntRuntime</code>
- * <li><code>DefaultCompilerAdapter.includeJavaRuntime</code>
- * <li><code>DefaultCompilerAdapter.location</code>
- * <li><code>DefaultCompilerAdapter.optimize</code>
- * <li><code>DefaultCompilerAdapter.target</code>
- * </ul>
- *
- * @return "true" on success
- */
- public boolean execute() {
-
- // Convert source files into source file names.
- File[] sourceFiles = this.compileList;
-
- // Determine output directory.
- File destinationDirectory = this.destDir == null ? Compiler.NO_DESTINATION_DIRECTORY : this.destDir;
-
- // Determine the source path.
- File[] optionalSourcePath = AntCompilerAdapter.pathToFiles(
- this.compileSourcepath != null ?
- this.compileSourcepath :
- this.src
- );
-
- // Determine the class path.
- File[] classPath = AntCompilerAdapter.pathToFiles(this.compileClasspath, new File[] { new File(".") });
-
- // Determine the ext dirs.
- File[] optionalExtDirs = AntCompilerAdapter.pathToFiles(this.extdirs);
-
- // Determine the boot class path
- File[] optionalBootClassPath = AntCompilerAdapter.pathToFiles(this.bootclasspath);
-
- // Determine the encoding.
- String optionalCharacterEncoding = this.encoding;
-
- // Determine verbosity.
- boolean verbose = this.verbose;
-
- // Determine debugging information.
- EnumeratorSet debuggingInformation;
- if (!this.debug) {
- debuggingInformation = DebuggingInformation.NONE;
- } else {
- String debugLevel = this.attributes.getDebugLevel();
- if (debugLevel == null) {
- debuggingInformation = DebuggingInformation.DEFAULT_DEBUGGING_INFORMATION;
- } else {
- try {
- debuggingInformation = new EnumeratorSet(DebuggingInformation.class, debugLevel);
- } catch (EnumeratorFormatException ex) {
- debuggingInformation = DebuggingInformation.NONE;
- }
- }
- }
-
- // Compile all source files.
- try {
- new Compiler(
- optionalSourcePath,
- classPath,
- optionalExtDirs,
- optionalBootClassPath,
- destinationDirectory,
- optionalCharacterEncoding,
- verbose,
- debuggingInformation,
- Compiler.DEFAULT_WARNING_HANDLE_PATTERNS,
- false // rebuild
- ).compile(sourceFiles);
- } catch (Scanner.ScanException e) {
- System.out.println(e.getMessage());
- return false;
- } catch (Parser.ParseException e) {
- System.out.println(e.getMessage());
- return false;
- } catch (CompileException e) {
- System.out.println(e.getMessage());
- return false;
- } catch (IOException e) {
- System.out.println(e.getMessage());
- return false;
- }
- return true;
- }
-
- /**
- * Convert a {@link org.apache.tools.ant.types.Path} into an array of
- * {@link File}.
- * @param path
- * @return The converted path, or <code>null</code> if <code>path</code> is <code>null</code>
- */
- private static File[] pathToFiles(Path path) {
- if (path == null) return null;
-
- String[] fileNames = path.list();
- File[] files = new File[fileNames.length];
- for (int i = 0; i < fileNames.length; ++i) files[i] = new File(fileNames[i]);
- return files;
- }
-
- /**
- * Convert a {@link org.apache.tools.ant.types.Path} into an array of
- * {@link File}.
- * @param path
- * @param defaultValue
- * @return The converted path, or, if <code>path</code> is <code>null</code>, the <code>defaultValue</code>
- */
- private static File[] pathToFiles(Path path, File[] defaultValue) {
- if (path == null) return defaultValue;
- return AntCompilerAdapter.pathToFiles(path);
- }
-}
-
-
diff --git a/src/org/codehaus/janino/AstCompilationUnitGenerator.java b/src/org/codehaus/janino/AstCompilationUnitGenerator.java
deleted file mode 100644
index 457e9eb..0000000
--- a/src/org/codehaus/janino/AstCompilationUnitGenerator.java
+++ /dev/null
@@ -1,42 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino;
-
-/**
- * @author Eugene Kuleshov
- */
-public interface AstCompilationUnitGenerator {
- Java.CompilationUnit generate() throws Exception;
-}
diff --git a/src/org/codehaus/janino/ByteArrayClassLoader.java b/src/org/codehaus/janino/ByteArrayClassLoader.java
deleted file mode 100644
index 227fcb9..0000000
--- a/src/org/codehaus/janino/ByteArrayClassLoader.java
+++ /dev/null
@@ -1,143 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino;
-
-import java.io.*;
-import java.util.*;
-
-import org.codehaus.janino.tools.Disassembler;
-
-/**
- * This {@link ClassLoader} allows for the loading of a set of Java<sup>TM</sup> classes
- * provided in class file format.
- */
-public class ByteArrayClassLoader extends ClassLoader {
- private static final boolean DEBUG = false;
-
- /**
- * The given {@link Map} of classes must not be modified afterwards.
- *
- * @param classes String className => byte[] data
- */
- public ByteArrayClassLoader(Map classes) {
- this.classes = classes;
- }
-
- /**
- * @see #ByteArrayClassLoader(Map)
- */
- public ByteArrayClassLoader(Map classes, ClassLoader parent) {
- super(parent);
- this.classes = classes;
- }
-
- /**
- * Implements {@link ClassLoader#findClass(String)}.
- * <p>
- * Notice that, although nowhere documented, no more than one thread at a time calls this
- * method, because {@link ClassLoader#loadClass(java.lang.String)} is
- * <code>synchronized</code>.
- */
- protected Class findClass(String name) throws ClassNotFoundException {
- byte[] data = (byte[]) this.classes.get(name);
- if (data == null) throw new ClassNotFoundException(name);
-
- if (DEBUG) {
- System.out.println("*** Disassembly of class \"" + name + "\":");
- try {
- new Disassembler().disasm(new ByteArrayInputStream(data));
- System.out.flush();
- } catch (IOException ex) {
- throw new RuntimeException("SNO: IOException despite ByteArrayInputStream");
- }
- }
-
- // Notice: Not inheriting the protection domain will cause problems with Java Web Start /
- // JNLP. See
- // http://jira.codehaus.org/browse/JANINO-104
- // http://www.nabble.com/-Help-jel--java.security.AccessControlException-to13073723.html
- return super.defineClass(
- name, // name
- data, 0, data.length, // b, off, len
- this.getClass().getProtectionDomain() // protectionDomain
- );
- }
-
- /**
- * An object is regarded equal to <code>this</code> iff
- * <ul>
- * <li>It is also an instance of {@link ByteArrayClassLoader}
- * <li>Both have the same parent {@link ClassLoader}
- * <li>Exactly the same classes (name, bytecode) were added to both
- * </ul>
- * Roughly speaking, equal {@link ByteArrayClassLoader}s will return functionally identical
- * {@link Class}es on {@link ClassLoader#loadClass(java.lang.String)}.
- */
- public boolean equals(Object o) {
- if (!(o instanceof ByteArrayClassLoader)) return false;
- if (this == o) return true;
- ByteArrayClassLoader that = (ByteArrayClassLoader) o;
-
- {
- final ClassLoader parentOfThis = this.getParent();
- final ClassLoader parentOfThat = that.getParent();
- if (parentOfThis == null ? parentOfThat != null : !parentOfThis.equals(parentOfThat)) return false;
- }
-
- if (this.classes.size() != that.classes.size()) return false;
- for (Iterator it = this.classes.entrySet().iterator(); it.hasNext();) {
- Map.Entry me = (Map.Entry) it.next();
- byte[] ba = (byte[]) that.classes.get(me.getKey());
- if (ba == null) return false; // Key missing in "that".
- if (!Arrays.equals((byte[]) me.getValue(), ba)) return false; // Byte arrays differ.
- }
- return true;
- }
- public int hashCode() {
- int hc = this.getParent().hashCode();
-
- for (Iterator it = this.classes.entrySet().iterator(); it.hasNext();) {
- Map.Entry me = (Map.Entry) it.next();
- hc ^= me.getKey().hashCode();
- byte[] ba = (byte[]) me.getValue();
- for (int i = 0; i < ba.length; ++i) {
- hc = (31 * hc) ^ ba[i];
- }
- }
- return hc;
- }
-
- private final Map classes; // String className => byte[] data
-}
diff --git a/src/org/codehaus/janino/CachingJavaSourceClassLoader.java b/src/org/codehaus/janino/CachingJavaSourceClassLoader.java
deleted file mode 100644
index 48a850c..0000000
--- a/src/org/codehaus/janino/CachingJavaSourceClassLoader.java
+++ /dev/null
@@ -1,225 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino;
-
-import java.io.*;
-import java.util.*;
-
-import org.codehaus.janino.util.*;
-import org.codehaus.janino.util.enumerator.*;
-import org.codehaus.janino.util.resource.*;
-
-/**
- * A {@link org.codehaus.janino.JavaSourceClassLoader} that uses a
- * resource storage provided by the application to cache compiled
- * classes and thus saving unnecessary recompilations.
- * <p>
- * The application provides access to the resource storeage through a pair of
- * a {@link org.codehaus.janino.util.resource.ResourceFinder} and a
- * {@link org.codehaus.janino.util.resource.ResourceCreator} (see
- * {@link #CachingJavaSourceClassLoader(ClassLoader, ResourceFinder, String, ResourceFinder, ResourceCreator, EnumeratorSet)}.
- * <p>
- * See {@link org.codehaus.janino.JavaSourceClassLoader#main(String[])} for
- * an example how to use this class.
- * <p>
- * <b>Notice:</b> You must NOT rely on that this class stores some particular data in some
- * particular resources through the given <code>classFileCacheResourceFinder/Creator</code>!
- * These serve only as a means for the {@link CachingJavaSourceClassLoader} to persistently
- * cache some data between invocations. In other words: If you want to compile <code>.java</code>
- * files into <code>.class</code> files, then don't use <i>this</i> class but {@link Compiler}
- * instead!
- */
-public class CachingJavaSourceClassLoader extends JavaSourceClassLoader {
- private final ResourceFinder classFileCacheResourceFinder;
- private final ResourceCreator classFileCacheResourceCreator;
- private final ResourceFinder sourceFinder;
-
- /**
- * See {@link #CachingJavaSourceClassLoader(ClassLoader, ResourceFinder, String, ResourceFinder, ResourceCreator, EnumeratorSet)}.
- *
- * @param optionalSourcePath Directories to scan for source files
- * @param cacheDirectory Directory to use for caching generated class files (see class description)
- */
- public CachingJavaSourceClassLoader(
- ClassLoader parentClassLoader,
- File[] optionalSourcePath,
- String optionalCharacterEncoding,
- File cacheDirectory,
- EnumeratorSet debuggingInformation
- ) {
- this(
- parentClassLoader, // parentClassLoader
- ( // sourceFinder
- optionalSourcePath == null ?
- (ResourceFinder) new DirectoryResourceFinder(new File(".")) :
- (ResourceFinder) new PathResourceFinder(optionalSourcePath)
- ),
- optionalCharacterEncoding, // optionalCharacterEncoding
- new DirectoryResourceFinder(cacheDirectory), // classFileCacheResourceFinder
- new DirectoryResourceCreator(cacheDirectory), // classFileCacheResourceCreator
- debuggingInformation // debuggingInformation
- );
- }
-
- /**
- * Notice that this class is thread-safe if and only if the
- * <code>classFileCacheResourceCreator</code> stores its data atomically,
- * i.e. the <code>classFileCacheResourceFinder</code> sees the resource
- * written by the <code>classFileCacheResourceCreator</code> only after
- * the {@link OutputStream} is closed.
- * <p>
- * In order to make the caching scheme work, both the
- * <code>classFileCacheResourceFinder</code> and the
- * <code>sourceFinder</code> must support the {@link org.codehaus.janino.util.resource.Resource#lastModified()}
- * method, so that the modification time of the source and the class files
- * can be compared.
- *
- * @param parentClassLoader Attempt to load classes through this one before looking for source files
- * @param sourceFinder Finds Java<sup>TM</sup> source for class <code>pkg.Cls</code> in resource <code>pkg/Cls.java</code>
- * @param optionalCharacterEncoding Encoding of Java<sup>TM</sup> source or <code>null</code> for platform default encoding
- * @param classFileCacheResourceFinder Finds precompiled class <code>pkg.Cls</code> in resource <code>pkg/Cls.class</code> (see class description)
- * @param classFileCacheResourceCreator Stores compiled class <code>pkg.Cls</code> in resource <code>pkg/Cls.class</code> (see class description)
- * @param debuggingInformation What debugging information to include into the generated class files
- */
- public CachingJavaSourceClassLoader(
- ClassLoader parentClassLoader,
- ResourceFinder sourceFinder,
- String optionalCharacterEncoding,
- ResourceFinder classFileCacheResourceFinder,
- ResourceCreator classFileCacheResourceCreator,
- EnumeratorSet debuggingInformation
- ) {
- super(parentClassLoader, sourceFinder, optionalCharacterEncoding, debuggingInformation);
- this.classFileCacheResourceFinder = classFileCacheResourceFinder;
- this.classFileCacheResourceCreator = classFileCacheResourceCreator;
- this.sourceFinder = sourceFinder;
- }
-
- /**
- * Override {@link JavaSourceClassLoader#generateBytecodes(String)} to implement
- * class file caching.
- *
- * @return String name => byte[] bytecode, or <code>null</code> if no source code could be found
- * @throws ClassNotFoundException on compilation problems or class file cache I/O problems
- */
- protected Map generateBytecodes(String className) throws ClassNotFoundException {
-
- // Check whether a class file resource exists in the cache.
- {
- Resource classFileResource = this.classFileCacheResourceFinder.findResource(ClassFile.getClassFileResourceName(className));
- if (classFileResource != null) {
-
- // Check whether a source file resource exists.
- Resource sourceResource = this.sourceFinder.findResource(ClassFile.getSourceResourceName(className));
- if (sourceResource == null) return null;
-
- // Check whether the class file is up-to-date.
- if (sourceResource.lastModified() < classFileResource.lastModified()) {
-
- // Yes, it is... read the bytecode from the file and define the class.
- byte[] bytecode;
- try {
- bytecode = CachingJavaSourceClassLoader.readResource(classFileResource);
- } catch (IOException ex) {
- throw new ClassNotFoundException("Reading class file from \"" + classFileResource + "\"", ex);
- }
- Map m = new HashMap();
- m.put(className, bytecode);
- return m;
- }
- }
- }
-
- // Cache miss... generate the bytecode from source.
- Map bytecodes = super.generateBytecodes(className);
- if (bytecodes == null) return null;
-
- // Write the generated bytecodes to the class file cache.
- for (Iterator it = bytecodes.entrySet().iterator(); it.hasNext();) {
- Map.Entry me = (Map.Entry) it.next();
- String className2 = (String) me.getKey();
- byte[] bytecode = (byte[]) me.getValue();
-
- try {
- CachingJavaSourceClassLoader.writeResource(
- this.classFileCacheResourceCreator,
- ClassFile.getClassFileResourceName(className2),
- bytecode
- );
- } catch (IOException ex) {
- throw new ClassNotFoundException("Writing class file to \"" + ClassFile.getClassFileResourceName(className2) + "\"", ex);
- }
- }
-
- return bytecodes;
- }
-
- /**
- * Read all bytes from the given resource.
- */
- private static byte[] readResource(Resource r) throws IOException {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- byte[] buffer = new byte[4096];
-
- InputStream is = r.open();
- try {
- for (;;) {
- int cnt = is.read(buffer);
- if (cnt == -1) break;
- baos.write(buffer, 0, cnt);
- }
- } finally {
- try { is.close(); } catch (IOException ex) {}
- }
-
- return baos.toByteArray();
- }
-
- /**
- * Create a resource with the given name and store the data in it.
- */
- private static void writeResource(
- ResourceCreator resourceCreator,
- String resourceName,
- byte[] data
- ) throws IOException {
- OutputStream os = resourceCreator.createResource(resourceName);
- try {
- os.write(data);
- } finally {
- try { os.close(); } catch (IOException ex) {}
- }
- }
-}
diff --git a/src/org/codehaus/janino/ClassBodyEvaluator.java b/src/org/codehaus/janino/ClassBodyEvaluator.java
deleted file mode 100644
index 9ca1cea..0000000
--- a/src/org/codehaus/janino/ClassBodyEvaluator.java
+++ /dev/null
@@ -1,495 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino;
-
-import java.io.*;
-
-import org.codehaus.janino.Parser.ParseException;
-import org.codehaus.janino.Scanner.ScanException;
-import org.codehaus.janino.util.enumerator.EnumeratorSet;
-
-/**
- * Parses a class body and returns it as a <tt>java.lang.Class</tt> object
- * ready for use with <tt>java.lang.reflect</tt>.
- * <p>
- * Example:
- * <pre>
- * import java.util.*;
- *
- * static private int a = 1;
- * private int b = 2;
- *
- * public void func(int c, int d) {
- * return func2(c, d);
- * }
- *
- * private static void func2(int e, int f) {
- * return e * f;
- * }
- * </pre>
- * <p>
- * The <code>optionalClassLoader</code> serves two purposes:
- * <ul>
- * <li>It is used to look for classes referenced by the class body.
- * <li>It is used to load the generated Java<sup>TM</sup> class
- * into the JVM; directly if it is a subclass of {@link
- * ByteArrayClassLoader}, or by creation of a temporary
- * {@link ByteArrayClassLoader} if not.
- * </ul>
- * To set up a {@link ClassBodyEvaluator} object, proceed as follows:
- * <ol>
- * <li>
- * Create the {@link ClassBodyEvaluator} using {@link #ClassBodyEvaluator()}
- * <li>
- * Configure the {@link ClassBodyEvaluator} by calling any of the following methods:
- * <ul>
- * <li>{@link org.codehaus.janino.SimpleCompiler#setParentClassLoader(ClassLoader)}
- * <li>{@link #setDefaultImports(String[])}
- * </ul>
- * <li>
- * Call any of the {@link org.codehaus.janino.Cookable#cook(Scanner)} methods to scan,
- * parse, compile and load the class body into the JVM.
- * </ol>
- * Alternatively, a number of "convenience constructors" exist that execute the steps described
- * above instantly.
- * <p>
- * To compile a class body and immediately instantiate an object, one of the
- * {@link #createFastClassBodyEvaluator(Scanner, Class, ClassLoader)} methods can be used.
- * <p>
- * The generated class may optionally extend/implement a given type; the returned instance can
- * safely be type-casted to that <code>optionalBaseType</code>.
- * <p>
- * Example:
- * <pre>
- * public interface Foo {
- * int bar(int a, int b);
- * }
- * ...
- * Foo f = (Foo) ClassBodyEvaluator.createFastClassBodyEvaluator(
- * new Scanner(null, new StringReader("public int bar(int a, int b) { return a + b; }")),
- * Foo.class, // Base type to extend/implement
- * (ClassLoader) null // Use current thread's context class loader
- * );
- * System.out.println("1 + 2 = " + f.bar(1, 2));
- * </pre>
- * Notice: The <code>optionalBaseType</code> must be accessible from the generated class,
- * i.e. it must either be declared <code>public</code>, or with default accessibility in the
- * same package as the generated class.
- */
-public class ClassBodyEvaluator extends SimpleCompiler {
- public static final String DEFAULT_CLASS_NAME = "SC";
- protected static final Class[] ZERO_CLASSES = new Class[0];
-
- private String[] optionalDefaultImports = null;
- protected String className = ClassBodyEvaluator.DEFAULT_CLASS_NAME;
- private Class optionalExtendedType = null;
- private Class[] implementedTypes = ClassBodyEvaluator.ZERO_CLASSES;
- private Class result = null; // null=uncooked
-
- /**
- * Equivalent to<pre>
- * ClassBodyEvaluator cbe = new ClassBodyEvaluator();
- * cbe.cook(classBody);</pre>
- *
- * @see #ClassBodyEvaluator()
- * @see Cookable#cook(String)
- */
- public ClassBodyEvaluator(
- String classBody
- ) throws CompileException, ParseException, ScanException {
- this.cook(classBody);
- }
-
- /**
- * Equivalent to<pre>
- * ClassBodyEvaluator cbe = new ClassBodyEvaluator();
- * cbe.cook(optionalFileName, is);</pre>
- *
- * @see #ClassBodyEvaluator()
- * @see Cookable#cook(String, InputStream)
- */
- public ClassBodyEvaluator(
- String optionalFileName,
- InputStream is
- ) throws CompileException, ParseException, ScanException, IOException {
- this.cook(optionalFileName, is);
- }
-
- /**
- * Equivalent to<pre>
- * ClassBodyEvaluator cbe = new ClassBodyEvaluator();
- * cbe.cook(optionalFileName, reader);</pre>
- *
- * @see #ClassBodyEvaluator()
- * @see Cookable#cook(String, Reader)
- */
- public ClassBodyEvaluator(
- String optionalFileName,
- Reader reader
- ) throws CompileException, ParseException, ScanException, IOException {
- this.cook(optionalFileName, reader);
- }
-
- /**
- * Equivalent to<pre>
- * ClassBodyEvaluator cbe = new ClassBodyEvaluator();
- * cbe.setParentClassLoader(optionalParentClassLoader);
- * cbe.cook(scanner);</pre>
- *
- * @see #ClassBodyEvaluator()
- * @see SimpleCompiler#setParentClassLoader(ClassLoader)
- * @see Cookable#cook(Scanner)
- */
- public ClassBodyEvaluator(
- Scanner scanner,
- ClassLoader optionalParentClassLoader
- ) throws CompileException, ParseException, ScanException, IOException {
- this.setParentClassLoader(optionalParentClassLoader);
- this.cook(scanner);
- }
-
- /**
- * Equivalent to<pre>
- * ClassBodyEvaluator cbe = new ClassBodyEvaluator();
- * cbe.setExtendedType(optionalExtendedType);
- * cbe.setImplementedTypes(implementedTypes);
- * cbe.setParentClassLoader(optionalParentClassLoader);
- * cbe.cook(scanner);</pre>
- *
- * @see #ClassBodyEvaluator()
- * @see #setExtendedType(Class)
- * @see #setImplementedTypes(Class[])
- * @see SimpleCompiler#setParentClassLoader(ClassLoader)
- * @see Cookable#cook(Scanner)
- */
- public ClassBodyEvaluator(
- Scanner scanner,
- Class optionalExtendedType,
- Class[] implementedTypes,
- ClassLoader optionalParentClassLoader
- ) throws CompileException, ParseException, ScanException, IOException {
- this.setExtendedType(optionalExtendedType);
- this.setImplementedTypes(implementedTypes);
- this.setParentClassLoader(optionalParentClassLoader);
- this.cook(scanner);
- }
-
- /**
- * Equivalent to<pre>
- * ClassBodyEvaluator cbe = new ClassBodyEvaluator();
- * cbe.setClassName(className);
- * cbe.setExtendedType(optionalExtendedType);
- * cbe.setImplementedTypes(implementedTypes);
- * cbe.setParentClassLoader(optionalParentClassLoader);
- * cbe.cook(scanner);</pre>
- *
- * @see #ClassBodyEvaluator()
- * @see #setClassName(String)
- * @see #setExtendedType(Class)
- * @see #setImplementedTypes(Class[])
- * @see SimpleCompiler#setParentClassLoader(ClassLoader)
- * @see Cookable#cook(Scanner)
- */
- public ClassBodyEvaluator(
- Scanner scanner,
- String className,
- Class optionalExtendedType,
- Class[] implementedTypes,
- ClassLoader optionalParentClassLoader
- ) throws CompileException, ParseException, ScanException, IOException {
- this.setClassName(className);
- this.setExtendedType(optionalExtendedType);
- this.setImplementedTypes(implementedTypes);
- this.setParentClassLoader(optionalParentClassLoader);
- this.cook(scanner);
- }
-
- public ClassBodyEvaluator() {}
-
- /**
- * "Default imports" add to the system import "java.lang", i.e. the evaluator may refer to
- * classes imported by default imports without having to explicitly declare IMPORT statements.
- * <p>
- * Notice that JDK 5 "static imports" are also supported, as shown in the following example.
- * <p>
- * Example: <pre>
- * sc.setDefaultImports(new String[] {
- * "java.util.Map", // Single type import
- * "java.io.*", // Type-import-on-demand
- * "static java.util.Collections.EMPTY_MAP", // Single static import
- * "static java.util.Collections.*", // Static-import-on-demand
- * });</pre>
- */
- public void setDefaultImports(String[] optionalDefaultImports) {
- assertNotCooked();
- this.optionalDefaultImports = optionalDefaultImports;
- }
-
- /**
- * Set the name of the generated class. Defaults to {@link #DEFAULT_CLASS_NAME}. In most cases,
- * there is no need to set this name, because the generated class is loaded into its own
- * {@link java.lang.ClassLoader} where its name cannot collide with classes generated by
- * other evaluators.
- * <p>
- * One reason to use this function is to have a class name in a non-default package, which
- * can be relevant when types and members with DEFAULT accessibility are accessed.
- */
- public void setClassName(String className) {
- if (className == null) throw new NullPointerException();
- assertNotCooked();
- this.className = className;
- }
-
- /**
- * Set a particular superclass that the generated class will extend. If <code>null</code> is
- * passed, the generated class will extend {@link Object}.
- * <p>
- * The common reason to set a base class for an evaluator is that the generated class can
- * directly access the base superclass's (non-private) members.
- */
- public void setExtendedType(Class optionalExtendedType) {
- assertNotCooked();
- this.optionalExtendedType = optionalExtendedType;
- }
-
- /**
- * Set a particular set of interfaces that the generated class will implement.
- */
- public void setImplementedTypes(Class[] implementedTypes) {
- if (implementedTypes == null) throw new NullPointerException("Zero implemented types must be specified as \"new Class[0]\", not \"null\"");
- assertNotCooked();
- this.implementedTypes = implementedTypes;
- }
-
- public void cook(Scanner scanner)
- throws CompileException, ParseException, ScanException, IOException {
- this.setUpClassLoaders();
-
- Java.CompilationUnit compilationUnit = this.makeCompilationUnit(scanner);
-
- // Add class declaration.
- Java.ClassDeclaration cd = this.addPackageMemberClassDeclaration(
- scanner.location(),
- compilationUnit
- );
-
- // Parse class body declarations (member declarations) until EOF.
- Parser parser = new Parser(scanner);
- while (!scanner.peek().isEOF()) {
- parser.parseClassBodyDeclaration(cd);
- }
-
- // Compile and load it.
- this.result = this.compileToClass(
- compilationUnit, // compilationUnit
- DebuggingInformation.ALL, // debuggingInformation
- this.className
- );
- }
-
- /**
- * Create a {@link Java.CompilationUnit}, set the default imports, and parse the import
- * declarations.
- * <p>
- * If the <code>optionalScanner</code> is given, a sequence of IMPORT directives is parsed
- * from it and added to the compilation unit.
- */
- protected final Java.CompilationUnit makeCompilationUnit(Scanner optionalScanner)
- throws ParseException, ScanException, IOException {
- Java.CompilationUnit cu = new Java.CompilationUnit(optionalScanner == null ? null : optionalScanner.getFileName());
-
- // Set default imports.
- if (this.optionalDefaultImports != null) {
- for (int i = 0; i < this.optionalDefaultImports.length; ++i) {
- Scanner s = new Scanner(null, new StringReader(this.optionalDefaultImports[i]));
- cu.addImportDeclaration(new Parser(s).parseImportDeclarationBody());
- if (!s.peek().isEOF()) throw new ParseException("Unexpected token \"" + s.peek() + "\" in default import", s.location());
- }
- }
-
- // Parse all available IMPORT declarations.
- if (optionalScanner != null) {
- Parser parser = new Parser(optionalScanner);
- while (optionalScanner.peek().isKeyword("import")) {
- cu.addImportDeclaration(parser.parseImportDeclaration());
- }
- }
-
- return cu;
- }
-
- /**
- * To the given {@link Java.CompilationUnit}, add
- * <ul>
- * <li>A class declaration with the configured name, superclass and interfaces
- * <li>A method declaration with the given return type, name, parameter
- * names and values and thrown exceptions
- * </ul>
- *
- * @return The created {@link Java.ClassDeclaration} object
- */
- protected Java.PackageMemberClassDeclaration addPackageMemberClassDeclaration(
- Location location,
- Java.CompilationUnit compilationUnit
- ) throws ParseException {
- String cn = this.className;
- int idx = cn.lastIndexOf('.');
- if (idx != -1) {
- compilationUnit.setPackageDeclaration(new Java.PackageDeclaration(location, cn.substring(0, idx)));
- cn = cn.substring(idx + 1);
- }
- Java.PackageMemberClassDeclaration tlcd = new Java.PackageMemberClassDeclaration(
- location, // location
- null, // optionalDocComment
- Mod.PUBLIC, // modifiers
- cn, // name
- this.classToType(location, this.optionalExtendedType), // optionalExtendedType
- this.classesToTypes(location, this.implementedTypes) // implementedTypes
- );
- compilationUnit.addPackageMemberTypeDeclaration(tlcd);
- return tlcd;
- }
-
- /**
- * Compile the given compilation unit, load all generated classes, and
- * return the class with the given name.
- * @param compilationUnit
- * @param debuggingInformation TODO
- * @param newClassName The fully qualified class name
- * @return The loaded class
- */
- protected final Class compileToClass(
- Java.CompilationUnit compilationUnit,
- EnumeratorSet debuggingInformation,
- String newClassName
- ) throws CompileException {
-
- // Compile and load the compilation unit.
- ClassLoader cl = this.compileToClassLoader(compilationUnit, debuggingInformation);
-
- // Find the generated class by name.
- try {
- return cl.loadClass(newClassName);
- } catch (ClassNotFoundException ex) {
- throw new RuntimeException("SNO: Generated compilation unit does not declare class \"" + newClassName + "\"");
- }
- }
-
- /**
- * Returns the loaded {@link Class}.
- * <p>
- * This method must only be called after {@link #cook(Scanner)}.
- * <p>
- * This method must not be called for instances of derived classes.
- */
- public Class getClazz() {
- if (this.getClass() != ClassBodyEvaluator.class) throw new IllegalStateException("Must not be called on derived instances");
- if (this.result == null) throw new IllegalStateException("Must only be called after \"cook()\"");
- return this.result;
- }
-
- /**
- * Scans, parses and compiles a class body from the tokens delivered by the the given
- * {@link Scanner}.
- * The generated class has the {@link #DEFAULT_CLASS_NAME} and extends the given
- * <code>optionalBaseType</code> (if that is a class), and implements the given
- * <code>optionalBaseType</code> (if that is an interface).
- * <p>
- * For an explanation of the "fast class body evaluator" concept, see the class description.
- *
- * @param scanner Source of class body tokens
- * @param optionalBaseType Base type to extend/implement
- * @param optionalParentClassLoader Used to load referenced classes, defaults to the current thread's "context class loader"
- * @return an object that extends/implements the given <code>optionalBaseType</code>
- * @see ClassBodyEvaluator
- */
- public static Object createFastClassBodyEvaluator(
- Scanner scanner,
- Class optionalBaseType,
- ClassLoader optionalParentClassLoader
- ) throws CompileException, ParseException, ScanException, IOException {
- return ClassBodyEvaluator.createFastClassBodyEvaluator(
- scanner, // scanner
- ClassBodyEvaluator.DEFAULT_CLASS_NAME, // className
- ( // optionalExtendedType
- optionalBaseType != null && !optionalBaseType.isInterface() ?
- optionalBaseType : null
- ),
- ( // implementedTypes
- optionalBaseType != null && optionalBaseType.isInterface() ?
- new Class[] { optionalBaseType } : new Class[0]
- ),
- optionalParentClassLoader // optionalParentClassLoader
- );
- }
-
- /**
- * Scans, parses and compiles a class body from the tokens delivered by the the given
- * {@link Scanner} with no default imports.
- * <p>
- * For an explanation of the "fast class body evaluator" concept, see the class description.
- *
- * @param scanner Source of class body tokens
- * @param className Name of generated class
- * @param optionalExtendedType Class to extend
- * @param implementedTypes Interfaces to implement
- * @param optionalParentClassLoader Used to load referenced classes, defaults to the current thread's "context class loader"
- * @return an object that extends the <code>optionalExtendedType</code> and implements the given <code>implementedTypes</code>
- * @see ClassBodyEvaluator
- */
- public static Object createFastClassBodyEvaluator(
- Scanner scanner,
- String className,
- Class optionalExtendedType,
- Class[] implementedTypes,
- ClassLoader optionalParentClassLoader
- ) throws CompileException, ParseException, ScanException, IOException {
- Class c = new ClassBodyEvaluator(
- scanner,
- className,
- optionalExtendedType,
- implementedTypes,
- optionalParentClassLoader
- ).getClazz();
- try {
- return c.newInstance();
- } catch (InstantiationException e) {
- throw new CompileException("Cannot instantiate abstract class -- one or more method implementations are missing", null);
- } catch (IllegalAccessException e) {
- // SNO - type and default constructor of generated class are PUBLIC.
- throw new RuntimeException(e.toString());
- }
- }
-}
diff --git a/src/org/codehaus/janino/ClassFileIClass.java b/src/org/codehaus/janino/ClassFileIClass.java
deleted file mode 100644
index 0365abf..0000000
--- a/src/org/codehaus/janino/ClassFileIClass.java
+++ /dev/null
@@ -1,449 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino;
-
-import java.util.*;
-
-import org.codehaus.janino.util.ClassFile;
-
-
-/**
- * A wrapper object that turns a {@link ClassFile} object into a
- * {@link IClass}.
- */
-public class ClassFileIClass extends IClass {
- private static final boolean DEBUG = false;
-
- private final ClassFile classFile;
- private final IClassLoader iClassLoader;
- private final short accessFlags;
-
- private final Map resolvedFields = new HashMap(); // FieldInfo => IField
-
- /**
- * @param classFile Source of data
- * @param iClassLoader {@link IClassLoader} through which to load other classes
- */
- public ClassFileIClass(
- ClassFile classFile,
- IClassLoader iClassLoader
- ) {
- this.classFile = classFile;
- this.iClassLoader = iClassLoader;
-
- // Determine class access flags.
- this.accessFlags = classFile.accessFlags;
- }
-
- // Implement IClass.
-
- protected IConstructor[] getDeclaredIConstructors2() {
- List iConstructors = new ArrayList();
-
- for (Iterator it = this.classFile.methodInfos.iterator(); it.hasNext();) {
- ClassFile.MethodInfo mi = (ClassFile.MethodInfo) it.next();
- IInvocable ii;
- try {
- ii = this.resolveMethod(mi);
- } catch (ClassNotFoundException ex) {
- throw new RuntimeException(ex.getMessage());
- }
- if (ii instanceof IConstructor) iConstructors.add(ii);
- }
-
- return (IConstructor[]) iConstructors.toArray(new IConstructor[iConstructors.size()]);
- }
-
- protected IMethod[] getDeclaredIMethods2() {
- List iMethods = new ArrayList();
-
- for (Iterator it = this.classFile.methodInfos.iterator(); it.hasNext();) {
- ClassFile.MethodInfo mi = (ClassFile.MethodInfo) it.next();
-
- // Skip JDK 1.5 synthetic methods (e.g. those generated for
- // covariant return values).
- if ((mi.getAccessFlags() & Mod.SYNTHETIC) != 0) continue;
-
- IInvocable ii;
- try {
- ii = this.resolveMethod(mi);
- } catch (ClassNotFoundException ex) {
- throw new RuntimeException(ex.getMessage());
- }
- if (ii instanceof IMethod) iMethods.add(ii);
- }
-
- return (IMethod[]) iMethods.toArray(new IMethod[iMethods.size()]);
- }
-
- protected IField[] getDeclaredIFields2() {
- IField[] ifs = new IClass.IField[this.classFile.fieldInfos.size()];
- for (int i = 0; i < this.classFile.fieldInfos.size(); ++i) {
- try {
- ifs[i] = this.resolveField((ClassFile.FieldInfo) this.classFile.fieldInfos.get(i));
- } catch (ClassNotFoundException ex) {
- throw new RuntimeException(ex.getMessage());
- }
- }
- return ifs;
- }
-
- protected IClass[] getDeclaredIClasses2() throws CompileException {
- ClassFile.InnerClassesAttribute ica = this.classFile.getInnerClassesAttribute();
- if (ica == null) return new IClass[0];
-
- List ices = ica.getEntries(); // ClassFile.InnerClassAttribute.Entry
- List res = new ArrayList(); // IClass
- for (Iterator it = ices.iterator(); it.hasNext();) {
- ClassFile.InnerClassesAttribute.Entry e = (ClassFile.InnerClassesAttribute.Entry) it.next();
- if (e.outerClassInfoIndex == this.classFile.thisClass) {
- try {
- res.add(this.resolveClass(e.innerClassInfoIndex));
- } catch (ClassNotFoundException ex) {
- throw new CompileException(ex.getMessage(), null);
- }
- }
- }
- return (IClass[]) res.toArray(new IClass[res.size()]);
- }
-
- protected IClass getDeclaringIClass2() throws CompileException {
- ClassFile.InnerClassesAttribute ica = this.classFile.getInnerClassesAttribute();
- if (ica == null) return null;
-
- List ices = ica.getEntries(); // ClassFile.InnerClassAttribute.Entry
- for (Iterator it = ices.iterator(); it.hasNext();) {
- ClassFile.InnerClassesAttribute.Entry e = (ClassFile.InnerClassesAttribute.Entry) it.next();
- if (e.innerClassInfoIndex == this.classFile.thisClass) {
- // Is this an anonymous class?
- if (e.outerClassInfoIndex == 0) return null;
- try {
- return this.resolveClass(e.outerClassInfoIndex);
- } catch (ClassNotFoundException ex) {
- throw new CompileException(ex.getMessage(), null);
- }
- }
- }
- return null;
- }
-
- protected IClass getOuterIClass2() throws CompileException {
- ClassFile.InnerClassesAttribute ica = this.classFile.getInnerClassesAttribute();
- if (ica == null) return null;
-
- List ices = ica.getEntries(); // ClassFile.InnerClassAttribute.Entry
- for (Iterator it = ices.iterator(); it.hasNext();) {
- ClassFile.InnerClassesAttribute.Entry e = (ClassFile.InnerClassesAttribute.Entry) it.next();
- if (e.innerClassInfoIndex == this.classFile.thisClass) {
- if (e.outerClassInfoIndex == 0) {
-
- // Anonymous class or local class.
- // TODO: Determine enclosing instance of anonymous class or local class
- return null;
- } else {
-
- // Member type.
- if ((e.innerClassAccessFlags & Mod.STATIC) != 0) return null;
- try {
- return this.resolveClass(e.outerClassInfoIndex);
- } catch (ClassNotFoundException ex) {
- throw new CompileException(ex.getMessage(), null);
- }
- }
- }
- }
- return null;
- }
-
- protected IClass getSuperclass2() throws CompileException {
- if (this.classFile.superclass == 0) return null;
- try {
- return this.resolveClass(this.classFile.superclass);
- } catch (ClassNotFoundException e) {
- throw new CompileException(e.getMessage(), null);
- }
- }
-
- public Access getAccess() {
- return ClassFileIClass.accessFlags2Access(this.accessFlags);
- }
-
- public boolean isFinal() {
- return (this.accessFlags & Mod.FINAL) != 0;
- }
-
- protected IClass[] getInterfaces2() throws CompileException {
- return this.resolveClasses(this.classFile.interfaces);
- }
-
- public boolean isAbstract() {
- return (this.accessFlags & Mod.ABSTRACT) != 0;
- }
-
- protected String getDescriptor2() {
- return Descriptor.fromClassName(this.classFile.getThisClassName());
- }
-
- public boolean isInterface() {
- return (this.accessFlags & Mod.INTERFACE) != 0;
- }
-
- public boolean isArray() {
- return false;
- }
-
- public boolean isPrimitive() {
- return false;
- }
-
- public boolean isPrimitiveNumeric() {
- return false;
- }
-
- protected IClass getComponentType2() {
- return null;
- }
-
- public void resolveHalf() throws ClassNotFoundException {
-
- // Resolve superclass.
- this.resolveClass(this.classFile.superclass);
-
- // Resolve interfaces.
- for (int i = 0; i < this.classFile.interfaces.length; ++i) {
- this.resolveClass(this.classFile.interfaces[i]);
- }
-
- // Resolve constructors and methods.
- for (int i = 0; i < this.classFile.methodInfos.size(); ++i) {
- this.resolveMethod((ClassFile.MethodInfo) this.classFile.methodInfos.get(i));
- }
-
- // Process fields.
- for (int i = 0; i < this.classFile.fieldInfos.size(); ++i) {
- this.resolveField((ClassFile.FieldInfo) this.classFile.fieldInfos.get(i));
- }
- }
-
- public void resolveAllClasses() throws ClassNotFoundException {
- for (short i = 0; i < this.classFile.constantPool.size(); ++i) {
- ClassFile.ConstantPoolInfo cpi = this.classFile.getConstantPoolInfo(i);
- if (cpi instanceof ClassFile.ConstantClassInfo) {
- this.resolveClass(i);
- } else
- if (cpi instanceof ClassFile.ConstantNameAndTypeInfo) {
- short descriptorIndex = ((ClassFile.ConstantNameAndTypeInfo) cpi).getDescriptorIndex();
- String descriptor = this.classFile.getConstantUtf8(descriptorIndex);
- if (descriptor.charAt(0) == '(') {
- MethodDescriptor md = new MethodDescriptor(descriptor);
- this.resolveClass(md.returnFD);
- for (int j = 0; j < md.parameterFDs.length; ++j) this.resolveClass(md.parameterFDs[j]);
- } else {
- this.resolveClass(descriptor);
- }
- }
- }
- }
-
- /**
- * @param index Index of the CONSTANT_Class_info to resolve (JVMS 4.4.1)
- */
- private IClass resolveClass(short index) throws ClassNotFoundException {
- if (ClassFileIClass.DEBUG) System.out.println("index=" + index);
- return this.resolveClass(Descriptor.fromInternalForm(this.classFile.getConstantClassName(index)));
- }
-
- private IClass resolveClass(String descriptor) throws ClassNotFoundException {
- if (ClassFileIClass.DEBUG) System.out.println("descriptor=" + descriptor);
-
- IClass result = (IClass) this.resolvedClasses.get(descriptor);
- if (result != null) return result;
-
- result = this.iClassLoader.loadIClass(descriptor);
- if (result == null) throw new ClassNotFoundException(descriptor);
-
- this.resolvedClasses.put(descriptor, result);
- return result;
- }
- private final Map resolvedClasses = new HashMap(); // String descriptor => IClass
-
- private IClass[] resolveClasses(short[] ifs) throws CompileException {
- IClass[] result = new IClass[ifs.length];
- for (int i = 0; i < result.length; ++i) {
- try {
- result[i] = this.resolveClass(ifs[i]);
- } catch (ClassNotFoundException e) {
- throw new CompileException(e.getMessage(), null);
- }
- }
- return result;
- }
-
- /**
- * Turn a {@link ClassFile.MethodInfo} into an {@link IInvocable}. This includes the checking and the
- * removal of the magic first parameter of an inner class constructor.
- *
- * @param methodInfo
- * @throws ClassNotFoundException
- */
- private IInvocable resolveMethod(final ClassFile.MethodInfo methodInfo) throws ClassNotFoundException {
- IInvocable result = (IInvocable) this.resolvedMethods.get(methodInfo);
- if (result != null) return result;
-
- // Determine method name.
- final String name = this.classFile.getConstantUtf8(methodInfo.getNameIndex());
-
- // Determine return type.
- MethodDescriptor md = new MethodDescriptor(this.classFile.getConstantUtf8(methodInfo.getDescriptorIndex()));
- final IClass returnType = this.resolveClass(md.returnFD);
-
- // Determine parameter types.
- final IClass[] parameterTypes = new IClass[md.parameterFDs.length];
- for (int i = 0; i < parameterTypes.length; ++i) parameterTypes[i] = this.resolveClass(md.parameterFDs[i]);
-
- // Determine thrown exceptions.
- IClass tes[] = null;
- ClassFile.AttributeInfo[] ais = methodInfo.getAttributes();
- for (int i = 0; i < ais.length; ++i) {
- ClassFile.AttributeInfo ai = ais[i];
- if (ai instanceof ClassFile.ExceptionsAttribute) {
- short[] teis = ((ClassFile.ExceptionsAttribute) ai).getExceptionIndexes();
- tes = new IClass[teis.length];
- for (int j = 0; j < teis.length; ++j) tes[j] = this.resolveClass(teis[j]);
- }
- }
- final IClass thrownExceptions[] = tes == null ? new IClass[0] : tes;
-
- // Determine access.
- final Access access = ClassFileIClass.accessFlags2Access(methodInfo.getAccessFlags());
-
- if (name.equals("<init>")) {
- result = new IClass.IConstructor() {
- public IClass[] getParameterTypes() throws CompileException {
-
- // Process magic first parameter of inner class constructor.
- IClass outerIClass = ClassFileIClass.this.getOuterIClass();
- if (outerIClass != null) {
- if (parameterTypes.length < 1) throw new RuntimeException("Inner class constructor lacks magic first parameter");
- if (parameterTypes[0] != outerIClass) throw new RuntimeException("Magic first parameter of inner class constructor has type \"" + parameterTypes[0].toString() + "\" instead of that of its enclosing instance (\"" + outerIClass.toString() + "\")");
- IClass[] tmp = new IClass[parameterTypes.length - 1];
- System.arraycopy(parameterTypes, 1, tmp, 0, tmp.length);
- return tmp;
- }
-
- return parameterTypes;
- }
- public IClass[] getThrownExceptions() throws CompileException { return thrownExceptions; }
- public Access getAccess() { return access; }
- };
- } else {
- result = new IClass.IMethod() {
- public String getName() { return name; }
- public IClass getReturnType() throws CompileException { return returnType; }
- public boolean isStatic() { return (methodInfo.getAccessFlags() & Mod.STATIC) != 0; }
- public boolean isAbstract() { return (methodInfo.getAccessFlags() & Mod.ABSTRACT) != 0; }
- public IClass[] getParameterTypes() throws CompileException { return parameterTypes; }
- public IClass[] getThrownExceptions() throws CompileException { return thrownExceptions; }
- public Access getAccess() { return access; }
- };
- }
- this.resolvedMethods.put(methodInfo, result);
- return result;
- }
- private final Map resolvedMethods = new HashMap(); // MethodInfo => IInvocable
-
- private IField resolveField(final ClassFile.FieldInfo fieldInfo) throws ClassNotFoundException {
- IField result = (IField) this.resolvedFields.get(fieldInfo);
- if (result != null) return result;
-
- // Determine field name.
- final String name = this.classFile.getConstantUtf8(fieldInfo.getNameIndex());
-
- // Determine field type.
- final String descriptor = this.classFile.getConstantUtf8(fieldInfo.getDescriptorIndex());
- final IClass type = this.resolveClass(descriptor);
-
- // Determine optional "constant value" of the field (JLS2 15.28, bullet
- // 12). If a field has a "ConstantValue" attribute, we assume that it
- // has a constant value. Notice that this assumption is not always
- // correct, because typical Java<sup>TM</sup> compilers do not
- // generate a "ConstantValue" attribute for fields like
- // "int RED = 0", because "0" is the default value for an integer
- // field.
- ClassFile.ConstantValueAttribute cva = null;
- ClassFile.AttributeInfo[] ais = fieldInfo.getAttributes();
- for (int i = 0; i < ais.length; ++i) {
- ClassFile.AttributeInfo ai = ais[i];
- if (ai instanceof ClassFile.ConstantValueAttribute) {
- cva = (ClassFile.ConstantValueAttribute) ai;
- break;
- }
- }
-
- Object ocv = null;
- if (cva != null) {
- ClassFile.ConstantPoolInfo cpi = this.classFile.getConstantPoolInfo(cva.getConstantValueIndex());
- if (cpi instanceof ClassFile.ConstantValuePoolInfo) {
- ocv = ((ClassFile.ConstantValuePoolInfo) cpi).getValue(this.classFile);
- } else
- {
- throw new RuntimeException("Unexpected constant pool info type \"" + cpi.getClass().getName() + "\"");
- }
- }
- final Object optionalConstantValue = ocv;
-
- // Determine access.
- final Access access = ClassFileIClass.accessFlags2Access(fieldInfo.getAccessFlags());
-
- result = new IField() {
- public Object getConstantValue() throws CompileException { return optionalConstantValue; }
- public String getName() { return name; }
- public IClass getType() throws CompileException { return type; }
- public boolean isStatic() { return (fieldInfo.getAccessFlags() & Mod.STATIC) != 0; }
- public Access getAccess() { return access; }
- };
- this.resolvedFields.put(fieldInfo, result);
- return result;
- }
-
- private static Access accessFlags2Access(short accessFlags) {
- return (
- (accessFlags & Mod.PUBLIC ) != 0 ? Access.PUBLIC :
- (accessFlags & Mod.PROTECTED) != 0 ? Access.PROTECTED :
- (accessFlags & Mod.PRIVATE ) != 0 ? Access.PRIVATE :
- Access.DEFAULT
- );
- }
-}
diff --git a/src/org/codehaus/janino/ClassLoaderIClassLoader.java b/src/org/codehaus/janino/ClassLoaderIClassLoader.java
deleted file mode 100644
index a02bb07..0000000
--- a/src/org/codehaus/janino/ClassLoaderIClassLoader.java
+++ /dev/null
@@ -1,108 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino;
-
-/**
- * An {@link IClassLoader} that loads {@link IClass}es through a reflection
- * {@link ClassLoader}.
- */
-public class ClassLoaderIClassLoader extends IClassLoader {
- private static final boolean DEBUG = false;
-
- /**
- * @param classLoader The delegate that loads the classes.
- */
- public ClassLoaderIClassLoader(ClassLoader classLoader) {
- super(
- null // optionalParentIClassLoader
- );
-
- if (classLoader == null) throw new NullPointerException();
-
- this.classLoader = classLoader;
- super.postConstruct();
- }
-
- /**
- * Equivalent to
- * <pre>
- * ClassLoaderIClassLoader(Thread.currentThread().getContextClassLoader())
- * </pre>
- */
- public ClassLoaderIClassLoader() {
- this(Thread.currentThread().getContextClassLoader());
- }
-
- public ClassLoader getClassLoader() {
- return this.classLoader;
- }
-
- /**
- * Find a new {@link IClass} by descriptor.
- */
- protected IClass findIClass(String descriptor) throws ClassNotFoundException {
-
- //
- // See also [ 931385 ] Janino 2.0 throwing exception on arrays of java.io.File:
- //
- // "ClassLoader.loadClass()" and "Class.forName()" should be identical,
- // but "ClassLoader.loadClass("[Ljava.lang.Object;")" throws a
- // ClassNotFoundException under JDK 1.5.0 beta.
- // Unclear whether this a beta version bug and SUN will fix this in the final
- // release, but "Class.forName()" seems to work fine in all cases, so we
- // use that.
- //
-
- Class clazz;
- try {
-// clazz = this.classLoader.loadClass(className);
- clazz = Class.forName(Descriptor.toClassName(descriptor), false, this.classLoader);
- } catch (ClassNotFoundException e) {
- if (e.getException() == null) {
- return null;
- } else
- {
- throw e;
- }
- }
- if (ClassLoaderIClassLoader.DEBUG) System.out.println("clazz = " + clazz);
-
- IClass result = new ReflectionIClass(clazz, this);
- this.defineIClass(result);
- return result;
- }
-
- private /*final*/ ClassLoader classLoader;
-}
diff --git a/src/org/codehaus/janino/CodeContext.java b/src/org/codehaus/janino/CodeContext.java
deleted file mode 100644
index aab646a..0000000
--- a/src/org/codehaus/janino/CodeContext.java
+++ /dev/null
@@ -1,1103 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino;
-
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Stack;
-
-import org.codehaus.janino.util.ClassFile;
-
-
-/**
- * The context of the compilation of a function (constructor or method). Manages generation of
- * byte code, the exception table, generation of line number tables, allocation of local variables,
- * determining of stack size and local variable table size and flow analysis.
- */
-public class CodeContext {
- private static final boolean DEBUG = false;
-
- private static final int INITIAL_SIZE = 128;
-
- private /*final*/ ClassFile classFile;
-
- private short maxStack;
- private short maxLocals;
- private byte[] code;
- private /*final*/ Offset beginning;
- private /*final*/ Inserter end;
- private Inserter currentInserter;
- private /*final*/ List exceptionTableEntries; // ExceptionTableEntry
-
- /**
- * Create an empty "Code" attribute.
- */
- public CodeContext(ClassFile classFile) {
- this.classFile = classFile;
-
- this.maxStack = 0;
- this.maxLocals = 0;
- this.code = new byte[CodeContext.INITIAL_SIZE];
- this.beginning = new Offset();
- this.end = new Inserter();
- this.currentInserter = this.end;
- this.exceptionTableEntries = new ArrayList();
-
- this.beginning.offset = 0;
- this.end.offset = 0;
- this.beginning.next = this.end;
- this.end.prev = this.beginning;
- }
-
- public ClassFile getClassFile() {
- return this.classFile;
- }
-
- /**
- * Allocate space for a local variable of the given size (1 or 2)
- * on the local variable array.
- *
- * As a side effect, the "max_locals" field of the "Code" attribute
- * is updated.
- *
- * The only way to deallocate local variables is to
- * {@link #saveLocalVariables()} and later {@link
- * #restoreLocalVariables()}.
- */
- public short allocateLocalVariable(
- short size // 1 or 2
- ) {
- short res = this.localVariableArrayLength;
- this.localVariableArrayLength += size;
- if (this.localVariableArrayLength > this.maxLocals) {
- this.maxLocals = this.localVariableArrayLength;
- }
-
- return res;
- }
-
- /**
- * Remember the current size of the local variables array.
- */
- public void saveLocalVariables() {
- this.savedLocalVariableArrayLengths.push(new Short(this.localVariableArrayLength));
- }
-
- /**
- * Restore the previous size of the local variables array.
- */
- public void restoreLocalVariables() {
- this.localVariableArrayLength = ((Short) this.savedLocalVariableArrayLengths.pop()).shortValue();
- }
-
- private static final byte UNEXAMINED = -1;
- private static final byte INVALID_OFFSET = -2;
-
- /**
- *
- * @param dos
- * @param lineNumberTableAttributeNameIndex 0 == don't generate a "LineNumberTable" attribute
- * @throws IOException
- */
- protected void storeCodeAttributeBody(
- DataOutputStream dos,
- short lineNumberTableAttributeNameIndex
- ) throws IOException {
- dos.writeShort(this.maxStack); // max_stack
- dos.writeShort(this.maxLocals); // max_locals
- dos.writeInt(this.end.offset); // code_length
- dos.write(this.code, 0, this.end.offset); // code
- dos.writeShort(this.exceptionTableEntries.size()); // exception_table_length
- for (int i = 0; i < this.exceptionTableEntries.size(); ++i) { // exception_table
- ExceptionTableEntry exceptionTableEntry = (ExceptionTableEntry) this.exceptionTableEntries.get(i);
- dos.writeShort(exceptionTableEntry.startPC.offset);
- dos.writeShort(exceptionTableEntry.endPC.offset);
- dos.writeShort(exceptionTableEntry.handlerPC.offset);
- dos.writeShort(exceptionTableEntry.catchType);
- }
-
- List attributes = new ArrayList(); // ClassFile.AttributeInfo
-
- // Add "LineNumberTable" attribute.
- if (lineNumberTableAttributeNameIndex != 0) {
- List lnt = new ArrayList();
- for (Offset o = this.beginning; o != null; o = o.next) {
- if (o instanceof LineNumberOffset) {
- lnt.add(new ClassFile.LineNumberTableAttribute.Entry(o.offset, ((LineNumberOffset) o).lineNumber));
- }
- }
- ClassFile.LineNumberTableAttribute.Entry[] lnte = (ClassFile.LineNumberTableAttribute.Entry[]) lnt.toArray(new ClassFile.LineNumberTableAttribute.Entry[lnt.size()]);
- attributes.add(new ClassFile.LineNumberTableAttribute(
- lineNumberTableAttributeNameIndex, // attributeNameIndex
- lnte // lineNumberTableEntries
- ));
- }
-
- dos.writeShort(attributes.size()); // attributes_count
- for (Iterator it = attributes.iterator(); it.hasNext();) { // attributes;
- ClassFile.AttributeInfo attribute = (ClassFile.AttributeInfo) it.next();
- attribute.store(dos);
- }
- }
-
- /**
- * Checks the code for consistency; updates the "maxStack" member.
- *
- * Notice: On inconsistencies, a "RuntimeException" is thrown (KLUDGE).
- */
- public void flowAnalysis(String functionName) {
- if (CodeContext.DEBUG) {
- System.err.println("flowAnalysis(" + functionName + ")");
- }
-
- byte[] stackSizes = new byte[this.end.offset];
- Arrays.fill(stackSizes, CodeContext.UNEXAMINED);
-
- // Analyze flow from offset zero.
- this.flowAnalysis(
- functionName,
- this.code, // code
- this.end.offset, // codeSize
- 0, // offset
- 0, // stackSize
- stackSizes // stackSizes
- );
-
- // Analyze flow from exception handler entry points.
- int analyzedExceptionHandlers = 0;
- while (analyzedExceptionHandlers != this.exceptionTableEntries.size()) {
- for (int i = 0; i < this.exceptionTableEntries.size(); ++i) {
- ExceptionTableEntry exceptionTableEntry = (ExceptionTableEntry) this.exceptionTableEntries.get(i);
- if (stackSizes[exceptionTableEntry.startPC.offset] != CodeContext.UNEXAMINED) {
- this.flowAnalysis(
- functionName,
- this.code, // code
- this.end.offset, // codeSize
- exceptionTableEntry.handlerPC.offset, // offset
- stackSizes[exceptionTableEntry.startPC.offset] + 1, // stackSize
- stackSizes // stackSizes
- );
- ++analyzedExceptionHandlers;
- }
- }
- }
-
- // Check results and determine maximum stack size.
- this.maxStack = 0;
- for (int i = 0; i < stackSizes.length; ++i) {
- byte ss = stackSizes[i];
- if (ss == CodeContext.UNEXAMINED) {
- if (CodeContext.DEBUG) {
- System.out.println(functionName + ": Unexamined code at offset " + i);
- return;
- } else {
- throw new RuntimeException(functionName + ": Unexamined code at offset " + i);
- }
- }
- if (ss > this.maxStack) this.maxStack = ss;
- }
- }
-
- private void flowAnalysis(
- String functionName,
- byte[] code, // Bytecode
- int codeSize, // Size
- int offset, // Current PC
- int stackSize, // Stack size on entry
- byte[] stackSizes // Stack sizes in code
- ) {
- for (;;) {
- if (CodeContext.DEBUG) System.out.println("Offset = " + offset + ", stack size = " + stackSize);
-
- // Check current bytecode offset.
- if (offset < 0 || offset >= codeSize) throw new RuntimeException(functionName + ": Offset out of range");
-
- // Have we hit an area that has already been analyzed?
- byte css = stackSizes[offset];
- if (css == stackSize) return; // OK.
- if (css == CodeContext.INVALID_OFFSET) throw new RuntimeException(functionName + ": Invalid offset");
- if (css != CodeContext.UNEXAMINED) {
- if (CodeContext.DEBUG) {
- System.err.println(functionName + ": Operand stack inconsistent at offset " + offset + ": Previous size " + css + ", now " + stackSize);
- return;
- } else {
- throw new RuntimeException(functionName + ": Operand stack inconsistent at offset " + offset + ": Previous size " + css + ", now " + stackSize);
- }
- }
- stackSizes[offset] = (byte) stackSize;
-
- // Analyze current opcode.
- byte opcode = code[offset];
- int operandOffset = offset + 1;
- short props;
- if (opcode == Opcode.WIDE) {
- opcode = code[operandOffset++];
- props = Opcode.WIDE_OPCODE_PROPERTIES[0xff & opcode];
- } else {
- props = Opcode.OPCODE_PROPERTIES[0xff & opcode];
- }
- if (props == Opcode.INVALID_OPCODE) throw new RuntimeException(functionName + ": Invalid opcode " + (0xff & opcode) + " at offset " + offset);
-
- switch (props & Opcode.SD_MASK) {
-
- case Opcode.SD_M4:
- case Opcode.SD_M3:
- case Opcode.SD_M2:
- case Opcode.SD_M1:
- case Opcode.SD_P0:
- case Opcode.SD_P1:
- case Opcode.SD_P2:
- stackSize += (props & Opcode.SD_MASK) - Opcode.SD_P0;
- break;
-
- case Opcode.SD_0:
- stackSize = 0;
- break;
-
- case Opcode.SD_GETFIELD:
- --stackSize;
- /* FALL THROUGH */
- case Opcode.SD_GETSTATIC:
- stackSize += this.determineFieldSize((short) (
- extract16BitValue(0, operandOffset, code)
- ));
- break;
-
- case Opcode.SD_PUTFIELD:
- --stackSize;
- /* FALL THROUGH */
- case Opcode.SD_PUTSTATIC:
- stackSize -= this.determineFieldSize((short) (
- extract16BitValue(0, operandOffset, code)
- ));
- break;
-
- case Opcode.SD_INVOKEVIRTUAL:
- case Opcode.SD_INVOKESPECIAL:
- case Opcode.SD_INVOKEINTERFACE:
- --stackSize;
- /* FALL THROUGH */
- case Opcode.SD_INVOKESTATIC:
- stackSize -= this.determineArgumentsSize((short) (
- extract16BitValue(0, operandOffset, code)
- ));
- break;
-
- case Opcode.SD_MULTIANEWARRAY:
- stackSize -= code[operandOffset + 2] - 1;
- break;
-
- default:
- throw new RuntimeException(functionName + ": Invalid stack delta");
- }
-
- if (stackSize < 0) {
- String msg = this.classFile.getThisClassName() + '.' + functionName + ": Operand stack underrun at offset " + offset;
- if (CodeContext.DEBUG) {
- System.err.println(msg);
- return;
- } else {
- throw new RuntimeException(msg);
- }
- }
-
- if (stackSize > Byte.MAX_VALUE) {
- String msg = this.classFile.getThisClassName() + '.' + functionName + ": Operand stack overflow at offset " + offset;
- if (CodeContext.DEBUG) {
- System.err.println(msg);
- return;
- } else {
- throw new RuntimeException(msg);
- }
- }
-
- switch (props & Opcode.OP1_MASK) {
-
- case 0:
- ;
- break;
-
- case Opcode.OP1_SB:
- case Opcode.OP1_UB:
- case Opcode.OP1_CP1:
- case Opcode.OP1_LV1:
- ++operandOffset;
- break;
-
- case Opcode.OP1_SS:
- case Opcode.OP1_CP2:
- case Opcode.OP1_LV2:
- operandOffset += 2;
- break;
-
- case Opcode.OP1_BO2:
- if (CodeContext.DEBUG) {
- System.out.println("Offset = " + offset);
- System.out.println("Operand offset = " + operandOffset);
- System.out.println(code[operandOffset]);
- System.out.println(code[operandOffset + 1]);
- }
- this.flowAnalysis(
- functionName,
- code, codeSize,
- extract16BitValue(offset, operandOffset, code),
- stackSize,
- stackSizes
- );
- operandOffset += 2;
- break;
-
- case Opcode.OP1_JSR:
- if (CodeContext.DEBUG) {
- System.out.println("Offset = " + offset);
- System.out.println("Operand offset = " + operandOffset);
- System.out.println(code[operandOffset]);
- System.out.println(code[operandOffset + 1]);
- }
- int targetOffset = extract16BitValue(offset, operandOffset, code);
- operandOffset += 2;
- if (stackSizes[targetOffset] == CodeContext.UNEXAMINED) {
- this.flowAnalysis(
- functionName,
- code, codeSize,
- targetOffset,
- stackSize + 1,
- stackSizes
- );
- }
- break;
-
- case Opcode.OP1_BO4:
- this.flowAnalysis(
- functionName,
- code, codeSize,
- extract32BitValue(offset, operandOffset, code),
- stackSize, stackSizes
- );
- operandOffset += 4;
- break;
-
- case Opcode.OP1_LOOKUPSWITCH:
- while ((operandOffset & 3) != 0) ++operandOffset;
- this.flowAnalysis(
- functionName,
- code, codeSize,
- extract32BitValue(offset, operandOffset, code),
- stackSize, stackSizes
- );
- operandOffset += 4;
-
- int npairs = extract32BitValue(0, operandOffset, code);
- operandOffset += 4;
-
- for (int i = 0; i < npairs; ++i) {
- operandOffset += 4; //skip match value
- this.flowAnalysis(
- functionName,
- code, codeSize,
- extract32BitValue(offset, operandOffset, code),
- stackSize, stackSizes
- );
- operandOffset += 4; //advance over offset
- }
- break;
-
- case Opcode.OP1_TABLESWITCH:
- while ((operandOffset & 3) != 0) ++operandOffset;
- this.flowAnalysis(
- functionName,
- code, codeSize,
- extract32BitValue(offset, operandOffset, code),
- stackSize, stackSizes
- );
- operandOffset += 4;
- int low = extract32BitValue(offset, operandOffset, code);
- operandOffset += 4;
- int hi = extract32BitValue(offset, operandOffset, code);
- operandOffset += 4;
- for (int i = low; i <= hi; ++i) {
- this.flowAnalysis(
- functionName,
- code, codeSize,
- extract32BitValue(offset, operandOffset, code),
- stackSize, stackSizes
- );
- operandOffset += 4;
- }
- break;
-
- default:
- throw new RuntimeException(functionName + ": Invalid OP1");
- }
-
- switch (props & Opcode.OP2_MASK) {
-
- case 0:
- ;
- break;
-
- case Opcode.OP2_SB:
- ++operandOffset;
- break;
-
- case Opcode.OP2_SS:
- operandOffset += 2;
- break;
-
- default:
- throw new RuntimeException(functionName + ": Invalid OP2");
- }
-
- switch (props & Opcode.OP3_MASK) {
-
- case 0:
- ;
- break;
-
- case Opcode.OP3_SB:
- ++operandOffset;
- break;
-
- default:
- throw new RuntimeException(functionName + ": Invalid OP3");
- }
-
- Arrays.fill(stackSizes, offset + 1, operandOffset, CodeContext.INVALID_OFFSET);
-
- if ((props & Opcode.NO_FALLTHROUGH) != 0) return;
- offset = operandOffset;
- }
- }
-
- /**
- * Extract a 16 bit value at offset in code and add bias to it
- * @param bias an int to skew the final result by (useful for calculating relative offsets)
- * @param offset the position in the code array to extract the bytes from
- * @param code the array of bytes
- * @return an integer that treats the two bytes at position offset as an UNSIGNED SHORT
- */
- private int extract16BitValue(int bias, int offset, byte[] code) {
- int res = bias + (
- (( code[offset ]) << 8) +
- ((0xff & code[offset+1]) )
- );
- if (CodeContext.DEBUG) {
- System.out.println("extract16BitValue(bias, offset) = (" + bias +", " + offset + ")");
- System.out.println("bytes = {" + code[offset] + ", " + code[offset+1] + "}");
- System.out.println("result = " + res);
- }
- return res;
- }
-
- /**
- * Extract a 32 bit value at offset in code and add bias to it
- * @param bias an int to skew the final result by (useful for calculating relative offsets)
- * @param offset the position in the code array to extract the bytes from
- * @param code the array of bytes
- * @return the 4 bytes at position offset + bias
- */
- private int extract32BitValue(int bias, int offset, byte[] code) {
- int res = bias + (
- (( code[offset ]) << 24) +
- ((0xff & code[offset+1]) << 16) +
- ((0xff & code[offset+2]) << 8) +
- ((0xff & code[offset+3]) )
- );
- if (CodeContext.DEBUG) {
- System.out.println("extract32BitValue(bias, offset) = (" + bias +", " + offset + ")");
- System.out.println(
- "bytes = {" +
- code[offset ] + ", " +
- code[offset+1] + ", " +
- code[offset+2] + ", " +
- code[offset+3] + "}"
- );
- System.out.println("result = " + res);
- }
- return res;
- }
-
- /**
- * fixUp() all of the offsets and relocate() all relocatables
- */
- public void fixUpAndRelocate() {
-
- // We do this in a loop to allow relocatables to adjust the size
- // of things in the byte stream. It is extremely unlikely, but possible
- // that a late relocatable will grow the size of the bytecode, and require
- // an earlier relocatable to switch from 32K mode to 64K mode branching
- do {
- fixUp();
- } while (!relocate());
- }
-
- /**
- * Fix up all offsets.
- */
- private void fixUp() {
- for (Offset o = this.beginning; o != this.end; o = o.next) {
- if (o instanceof FixUp) ((FixUp) o).fixUp();
- }
- }
-
- /**
- * Relocate all relocatables and aggregate their response into a single one
- * @return true if all of them relocated successfully
- * false if any of them needed to change size
- */
- private boolean relocate() {
- boolean finished = true;
- for (int i = 0; i < this.relocatables.size(); ++i) {
- //do not terminate earlier so that everything gets a chance to grow in the first pass
- //changes the common case for this to be O(n) instead of O(n**2)
- boolean part = ((Relocatable) this.relocatables.get(i)).relocate();
- finished = finished && part;
- }
- return finished;
- }
-
- /**
- * Analyse the descriptor of the Fieldref and return its size.
- */
- private int determineFieldSize(short idx) {
- ClassFile.ConstantFieldrefInfo cfi = (ClassFile.ConstantFieldrefInfo) this.classFile.getConstantPoolInfo(idx);
- ClassFile.ConstantNameAndTypeInfo cnati = (ClassFile.ConstantNameAndTypeInfo) this.classFile.getConstantPoolInfo(cfi.getNameAndTypeIndex());
- ClassFile.ConstantUtf8Info cui = (ClassFile.ConstantUtf8Info) this.classFile.getConstantPoolInfo(cnati.getDescriptorIndex());
- return Descriptor.size(cui.getString());
- }
-
- /**
- * Analyse the descriptor of the Methodref and return the sum of the
- * arguments' sizes minus the return value's size.
- */
- private int determineArgumentsSize(short idx) {
- ClassFile.ConstantPoolInfo cpi = this.classFile.getConstantPoolInfo(idx);
- ClassFile.ConstantNameAndTypeInfo nat = (ClassFile.ConstantNameAndTypeInfo) this.classFile.getConstantPoolInfo(
- cpi instanceof ClassFile.ConstantInterfaceMethodrefInfo ?
- ((ClassFile.ConstantInterfaceMethodrefInfo) cpi).getNameAndTypeIndex() :
- ((ClassFile.ConstantMethodrefInfo) cpi).getNameAndTypeIndex()
- );
- ClassFile.ConstantUtf8Info cui = (ClassFile.ConstantUtf8Info) this.classFile.getConstantPoolInfo(nat.getDescriptorIndex());
- String desc = cui.getString();
-
- if (desc.charAt(0) != '(') throw new RuntimeException("Method descriptor does not start with \"(\"");
- int i = 1;
- int res = 0;
- for (;;) {
- switch (desc.charAt(i++)) {
- case ')':
- return res - Descriptor.size(desc.substring(i));
- case 'B': case 'C': case 'F': case 'I': case 'S': case 'Z':
- res += 1;
- break;
- case 'D': case 'J':
- res += 2;
- break;
- case '[':
- res += 1;
- while (desc.charAt(i) == '[') ++i;
- if ("BCFISZDJ".indexOf(desc.charAt(i)) != -1) { ++i; break; }
- if (desc.charAt(i) != 'L') throw new RuntimeException("Invalid char after \"[\"");
- ++i;
- while (desc.charAt(i++) != ';');
- break;
- case 'L':
- res += 1;
- while (desc.charAt(i++) != ';');
- break;
- default:
- throw new RuntimeException("Invalid method descriptor");
- }
- }
- }
-
- /**
- * Inserts a sequence of bytes at the current insertion position. Creates
- * {@link LineNumberOffset}s as necessary.
- *
- * @param lineNumber The line number that corresponds to the byte code, or -1
- * @param b
- */
- public void write(short lineNumber, byte[] b) {
- if (b.length == 0) return;
-
- int ico = this.currentInserter.offset;
- this.makeSpace(lineNumber, b.length);
- System.arraycopy(b, 0, this.code, ico, b.length);
- }
-
- /**
- * Inserts a byte at the current insertion position. Creates
- * {@link LineNumberOffset}s as necessary.
- * <p>
- * This method is an optimization to avoid allocating small byte[] and ease
- * GC load.
- *
- * @param lineNumber The line number that corresponds to the byte code, or -1
- * @param b1
- */
- public void write(short lineNumber, byte b1) {
- int ico = this.currentInserter.offset;
- this.makeSpace(lineNumber, 1);
- this.code[ico] = b1;
- }
-
- /**
- * Inserts bytes at the current insertion position. Creates
- * {@link LineNumberOffset}s as necessary.
- * <p>
- * This method is an optimization to avoid allocating small byte[] and ease
- * GC load.
- *
- * @param lineNumber The line number that corresponds to the byte code, or -1
- * @param b1
- * @param b2
- */
- public void write(short lineNumber, byte b1, byte b2) {
- int ico = this.currentInserter.offset;
- this.makeSpace(lineNumber, 2);
- this.code[ico++] = b1;
- this.code[ico ] = b2;
- }
-
- /**
- * Inserts bytes at the current insertion position. Creates
- * {@link LineNumberOffset}s as necessary.
- * <p>
- * This method is an optimization to avoid allocating small byte[] and ease
- * GC load.
- *
- * @param lineNumber The line number that corresponds to the byte code, or -1
- * @param b1
- * @param b2
- * @param b3
- */
- public void write(short lineNumber, byte b1, byte b2, byte b3) {
- int ico = this.currentInserter.offset;
- this.makeSpace(lineNumber, 3);
- this.code[ico++] = b1;
- this.code[ico++] = b2;
- this.code[ico ] = b3;
- }
-
- /**
- * Inserts bytes at the current insertion position. Creates
- * {@link LineNumberOffset}s as necessary.
- * <p>
- * This method is an optimization to avoid allocating small byte[] and ease
- * GC load.
- *
- * @param lineNumber The line number that corresponds to the byte code, or -1
- * @param b1
- * @param b2
- * @param b3
- * @param b4
- */
- public void write(short lineNumber, byte b1, byte b2, byte b3, byte b4) {
- int ico = this.currentInserter.offset;
- this.makeSpace(lineNumber, 4);
- this.code[ico++] = b1;
- this.code[ico++] = b2;
- this.code[ico++] = b3;
- this.code[ico ] = b4;
- }
-
- /**
- * Add space for size bytes at current offset. Creates
- * {@link LineNumberOffset}s as necessary.
- *
- * @param lineNumber The line number that corresponds to the byte code, or -1
- * @param size The size in bytes to inject
- */
- public void makeSpace(short lineNumber, int size) {
- if (size == 0) return;
-
- INSERT_LINE_NUMBER_OFFSET:
- if (lineNumber != -1) {
- Offset o;
- for (o = this.currentInserter.prev; o != this.beginning; o = o.prev) {
- if (o instanceof LineNumberOffset) {
- if (((LineNumberOffset) o).lineNumber == lineNumber) break INSERT_LINE_NUMBER_OFFSET;
- break;
- }
- }
- LineNumberOffset lno = new LineNumberOffset(this.currentInserter.offset, lineNumber);
- lno.prev = this.currentInserter.prev;
- lno.next = this.currentInserter;
- this.currentInserter.prev.next = lno;
- this.currentInserter.prev = lno;
- }
-
- int ico = this.currentInserter.offset;
- if (this.end.offset + size <= this.code.length) {
- // Optimization to avoid a trivial method call in the common case
- if(ico != this.end.offset) {
- System.arraycopy(this.code, ico, this.code, ico + size, this.end.offset - ico);
- }
- } else {
- byte[] oldCode = this.code;
- //double size to avoid horrible performance, but don't grow over our limit
- int newSize = Math.max(Math.min(oldCode.length * 2, 0xffff), oldCode.length + size);
- if (newSize > 0xffff) throw new RuntimeException("Code attribute in class \"" + this.classFile.getThisClassName() + "\" grows beyond 64 KB");
- this.code = new byte[newSize];
- System.arraycopy(oldCode, 0, this.code, 0, ico);
- System.arraycopy(oldCode, ico, this.code, ico + size, this.end.offset - ico);
- }
- Arrays.fill(this.code, ico, ico + size, (byte)0);
- for (Offset o = this.currentInserter; o != null; o = o.next) o.offset += size;
- }
-
- /**
- * @param lineNumber The line number that corresponds to the byte code, or -1
- */
- public void writeShort(short lineNumber, int v) {
- this.write(lineNumber, (byte) (v >> 8), (byte) v);
- }
-
- /**
- * @param lineNumber The line number that corresponds to the byte code, or -1
- */
- public void writeBranch(short lineNumber, int opcode, final Offset dst) {
- this.relocatables.add(new Branch(opcode, dst));
- this.write(lineNumber, (byte) opcode, (byte) -1, (byte) -1);
- }
-
- private class Branch extends Relocatable {
- public Branch(int opcode, Offset destination) {
- this.opcode = opcode;
- this.source = CodeContext.this.newInserter();
- this.destination = destination;
- if (opcode == Opcode.JSR_W || opcode == Opcode.GOTO_W) {
- //no need to expand wide opcodes
- this.expanded = true;
- } else {
- this.expanded = false;
- }
- }
-
- public boolean relocate() {
- if (this.destination.offset == Offset.UNSET) throw new RuntimeException("Cannot relocate branch to unset destination offset");
- int offset = this.destination.offset - this.source.offset;
-
- if (!this.expanded && (offset > Short.MAX_VALUE || offset < Short.MIN_VALUE)) {
- //we want to insert the data without skewing our source position,
- //so we will cache it and then restore it later.
- int pos = this.source.offset;
- CodeContext.this.pushInserter(this.source); {
- // promotion to a wide instruction only requires 2 extra bytes
- // everything else requires a new GOTO_W instruction after a negated if
- CodeContext.this.makeSpace(
- (short) -1,
- this.opcode == Opcode.GOTO ? 2 : this.opcode == Opcode.JSR ? 2 : 5
- );
- } CodeContext.this.popInserter();
- this.source.offset = pos;
- this.expanded = true;
- return false;
- }
-
- final byte[] ba;
- if (!this.expanded) {
- //we fit in a 16-bit jump
- ba = new byte[] { (byte) this.opcode, (byte) (offset >> 8), (byte) offset };
- } else {
- if (this.opcode == Opcode.GOTO || this.opcode == Opcode.JSR) {
- ba = new byte[] {
- (byte) (this.opcode + 33), // GOTO => GOTO_W; JSR => JSR_W
- (byte) (offset >> 24),
- (byte) (offset >> 16),
- (byte) (offset >> 8),
- (byte) offset
- };
- } else
- {
- //exclude the if-statement from jump target
- //if jumping backwards this will increase the jump to go over it
- //if jumping forwards this will decrease the jump by it
- offset -= 3;
-
- // [if cond offset]
- //expands to
- // [if !cond skip_goto]
- // [GOTO_W offset]
- ba = new byte[] {
- CodeContext.invertBranchOpcode((byte) this.opcode),
- (byte) 0,
- (byte) 8, //jump from this instruction past the GOTO_W
- (byte) Opcode.GOTO_W,
- (byte) (offset >> 24),
- (byte) (offset >> 16),
- (byte) (offset >> 8),
- (byte) offset
- };
- }
- }
- System.arraycopy(ba, 0, CodeContext.this.code, this.source.offset, ba.length);
- return true;
- }
-
- private boolean expanded; //marks whether this has been expanded to account for a wide branch
- private final int opcode;
- private final Inserter source;
- private final Offset destination;
- }
-
- /**
- * E.g. {@link Opcode#IFLT} ("less than") inverts to {@link Opcode#IFGE} ("greater than or equal to").
- */
- private static byte invertBranchOpcode(byte branchOpcode) {
- return ((Byte) CodeContext.BRANCH_OPCODE_INVERSION.get(new Byte(branchOpcode))).byteValue();
- }
- private static final Map BRANCH_OPCODE_INVERSION = CodeContext.createBranchOpcodeInversion(); // Map<Byte branch-opcode, Byte inverted-branch-opcode>
- private static Map createBranchOpcodeInversion() {
- Map m = new HashMap();
- m.put(new Byte(Opcode.IF_ACMPEQ), new Byte(Opcode.IF_ACMPNE));
- m.put(new Byte(Opcode.IF_ACMPNE), new Byte(Opcode.IF_ACMPEQ));
- m.put(new Byte(Opcode.IF_ICMPEQ), new Byte(Opcode.IF_ICMPNE));
- m.put(new Byte(Opcode.IF_ICMPNE), new Byte(Opcode.IF_ICMPEQ));
- m.put(new Byte(Opcode.IF_ICMPGE), new Byte(Opcode.IF_ICMPLT));
- m.put(new Byte(Opcode.IF_ICMPLT), new Byte(Opcode.IF_ICMPGE));
- m.put(new Byte(Opcode.IF_ICMPGT), new Byte(Opcode.IF_ICMPLE));
- m.put(new Byte(Opcode.IF_ICMPLE), new Byte(Opcode.IF_ICMPGT));
- m.put(new Byte(Opcode.IFEQ), new Byte(Opcode.IFNE));
- m.put(new Byte(Opcode.IFNE), new Byte(Opcode.IFEQ));
- m.put(new Byte(Opcode.IFGE), new Byte(Opcode.IFLT));
- m.put(new Byte(Opcode.IFLT), new Byte(Opcode.IFGE));
- m.put(new Byte(Opcode.IFGT), new Byte(Opcode.IFLE));
- m.put(new Byte(Opcode.IFLE), new Byte(Opcode.IFGT));
- m.put(new Byte(Opcode.IFNULL), new Byte(Opcode.IFNONNULL));
- m.put(new Byte(Opcode.IFNONNULL), new Byte(Opcode.IFNULL));
- return Collections.unmodifiableMap(m);
- }
-
- public void writeOffset(short lineNumber, Offset src, final Offset dst) {
- this.relocatables.add(new OffsetBranch(this.newOffset(), src, dst));
- this.write(lineNumber, (byte) -1, (byte) -1, (byte) -1, (byte) -1);
- }
-
- private class OffsetBranch extends Relocatable {
- public OffsetBranch(Offset where, Offset source, Offset destination) {
- this.where = where;
- this.source = source;
- this.destination = destination;
- }
- public boolean relocate() {
- if (
- this.source.offset == Offset.UNSET ||
- this.destination.offset == Offset.UNSET
- ) throw new RuntimeException("Cannot relocate offset branch to unset destination offset");
- int offset = this.destination.offset - this.source.offset;
- byte[] ba = new byte[] {
- (byte) (offset >> 24),
- (byte) (offset >> 16),
- (byte) (offset >> 8),
- (byte) offset
- };
- System.arraycopy(ba, 0, CodeContext.this.code, this.where.offset, 4);
- return true;
- }
- private final Offset where, source, destination;
- }
-
- public Offset newOffset() {
- Offset o = new Offset();
- o.set();
- return o;
- }
-
- /**
- * Allocate an {@link Inserter}, set it to the current offset, and
- * insert it before the current offset.
- *
- * In clear text, this means that you can continue writing to the
- * "Code" attribute, then {@link #pushInserter(CodeContext.Inserter)} the
- * {@link Inserter}, then write again (which inserts bytes into the
- * "Code" attribute at the previously remembered position), and then
- * {@link #popInserter()}.
- */
- public Inserter newInserter() {
- Inserter i = new Inserter();
- i.set();
- return i;
- }
-
- public Inserter currentInserter() {
- return this.currentInserter;
- }
-
- /**
- * Remember the current {@link Inserter}, then replace it with the
- * new one.
- */
- public void pushInserter(Inserter ins) {
- if (ins.nextInserter != null) throw new RuntimeException("An Inserter can only be pushed once at a time");
- ins.nextInserter = this.currentInserter;
- this.currentInserter = ins;
- }
-
- /**
- * Replace the current {@link Inserter} with the remembered one (see
- * {@link #pushInserter(CodeContext.Inserter)}).
- */
- public void popInserter() {
- Inserter ni = this.currentInserter.nextInserter;
- if (ni == null) throw new RuntimeException("Code inserter stack underflow");
- this.currentInserter.nextInserter = null; // Mark it as "unpushed".
- this.currentInserter = ni;
- }
-
- /**
- * A class that represents an offset within a "Code" attribute.
- *
- * The concept of an "offset" is that if one writes into the middle of
- * a "Code" attribute, all offsets behind the insertion point are
- * automatically shifted.
- */
- public class Offset {
- int offset = Offset.UNSET;
- Offset prev = null, next = null;
- final static int UNSET = -1;
-
- /**
- * Set this "Offset" to the offset of the current inserter; insert
- * this "Offset" before the current inserter.
- */
- public void set() {
- if (this.offset != Offset.UNSET) throw new RuntimeException("Cannot \"set()\" Offset more than once");
-
- this.offset = CodeContext.this.currentInserter.offset;
- this.prev = CodeContext.this.currentInserter.prev;
- this.next = CodeContext.this.currentInserter;
-
- this.prev.next = this;
- this.next.prev = this;
- }
- public final CodeContext getCodeContext() { return CodeContext.this; }
-
- public String toString() {
- return CodeContext.this.classFile.getThisClassName() + ": " + this.offset;
- }
- }
-
- /**
- * Add another entry to the "exception_table" of this code attribute (see JVMS 4.7.3).
- * @param startPC
- * @param endPC
- * @param handlerPC
- * @param catchTypeFD
- */
- public void addExceptionTableEntry(
- Offset startPC,
- Offset endPC,
- Offset handlerPC,
- String catchTypeFD // null == "finally" clause
- ) {
- this.exceptionTableEntries.add(new ExceptionTableEntry(
- startPC,
- endPC,
- handlerPC,
- catchTypeFD == null ? (short) 0 : this.classFile.addConstantClassInfo(catchTypeFD)
- ));
- }
-
- /**
- * Representation of an entry in the "exception_table" of a "Code" attribute (see JVMS
- * 4.7.3).
- */
- private static class ExceptionTableEntry {
- public ExceptionTableEntry(
- Offset startPC,
- Offset endPC,
- Offset handlerPC,
- short catchType
- ) {
- this.startPC = startPC;
- this.endPC = endPC;
- this.handlerPC = handlerPC;
- this.catchType = catchType;
- }
- private final Offset startPC, endPC, handlerPC;
- private final short catchType; // 0 == "finally" clause
- }
-
- /**
- * A class that implements an insertion point into a "Code"
- * attribute.
- */
- public class Inserter extends Offset {
- private Inserter nextInserter = null; // null == not in "currentInserter" stack
- }
-
- public class LineNumberOffset extends Offset {
- private final int lineNumber;
- public LineNumberOffset(int offset, int lineNumber) {
- this.lineNumber = lineNumber;
- this.offset = offset;
- }
- }
-
- private abstract class Relocatable {
- /**
- * Relocate this object.
- * @return true if the relocation succeeded in place
- * false if the relocation grew the number of bytes required
- */
- public abstract boolean relocate();
- }
-
- private short localVariableArrayLength = 0;
- private final Stack savedLocalVariableArrayLengths = new Stack();
- private final List relocatables = new ArrayList();
-
- /**
- * A throw-in interface that marks {@link CodeContext.Offset}s
- * as "fix-ups": During the execution of
- * {@link CodeContext#fixUp}, all "fix-ups" are invoked and
- * can do last touches to the code attribute.
- * <p>
- * This is currently used for inserting the "padding bytes" into the
- * TABLESWITCH and LOOKUPSWITCH instructions.
- */
- public interface FixUp {
- void fixUp();
- }
-}
diff --git a/src/org/codehaus/janino/CompileException.java b/src/org/codehaus/janino/CompileException.java
deleted file mode 100644
index 8306520..0000000
--- a/src/org/codehaus/janino/CompileException.java
+++ /dev/null
@@ -1,50 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino;
-
-import org.codehaus.janino.util.*;
-
-/**
- * An exception that reflects an error during compilation.
- */
-public class CompileException extends LocatedException {
-
- public CompileException(String message, Location optionalLocation) {
- super(message, optionalLocation);
- }
- public CompileException(String message, Location optionalLocation, Throwable cause) {
- super(message, optionalLocation, cause);
- }
-}
diff --git a/src/org/codehaus/janino/Compiler.java b/src/org/codehaus/janino/Compiler.java
deleted file mode 100644
index 38104f5..0000000
--- a/src/org/codehaus/janino/Compiler.java
+++ /dev/null
@@ -1,846 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino;
-
-import java.util.*;
-import java.io.*;
-
-import org.codehaus.janino.Parser.ParseException;
-import org.codehaus.janino.Scanner.ScanException;
-import org.codehaus.janino.UnitCompiler.ErrorHandler;
-import org.codehaus.janino.tools.Disassembler;
-import org.codehaus.janino.util.*;
-import org.codehaus.janino.util.enumerator.*;
-import org.codehaus.janino.util.resource.*;
-
-
-/**
- * A simplified substitute for the <tt>javac</tt> tool.
- *
- * Usage:
- * <pre>
- * java org.codehaus.janino.Compiler \
- * [ -d <i>destination-dir</i> ] \
- * [ -sourcepath <i>dirlist</i> ] \
- * [ -classpath <i>dirlist</i> ] \
- * [ -extdirs <i>dirlist</i> ] \
- * [ -bootclasspath <i>dirlist</i> ] \
- * [ -encoding <i>encoding</i> ] \
- * [ -verbose ] \
- * [ -g:none ] \
- * [ -g:{lines,vars,source} ] \
- * [ -warn:<i>pattern-list</i> ] \
- * <i>source-file</i> ...
- * java org.codehaus.janino.Compiler -help
- * </pre>
- */
-public class Compiler {
- private static final boolean DEBUG = false;
-
- /**
- * Command line interface.
- */
- public static void main(String[] args) {
- File destinationDirectory = Compiler.NO_DESTINATION_DIRECTORY;
- File[] optionalSourcePath = null;
- File[] classPath = { new File(".") };
- File[] optionalExtDirs = null;
- File[] optionalBootClassPath = null;
- String optionalCharacterEncoding = null;
- boolean verbose = false;
- EnumeratorSet debuggingInformation = DebuggingInformation.DEFAULT_DEBUGGING_INFORMATION;
- StringPattern[] warningHandlePatterns = Compiler.DEFAULT_WARNING_HANDLE_PATTERNS;
- boolean rebuild = false;
-
- // Process command line options.
- int i;
- for (i = 0; i < args.length; ++i) {
- String arg = args[i];
- if (arg.charAt(0) != '-') break;
- if (arg.equals("-d")) {
- destinationDirectory = new File(args[++i]);
- } else
- if (arg.equals("-sourcepath")) {
- optionalSourcePath = PathResourceFinder.parsePath(args[++i]);
- } else
- if (arg.equals("-classpath")) {
- classPath = PathResourceFinder.parsePath(args[++i]);
- } else
- if (arg.equals("-extdirs")) {
- optionalExtDirs = PathResourceFinder.parsePath(args[++i]);
- } else
- if (arg.equals("-bootclasspath")) {
- optionalBootClassPath = PathResourceFinder.parsePath(args[++i]);
- } else
- if (arg.equals("-encoding")) {
- optionalCharacterEncoding = args[++i];
- } else
- if (arg.equals("-verbose")) {
- verbose = true;
- } else
- if (arg.equals("-g")) {
- debuggingInformation = DebuggingInformation.ALL;
- } else
- if (arg.startsWith("-g:")) {
- try {
- debuggingInformation = new EnumeratorSet(DebuggingInformation.class, arg.substring(3));
- } catch (EnumeratorFormatException ex) {
- System.err.println("Invalid debugging option \"" + arg + "\", only \"" + DebuggingInformation.ALL + "\" allowed");
- System.exit(1);
- }
- } else
- if (arg.startsWith("-warn:")) {
- warningHandlePatterns = StringPattern.parseCombinedPattern(arg.substring(6));
- } else
- if (arg.equals("-rebuild")) {
- rebuild = true;
- } else
- if (arg.equals("-help")) {
- for (int j = 0; j < Compiler.USAGE.length; ++j) System.out.println(Compiler.USAGE[j]);
- System.exit(1);
- } else {
- System.err.println("Unrecognized command line option \"" + arg + "\"; try \"-help\".");
- System.exit(1);
- }
- }
-
- // Get source file names.
- if (i == args.length) {
- System.err.println("No source files given on command line; try \"-help\".");
- System.exit(1);
- }
- File[] sourceFiles = new File[args.length - i];
- for (int j = i; j < args.length; ++j) sourceFiles[j - i] = new File(args[j]);
-
- // Create the compiler object.
- final Compiler compiler = new Compiler(
- optionalSourcePath,
- classPath,
- optionalExtDirs,
- optionalBootClassPath,
- destinationDirectory,
- optionalCharacterEncoding,
- verbose,
- debuggingInformation,
- warningHandlePatterns,
- rebuild
- );
-
- // Compile source files.
- try {
- compiler.compile(sourceFiles);
- } catch (Exception e) {
- System.err.println(e.toString());
- System.exit(1);
- }
- }
-
- private static final String[] USAGE = {
- "Usage:",
- "",
- " java " + Compiler.class.getName() + " [ <option> ] ... <source-file> ...",
- "",
- "Supported <option>s are:",
- " -d <output-dir> Where to save class files",
- " -sourcepath <dirlist> Where to look for other source files",
- " -classpath <dirlist> Where to look for other class files",
- " -extdirs <dirlist> Where to look for other class files",
- " -bootclasspath <dirlist> Where to look for other class files",
- " -encoding <encoding> Encoding of source files, e.g. \"UTF-8\" or \"ISO-8859-1\"",
- " -verbose",
- " -g Generate all debugging info",
- " -g:none Generate no debugging info",
- " -g:{lines,vars,source} Generate only some debugging info",
- " -warn:<pattern-list> Issue certain warnings; examples:",
- " -warn:* Enables all warnings",
- " -warn:IASF Only warn against implicit access to static fields",
- " -warn:*-IASF Enables all warnings, except those against implicit",
- " access to static fields",
- " -warn:*-IA*+IASF Enables all warnings, except those against implicit",
- " accesses, but do warn against implicit access to",
- " static fields",
- " -rebuild Compile all source files, even if the class files",
- " seems up-to-date",
- " -help",
- "",
- "The default encoding in this environment is \"" + new InputStreamReader(new ByteArrayInputStream(new byte[0])).getEncoding() + "\".",
- };
-
- private /*final*/ ResourceFinder classFileFinder;
- public static final ResourceFinder FIND_NEXT_TO_SOURCE_FILE = null; // Special value for "classFileResourceFinder".
- private /*final*/ ResourceCreator classFileCreator;
- public static final ResourceCreator CREATE_NEXT_TO_SOURCE_FILE = null; // Special value for "classFileResourceCreator".
- private /*final*/ String optionalCharacterEncoding;
- private /*final*/ Benchmark benchmark;
- private /*final*/ EnumeratorSet debuggingInformation;
- private /*final*/ WarningHandler optionalWarningHandler;
- private UnitCompiler.ErrorHandler optionalCompileErrorHandler = null;
-
- private /*final*/ IClassLoader iClassLoader;
- private final ArrayList parsedCompilationUnits = new ArrayList(); // UnitCompiler
-
- /**
- * Initialize a Java<sup>TM</sup> compiler with the given parameters.
- * <p>
- * Classes are searched in the following order:
- * <ul>
- * <li>If <code>optionalBootClassPath</code> is <code>null</code>:
- * <ul>
- * <li>Through the system class loader of the JVM that runs JANINO
- * </ul>
- * <li>If <code>optionalBootClassPath</code> is not <code>null</code>:
- * <ul>
- * <li>Through the <code>optionalBootClassPath</code>
- * </ul>
- * <li>If <code>optionalExtDirs</code> is not <code>null</code>:
- * <ul>
- * <li>Through the <code>optionalExtDirs</code>
- * </ul>
- * <li>Through the <code>classPath</code>
- * <li>If <code>optionalSourcePath</code> is <code>null</code>:
- * <ul>
- * <li>Through source files found on the <code>classPath</code>
- * </ul>
- * <li>If <code>optionalSourcePath</code> is not <code>null</code>:
- * <ul>
- * <li>Through source files found on the <code>sourcePath</code>
- * </ul>
- * </ul>
- * <p>
- * The file name of a class file that represents class "pkg.Example"
- * is determined as follows:
- * <ul>
- * <li>
- * If <code>optionalDestinationDirectory</code> is not {@link #NO_DESTINATION_DIRECTORY}:
- * <code><i>optionalDestinationDirectory</i>/pkg/Example.class</code>
- * <li>
- * If <code>optionalDestinationDirectory</code> is {@link #NO_DESTINATION_DIRECTORY}:
- * <code>dir1/dir2/Example.class</code> (Assuming that the file name of the
- * source file that declares the class was
- * <code>dir1/dir2/Any.java</code>.)
- * </ul>
- *
- * @see #DEFAULT_WARNING_HANDLE_PATTERNS
- */
- public Compiler(
- final File[] optionalSourcePath,
- final File[] classPath,
- final File[] optionalExtDirs,
- final File[] optionalBootClassPath,
- final File destinationDirectory,
- final String optionalCharacterEncoding,
- boolean verbose,
- EnumeratorSet debuggingInformation,
- StringPattern[] warningHandlePatterns,
- boolean rebuild
- ) {
- this(
- new PathResourceFinder( // sourceFinder
- optionalSourcePath == null ? classPath : optionalSourcePath
- ),
- Compiler.createJavacLikePathIClassLoader( // iClassLoader
- optionalBootClassPath,
- optionalExtDirs,
- classPath
- ),
- ( // classFileFinder
- rebuild ? ResourceFinder.EMPTY_RESOURCE_FINDER :
- destinationDirectory == Compiler.NO_DESTINATION_DIRECTORY ? Compiler.FIND_NEXT_TO_SOURCE_FILE :
- new DirectoryResourceFinder(destinationDirectory)
- ),
- ( // classFileCreator
- destinationDirectory == Compiler.NO_DESTINATION_DIRECTORY ? Compiler.CREATE_NEXT_TO_SOURCE_FILE :
- new DirectoryResourceCreator(destinationDirectory)
- ),
- optionalCharacterEncoding, // optionalCharacterEncoding
- verbose, // verbose
- debuggingInformation, // debuggingInformation
- new FilterWarningHandler( // optionalWarningHandler
- warningHandlePatterns,
- new SimpleWarningHandler() // <= Anonymous class here is complicated because the enclosing instance is not fully initialized yet
- )
- );
-
- this.benchmark.report("*** JANINO - an embedded compiler for the Java(TM) programming language");
- this.benchmark.report("*** For more information visit http://janino.codehaus.org");
- this.benchmark.report("Source path", optionalSourcePath );
- this.benchmark.report("Class path", classPath );
- this.benchmark.report("Ext dirs", optionalExtDirs );
- this.benchmark.report("Boot class path", optionalBootClassPath );
- this.benchmark.report("Destination directory", destinationDirectory );
- this.benchmark.report("Character encoding", optionalCharacterEncoding );
- this.benchmark.report("Verbose", new Boolean(verbose) );
- this.benchmark.report("Debugging information", debuggingInformation );
- this.benchmark.report("Warning handle patterns", warningHandlePatterns);
- this.benchmark.report("Rebuild", new Boolean(rebuild) );
- }
- public static final File NO_DESTINATION_DIRECTORY = null; // Backwards compatibility -- previously, "null" was officially documented
- public static class SimpleWarningHandler implements WarningHandler {
- public void handleWarning(String handle, String message, Location optionalLocation) {
- StringBuffer sb = new StringBuffer();
- if (optionalLocation != null) sb.append(optionalLocation).append(": ");
- sb.append("Warning ").append(handle).append(": ").append(message);
- System.err.println(sb.toString());
- }
- }
- public static final StringPattern[] DEFAULT_WARNING_HANDLE_PATTERNS = StringPattern.PATTERNS_NONE;
-
- /**
- * To mimic the behavior of JAVAC with a missing "-d" command line option,
- * pass {@link #FIND_NEXT_TO_SOURCE_FILE} as the <code>classFileResourceFinder</code> and
- * {@link #CREATE_NEXT_TO_SOURCE_FILE} as the <code>classFileResourceCreator</code>.
- * <p>
- * If it is impossible to check whether an already-compiled class file
- * exists, or if you want to enforce recompilation, pass
- * {@link ResourceFinder#EMPTY_RESOURCE_FINDER} as the
- * <code>classFileResourceFinder</code>.
- *
- * @param sourceFinder Finds extra Java compilation units that need to be compiled (a.k.a. "sourcepath")
- * @param iClassLoader loads auxiliary {@link IClass}es; e.g. <code>new ClassLoaderIClassLoader(ClassLoader)</code>
- * @param classFileFinder Where to look for up-to-date class files that need not be compiled
- * @param classFileCreator Used to store generated class files
- * @param optionalCharacterEncoding
- * @param verbose
- * @param debuggingInformation a combination of <code>Java.DEBUGGING_...</code>
- * @param optionalWarningHandler used to issue warnings
- */
- public Compiler(
- ResourceFinder sourceFinder,
- IClassLoader iClassLoader,
- ResourceFinder classFileFinder,
- ResourceCreator classFileCreator,
- final String optionalCharacterEncoding,
- boolean verbose,
- EnumeratorSet debuggingInformation,
- WarningHandler optionalWarningHandler
- ) {
- this.classFileFinder = classFileFinder;
- this.classFileCreator = classFileCreator;
- this.optionalCharacterEncoding = optionalCharacterEncoding;
- this.benchmark = new Benchmark(verbose);
- this.debuggingInformation = debuggingInformation;
- this.optionalWarningHandler = optionalWarningHandler;
-
- // Set up the IClassLoader.
- this.iClassLoader = new CompilerIClassLoader(
- sourceFinder,
- iClassLoader
- );
- }
-
- /**
- * Install a custom {@link UnitCompiler.ErrorHandler}. The default
- * {@link UnitCompiler.ErrorHandler} prints the first 20 compile errors to
- * {@link System#err} and then throws a {@link CompileException}.
- * <p>
- * Passing <code>null</code> restores the default {@link UnitCompiler.ErrorHandler}.
- * <p>
- * Notice that scan and parse errors are <i>not</i> redirected to this {@link ErrorHandler},
- * instead, they cause a {@link ScanException} or a {@link ParseException} to be thrown.
- * Also, the {@link Compiler} may choose to throw {@link CompileException}s in certain,
- * fatal compile error situations, even if an {@link ErrorHandler} is installed.
- * <p>
- * In other words: In situations where compilation can reasonably continue after a compile
- * error, the {@link ErrorHandler} is called; all other error conditions cause a
- * {@link CompileException}, {@link ParseException} or {@link ScanException} to be thrown.
- */
- public void setCompileErrorHandler(UnitCompiler.ErrorHandler optionalCompileErrorHandler) {
- this.optionalCompileErrorHandler = optionalCompileErrorHandler;
- }
-
- /**
- * Create an {@link IClassLoader} that looks for classes in the given "boot class
- * path", then in the given "extension directories", and then in the given
- * "class path".
- * <p>
- * The default for the <code>optionalBootClassPath</code> is the path defined in
- * the system property "sun.boot.class.path", and the default for the
- * <code>optionalExtensionDirs</code> is the path defined in the "java.ext.dirs"
- * system property.
- */
- private static IClassLoader createJavacLikePathIClassLoader(
- final File[] optionalBootClassPath,
- final File[] optionalExtDirs,
- final File[] classPath
- ) {
- ResourceFinder bootClassPathResourceFinder = new PathResourceFinder(
- optionalBootClassPath == null ?
- PathResourceFinder.parsePath(System.getProperty("sun.boot.class.path")):
- optionalBootClassPath
- );
- ResourceFinder extensionDirectoriesResourceFinder = new JarDirectoriesResourceFinder(
- optionalExtDirs == null ?
- PathResourceFinder.parsePath(System.getProperty("java.ext.dirs")):
- optionalExtDirs
- );
- ResourceFinder classPathResourceFinder = new PathResourceFinder(classPath);
-
- // We can load classes through "ResourceFinderIClassLoader"s, which means
- // they are read into "ClassFile" objects, or we can load classes through
- // "ClassLoaderIClassLoader"s, which means they are loaded into the JVM.
- //
- // In my environment, the latter is slightly faster. No figures about
- // resource usage yet.
- //
- // In applications where the generated classes are not loaded into the
- // same JVM instance, we should avoid to use the
- // ClassLoaderIClassLoader, because that assumes that final fields have
- // a constant value, even if not compile-time-constant but only
- // initialization-time constant. The classical example is
- // "File.separator", which is non-blank final, but not compile-time-
- // constant.
- if (true) {
- IClassLoader icl;
- icl = new ResourceFinderIClassLoader(bootClassPathResourceFinder, null);
- icl = new ResourceFinderIClassLoader(extensionDirectoriesResourceFinder, icl);
- icl = new ResourceFinderIClassLoader(classPathResourceFinder, icl);
- return icl;
- } else {
- ClassLoader cl;
-
- cl = SimpleCompiler.BOOT_CLASS_LOADER;
- cl = new ResourceFinderClassLoader(bootClassPathResourceFinder, cl);
- cl = new ResourceFinderClassLoader(extensionDirectoriesResourceFinder, cl);
- cl = new ResourceFinderClassLoader(classPathResourceFinder, cl);
-
- return new ClassLoaderIClassLoader(cl);
- }
- }
-
- /**
- * Reads a set of Java<sup>TM</sup> compilation units (a.k.a. "source
- * files") from the file system, compiles them into a set of "class
- * files" and stores these in the file system. Additional source files are
- * parsed and compiled on demand through the "source path" set of
- * directories.
- * <p>
- * For example, if the source path comprises the directories "A/B" and "../C",
- * then the source file for class "com.acme.Main" is searched in
- * <dl>
- * <dd>A/B/com/acme/Main.java
- * <dd>../C/com/acme/Main.java
- * </dl>
- * Notice that it does make a difference whether you pass multiple source
- * files to {@link #compile(File[])} or if you invoke
- * {@link #compile(File[])} multiply: In the former case, the source
- * files may contain arbitrary references among each other (even circular
- * ones). In the latter case, only the source files on the source path
- * may contain circular references, not the <code>sourceFiles</code>.
- * <p>
- * This method must be called exactly once after object construction.
- * <p>
- * Compile errors are reported as described at
- * {@link #setCompileErrorHandler(UnitCompiler.ErrorHandler)}.
- *
- * @param sourceFiles Contain the compilation units to compile
- * @return <code>true</code> for backwards compatibility (return value can safely be ignored)
- * @throws CompileException Fatal compilation error, or the {@link CompileException} thrown be the installed compile error handler
- * @throws ParseException Parse error
- * @throws ScanException Scan error
- * @throws IOException Occurred when reading from the <code>sourceFiles</code>
- */
- public boolean compile(File[] sourceFiles)
- throws Scanner.ScanException, Parser.ParseException, CompileException, IOException {
- this.benchmark.report("Source files", sourceFiles);
-
- Resource[] sourceFileResources = new Resource[sourceFiles.length];
- for (int i = 0; i < sourceFiles.length; ++i) sourceFileResources[i] = new FileResource(sourceFiles[i]);
- this.compile(sourceFileResources);
- return true;
- }
-
- /**
- * See {@link #compile(File[])}.
- *
- * @param sourceResources Contain the compilation units to compile
- * @return <code>true</code> for backwards compatibility (return value can safely be ignored)
- */
- public boolean compile(Resource[] sourceResources)
- throws Scanner.ScanException, Parser.ParseException, CompileException, IOException {
-
- // Set up the compile error handler as described at "setCompileErrorHandler()".
- UnitCompiler.ErrorHandler ceh = (
- this.optionalCompileErrorHandler != null
- ? this.optionalCompileErrorHandler
- : new UnitCompiler.ErrorHandler() {
- int compileErrorCount = 0;
- public void handleError(String message, Location optionalLocation) throws CompileException {
- CompileException ex = new CompileException(message, optionalLocation);
- if (++this.compileErrorCount >= 20) throw ex;
- System.err.println(ex.getMessage());
- }
- }
- );
-
- this.benchmark.beginReporting();
- try {
-
- // Parse all source files.
- this.parsedCompilationUnits.clear();
- for (int i = 0; i < sourceResources.length; ++i) {
- if (Compiler.DEBUG) System.out.println("Compiling \"" + sourceResources[i] + "\"");
- this.parsedCompilationUnits.add(new UnitCompiler(this.parseCompilationUnit(
- sourceResources[i].getFileName(), // fileName
- new BufferedInputStream(sourceResources[i].open()), // inputStream
- this.optionalCharacterEncoding // optionalCharacterEncoding
- ), this.iClassLoader));
- }
-
- // Compile all parsed compilation units. The vector of parsed CUs may
- // grow while they are being compiled, but eventually all CUs will
- // be compiled.
- for (int i = 0; i < this.parsedCompilationUnits.size(); ++i) {
- UnitCompiler unitCompiler = (UnitCompiler) this.parsedCompilationUnits.get(i);
- Java.CompilationUnit cu = unitCompiler.compilationUnit;
- if (cu.optionalFileName == null) throw new RuntimeException();
- File sourceFile = new File(cu.optionalFileName);
-
- unitCompiler.setCompileErrorHandler(ceh);
- unitCompiler.setWarningHandler(this.optionalWarningHandler);
-
- this.benchmark.beginReporting("Compiling compilation unit \"" + sourceFile + "\"");
- ClassFile[] classFiles;
- try {
-
- // Compile the compilation unit.
- classFiles = unitCompiler.compileUnit(this.debuggingInformation);
- } finally {
- this.benchmark.endReporting();
- }
-
- // Store the compiled classes and interfaces into class files.
- this.benchmark.beginReporting("Storing " + classFiles.length + " class file(s) resulting from compilation unit \"" + sourceFile + "\"");
- try {
- for (int j = 0; j < classFiles.length; ++j) {
- this.storeClassFile(classFiles[j], sourceFile);
- }
- } finally {
- this.benchmark.endReporting();
- }
- }
- } finally {
- this.benchmark.endReporting("Compiled " + this.parsedCompilationUnits.size() + " compilation unit(s)");
- }
- return true;
- }
-
- /**
- * Read one compilation unit from a file and parse it.
- * <p>
- * The <code>inputStream</code> is closed before the method returns.
- * @return the parsed compilation unit
- */
- private Java.CompilationUnit parseCompilationUnit(
- String fileName,
- InputStream inputStream,
- String optionalCharacterEncoding
- ) throws Scanner.ScanException, Parser.ParseException, IOException {
- try {
- Scanner scanner = new Scanner(fileName, inputStream, optionalCharacterEncoding);
- scanner.setWarningHandler(this.optionalWarningHandler);
- Parser parser = new Parser(scanner);
- parser.setWarningHandler(this.optionalWarningHandler);
-
- this.benchmark.beginReporting("Parsing \"" + fileName + "\"");
- try {
- return parser.parseCompilationUnit();
- } finally {
- this.benchmark.endReporting();
- }
- } finally {
- inputStream.close();
- }
- }
-
- /**
- * Construct the name of a file that could store the byte code of the class with the given
- * name.
- * <p>
- * If <code>optionalDestinationDirectory</code> is non-null, the returned path is the
- * <code>optionalDestinationDirectory</code> plus the package of the class (with dots replaced
- * with file separators) plus the class name plus ".class". Example:
- * "destdir/pkg1/pkg2/Outer$Inner.class"
- * <p>
- * If <code>optionalDestinationDirectory</code> is null, the returned path is the
- * directory of the <code>sourceFile</code> plus the class name plus ".class". Example:
- * "srcdir/Outer$Inner.class"
- * @param className E.g. "pkg1.pkg2.Outer$Inner"
- * @param sourceFile E.g. "srcdir/Outer.java"
- * @param optionalDestinationDirectory E.g. "destdir"
- */
- public static File getClassFile(String className, File sourceFile, File optionalDestinationDirectory) {
- if (optionalDestinationDirectory != null) {
- return new File(optionalDestinationDirectory, ClassFile.getClassFileResourceName(className));
- } else {
- int idx = className.lastIndexOf('.');
- return new File(sourceFile.getParentFile(), ClassFile.getClassFileResourceName(className.substring(idx + 1)));
- }
- }
-
- /**
- * Store the byte code of this {@link ClassFile} in the file system. Directories are created
- * as necessary.
- * @param classFile
- * @param sourceFile Required to compute class file path if no destination directory given
- */
- public void storeClassFile(ClassFile classFile, final File sourceFile) throws IOException {
- String classFileResourceName = ClassFile.getClassFileResourceName(classFile.getThisClassName());
-
- // Determine where to create the class file.
- ResourceCreator rc;
- if (this.classFileCreator != Compiler.CREATE_NEXT_TO_SOURCE_FILE) {
- rc = this.classFileCreator;
- } else {
-
- // If the JAVAC option "-d" is given, place the class file next
- // to the source file, irrespective of the package name.
- rc = new FileResourceCreator() {
- protected File getFile(String resourceName) {
- return new File(
- sourceFile.getParentFile(),
- resourceName.substring(resourceName.lastIndexOf('/') + 1)
- );
- }
- };
- }
- OutputStream os = rc.createResource(classFileResourceName);
- try {
- if (DEBUG) {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- classFile.store(baos);
- byte[] ba = baos.toByteArray();
- System.out.println("*** Disassembly of class \"" + classFile.getThisClassName() + "\":");
- try {
- new Disassembler().disasm(new ByteArrayInputStream(ba));
- System.out.flush();
- } catch (IOException ex) {
- throw new RuntimeException("SNO: IOException despite ByteArrayInputStream");
- }
- os.write(ba);
- } else
- {
- classFile.store(os);
- }
- } catch (IOException ex) {
- try { os.close(); } catch (IOException e) {}
- os = null;
- if (!rc.deleteResource(classFileResourceName)) throw new IOException("Could not delete incompletely written class file \"" + classFileResourceName + "\"");
- throw ex;
- } finally {
- if (os != null) try { os.close(); } catch (IOException e) {}
- }
- }
-
- /**
- * A specialized {@link IClassLoader} that loads {@link IClass}es from the following
- * sources:
- * <ol>
- * <li>An already-parsed compilation unit
- * <li>A class file in the output directory (if existant and younger than source file)
- * <li>A source file in any of the source path directories
- * <li>The parent class loader
- * </ol>
- * Notice that the {@link CompilerIClassLoader} is an inner class of {@link Compiler} and
- * heavily uses {@link Compiler}'s members.
- */
- private class CompilerIClassLoader extends IClassLoader {
- private final ResourceFinder sourceFinder;
-
- /**
- * @param sourceFinder Where to look for source files
- * @param optionalParentIClassLoader {@link IClassLoader} through which {@link IClass}es are to be loaded
- */
- public CompilerIClassLoader(
- ResourceFinder sourceFinder,
- IClassLoader optionalParentIClassLoader
- ) {
- super(optionalParentIClassLoader);
- this.sourceFinder = sourceFinder;
- super.postConstruct();
- }
-
- /**
- * @param type field descriptor of the {@IClass} to load, e.g. "Lpkg1/pkg2/Outer$Inner;"
- * @return <code>null</code> if a the type could not be found
- * @throws ClassNotFoundException if an exception was raised while loading the {@link IClass}
- */
- protected IClass findIClass(final String type) throws ClassNotFoundException {
- if (Compiler.DEBUG) System.out.println("type = " + type);
-
- // Determine the class name.
- String className = Descriptor.toClassName(type); // E.g. "pkg1.pkg2.Outer$Inner"
- if (Compiler.DEBUG) System.out.println("2 className = \"" + className + "\"");
-
- // Do not attempt to load classes from package "java".
- if (className.startsWith("java.")) return null;
-
- // Determine the name of the top-level class.
- String topLevelClassName;
- {
- int idx = className.indexOf('$');
- topLevelClassName = idx == -1 ? className : className.substring(0, idx);
- }
-
- // Check the already-parsed compilation units.
- for (int i = 0; i < Compiler.this.parsedCompilationUnits.size(); ++i) {
- UnitCompiler uc = (UnitCompiler) Compiler.this.parsedCompilationUnits.get(i);
- IClass res = uc.findClass(topLevelClassName);
- if (res != null) {
- if (!className.equals(topLevelClassName)) {
- res = uc.findClass(className);
- if (res == null) return null;
- }
- this.defineIClass(res);
- return res;
- }
- }
-
- // Search source path for uncompiled class.
- final Resource sourceResource = this.sourceFinder.findResource(ClassFile.getSourceResourceName(className));
- if (sourceResource == null) return null;
-
- // Find an existing class file.
- Resource classFileResource;
- if (Compiler.this.classFileFinder != Compiler.FIND_NEXT_TO_SOURCE_FILE) {
- classFileResource = Compiler.this.classFileFinder.findResource(ClassFile.getClassFileResourceName(className));
- } else {
- if (!(sourceResource instanceof FileResource)) return null;
- File classFile = new File(
- ((FileResource) sourceResource).getFile().getParentFile(),
- ClassFile.getClassFileResourceName(className.substring(className.lastIndexOf('.') + 1))
- );
- classFileResource = classFile.exists() ? new FileResource(classFile) : null;
- }
-
- // Compare source modification time against class file modification time.
- if (classFileResource != null && sourceResource.lastModified() <= classFileResource.lastModified()) {
-
- // The class file is up-to-date; load it.
- return this.defineIClassFromClassFileResource(classFileResource);
- } else {
-
- // Source file not yet compiled or younger than class file.
- return this.defineIClassFromSourceResource(sourceResource, className);
- }
- }
-
- /**
- * Parse the compilation unit stored in the given <code>sourceResource</code>, remember it in
- * <code>Compiler.this.parsedCompilationUnits</code> (it may declare other classes that
- * are needed later), find the declaration of the type with the given
- * <code>className</code>, and define it in the {@link IClassLoader}.
- * <p>
- * Notice that the CU is not compiled here!
- */
- private IClass defineIClassFromSourceResource(
- Resource sourceResource,
- String className
- ) throws ClassNotFoundException {
-
- // Parse the source file.
- UnitCompiler uc;
- try {
- Java.CompilationUnit cu = Compiler.this.parseCompilationUnit(
- sourceResource.getFileName(), // fileName
- new BufferedInputStream(sourceResource.open()), // inputStream
- Compiler.this.optionalCharacterEncoding // optionalCharacterEncoding
- );
- uc = new UnitCompiler(cu, Compiler.this.iClassLoader);
- } catch (IOException ex) {
- throw new ClassNotFoundException("Parsing compilation unit \"" + sourceResource + "\"", ex);
- } catch (Parser.ParseException ex) {
- throw new ClassNotFoundException("Parsing compilation unit \"" + sourceResource + "\"", ex);
- } catch (Scanner.ScanException ex) {
- throw new ClassNotFoundException("Parsing compilation unit \"" + sourceResource + "\"", ex);
- } catch (CompileException ex) {
- throw new ClassNotFoundException("Parsing compilation unit \"" + sourceResource + "\"", ex);
- }
-
- // Remember compilation unit for later compilation.
- Compiler.this.parsedCompilationUnits.add(uc);
-
- // Define the class.
- IClass res = uc.findClass(className);
- if (res == null) {
-
- // This is a really complicated case: We may find a source file on the source
- // path that seemingly contains the declaration of the class we are looking
- // for, but doesn't. This is possible if the underlying file system has
- // case-insensitive file names and/or file names that are limited in length
- // (e.g. DOS 8.3).
- return null;
- }
- this.defineIClass(res);
- return res;
- }
-
- /**
- * Open the given <code>classFileResource</code>, read its contents, define it in the
- * {@link IClassLoader}, and resolve it (this step may involve loading more classes).
- */
- private IClass defineIClassFromClassFileResource(Resource classFileResource) throws ClassNotFoundException {
- Compiler.this.benchmark.beginReporting("Loading class file \"" + classFileResource.getFileName() + "\"");
- try {
- InputStream is = null;
- ClassFile cf;
- try {
- is = classFileResource.open();
- cf = new ClassFile(new BufferedInputStream(is));
- } catch (IOException ex) {
- throw new ClassNotFoundException("Opening class file resource \"" + classFileResource + "\"", ex);
- } finally {
- if (is != null) try { is.close(); } catch (IOException e) {}
- }
- ClassFileIClass result = new ClassFileIClass(
- cf, // classFile
- CompilerIClassLoader.this // iClassLoader
- );
-
- // Important: We must FIRST call "defineIClass()" so that the
- // new IClass is known to the IClassLoader, and THEN
- // "resolveAllClasses()", because otherwise endless recursion could
- // occur.
- this.defineIClass(result);
- result.resolveAllClasses();
-
- return result;
- } finally {
- Compiler.this.benchmark.endReporting();
- }
- }
- }
-}
-
-
diff --git a/src/org/codehaus/janino/Cookable.java b/src/org/codehaus/janino/Cookable.java
deleted file mode 100644
index 16ff334..0000000
--- a/src/org/codehaus/janino/Cookable.java
+++ /dev/null
@@ -1,150 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino;
-
-import java.io.*;
-
-/**
- * "Cooking" means scanning a sequence of Java<sup>TM</sup> tokens with a {@link
- * org.codehaus.janino.Scanner} and turning them into some artifact. For example, if you cook a
- * {@link ClassBodyEvaluator}, then the tokens are interpreted as a class body and compiled into
- * a {@link Class} which is accessible through {@link ClassBodyEvaluator#getClazz()}.
- * <p>
- * This class declares numerous <code>cook*()</code> methods
- * that use a {@link java.lang.String}, a {@link java.io.File}, an {@link java.io.InputStream} or
- * a {@link java.io.Reader} as the source of characters for scanning.
- * <p>
- * The <code>cook*()</code> methods eventually invoke the abstract {@link #cook(Scanner)}
- * method with a correctly configured {@link org.codehaus.janino.Scanner}.
- */
-public abstract class Cookable {
-
- /**
- * To be implemented by the derived classes.
- */
- public abstract void cook(Scanner scanner)
- throws CompileException, Parser.ParseException, Scanner.ScanException, IOException;
-
- // The "cook()" method family.
-
- public final void cook(Reader r)
- throws CompileException, Parser.ParseException, Scanner.ScanException, IOException {
- this.cook(null, r);
- }
-
- /**
- * @param optionalFileName Used when reporting errors and warnings.
- */
- public final void cook(String optionalFileName, Reader r)
- throws CompileException, Parser.ParseException, Scanner.ScanException, IOException {
- this.cook(new Scanner(optionalFileName, r));
- }
-
- /**
- * Cook tokens from an {@link InputStream}, encoded in the "platform default encoding".
- */
- public final void cook(InputStream is)
- throws CompileException, Parser.ParseException, Scanner.ScanException, IOException {
- this.cook(null, is);
- }
-
- /**
- * Cook tokens from an {@link InputStream}, encoded in the "platform default encoding".
- *
- * @param optionalFileName Used when reporting errors and warnings.
- */
- public final void cook(String optionalFileName, InputStream is)
- throws CompileException, Parser.ParseException, Scanner.ScanException, IOException {
- this.cook(optionalFileName, is, null);
- }
- public final void cook(InputStream is, String optionalEncoding)
- throws CompileException, Parser.ParseException, Scanner.ScanException, IOException {
- this.cook(new Scanner(null, is, optionalEncoding));
- }
-
- /**
- * @param optionalFileName Used when reporting errors and warnings.
- */
- public final void cook(String optionalFileName, InputStream is, String optionalEncoding)
- throws CompileException, Parser.ParseException, Scanner.ScanException, IOException {
- this.cook(new Scanner(optionalFileName, is, optionalEncoding));
- }
-
- /**
- * Cook tokens from a {@link java.lang.String}.
- * <p>
- * <b>Notice:</b> If you pass a string literal, be sure to escape all Java<sup>TM</sup> special
- * characters, especially backslashes.
- */
- public final void cook(String s)
- throws CompileException, Parser.ParseException, Scanner.ScanException {
- try {
- this.cook(new StringReader(s));
- } catch (IOException ex) {
- throw new RuntimeException("SNO: IOException despite StringReader");
- }
- }
-
- /**
- * Cook tokens from the given {@link File}, encoded in the "platform default encoding".
- */
- public final void cookFile(File file)
- throws CompileException, Parser.ParseException, Scanner.ScanException, IOException {
- this.cookFile(file, null);
- }
- public final void cookFile(File file, String optionalEncoding)
- throws CompileException, Parser.ParseException, Scanner.ScanException, IOException {
- InputStream is = new FileInputStream(file);
- try {
- this.cook(new Scanner(file.getAbsolutePath(), is, optionalEncoding));
- is.close();
- is = null;
- } finally {
- if (is != null) try { is.close(); } catch (IOException ex) {}
- }
- }
-
- /**
- * Cook tokens from the named file, encoded in the "platform default encoding".
- */
- public final void cookFile(String fileName)
- throws CompileException, Parser.ParseException, Scanner.ScanException, IOException {
- this.cookFile(fileName, null);
- }
- public final void cookFile(String fileName, String optionalEncoding)
- throws CompileException, Parser.ParseException, Scanner.ScanException, IOException {
- this.cookFile(new File(fileName), optionalEncoding);
- }
-}
diff --git a/src/org/codehaus/janino/DebuggingInformation.java b/src/org/codehaus/janino/DebuggingInformation.java
deleted file mode 100644
index 1232292..0000000
--- a/src/org/codehaus/janino/DebuggingInformation.java
+++ /dev/null
@@ -1,59 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino;
-
-import org.codehaus.janino.util.enumerator.*;
-
-public class DebuggingInformation extends Enumerator {
- public static final DebuggingInformation SOURCE = new DebuggingInformation("source");
- public static final DebuggingInformation LINES = new DebuggingInformation("lines");
- public static final DebuggingInformation VARS = new DebuggingInformation("vars");
-
- public static final EnumeratorSet NONE = new EnumeratorSet(DebuggingInformation.class ).setName("none");
- public static final EnumeratorSet ALL = new EnumeratorSet(DebuggingInformation.class, true).setName("all");
-
- public static final EnumeratorSet DEFAULT_DEBUGGING_INFORMATION = (
- new EnumeratorSet(DebuggingInformation.class)
- .add(DebuggingInformation.LINES)
- .add(DebuggingInformation.SOURCE)
- );
-
- private DebuggingInformation(String name) {
- super(name);
- }
- public static DebuggingInformation fromString(String name) throws EnumeratorFormatException {
- return (DebuggingInformation) Enumerator.fromString(name, DebuggingInformation.class);
- }
-}
diff --git a/src/org/codehaus/janino/Descriptor.java b/src/org/codehaus/janino/Descriptor.java
deleted file mode 100644
index 25aef18..0000000
--- a/src/org/codehaus/janino/Descriptor.java
+++ /dev/null
@@ -1,270 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino;
-
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
-/**
- * Helper class that defines useful methods for handling "field descriptors"
- * (JVMS 4.3.2) and "method descriptors" (JVMS 4.3.3).<p>
- * Typical descriptors are:
- * <ul>
- * <li><code>I</code> Integer
- * <li><code>[I</code> Array of integer
- * <li><code>Lpkg1/pkg2/Cls;</code> Class
- * <li><code>Lpkg1/pkg2/Outer$Inner;</code> Member class
- * </ul>
- */
-public class Descriptor {
- public static boolean isReference(String d) {
- return d.length() > 1;
- }
- public static boolean isClassOrInterfaceReference(String d) {
- return d.charAt(0) == 'L';
- }
- public static boolean isArrayReference(String d) {
- return d.charAt(0) == '[';
- }
- public static String getComponentDescriptor(String d) {
- if (d.charAt(0) != '[') throw new RuntimeException("Cannot determine component descriptor from non-array descriptor \"" + d + "\"");
- return d.substring(1);
- }
- public static short size(String d) {
- if (d.equals(Descriptor.VOID_)) return 0;
- if (Descriptor.hasSize1(d)) return 1;
- if (Descriptor.hasSize2(d)) return 2;
- throw new RuntimeException("No size defined for type \"" + Descriptor.toString(d) + "\"");
- }
- public static boolean hasSize1(String d) {
- if (d.length() == 1) return "BCFISZ".indexOf(d) != -1;
- return Descriptor.isReference(d);
- }
- public static boolean hasSize2(String d) {
- return d.equals(Descriptor.LONG_) || d.equals(Descriptor.DOUBLE_);
- }
-
- // Pretty-print.
- public static String toString(String d) {
- int idx = 0;
- StringBuffer sb = new StringBuffer();
- if (d.charAt(0) == '(') {
- ++idx;
- sb.append("(");
- while (idx < d.length() && d.charAt(idx) != ')') {
- if (idx != 1) sb.append(", ");
- idx = Descriptor.toString(d, idx, sb);
- }
- if (idx >= d.length()) throw new RuntimeException("Invalid descriptor \"" + d + "\"");
- sb.append(") => ");
- ++idx;
- }
- Descriptor.toString(d, idx, sb);
- return sb.toString();
- }
- private static int toString(String d, int idx, StringBuffer sb) {
- int dimensions = 0;
- while (idx < d.length() && d.charAt(idx) == '[') {
- ++dimensions;
- ++idx;
- }
- if (idx >= d.length()) throw new RuntimeException("Invalid descriptor \"" + d + "\"");
- switch (d.charAt(idx)) {
- case 'L':
- {
- int idx2 = d.indexOf(';', idx);
- if (idx2 == -1) throw new RuntimeException("Invalid descriptor \"" + d + "\"");
- sb.append(d.substring(idx + 1, idx2).replace('/', '.'));
- idx = idx2;
- }
- break;
- case 'V': sb.append("void"); break;
- case 'B': sb.append("byte"); break;
- case 'C': sb.append("char"); break;
- case 'D': sb.append("double"); break;
- case 'F': sb.append("float"); break;
- case 'I': sb.append("int"); break;
- case 'J': sb.append("long"); break;
- case 'S': sb.append("short"); break;
- case 'Z': sb.append("boolean"); break;
- default:
- throw new RuntimeException("Invalid descriptor \"" + d + "\"");
- }
- for (; dimensions > 0; --dimensions) sb.append("[]");
- return idx + 1;
- }
-
- /**
- * Convert a class name as defined by "Class.getName()" into a
- * descriptor.
- */
- public static String fromClassName(String className) {
- String res = (String)Descriptor.classNameToDescriptor.get(className);
- if(res != null) { return res; }
- if (className.startsWith("[")) return className.replace('.', '/');
- return 'L' + className.replace('.', '/') + ';';
- }
-
- /**
- * Convert a class name in the "internal form" as described in JVMS 4.2 into a descriptor.
- * <p>
- * Also implement the encoding of array types as described in JVMS 4.4.1.
- */
- public static String fromInternalForm(String internalForm) {
- if (internalForm.charAt(0) == '[') return internalForm;
- return 'L' + internalForm + ';';
- }
-
- /**
- * Convert a field descriptor into a class name as defined by {@link
- * Class#getName()}.
- */
- public static String toClassName(String d) {
- String res = (String)Descriptor.descriptorToClassName.get(d);
- if(res != null) { return res; }
-
- char firstChar = d.charAt(0);
- if (firstChar == 'L' && d.endsWith(";")) {
- // Class or interface -- convert "Ljava/lang/String;" to "java.lang.String".
- return d.substring(1, d.length() - 1).replace('/', '.');
- }
- if (firstChar == '[') {
- // Array type -- convert "[Ljava/lang/String;" to "[Ljava.lang.String;".
- return d.replace('/', '.');
- }
- throw new RuntimeException("(Invalid field descriptor \"" + d + "\")");
- }
-
- /**
- * Convert a descriptor into the "internal form" as defined by JVMS 4.2.
- */
- public static String toInternalForm(String d) {
- if (d.charAt(0) != 'L') throw new RuntimeException("Attempt to convert non-class descriptor \"" + d + "\" into internal form");
- return d.substring(1, d.length() - 1);
- }
-
- public static boolean isPrimitive(String d) {
- return d.length() == 1 && "VBCDFIJSZ".indexOf(d.charAt(0)) != -1;
- }
-
- public static boolean isPrimitiveNumeric(String d) {
- return d.length() == 1 && "BDFIJSC".indexOf(d.charAt(0)) != -1;
- }
-
- /**
- * Returns the package name of a class or interface reference descriptor,
- * or <code>null</code> if the class or interface is declared in the
- * default package.
- */
- public static String getPackageName(String d) {
- if (d.charAt(0) != 'L') throw new RuntimeException("Attempt to get package name of non-class descriptor \"" + d + "\"");
- int idx = d.lastIndexOf('/');
- return idx == -1 ? null : d.substring(1, idx).replace('/', '.');
- }
-
- /**
- * Check whether two reference types are declared in the same package.
- */
- public static boolean areInSamePackage(String d1, String d2) {
- String packageName1 = Descriptor.getPackageName(d1);
- String packageName2 = Descriptor.getPackageName(d2);
- return packageName1 == null ? packageName2 == null : packageName1.equals(packageName2);
- }
-
- public final static String VOID_ = "V";
- public final static String BYTE_ = "B";
- public final static String CHAR_ = "C";
- public final static String DOUBLE_ = "D";
- public final static String FLOAT_ = "F";
- public final static String INT_ = "I";
- public final static String LONG_ = "J";
- public final static String SHORT_ = "S";
- public final static String BOOLEAN_ = "Z";
- public final static String OBJECT = "Ljava/lang/Object;";
- public final static String STRING = "Ljava/lang/String;";
- public final static String STRING_BUFFER = "Ljava/lang/StringBuffer;";
- public final static String STRING_BUILDER = "Ljava/lang/StringBuilder;"; // Since 1.5!
- public final static String CLASS = "Ljava/lang/Class;";
- public final static String THROWABLE = "Ljava/lang/Throwable;";
- public final static String RUNTIME_EXCEPTION = "Ljava/lang/RuntimeException;";
- public final static String ERROR = "Ljava/lang/Error;";
- public final static String CLONEABLE = "Ljava/lang/Cloneable;";
- public final static String SERIALIZABLE = "Ljava/io/Serializable;";
- public final static String BOOLEAN = "Ljava/lang/Boolean;";
- public final static String BYTE = "Ljava/lang/Byte;";
- public final static String CHARACTER = "Ljava/lang/Character;";
- public final static String SHORT = "Ljava/lang/Short;";
- public final static String INTEGER = "Ljava/lang/Integer;";
- public final static String LONG = "Ljava/lang/Long;";
- public final static String FLOAT = "Ljava/lang/Float;";
- public final static String DOUBLE = "Ljava/lang/Double;";
- private final static Map classNameToDescriptor = new HashMap();
- private final static Map descriptorToClassName = new HashMap();
- static {
- descriptorToClassName.put(Descriptor.VOID_, "void");
- descriptorToClassName.put(Descriptor.BYTE_, "byte");
- descriptorToClassName.put(Descriptor.CHAR_, "char");
- descriptorToClassName.put(Descriptor.DOUBLE_, "double");
- descriptorToClassName.put(Descriptor.FLOAT_, "float");
- descriptorToClassName.put(Descriptor.INT_, "int");
- descriptorToClassName.put(Descriptor.LONG_, "long");
- descriptorToClassName.put(Descriptor.SHORT_, "short");
- descriptorToClassName.put(Descriptor.BOOLEAN_, "boolean");
- descriptorToClassName.put(Descriptor.OBJECT, "java.lang.Object");
- descriptorToClassName.put(Descriptor.STRING, "java.lang.String");
- descriptorToClassName.put(Descriptor.STRING_BUFFER, "java.lang.StringBuffer");
- descriptorToClassName.put(Descriptor.STRING_BUILDER, "java.lang.StringBuilder");
- descriptorToClassName.put(Descriptor.CLASS, "java.lang.Class");
- descriptorToClassName.put(Descriptor.THROWABLE, "java.lang.Throwable");
- descriptorToClassName.put(Descriptor.RUNTIME_EXCEPTION, "java.lang.RuntimeException");
- descriptorToClassName.put(Descriptor.ERROR, "java.lang.Error");
- descriptorToClassName.put(Descriptor.CLONEABLE, "java.lang.Cloneable");
- descriptorToClassName.put(Descriptor.SERIALIZABLE, "java.io.Serializable");
- descriptorToClassName.put(Descriptor.BOOLEAN, "java.lang.Boolean");
- descriptorToClassName.put(Descriptor.BYTE, "java.lang.Byte");
- descriptorToClassName.put(Descriptor.CHARACTER, "java.lang.Character");
- descriptorToClassName.put(Descriptor.SHORT, "java.lang.Short");
- descriptorToClassName.put(Descriptor.INTEGER, "java.lang.Integer");
- descriptorToClassName.put(Descriptor.LONG, "java.lang.Long");
- descriptorToClassName.put(Descriptor.FLOAT, "java.lang.Float");
- descriptorToClassName.put(Descriptor.DOUBLE, "java.lang.Double");
-
- for(Iterator it = descriptorToClassName.entrySet().iterator(); it.hasNext();) {
- Map.Entry e = (Map.Entry) it.next();
- classNameToDescriptor.put(e.getValue(), e.getKey());
- }
- }
-}
diff --git a/src/org/codehaus/janino/ExpressionEvaluator.java b/src/org/codehaus/janino/ExpressionEvaluator.java
deleted file mode 100644
index fa256ba..0000000
--- a/src/org/codehaus/janino/ExpressionEvaluator.java
+++ /dev/null
@@ -1,525 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino;
-
-import java.io.*;
-import java.util.*;
-
-import org.codehaus.janino.Java.AmbiguousName;
-import org.codehaus.janino.Java.Rvalue;
-import org.codehaus.janino.Parser.ParseException;
-import org.codehaus.janino.Scanner.ScanException;
-import org.codehaus.janino.Visitor.RvalueVisitor;
-import org.codehaus.janino.util.PrimitiveWrapper;
-import org.codehaus.janino.util.Traverser;
-
-/**
- * An engine that evaluates expressions in Java<sup>TM</sup> bytecode.
- * <p>
- * The syntax of the expression to compile is that of a Java<sup>TM</sup> expression, as defined
- * in the <a href="http://java.sun.com/docs/books/jls/second_edition">Java Language Specification,
- * 2nd edition</a>, section
- * <a href="http://java.sun.com/docs/books/jls/second_edition/html/expressions.doc.html#44393">15</a>.
- * Notice that a Java<sup>TM</sup> expression does not have a concluding semicolon.
- * <p>
- * Example:<pre>
- * a + 7 * b</pre>
- * (Notice that this expression refers to two parameters "a" and "b", as explained below.)
- * <p>
- * The expression may optionally be preceeded with a sequence of import directives like
- * <pre>
- * import java.text.*;
- * new DecimalFormat("####,###.##").format(10200020.345345)
- * </pre>
- * (Notice that the import directive is concluded with a semicolon, while the expression is not.)
- * This feature is not available if you compile many expressions at a time (see below).
- * <p>
- * The expression evaluator is implemented by creating and compiling a temporary compilation unit
- * defining one class with one static method with one RETURN statement.
- * <p>
- * To set up an {@link ExpressionEvaluator} object, proceed as follows:
- * <ol>
- * <li>
- * Create the {@link ExpressionEvaluator} using {@link #ExpressionEvaluator()}
- * <li>
- * Configure the {@link ExpressionEvaluator} by calling any of the following methods:
- * <ul>
- * <li>{@link #setExpressionType(Class)}
- * <li>{@link org.codehaus.janino.ScriptEvaluator#setParameters(String[], Class[])}
- * <li>{@link org.codehaus.janino.ScriptEvaluator#setThrownExceptions(Class[])}
- * <li>{@link org.codehaus.janino.SimpleCompiler#setParentClassLoader(ClassLoader)}
- * <li>{@link org.codehaus.janino.ClassBodyEvaluator#setDefaultImports(String[])}
- * </ul>
- * <li>
- * Call any of the {@link org.codehaus.janino.Cookable#cook(Scanner)} methods to scan,
- * parse, compile and load the expression into the JVM.
- * </ol>
- * After the {@link ExpressionEvaluator} object is set up, the expression can be evaluated as
- * often with different parameter values (see {@link #evaluate(Object[])}). This evaluation is
- * very fast, compared to the compilation.
- * <p>
- * Less common methods exist that allow for the specification of the name of the generated class,
- * the class it extends, the interfaces it implements, the name of the method that executes the
- * expression, the exceptions that this method (i.e. the expression) is allowed to throw, and the
- * {@link ClassLoader} that is used to define the generated class and to load classes referenced by
- * the expression.
- * <p>
- * Alternatively, a number of "convenience constructors" exist that execute the steps described
- * above instantly.
- * <p>
- * If you want to compile many expressions at the same time, you have the option to cook an
- * <i>array</i> of expressions in one {@link ExpressionEvaluator} by using the following methods:
- * <ul>
- * <li>{@link #setMethodNames(String[])}
- * <li>{@link #setParameters(String[][], Class[][])}
- * <li>{@link #setExpressionTypes(Class[])}
- * <li>{@link #setStaticMethod(boolean[])}
- * <li>{@link #setThrownExceptions(Class[][])}
- * <li>{@link #cook(Scanner[])}
- * <li>{@link #evaluate(int, Object[])}
- * </ul>
- * Notice that these methods have array parameters in contrast to their one-expression brethren.
- * <p>
- * Notice that for <i>functionally</i> identical {@link ExpressionEvaluator}s,
- * {@link java.lang.Object#equals(java.lang.Object)} will return <code>true</code>. E.g. "a+b" and
- * "c + d" are functionally identical if "a" and "c" have the same type, and so do "b" and "d".
- * <p>
- * If the parameter and return types of the expression are known at compile time, then a "fast"
- * expression evaluator can be instantiated through
- * {@link #createFastExpressionEvaluator(String, Class, String[], ClassLoader)}. Expression
- * evaluation is faster than through {@link #evaluate(Object[])}, because it is not done through
- * reflection but through direct method invocation.
- * <p>
- * Example:
- * <pre>
- * public interface Foo {
- * int bar(int a, int b);
- * }
- * ...
- * Foo f = (Foo) ExpressionEvaluator.createFastExpressionEvaluator(
- * "a + b", // expression to evaluate
- * Foo.class, // interface that describes the expression's signature
- * new String[] { "a", "b" }, // the parameters' names
- * (ClassLoader) null // Use current thread's context class loader
- * );
- * System.out.println("1 + 2 = " + f.bar(1, 2)); // Evaluate the expression
- * </pre>
- * Notice: The <code>interfaceToImplement</code> must either be declared <code>public</code>,
- * or with package scope in the root package (i.e. "no" package).
- * <p>
- * On my system (Intel P4, 2 GHz, MS Windows XP, JDK 1.4.1), expression "x + 1"
- * evaluates as follows:
- * <table>
- * <tr><td></td><th>Server JVM</th><th>Client JVM</th></td></tr>
- * <tr><td>Normal EE</td><td>23.7 ns</td><td>64.0 ns</td></tr>
- * <tr><td>Fast EE</td><td>31.2 ns</td><td>42.2 ns</td></tr>
- * </table>
- * (How can it be that interface method invocation is slower than reflection for
- * the server JVM?)
- * <p>
- * The expression may refer to a set of parameters with the given
- * <code>parameterNames</code> and <code>parameterTypes</code>.
- * <p>
- * <code>parameterNames</code> and <code>parameterTypes</code> must have the
- * same number of elements.
- * <p>
- * The parameters and/or the return value can be of primitive type, e.g.
- * {@link Double#TYPE}.
- * <p>
- * The <code>optionalClassLoader</code> serves two purposes:
- * <ul>
- * <li>It is used to look for classes referenced by the script.
- * <li>It is used to load the generated Java<sup>TM</sup> class
- * into the JVM; directly if it is a subclass of {@link
- * ByteArrayClassLoader}, or by creation of a temporary
- * {@link ByteArrayClassLoader} if not.
- * </ul>
- * If the <code>optionalClassLoader</code> is <code>null</code>, then the
- * current thread's context class loader is used.
- * <p>
- * A number of constructors exist that provide useful default values for
- * the various parameters, or parse their script from a {@link String}
- * instead of a {@link Scanner}. (You hardly want to use a scanner other than
- * the default scanner.)
- * <p>
- * If the type of the expression is not fixed, you can pass a <code>null</code>
- * <code>optionalExpressionType<code> argument; in this case, references are
- * returned as {@link Object}s, and primitive values are wrapped in their
- * wrapper classes.
- * <p>
- * If <code>optionalExpressionType</code> is {@link Void#TYPE}, then the
- * expression must be an invocation of a <code>void</code> method.
- */
-public class ExpressionEvaluator extends ScriptEvaluator {
- public static final Class ANY_TYPE = null;
-
- private Class[] optionalExpressionTypes = null;
-
- /**
- * Equivalent to<pre>
- * ExpressionEvaluator ee = new ExpressionEvaluator();
- * ee.setExpressionType(expressionType);
- * ee.setParameters(parameterNames, parameterTypes);
- * ee.cook(expression);</pre>
- *
- * @see #ExpressionEvaluator()
- * @see ExpressionEvaluator#setExpressionType(Class)
- * @see ScriptEvaluator#setParameters(String[], Class[])
- * @see Cookable#cook(String)
- */
- public ExpressionEvaluator(
- String expression,
- Class expressionType,
- String[] parameterNames,
- Class[] parameterTypes
- ) throws CompileException, Parser.ParseException, Scanner.ScanException {
- this.setExpressionType(expressionType);
- this.setParameters(parameterNames, parameterTypes);
- this.cook(expression);
- }
-
- /**
- * Equivalent to<pre>
- * ExpressionEvaluator ee = new ExpressionEvaluator();
- * ee.setExpressionType(expressionType);
- * ee.setParameters(parameterNames, parameterTypes);
- * ee.setThrownExceptions(thrownExceptions);
- * ee.setParentClassLoader(optionalParentClassLoader);
- * ee.cook(expression);</pre>
- *
- * @see #ExpressionEvaluator()
- * @see ExpressionEvaluator#setExpressionType(Class)
- * @see ScriptEvaluator#setParameters(String[], Class[])
- * @see ScriptEvaluator#setThrownExceptions(Class[])
- * @see SimpleCompiler#setParentClassLoader(ClassLoader)
- * @see Cookable#cook(String)
- */
- public ExpressionEvaluator(
- String expression,
- Class expressionType,
- String[] parameterNames,
- Class[] parameterTypes,
- Class[] thrownExceptions,
- ClassLoader optionalParentClassLoader
- ) throws CompileException, Parser.ParseException, Scanner.ScanException {
- this.setExpressionType(expressionType);
- this.setParameters(parameterNames, parameterTypes);
- this.setThrownExceptions(thrownExceptions);
- this.setParentClassLoader(optionalParentClassLoader);
- this.cook(expression);
- }
-
- /**
- * Equivalent to<pre>
- * ExpressionEvaluator ee = new ExpressionEvaluator();
- * ee.setExpressionType(expressionType);
- * ee.setParameters(parameterNames, parameterTypes);
- * ee.setThrownExceptions(thrownExceptions);
- * ee.setExtendedType(optionalExtendedType);
- * ee.setImplementedTypes(implementedTypes);
- * ee.setParentClassLoader(optionalParentClassLoader);
- * ee.cook(expression);</pre>
- *
- * @see #ExpressionEvaluator()
- * @see ExpressionEvaluator#setExpressionType(Class)
- * @see ScriptEvaluator#setParameters(String[], Class[])
- * @see ScriptEvaluator#setThrownExceptions(Class[])
- * @see ClassBodyEvaluator#setExtendedType(Class)
- * @see ClassBodyEvaluator#setImplementedTypes(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, Parser.ParseException, Scanner.ScanException {
- this.setExpressionType(expressionType);
- this.setParameters(parameterNames, parameterTypes);
- this.setThrownExceptions(thrownExceptions);
- this.setExtendedType(optionalExtendedType);
- this.setImplementedTypes(implementedTypes);
- this.setParentClassLoader(optionalParentClassLoader);
- this.cook(expression);
- }
-
- /**
- * Equivalent to<pre>
- * ExpressionEvaluator ee = new ExpressionEvaluator();
- * ee.setClassName(className);
- * ee.setExtendedType(optionalExtendedType);
- * ee.setImplementedTypes(implementedTypes);
- * ee.setStaticMethod(staticMethod);
- * ee.setExpressionType(expressionType);
- * ee.setMethodName(methodName);
- * ee.setParameters(parameterNames, parameterTypes);
- * ee.setThrownExceptions(thrownExceptions);
- * ee.setParentClassLoader(optionalParentClassLoader);
- * ee.cook(scanner);
- *
- * @see #ExpressionEvaluator()
- * @see ClassBodyEvaluator#setClassName(String)
- * @see ClassBodyEvaluator#setExtendedType(Class)
- * @see ClassBodyEvaluator#setImplementedTypes(Class[])
- * @see ScriptEvaluator#setStaticMethod(boolean)
- * @see ExpressionEvaluator#setExpressionType(Class)
- * @see ScriptEvaluator#setMethodName(String)
- * @see ScriptEvaluator#setParameters(String[], Class[])
- * @see ScriptEvaluator#setThrownExceptions(Class[])
- * @see SimpleCompiler#setParentClassLoader(ClassLoader)
- * @see Cookable#cook(Scanner)
- */
- public ExpressionEvaluator(
- Scanner scanner,
- String className,
- Class optionalExtendedType,
- Class[] implementedTypes,
- boolean staticMethod,
- Class expressionType,
- String methodName,
- String[] parameterNames,
- Class[] parameterTypes,
- Class[] thrownExceptions,
- ClassLoader optionalParentClassLoader
- ) throws Scanner.ScanException, Parser.ParseException, CompileException, IOException {
- this.setClassName(className);
- this.setExtendedType(optionalExtendedType);
- this.setImplementedTypes(implementedTypes);
- this.setStaticMethod(staticMethod);
- this.setExpressionType(expressionType);
- this.setMethodName(methodName);
- this.setParameters(parameterNames, parameterTypes);
- this.setThrownExceptions(thrownExceptions);
- this.setParentClassLoader(optionalParentClassLoader);
- this.cook(scanner);
- }
-
- public ExpressionEvaluator() {}
-
- /**
- * Define the type of the expression. The special type {@link #ANY_TYPE} allows the expression
- * to return any type (primitive or reference).
- * <p>
- * Defaults to {@link #ANY_TYPE}.
- */
- public void setExpressionType(Class expressionType) {
- this.setExpressionTypes(new Class[] { expressionType });
- }
-
- public void setExpressionTypes(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);
- }
-
- protected Class getDefaultReturnType() {
- return Object.class;
- }
-
- protected Java.Block makeBlock(int idx, Scanner scanner) throws ParseException, ScanException, IOException {
- Java.Block block = new Java.Block(scanner.location());
-
- Parser parser = new Parser(scanner);
-
- // Parse the expression.
- Rvalue value = parser.parseExpression().toRvalueOrPE();
-
- Class et = this.optionalExpressionTypes == null ? ANY_TYPE : this.optionalExpressionTypes[idx];
- if (et == void.class) {
-
- // ExpressionEvaluator with an expression type "void" is a simple expression statement.
- block.addStatement(new Java.ExpressionStatement(value));
- } else {
-
- // Special case: Expression type "ANY_TYPE" means return type "Object" and automatic
- // wrapping of primitive types.
- if (et == ANY_TYPE) {
- value = new Java.MethodInvocation(
- scanner.location(), // location
- new Java.ReferenceType( // optionalTarget
- scanner.location(), // location
- new String[] { "org", "codehaus", "janino", "util", "PrimitiveWrapper" } // identifiers
- ),
- "wrap", // methodName
- new Java.Rvalue[] { value } // arguments
- );
-
- // Make sure "PrimitiveWrapper" is compiled.
- PrimitiveWrapper.wrap(99);
-
- // Add "PrimitiveWrapper" as an auxiliary class.
- this.classToType(null, PrimitiveWrapper.class);
- }
-
- // Add a return statement.
- block.addStatement(new Java.ReturnStatement(scanner.location(), value));
- }
- if (!scanner.peek().isEOF()) throw new Parser.ParseException("Unexpected token \"" + scanner.peek() + "\"", scanner.location());
-
- return block;
- }
-
- /**
- * Creates a "fast expression evaluator" from the given {@link java.lang.String}
- * <code>expression</code>, generating a class with the {@link #DEFAULT_CLASS_NAME} that
- * extends {@link Object}.
- * <p>
- * See the class description for an explanation of the "fast expression evaluator" concept.
- *
- * @see #createFastExpressionEvaluator(Scanner, String[], String, Class, Class, String[], ClassLoader)
- * @see ExpressionEvaluator
- */
- public static Object createFastExpressionEvaluator(
- String expression,
- Class interfaceToImplement,
- String[] parameterNames,
- ClassLoader optionalParentClassLoader
- ) throws CompileException, Parser.ParseException, Scanner.ScanException {
- ExpressionEvaluator ee = new ExpressionEvaluator();
- ee.setParentClassLoader(optionalParentClassLoader);
- return ScriptEvaluator.createFastEvaluator(ee, expression, parameterNames, interfaceToImplement);
- }
-
- /**
- * Creates a "fast expression evaluator" from the given {@link Scanner} with no default
- * imports.
- * <p>
- * See the class description for an explanation of the "fast expression evaluator" concept.
- *
- * @see #createFastExpressionEvaluator(Scanner, String[], String, Class, Class, String[], ClassLoader)
- * @see ExpressionEvaluator
- */
- public static Object createFastExpressionEvaluator(
- Scanner scanner,
- String className,
- Class optionalExtendedType,
- Class interfaceToImplement,
- String[] parameterNames,
- ClassLoader optionalParentClassLoader
- ) throws CompileException, Parser.ParseException, Scanner.ScanException, IOException {
- ExpressionEvaluator ee = new ExpressionEvaluator();
- ee.setClassName(className);
- ee.setExtendedType(optionalExtendedType);
- ee.setParentClassLoader(optionalParentClassLoader);
- return ScriptEvaluator.createFastEvaluator(ee, scanner, parameterNames, interfaceToImplement);
- }
-
- /**
- * Creates a "fast expression evaluator".
- * <p>
- * See the class description for an explanation of the "fast expression evaluator" concept.
- * <p>
- * Notice: The <code>interfaceToImplement</code> must either be declared <code>public</code>,
- * or with package scope in the same package as <code>className</code>.
- *
- * @param scanner Source of expression tokens
- * @param optionalDefaultImports Default imports, e.g. <code>{ "java.util.Map", "java.io.*" }</code>
- * @param className Name of generated class
- * @param optionalExtendedType Class to extend
- * @param interfaceToImplement Must declare exactly the one method that defines the expression's signature
- * @param parameterNames The expression references the parameters through these names
- * @param optionalParentClassLoader Used to load referenced classes, defaults to the current thread's "context class loader"
- * @return an object that implements the given interface and extends the <code>optionalExtendedType</code>
- * @see ExpressionEvaluator
- */
- public static Object createFastExpressionEvaluator(
- Scanner scanner,
- String[] optionalDefaultImports,
- String className,
- Class optionalExtendedType,
- Class interfaceToImplement,
- String[] parameterNames,
- ClassLoader optionalParentClassLoader
- ) throws CompileException, Parser.ParseException, Scanner.ScanException, IOException {
- ExpressionEvaluator ee = new ExpressionEvaluator();
- ee.setClassName(className);
- ee.setExtendedType(optionalExtendedType);
- ee.setDefaultImports(optionalDefaultImports);
- ee.setParentClassLoader(optionalParentClassLoader);
- return ScriptEvaluator.createFastEvaluator(ee, scanner, parameterNames, interfaceToImplement);
- }
-
- /**
- * Guess the names of the parameters used in the given expression. The strategy is to look
- * at all "ambiguous names" in the expression (e.g. in "a.b.c.d()", the ambiguous name
- * is "a.b.c"), and then at the first components of the ambiguous name.
- * <ul>
- * <li>If any component starts with an upper-case letter, then ambiguous name is assumed to
- * be a type name.
- * <li>Otherwise, it is assumed to be a parameter name.
- * </ul>
- *
- * @see Scanner#Scanner(String, Reader)
- */
- public static String[] guessParameterNames(Scanner scanner) throws ParseException, ScanException, IOException {
- Parser parser = new Parser(scanner);
-
- // Eat optional leading import declarations.
- while (scanner.peek().isKeyword("import")) parser.parseImportDeclaration();
-
- // Parse the expression.
- Rvalue rvalue = parser.parseExpression().toRvalueOrPE();
- if (!scanner.peek().isEOF()) throw new Parser.ParseException("Unexpected token \"" + scanner.peek() + "\"", scanner.location());
-
- // Traverse the expression for ambiguous names and guess which of them are parameter names.
- final Set parameterNames = new HashSet();
- rvalue.accept((RvalueVisitor) new Traverser() {
- public void traverseAmbiguousName(AmbiguousName an) {
-
- // If any of the components starts with an upper-case letter, then the ambiguous
- // name is most probably a type name, e.g. "System.out" or "java.lang.System.out".
- for (int i = 0; i < an.identifiers.length; ++i) {
- if (Character.isUpperCase(an.identifiers[i].charAt(0))) return;
- }
-
- // It's most probably a parameter name (although it could be a field name as well).
- parameterNames.add(an.identifiers[0]);
- }
- }.comprehensiveVisitor());
-
- return (String[]) parameterNames.toArray(new String[parameterNames.size()]);
- }
-}
diff --git a/src/org/codehaus/janino/FilterWarningHandler.java b/src/org/codehaus/janino/FilterWarningHandler.java
deleted file mode 100644
index 0ec6d3c..0000000
--- a/src/org/codehaus/janino/FilterWarningHandler.java
+++ /dev/null
@@ -1,57 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino;
-
-import org.codehaus.janino.util.StringPattern;
-
-public class FilterWarningHandler implements WarningHandler {
- private final StringPattern[] handlePatterns;
- private final WarningHandler delegate;
-
- /**
- * Popular values for the <code>handlePatterns</code> parameter are
- * {@link StringPattern#PATTERNS_ALL} and {@link StringPattern#PATTERNS_NONE}.
- */
- public FilterWarningHandler(StringPattern[] handlePatterns, WarningHandler delegate) {
- this.handlePatterns = handlePatterns;
- this.delegate = delegate;
- }
-
- public void handleWarning(String handle, String message, Location optionalLocation) {
- if (StringPattern.matches(this.handlePatterns, handle)) {
- this.delegate.handleWarning(handle, message, optionalLocation);
- }
- }
-}
diff --git a/src/org/codehaus/janino/IClass.java b/src/org/codehaus/janino/IClass.java
deleted file mode 100644
index 9bfbd2f..0000000
--- a/src/org/codehaus/janino/IClass.java
+++ /dev/null
@@ -1,819 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino;
-
-import java.util.*;
-
-/**
- * A simplified equivalent to "java.lang.reflect".
- */
-public abstract class IClass {
- private static final boolean DEBUG = false;
-
- public static final IClass VOID = new PrimitiveIClass(Descriptor.VOID_);
- public static final IClass BYTE = new PrimitiveIClass(Descriptor.BYTE_);
- public static final IClass CHAR = new PrimitiveIClass(Descriptor.CHAR_);
- public static final IClass DOUBLE = new PrimitiveIClass(Descriptor.DOUBLE_);
- public static final IClass FLOAT = new PrimitiveIClass(Descriptor.FLOAT_);
- public static final IClass INT = new PrimitiveIClass(Descriptor.INT_);
- public static final IClass LONG = new PrimitiveIClass(Descriptor.LONG_);
- public static final IClass SHORT = new PrimitiveIClass(Descriptor.SHORT_);
- public static final IClass BOOLEAN = new PrimitiveIClass(Descriptor.BOOLEAN_);
-
- private static class PrimitiveIClass extends IClass {
- private final String fieldDescriptor;
-
- public PrimitiveIClass(String fieldDescriptor) {
- this.fieldDescriptor = fieldDescriptor;
- }
- protected IClass getComponentType2() { return null; }
- protected IClass[] getDeclaredIClasses2() { return new IClass[0]; }
- protected IConstructor[] getDeclaredIConstructors2() { return new IConstructor[0]; }
- protected IField[] getDeclaredIFields2() { return new IField[0]; }
- protected IMethod[] getDeclaredIMethods2() { return new IMethod[0]; }
- protected IClass getDeclaringIClass2() { return null; }
- protected String getDescriptor2() { return this.fieldDescriptor; }
- protected IClass[] getInterfaces2() { return new IClass[0]; }
- protected IClass getOuterIClass2() { return null; }
- protected IClass getSuperclass2() { return null; }
- public boolean isAbstract() { return false; }
- public boolean isArray() { return false; }
- public boolean isFinal() { return true; }
- public boolean isInterface() { return false; }
- public boolean isPrimitive() { return true; }
- public boolean isPrimitiveNumeric() { return Descriptor.isPrimitiveNumeric(this.fieldDescriptor); }
- public Access getAccess() { return Access.PUBLIC; }
- }
-
- /**
- * Returns all the constructors declared by the class represented by the
- * type. If the class has a default constructor, it is included.
- * <p>
- * Returns an array with zero elements for an interface, array, primitive type or
- * "void".
- */
- public final IConstructor[] getDeclaredIConstructors() {
- if (this.declaredIConstructors == null) {
- this.declaredIConstructors = this.getDeclaredIConstructors2();
- }
- return this.declaredIConstructors;
- }
- private IConstructor[] declaredIConstructors = null;
- protected abstract IConstructor[] getDeclaredIConstructors2();
-
- /**
- * Returns the methods of the class or interface (but not inherited
- * methods).<br>
- * Returns an empty array for an array, primitive type or "void".
- */
- public final IMethod[] getDeclaredIMethods() {
- if (this.declaredIMethods == null) {
- this.declaredIMethods = this.getDeclaredIMethods2();
- }
- return this.declaredIMethods;
- }
- protected IMethod[] declaredIMethods = null;
- protected abstract IMethod[] getDeclaredIMethods2();
-
- /**
- * Returns all methods with the given name declared in the class or
- * interface (but not inherited methods).<br>
- * Returns an empty array if no methods with that name are declared.
- *
- * @return an array of {@link IMethod}s that must not be modified
- */
- public final IMethod[] getDeclaredIMethods(String methodName) {
- if (this.declaredIMethodCache == null) {
- Map m = new HashMap();
-
- // Fill the map with "IMethod"s and "List"s.
- IMethod[] dims = this.getDeclaredIMethods();
- for (int i = 0; i < dims.length; i++) {
- IMethod dim = dims[i];
- String mn = dim.getName();
- Object o = m.get(mn);
- if (o == null) {
- m.put(mn, dim);
- } else
- if (o instanceof IMethod) {
- List l = new ArrayList();
- l.add(o);
- l.add(dim);
- m.put(mn, l);
- } else {
- ((List) o).add(dim);
- }
- }
-
- // Convert "IMethod"s and "List"s to "IMethod[]"s.
- for (Iterator it = m.entrySet().iterator(); it.hasNext();) {
- Map.Entry me = (Map.Entry) it.next();
- Object v = me.getValue();
- if (v instanceof IMethod) {
- me.setValue(new IMethod[] { (IMethod) v });
- } else {
- List l = (List) v;
- me.setValue(l.toArray(new IMethod[l.size()]));
- }
- }
- this.declaredIMethodCache = m;
- }
-
- IMethod[] methods = (IMethod[]) this.declaredIMethodCache.get(methodName);
- return methods == null ? IClass.NO_IMETHODS : methods;
- }
- /*package*/ Map declaredIMethodCache = null; // String methodName => IMethod[]
-
- /**
- * Returns all methods declared in the class or interface, its superclasses and its
- * superinterfaces.<br>
- * For overridden methods, only the last non-abstract implementation is returned.
- *
- * @return an array of {@link IMethod}s that must not be modified
- */
- public final IMethod[] getIMethods() throws CompileException {
- if (this.iMethodCache == null) {
- Map m = new HashMap();
- this.getIMethods(m);
- Collection iMethods = m.values();
- this.iMethodCache = (IMethod[]) iMethods.toArray(new IMethod[iMethods.size()]);
- }
- return this.iMethodCache;
- }
- /*package*/ IMethod[] iMethodCache = null;
- private void getIMethods(Map result) throws CompileException {
- IMethod[] ms = this.getDeclaredIMethods();
- for (int i = 0; i < ms.length; ++i) {
- IMethod m = ms[i];
- String key = m.getName() + m.getDescriptor();
- IMethod m2 = (IMethod) result.get(key);
- if (m2 == null || m2.isAbstract()) result.put(key, m);
- }
- {
- IClass sc = this.getSuperclass();
- if (sc != null) sc.getIMethods(result);
- }
- {
- IClass[] iis = this.getInterfaces();
- for (int i = 0; i < iis.length; ++i) iis[i].getIMethods(result);
- }
- }
-
- public static final IMethod[] NO_IMETHODS = new IMethod[0];
-
- public final boolean hasIMethod(String methodName, IClass[] parameterTypes) throws CompileException {
- IMethod[] ims = this.getDeclaredIMethods(methodName);
- for (int i = 0; i < ims.length; ++i) {
- IClass[] pts = ims[i].getParameterTypes();
- if (Arrays.equals(pts, parameterTypes)) return true;
- }
- return false;
- }
-
- /**
- * Returns the fields of a class or interface (but not inherited
- * fields).<br>
- * Returns an empty array for an array, primitive type or "void".
- */
- public final IField[] getDeclaredIFields() {
- if (this.declaredIFields == null) {
- this.declaredIFields = this.getDeclaredIFields2();
- }
- return this.declaredIFields;
- }
- public final IField getDeclaredIField(String name) {
- if(this.declaredIFieldsCache == null) {
- IField[] fields = getDeclaredIFields();
- Map m = new HashMap();
- for(int i = 0; i < fields.length; ++i) {
- m.put(fields[i].getName(), fields[i]);
- }
- this.declaredIFieldsCache = m;
- }
- return (IField) this.declaredIFieldsCache.get(name);
- }
-
- protected void clearIFieldCaches() {
- this.declaredIFields = null;
- this.declaredIFieldsCache = null;
- }
-
- private Map declaredIFieldsCache = null; // String name => IField
- private IField[] declaredIFields = null;
- protected abstract IField[] getDeclaredIFields2();
-
- /**
- * Returns the synthetic fields of an anonymous or local class, in
- * the order in which they are passed to all constructors.
- */
- public IField[] getSyntheticIFields() {
- return new IField[0];
- }
-
- /**
- * Returns the classes and interfaces declared as members of the class
- * (but not inherited classes and interfaces).<br>
- * Returns an empty array for an array, primitive type or "void".
- */
- public final IClass[] getDeclaredIClasses() throws CompileException {
- if (this.declaredIClasses == null) {
- this.declaredIClasses = this.getDeclaredIClasses2();
- }
- return this.declaredIClasses;
- }
- private IClass[] declaredIClasses = null;
- protected abstract IClass[] getDeclaredIClasses2() throws CompileException;
-
- /**
- * If this class is a member class, return the declaring class, otherwise return
- * <code>null</code>.
- */
- public final IClass getDeclaringIClass() throws CompileException {
- if (!this.declaringIClassIsCached) {
- this.declaringIClass = this.getDeclaringIClass2();
- this.declaringIClassIsCached = true;
- }
- return this.declaringIClass;
- }
- private boolean declaringIClassIsCached = false;
- private IClass declaringIClass = null;
- protected abstract IClass getDeclaringIClass2() throws CompileException;
-
- /**
- * The following types have an "outer class":
- * <ul>
- * <li>Anonymous classes declared in a non-static method of a class
- * <li>Local classes declared in a non-static method of a class
- * <li>Non-static member classes
- * </ul>
- */
- public final IClass getOuterIClass() throws CompileException {
- if (!this.outerIClassIsCached) {
- this.outerIClass = this.getOuterIClass2();
- this.outerIClassIsCached = true;
- }
- return this.outerIClass;
- }
- private boolean outerIClassIsCached = false;
- private IClass outerIClass = null;
- protected abstract IClass getOuterIClass2() throws CompileException;
-
- /**
- * Returns the superclass of the class.<br>
- * Returns "null" for class "Object", interfaces, arrays, primitive types
- * and "void".
- */
- public final IClass getSuperclass() throws CompileException {
- if (!this.superclassIsCached) {
- this.superclass = this.getSuperclass2();
- this.superclassIsCached = true;
- if (this.superclass != null && this.superclass.isSubclassOf(this)) throw new CompileException("Class circularity detected for \"" + Descriptor.toClassName(this.getDescriptor()) + "\"", null);
- }
- return this.superclass;
- }
- private boolean superclassIsCached = false;
- private IClass superclass = null;
- protected abstract IClass getSuperclass2() throws CompileException;
-
- public abstract Access getAccess();
-
- /**
- * Whether subclassing is allowed (JVMS 4.1 access_flags)
- * @return <code>true</code> if subclassing is prohibited
- */
- public abstract boolean isFinal();
-
- /**
- * Returns the interfaces implemented by the class.<br>
- * Returns the superinterfaces of the interface.<br>
- * Returns "Cloneable" and "Serializable" for arrays.<br>
- * Returns an empty array for primitive types and "void".
- */
- public final IClass[] getInterfaces() throws CompileException {
- if (this.interfaces == null) {
- this.interfaces = this.getInterfaces2();
- for (int i = 0; i < this.interfaces.length; ++i) {
- if (this.interfaces[i].implementsInterface(this)) throw new CompileException("Interface circularity detected for \"" + Descriptor.toClassName(this.getDescriptor()) + "\"", null);
- }
- }
- return this.interfaces;
- }
- private IClass[] interfaces = null;
- protected abstract IClass[] getInterfaces2() throws CompileException;
-
- /**
- * Whether the class may be instantiated (JVMS 4.1 access_flags)
- * @return <code>true</code> if instantiation is prohibited
- */
- public abstract boolean isAbstract();
-
- /**
- * Returns the field descriptor for the type as defined by JVMS 4.3.2.
- */
- public final String getDescriptor() {
- if (this.descriptor == null) {
- this.descriptor = this.getDescriptor2();
- }
- return this.descriptor;
- }
- private String descriptor = null;
- protected abstract String getDescriptor2();
-
- /**
- * Convenience method that determines the field descriptors of an array of {@link IClass}es.
- * @see #getDescriptor()
- */
- public static String[] getDescriptors(IClass[] iClasses) {
- String[] descriptors = new String[iClasses.length];
- for (int i = 0; i < iClasses.length; ++i) descriptors[i] = iClasses[i].getDescriptor();
- return descriptors;
- }
-
- /**
- * Returns "true" if this type represents an interface.
- */
- public abstract boolean isInterface();
-
- /**
- * Returns "true" if this type represents an array.
- */
- public abstract boolean isArray();
-
- /**
- * Returns "true" if this type represents a primitive type or "void".
- */
- public abstract boolean isPrimitive();
-
- /**
- * Returns "true" if this type represents "byte", "short", "int", "long",
- * "char", "float" or "double".
- */
- public abstract boolean isPrimitiveNumeric();
-
- /**
- * Returns the component type of the array.<br>
- * Returns "null" for classes, interfaces, primitive types and "void".
- */
- public final IClass getComponentType() {
- if (!this.componentTypeIsCached) {
- this.componentType = this.getComponentType2();
- this.componentTypeIsCached = true;
- }
- return this.componentType;
- }
- private boolean componentTypeIsCached = false;
- private IClass componentType = null;
- protected abstract IClass getComponentType2();
-
- /**
- * Returns a string representation for this object.
- */
- public String toString() { return Descriptor.toClassName(this.getDescriptor()); }
-
- /**
- * Determine if "this" is assignable from "that". This is true if "this"
- * is identical with "that" (JLS2 5.1.1), or if "that" is
- * widening-primitive-convertible to "this" (JLS2 5.1.2), or if "that" is
- * widening-reference-convertible to "this" (JLS2 5.1.4).
- */
- public boolean isAssignableFrom(IClass that) throws CompileException {
-
- // Identity conversion, JLS2 5.1.1
- if (this == that) return true;
-
- // Widening primitive conversion, JLS2 5.1.2
- {
- String ds = that.getDescriptor() + this.getDescriptor();
- if (ds.length() == 2 && IClass.PRIMITIVE_WIDENING_CONVERSIONS.contains(ds)) return true;
- }
-
- // Widening reference conversion, JLS2 5.1.4
- {
-
- // JLS 5.1.4.1: Target type is superclass of source class type.
- if (that.isSubclassOf(this)) return true;
-
- // JLS 5.1.4.2: Source class type implements target interface type.
- // JLS 5.1.4.4: Source interface type implements target interface type.
- if (that.implementsInterface(this)) return true;
-
- // JLS 5.1.4.3 Convert "null" literal to any reference type.
- if (that == IClass.VOID && !this.isPrimitive()) return true;
-
- // JLS 5.1.4.5: From any interface to type "Object".
- if (that.isInterface() && this.getDescriptor().equals(Descriptor.OBJECT)) return true;
-
- if (that.isArray()) {
-
- // JLS 5.1.4.6: From any array type to type "Object".
- if (this.getDescriptor().equals(Descriptor.OBJECT)) return true;
-
- // JLS 5.1.4.7: From any array type to type "Cloneable".
- if (this.getDescriptor().equals(Descriptor.CLONEABLE)) return true;
-
- // JLS 5.1.4.8: From any array type to type "java.io.Serializable".
- if (this.getDescriptor().equals(Descriptor.SERIALIZABLE)) return true;
-
- // JLS 5.1.4.9: From SC[] to TC[] while SC if widening reference convertible to TC.
- if (this.isArray()) {
- IClass thisCT = this.getComponentType();
- IClass thatCT = that.getComponentType();
- if (!thisCT.isPrimitive() && thisCT.isAssignableFrom(thatCT)) return true;
- }
- }
- }
- return false;
- }
-
- private static final Set PRIMITIVE_WIDENING_CONVERSIONS = new HashSet();
- static {
- String[] pwcs = new String[] {
- Descriptor.BYTE_ + Descriptor.SHORT_,
-
- Descriptor.BYTE_ + Descriptor.INT_,
- Descriptor.SHORT_ + Descriptor.INT_,
- Descriptor.CHAR_ + Descriptor.INT_,
-
- Descriptor.BYTE_ + Descriptor.LONG_,
- Descriptor.SHORT_ + Descriptor.LONG_,
- Descriptor.CHAR_ + Descriptor.LONG_,
- Descriptor.INT_ + Descriptor.LONG_,
-
- Descriptor.BYTE_ + Descriptor.FLOAT_,
- Descriptor.SHORT_ + Descriptor.FLOAT_,
- Descriptor.CHAR_ + Descriptor.FLOAT_,
- Descriptor.INT_ + Descriptor.FLOAT_,
-
- Descriptor.LONG_ + Descriptor.FLOAT_,
-
- Descriptor.BYTE_ + Descriptor.DOUBLE_,
- Descriptor.SHORT_ + Descriptor.DOUBLE_,
- Descriptor.CHAR_ + Descriptor.DOUBLE_,
- Descriptor.INT_ + Descriptor.DOUBLE_,
-
- Descriptor.LONG_ + Descriptor.DOUBLE_,
-
- Descriptor.FLOAT_ + Descriptor.DOUBLE_,
- };
- for (int i = 0; i < pwcs.length; ++i) IClass.PRIMITIVE_WIDENING_CONVERSIONS.add(pwcs[i]);
- }
-
- /**
- * Returns <code>true</code> if this class is an immediate or non-immediate
- * subclass of <code>that</code> class.
- */
- public boolean isSubclassOf(IClass that) throws CompileException {
- for (IClass sc = this.getSuperclass(); sc != null; sc = sc.getSuperclass()) {
- if (sc == that) return true;
- }
- return false;
- }
-
- /**
- * If <code>this</code> represents a class: Return <code>true</code> if this class
- * directly or indirectly implements <code>that</code> interface.
- * <p>
- * If <code>this</code> represents an interface: Return <code>true</code> if this
- * interface directly or indirectly extends <code>that</code> interface.
- */
- public boolean implementsInterface(IClass that) throws CompileException {
- for (IClass c = this; c != null; c = c.getSuperclass()) {
- IClass[] tis = c.getInterfaces();
- for (int i = 0; i < tis.length; ++i) {
- IClass ti = tis[i];
- if (ti == that || ti.implementsInterface(that)) return true;
- }
- }
- return false;
- }
-
- /**
- * Get an {@link IClass} that represents an n-dimensional array of this type.
- *
- * @param n dimension count
- * @param objectType Required because the superclass of an array class is {@link Object} by definition
- */
- public IClass getArrayIClass(int n, IClass objectType) {
- IClass result = this;
- for (int i = 0; i < n; ++i) result = result.getArrayIClass(objectType);
- return result;
- }
-
- /**
- * Get an {@link IClass} that represents an array of this type.
- *
- * @param objectType Required because the superclass of an array class is {@link Object} by definition
- */
- public IClass getArrayIClass(IClass objectType) {
- if (this.arrayIClass == null) this.arrayIClass = this.getArrayIClass2(objectType);
- return this.arrayIClass;
- }
- private IClass arrayIClass = null;
-
- private IClass getArrayIClass2(final IClass objectType) {
- final IClass componentType = this;
- return new IClass() {
- public IClass.IConstructor[] getDeclaredIConstructors2() { return new IClass.IConstructor[0]; }
-
- // Special trickery #17: Arrays override "Object.clone()", but without "throws
- // CloneNotSupportedException"!
- public IClass.IMethod[] getDeclaredIMethods2() {
- return new IClass.IMethod[] {
- new IMethod() {
- public String getName() { return "clone"; }
- public IClass getReturnType() { return objectType /*ot*/; }
- public boolean isAbstract() { return false; }
- public boolean isStatic() { return false; }
- public Access getAccess() { return Access.PUBLIC; }
- public IClass[] getParameterTypes() { return new IClass[0]; }
- public IClass[] getThrownExceptions() { return new IClass[0]; }
- }
- };
- }
- public IClass.IField[] getDeclaredIFields2() { return new IClass.IField[0]; }
- public IClass[] getDeclaredIClasses2() { return new IClass[0]; }
- public IClass getDeclaringIClass2() { return null; }
- public IClass getOuterIClass2() { return null; }
- public IClass getSuperclass2() { return objectType; }
- public IClass[] getInterfaces2() { return new IClass[0]; }
- public String getDescriptor2() { return '[' + componentType.getDescriptor(); }
- public Access getAccess() { return componentType.getAccess(); }
- public boolean isFinal() { return true; }
- public boolean isInterface() { return false; }
- public boolean isAbstract() { return false; }
- public boolean isArray() { return true; }
- public boolean isPrimitive() { return false; }
- public boolean isPrimitiveNumeric() { return false; }
- public IClass getComponentType2() { return componentType; }
-
- public String toString() { return componentType.toString() + "[]"; }
- };
- }
-
- /**
- * If <code>optionalName</code> is <code>null</code>, find all {@link IClass}es visible in the
- * scope of the current class.
- * <p>
- * If <code>optionalName</code> is not <code>null</code>, find the member {@link IClass}es
- * that has the given name. If the name is ambiguous (i.e. if more than one superclass,
- * interface of enclosing type declares a type with that name), then the size of the
- * returned array is greater than one.
- * <p>
- * Examines superclasses, interfaces and enclosing type declarations.
- * @return an array of {@link IClass}es in unspecified order, possibly of length zero
- */
- IClass[] findMemberType(String optionalName) throws CompileException {
- IClass[] res = (IClass[]) this.memberTypeCache.get(optionalName);
- if (res == null) {
-
- // Notice: A type may be added multiply to the result set because we are in its scope
- // multiply. E.g. the type is a member of a superclass AND a member of an enclosing type.
- Set s = new HashSet(); // IClass
- this.findMemberType(optionalName, s);
- res = s.isEmpty() ? IClass.ZERO_ICLASSES : (IClass[]) s.toArray(new IClass[s.size()]);
-
- this.memberTypeCache.put(optionalName, res);
- }
-
- return res;
- }
- private final Map memberTypeCache = new HashMap(); // String name => IClass[]
- private static final IClass[] ZERO_ICLASSES = new IClass[0];
- private void findMemberType(String optionalName, Collection result) throws CompileException {
-
- // Search for a type with the given name in the current class.
- IClass[] memberTypes = this.getDeclaredIClasses();
- if (optionalName == null) {
- result.addAll(Arrays.asList(memberTypes));
- } else {
- String memberDescriptor = Descriptor.fromClassName(Descriptor.toClassName(this.getDescriptor()) + '$' + optionalName);
- for (int i = 0; i < memberTypes.length; ++i) {
- final IClass mt = memberTypes[i];
- if (mt.getDescriptor().equals(memberDescriptor)) {
- result.add(mt);
- return;
- }
- }
- }
-
- // Examine superclass.
- {
- IClass superclass = this.getSuperclass();
- if (superclass != null) superclass.findMemberType(optionalName, result);
- }
-
- // Examine interfaces.
- {
- IClass[] ifs = this.getInterfaces();
- for (int i = 0; i < ifs.length; ++i) ifs[i].findMemberType(optionalName, result);
- }
-
- // Examine enclosing type declarations.
- {
- IClass declaringIClass = this.getDeclaringIClass();
- IClass outerIClass = this.getOuterIClass();
- if (declaringIClass != null) {
- declaringIClass.findMemberType(optionalName, result);
- }
- if (outerIClass != null && outerIClass != declaringIClass) {
- outerIClass.findMemberType(optionalName, result);
- }
- }
- }
-
- public interface IMember {
-
- /**
- * @return One of {@link Access#PRIVATE}, {@link Access#PROTECTED},
- * {@link Access#DEFAULT} and {@link Access#PUBLIC}.
- */
- Access getAccess();
-
- /**
- * Returns the {@link IClass} that declares this {@link IClass.IMember}.
- */
- IClass getDeclaringIClass();
- }
-
- public abstract class IInvocable implements IMember {
-
- // Implement IMember.
- public abstract Access getAccess();
- public IClass getDeclaringIClass() { return IClass.this; }
- public abstract IClass[] getParameterTypes() throws CompileException;
- public abstract String getDescriptor() throws CompileException;
- public abstract IClass[] getThrownExceptions() throws CompileException;
-
- public boolean isMoreSpecificThan(IInvocable that) throws CompileException {
- if (IClass.DEBUG) System.out.print("\"" + this + "\".isMoreSpecificThan(\"" + that + "\") => ");
-
- // 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 JLS2Tests / 15.12.2.2
- if (false) {
- if (!that.getDeclaringIClass().isAssignableFrom(this.getDeclaringIClass())) {
- if (IClass.DEBUG) System.out.println("falsE");
- return false;
- }
- }
-
- IClass[] thisParameterTypes = this.getParameterTypes();
- IClass[] thatParameterTypes = that.getParameterTypes();
- int i;
- for (i = 0; i < thisParameterTypes.length; ++i) {
- if (!thatParameterTypes[i].isAssignableFrom(thisParameterTypes[i])) {
- if (IClass.DEBUG) System.out.println("false");
- return false;
- }
- }
- if (IClass.DEBUG) System.out.println("true");
- return !Arrays.equals(thisParameterTypes, thatParameterTypes);
- }
- public boolean isLessSpecificThan(IInvocable that) throws CompileException {
- return that.isMoreSpecificThan(this);
- }
- public abstract String toString();
- }
- public abstract class IConstructor extends IInvocable {
-
- /**
- * Opposed to {@link java.lang.reflect.Constructor#getParameterTypes()}, the
- * return value of this method does not include the optionally leading "synthetic
- * parameters".
- */
- public abstract IClass[] getParameterTypes() throws CompileException;
-
- /**
- * Opposed to {@link #getParameterTypes()}, the method descriptor returned by this
- * method does include the optionally leading synthetic parameters.
- */
- public String getDescriptor() throws CompileException {
- IClass[] parameterTypes = this.getParameterTypes();
-
- IClass outerIClass = IClass.this.getOuterIClass();
- if (outerIClass != null) {
- IClass[] tmp = new IClass[parameterTypes.length + 1];
- tmp[0] = outerIClass;
- System.arraycopy(parameterTypes, 0, tmp, 1, parameterTypes.length);
- parameterTypes = tmp;
- }
-
- return new MethodDescriptor(IClass.getDescriptors(parameterTypes), Descriptor.VOID_).toString();
- }
- public String toString() {
- StringBuffer sb = new StringBuffer(this.getDeclaringIClass().toString());
- sb.append('(');
- try {
- IClass[] parameterTypes = this.getParameterTypes();
- for (int i = 0; i < parameterTypes.length; ++i) {
- if (i > 0) sb.append(", ");
- sb.append(parameterTypes[i].toString());
- }
- } catch (CompileException ex) {
- sb.append("<invalid type>");
- }
- sb.append(')');
- return sb.toString();
- }
- }
- public abstract class IMethod extends IInvocable {
- public abstract boolean isStatic();
- public abstract boolean isAbstract();
- public abstract IClass getReturnType() throws CompileException;
- public abstract String getName();
- public String getDescriptor() throws CompileException {
- return new MethodDescriptor(
- IClass.getDescriptors(this.getParameterTypes()),
- this.getReturnType().getDescriptor()
- ).toString();
- }
- public String toString() {
- StringBuffer sb = new StringBuffer();
- try {
- sb.append(this.getReturnType().toString());
- } catch (CompileException ex) {
- sb.append("<invalid type>");
- }
- sb.append(' ');
- sb.append(this.getDeclaringIClass().toString());
- sb.append('.');
- sb.append(this.getName());
- sb.append('(');
- try {
- IClass[] parameterTypes = this.getParameterTypes();
- for (int i = 0; i < parameterTypes.length; ++i) {
- if (i > 0) sb.append(", ");
- sb.append(parameterTypes[i].toString());
- }
- } catch (CompileException ex) {
- sb.append("<invalid type>");
- }
- sb.append(')');
- try {
- IClass[] tes = this.getThrownExceptions();
- if (tes.length > 0) {
- sb.append(" throws ").append(tes[0]);
- for (int i = 1; i < tes.length; ++i) sb.append(", ").append(tes[i]);
- }
- } catch (CompileException ex) {
- sb.append("<invalid thrown exception type>");
- }
- return sb.toString();
- }
- }
- public abstract class IField implements IMember {
-
- // Implement IMember.
- public abstract Access getAccess();
- public IClass getDeclaringIClass() { return IClass.this; }
-
- public abstract boolean isStatic();
- public abstract IClass getType() throws CompileException;
- public abstract String getName();
- public String getDescriptor() throws CompileException { return this.getType().getDescriptor(); }
-
- /**
- * Returns the value of the field if it is a compile-time constant
- * value, i.e. the field is FINAL and its initializer is a constant
- * expression (JLS2 15.28, bullet 12).
- */
- public abstract Object getConstantValue() throws CompileException;
- public String toString() { return this.getDeclaringIClass().toString() + "." + this.getName(); }
- }
-}
diff --git a/src/org/codehaus/janino/IClassLoader.java b/src/org/codehaus/janino/IClassLoader.java
deleted file mode 100644
index 9f7df5e..0000000
--- a/src/org/codehaus/janino/IClassLoader.java
+++ /dev/null
@@ -1,227 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino;
-
-import java.util.*;
-
-/**
- * Loads an {@link IClass} by type name.
- */
-public abstract class IClassLoader {
- private static final boolean DEBUG = false;
-
- public IClass OBJECT;
- public IClass STRING;
- public IClass CLASS;
- public IClass THROWABLE;
- public IClass RUNTIME_EXCEPTION;
- public IClass ERROR;
- public IClass CLONEABLE;
- public IClass SERIALIZABLE;
- public IClass BOOLEAN;
- public IClass BYTE;
- public IClass CHARACTER;
- public IClass SHORT;
- public IClass INTEGER;
- public IClass LONG;
- public IClass FLOAT;
- public IClass DOUBLE;
-
- public IClassLoader(IClassLoader optionalParentIClassLoader) {
- this.optionalParentIClassLoader = optionalParentIClassLoader;
- }
-
- /**
- * This method must be called by the constructor of the directly derived
- * class. (The reason being is that this method invokes abstract
- * {@link #loadIClass(String)} which will not work until the implementing
- * class is constructed.)
- */
- protected final void postConstruct() {
- try {
- this.OBJECT = this.loadIClass(Descriptor.OBJECT);
- this.STRING = this.loadIClass(Descriptor.STRING);
- this.CLASS = this.loadIClass(Descriptor.CLASS);
- this.THROWABLE = this.loadIClass(Descriptor.THROWABLE);
- this.RUNTIME_EXCEPTION = this.loadIClass(Descriptor.RUNTIME_EXCEPTION);
- this.ERROR = this.loadIClass(Descriptor.ERROR);
- this.CLONEABLE = this.loadIClass(Descriptor.CLONEABLE);
- this.SERIALIZABLE = this.loadIClass(Descriptor.SERIALIZABLE);
- this.BOOLEAN = this.loadIClass(Descriptor.BOOLEAN);
- this.BYTE = this.loadIClass(Descriptor.BYTE);
- this.CHARACTER = this.loadIClass(Descriptor.CHARACTER);
- this.SHORT = this.loadIClass(Descriptor.SHORT);
- this.INTEGER = this.loadIClass(Descriptor.INTEGER);
- this.LONG = this.loadIClass(Descriptor.LONG);
- this.FLOAT = this.loadIClass(Descriptor.FLOAT);
- this.DOUBLE = this.loadIClass(Descriptor.DOUBLE);
- } catch (ClassNotFoundException e) {
- throw new RuntimeException("Cannot load simple types");
- }
- }
-
- /**
- * Get an {@link IClass} by field descriptor.
- *
- * @return <code>null</code> if an {@link IClass} could not be loaded
- * @throws {@link ClassNotFoundException} if an exception was raised while loading the {@link IClass}
- */
- public final IClass loadIClass(String fieldDescriptor) throws ClassNotFoundException {
- if (IClassLoader.DEBUG) System.out.println(this + ": Load type \"" + fieldDescriptor + "\"");
-
- if (Descriptor.isPrimitive(fieldDescriptor)) {
- return (
- fieldDescriptor.equals(Descriptor.VOID_ ) ? IClass.VOID :
- fieldDescriptor.equals(Descriptor.BYTE_ ) ? IClass.BYTE :
- fieldDescriptor.equals(Descriptor.CHAR_ ) ? IClass.CHAR :
- fieldDescriptor.equals(Descriptor.DOUBLE_ ) ? IClass.DOUBLE :
- fieldDescriptor.equals(Descriptor.FLOAT_ ) ? IClass.FLOAT :
- fieldDescriptor.equals(Descriptor.INT_ ) ? IClass.INT :
- fieldDescriptor.equals(Descriptor.LONG_ ) ? IClass.LONG :
- fieldDescriptor.equals(Descriptor.SHORT_ ) ? IClass.SHORT :
- fieldDescriptor.equals(Descriptor.BOOLEAN_) ? IClass.BOOLEAN :
- null
- );
- }
-
- // Ask parent IClassLoader first.
- if (this.optionalParentIClassLoader != null) {
- IClass res = this.optionalParentIClassLoader.loadIClass(fieldDescriptor);
- if (res != null) return res;
- }
-
- // We need to synchronize here because "unloadableIClasses" and
- // "loadedIClasses" are unsynchronized containers.
- IClass result;
- synchronized (this) {
-
- // Class could not be loaded before?
- if (this.unloadableIClasses.contains(fieldDescriptor)) return null;
-
- // Class already loaded?
- result = (IClass) this.loadedIClasses.get(fieldDescriptor);
- if (result != null) return result;
-
- // Special handling for array types.
- if (Descriptor.isArrayReference(fieldDescriptor)) {
-
- // Load the component type.
- IClass componentIClass = this.loadIClass(
- Descriptor.getComponentDescriptor(fieldDescriptor)
- );
- if (componentIClass == null) return null;
-
- // Now get and define the array type.
- IClass arrayIClass = componentIClass.getArrayIClass(this.OBJECT);
- this.loadedIClasses.put(fieldDescriptor, arrayIClass);
- return arrayIClass;
- }
-
- // Load the class through the {@link #findIClass(String)} method implemented by the
- // derived class.
- if (IClassLoader.DEBUG) System.out.println("call IClassLoader.findIClass(\"" + fieldDescriptor + "\")");
- result = this.findIClass(fieldDescriptor);
- if (result == null) {
- this.unloadableIClasses.add(fieldDescriptor);
- return null;
- }
- }
-
- if (!result.getDescriptor().equalsIgnoreCase(fieldDescriptor)) throw new RuntimeException("\"findIClass()\" returned \"" + result.getDescriptor() + "\" instead of \"" + fieldDescriptor + "\"");
-
- if (IClassLoader.DEBUG) System.out.println(this + ": Loaded type \"" + fieldDescriptor + "\" as " + result);
-
- return result;
- }
-
- /**
- * Find a new {@link IClass} by descriptor; return <code>null</code> if a class
- * for that <code>descriptor</code> could not be found.
- * <p>
- * Similar {@link java.lang.ClassLoader#findClass(java.lang.String)}, this method
- * must
- * <ul>
- * <li>Get an {@link IClass} object from somewhere for the given type
- * <li>Call {@link #defineIClass(IClass)} with that {@link IClass} object as
- * the argument
- * <li>Return the {@link IClass} object
- * </ul>
- * <p>
- * The format of a <code>descriptor</code> is defined in JVMS 4.3.2. Typical
- * descriptors are:
- * <ul>
- * <li><code>I</code> (Integer)
- * <li><code>Lpkg1/pkg2/Cls;</code> (Class declared in package)
- * <li><code>Lpkg1/pkg2/Outer$Inner;</code> Member class
- * </ul>
- * Notice that this method is never called for array types.
- * <p>
- * Notice that this method is never called from more than one thread at a time.
- * In other words, implementations of this method need not be synchronized.
- *
- * @return <code>null</code> if a class with that descriptor could not be found
- * @throws ClassNotFoundException if an exception was raised while loading the class
- */
- protected abstract IClass findIClass(String descriptor) throws ClassNotFoundException;
-
- /**
- * Define an {@link IClass} in the context of this {@link IClassLoader}.
- * If an {@link IClass} with that descriptor already exists, a
- * {@link RuntimeException} is thrown.
- * <p>
- * This method should only be called from an implementation of
- * {@link #findIClass(String)}.
- *
- * @throws RuntimeException A different {@link IClass} object is already defined for this type
- */
- protected final void defineIClass(IClass iClass) {
- String descriptor = iClass.getDescriptor();
-
- // Already defined?
- IClass loadedIClass = (IClass) this.loadedIClasses.get(descriptor);
- if (loadedIClass != null) {
- if (loadedIClass == iClass) return;
- throw new RuntimeException("Non-identical definition of IClass \"" + descriptor + "\"");
- }
-
- // Define.
- this.loadedIClasses.put(descriptor, iClass);
- if (IClassLoader.DEBUG) System.out.println(this + ": Defined type \"" + descriptor + "\"");
- }
-
- private final IClassLoader optionalParentIClassLoader;
- private final Map loadedIClasses = new HashMap(); // String descriptor => IClass
- private final Set unloadableIClasses = new HashSet(); // String descriptor
-}
diff --git a/src/org/codehaus/janino/Java.java b/src/org/codehaus/janino/Java.java
deleted file mode 100644
index f2a7aa7..0000000
--- a/src/org/codehaus/janino/Java.java
+++ /dev/null
@@ -1,2924 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.SortedMap;
-import java.util.TreeMap;
-
-import org.codehaus.janino.util.Traverser;
-import org.codehaus.janino.util.iterator.ReverseListIterator;
-
-
-/**
- * This wrapper class defines classes that represent the elements of the
- * Java<sup>TM</sup> programming language.
- * <p>
- * Notices:
- * <ul>
- * <li>"JLS1" refers to <a href="http://java.sun.com/docs/books/jls/first_edition/html/index.html">"The Java<sup>TM</sup> Language Specification, First Edition"</a>.
- * <li>"JLS" or "JLS2" refers to <a href="http://java.sun.com/docs/books/jls/second_edition/html/j.title.doc.html">"The Java<sup>TM</sup> Language Specification, Second Edition"</a>.
- * </ul>
- */
-
-public class Java {
- private Java() {} // Don't instantiate me.
-
- public interface Scope {
- public Scope getEnclosingScope();
- }
-
- /**
- * This interface is implemented by objects which are associated with a
- * location in the source code.
- */
- public interface Locatable {
- public Location getLocation();
-
- /**
- * Throw a {@link Parser.ParseException} with the given message and this
- * object's location.
- *
- * @param message The message to report
- */
- public void throwParseException(String message) throws Parser.ParseException;
- }
- public static abstract class Located implements Locatable {
- private final Location location;
-
- protected Located(Location location) {
- this.location = location;
- }
-
- // Implement "Locatable".
-
- public Location getLocation() { return this.location; }
- public void throwParseException(String message) throws Parser.ParseException {
- throw new Parser.ParseException(message, this.location);
- }
- }
-
- /**
- * Holds the result of {@link Parser#parseCompilationUnit}.
- */
- public static final class CompilationUnit implements Scope {
- public /*final*/ String optionalFileName;
- public PackageDeclaration optionalPackageDeclaration = null;
- public final List importDeclarations = new ArrayList(); // ImportDeclaration
- public final List packageMemberTypeDeclarations = new ArrayList(); // PackageMemberTypeDeclaration
-
- public CompilationUnit(String optionalFileName) {
- this.optionalFileName = optionalFileName;
- }
-
- // Implement "Scope".
- public Scope getEnclosingScope() { throw new RuntimeException("A compilation unit has no enclosing scope"); }
-
- public void setPackageDeclaration(PackageDeclaration packageDeclaration) {
- if (this.optionalPackageDeclaration != null) throw new RuntimeException("Re-setting package declaration");
- this.optionalPackageDeclaration = packageDeclaration;
- }
-
- public void addImportDeclaration(CompilationUnit.ImportDeclaration id) {
-
- // Conflicting imports are checked in UnitCompiler, not here.
- this.importDeclarations.add(id);
- }
-
- public void addPackageMemberTypeDeclaration(PackageMemberTypeDeclaration pmtd) {
- this.packageMemberTypeDeclarations.add(pmtd);
- pmtd.setDeclaringCompilationUnit(this);
- }
-
- /**
- * Get all classes and interfaces declared in this compilation unit.
- */
- public PackageMemberTypeDeclaration[] getPackageMemberTypeDeclarations() {
- return (PackageMemberTypeDeclaration[]) this.packageMemberTypeDeclarations.toArray(new PackageMemberTypeDeclaration[this.packageMemberTypeDeclarations.size()]);
- }
-
- /**
- * Return the package member class or interface declared with the given name.
- * @param name Declared (i.e. not the fully qualified) name
- * @return <code>null</code> if a package member type with that name is not declared in this compilation unit
- */
- public PackageMemberTypeDeclaration getPackageMemberTypeDeclaration(String name) {
- for (Iterator it = this.packageMemberTypeDeclarations.iterator(); it.hasNext();) {
- PackageMemberTypeDeclaration pmtd = (PackageMemberTypeDeclaration) it.next();
- if (pmtd.getName().equals(name)) return pmtd;
- }
- return null;
- }
-
- /**
- * Represents a single type import declaration like<pre>
- * import java.util.Map;</pre>
- */
- public static class SingleTypeImportDeclaration extends ImportDeclaration {
- public final String[] identifiers;
-
- public SingleTypeImportDeclaration(Location location, String[] identifiers) {
- super(location);
- this.identifiers = identifiers;
- }
- public final void accept(Visitor.ImportVisitor visitor) { visitor.visitSingleTypeImportDeclaration(this); }
- public String toString() {
- return "import " + Java.join(this.identifiers, ".") + ';';
- }
- }
-
- /**
- * Represents a type-import-on-demand declaration like<pre>
- * import java.util.*;</pre>
- */
- public static class TypeImportOnDemandDeclaration extends ImportDeclaration {
- public final String[] identifiers;
-
- public TypeImportOnDemandDeclaration(Location location, String[] identifiers) {
- super(location);
- this.identifiers = identifiers;
- }
- public final void accept(Visitor.ImportVisitor visitor) { visitor.visitTypeImportOnDemandDeclaration(this); }
- public String toString() {
- return "import " + Java.join(this.identifiers, ".") + ".*;";
- }
- }
-
- /**
- * Represents a single static import declaration like<pre>
- * import java.util.Collections.EMPTY_MAP;</pre>
- */
- public static class SingleStaticImportDeclaration extends ImportDeclaration {
- public final String[] identifiers;
-
- public SingleStaticImportDeclaration(Location location, String[] identifiers) {
- super(location);
- this.identifiers = identifiers;
- }
- public final void accept(Visitor.ImportVisitor visitor) { visitor.visitSingleStaticImportDeclaration(this); }
- }
-
- /**
- * Represents a static-import-on-demand declaration like<pre>
- * import java.util.Collections.*;</pre>
- */
- public static class StaticImportOnDemandDeclaration extends ImportDeclaration {
- public final String[] identifiers;
-
- public StaticImportOnDemandDeclaration(Location location, String[] identifiers) {
- super(location);
- this.identifiers = identifiers;
- }
- public final void accept(Visitor.ImportVisitor visitor) { visitor.visitStaticImportOnDemandDeclaration(this); }
- }
-
- public abstract static class ImportDeclaration extends Java.Located {
- public ImportDeclaration(Location location) {
- super(location);
- }
- public abstract void accept(Visitor.ImportVisitor visitor);
- }
- }
-
- /**
- * Represents a package declaration like<pre>
- * package com.acme.tools;</pre>
- */
- public static class PackageDeclaration extends Located {
- public final String packageName;
-
- public PackageDeclaration(Location location, String packageName) {
- super(location);
- this.packageName = packageName;
- }
- }
-
- public interface TypeDeclaration extends Locatable, Scope {
-
- /**
- * Return the member type with the given name.
- * @return <code>null</code> if a member type with that name is not declared
- */
- MemberTypeDeclaration getMemberTypeDeclaration(String name);
-
- /**
- * Determine the effective class name, e.g. "pkg.Outer$Inner".
- */
- String getClassName();
-
- /**
- * Creates a unique name for a local class or interface.
- */
- String createLocalTypeName(String localTypeName);
-
- /**
- * Creates a unique name for an anonymous class.
- */
- String createAnonymousClassName();
-
- void accept(Visitor.TypeDeclarationVisitor visitor);
- }
-
- public interface DocCommentable {
-
- /**
- * Returns the doc comment of the object or <code>null</code>.
- */
- public String getDocComment();
-
- /**
- * Returns <code>true</code> if the object has a doc comment and
- * the <code>@#deprecated</code> tag appears in the doc
- * comment.
- */
- public boolean hasDeprecatedDocTag();
- }
-
- /**
- * Represents a class or interface declaration on compilation unit level. These are called
- * "package member types" because they are immediate members of a package, e.g.
- * "java.lang.String".
- */
- public interface PackageMemberTypeDeclaration extends NamedTypeDeclaration {
- void setDeclaringCompilationUnit(CompilationUnit declaringCompilationUnit);
- CompilationUnit getDeclaringCompilationUnit();
- }
-
- /**
- * Represents a class or interface declaration where the immediately enclosing scope is
- * another class or interface declaration.
- */
- public interface MemberTypeDeclaration extends NamedTypeDeclaration, TypeBodyDeclaration {
- }
-
- /**
- * Represents the declaration of a class or an interface that has a name. (All type
- * declarations are named, except for anonymous classes.)
- */
- public interface NamedTypeDeclaration extends TypeDeclaration {
-
- /**
- * Returns the declared (not the fully qualified) name of the class or interface.
- */
- public String getName();
- }
-
- /**
- * Represents the declaration of an inner class, i.e. a class that exists in the context of
- * zero or more "enclosing instances". These are anonymous classes, local classes and member
- * classes.
- */
- interface InnerClassDeclaration extends TypeDeclaration {
-
- /**
- * Inner classes have zero or more synthetic fields that hold references to their enclosing
- * context:
- * <dl>
- * <dt><code>this$<i>n</i></code></dt>
- * <dd>
- * (Mandatory for non-private non-static member classes; optional for private non-static
- * member classes, local classes in non-static context, and anonymous classes in
- * non-static context; forbidden for static member classes, local classes in static
- * context, and anonymous classes in static context)
- * Holds a reference to the immediately enclosing instance. <code><i>n</i></code> is
- * N-1 for the Nth nesting level; e.g. the public non-static member class of a
- * package member class has a synthetic field <code>this$0</code>.
- * </dd>
- * <dt><code>val$<i>local-variable-name</i></code></dt>
- * <dd>
- * (Allowed for local classes and anonymous classes; forbidden for member classes)
- * Hold copies of <code>final</code> local variables of the defining context.
- * </dd>
- * </dl>
- * Notice that these fields are not included in the {@link IClass.IField} array returned
- * by {@link IClass#getDeclaredIFields()}.
- * <p>
- * If a synthetic field with the same name exists already, then it must have the same
- * type and the redefinition is ignored.
- * @param iField
- */
- void defineSyntheticField(IClass.IField iField) throws CompileException;
- }
-
- public abstract static class AbstractTypeDeclaration implements TypeDeclaration {
- private final Location location;
- public final short modifiers;
- public final List declaredMethods = new ArrayList(); // MethodDeclarator
- public final List declaredClassesAndInterfaces = new ArrayList(); // MemberTypeDeclaration
- private Scope enclosingScope = null;
-
- /*package*/ IClass resolvedType = null;
-
- public AbstractTypeDeclaration(
- Location location,
- short modifiers
- ) {
- this.location = location;
- this.modifiers = modifiers;
- }
-
- public void setEnclosingScope(Scope enclosingScope) {
- if (this.enclosingScope != null && enclosingScope != this.enclosingScope) throw new RuntimeException("Enclosing scope is already set for type declaration \"" + this.toString() + "\" at " + this.getLocation());
- this.enclosingScope = enclosingScope;
- }
- public Scope getEnclosingScope() {
- return this.enclosingScope;
- }
-
- public void addDeclaredMethod(MethodDeclarator method) {
- this.declaredMethods.add(method);
- method.setDeclaringType(this);
- }
-
- public void invalidateMethodCaches() {
- if (this.resolvedType != null) {
- this.resolvedType.declaredIMethods = null;
- this.resolvedType.declaredIMethodCache = null;
- }
- }
-
- // Implement TypeDeclaration.
- public void addMemberTypeDeclaration(MemberTypeDeclaration mcoid) {
- this.declaredClassesAndInterfaces.add(mcoid);
- mcoid.setDeclaringType(this);
- }
- public Collection getMemberTypeDeclarations() {
- return this.declaredClassesAndInterfaces;
- }
- public MemberTypeDeclaration getMemberTypeDeclaration(String name) {
- for (Iterator it = this.declaredClassesAndInterfaces.iterator(); it.hasNext();) {
- MemberTypeDeclaration mtd = (MemberTypeDeclaration) it.next();
- if (mtd.getName().equals(name)) return mtd;
- }
- return null;
- }
- public MethodDeclarator getMethodDeclaration(String name) {
- for (Iterator it = this.declaredMethods.iterator(); it.hasNext();) {
- MethodDeclarator md = (MethodDeclarator) it.next();
- if (md.name.equals(name)) return md;
- }
- return null;
- }
- public String createLocalTypeName(String localTypeName) {
- return (
- this.getClassName()
- + '$'
- + ++this.localClassCount
- + '$'
- + localTypeName
- );
- }
- public String createAnonymousClassName() {
- return (
- this.getClassName()
- + '$'
- + ++this.anonymousClassCount
- );
- }
-
- // Implement "Locatable".
- public Location getLocation() { return this.location; }
- public void throwParseException(String message) throws Parser.ParseException {
- throw new Parser.ParseException(message, this.location);
- }
-
- abstract public String toString();
-
- public int anonymousClassCount = 0; // For naming anonymous classes.
- public int localClassCount = 0; // For naming local classes.
- }
-
- public abstract static class ClassDeclaration extends AbstractTypeDeclaration {
- public final List constructors = new ArrayList(); // ConstructorDeclarator
- public final List variableDeclaratorsAndInitializers = new ArrayList(); // TypeBodyDeclaration
-
- public ClassDeclaration(
- Location location,
- short modifiers
- ) {
- super(location, modifiers);
- }
-
- public void addConstructor(ConstructorDeclarator cd) {
- this.constructors.add(cd);
- cd.setDeclaringType(this);
- }
- public void addVariableDeclaratorOrInitializer(TypeBodyDeclaration tbd) {
- this.variableDeclaratorsAndInitializers.add(tbd);
- tbd.setDeclaringType(this);
-
- // Clear resolved type cache.
- if (this.resolvedType != null) this.resolvedType.clearIFieldCaches();
- }
-
- // Compile time members.
-
- // Implement InnerClassDeclaration.
- public void defineSyntheticField(IClass.IField iField) throws CompileException {
- if (!(this instanceof InnerClassDeclaration)) throw new RuntimeException();
-
- IClass.IField if2 = (IClass.IField) this.syntheticFields.get(iField.getName());
- if (if2 != null) {
- if (iField.getType() != if2.getType()) throw new RuntimeException();
- return;
- }
- this.syntheticFields.put(iField.getName(), iField);
- }
-
- /**
- * Return the declared constructors, or the default constructor.
- */
- ConstructorDeclarator[] getConstructors() {
- if (this.constructors.isEmpty()) {
- ConstructorDeclarator defaultConstructor = new ConstructorDeclarator(
- this.getLocation(), // location
- null, // optionalDocComment
- Mod.PUBLIC, // modifiers
- new FunctionDeclarator.FormalParameter[0], // formalParameters
- new Type[0], // thrownExceptions
- null, // optionalExplicitConstructorInvocation
- new Block(this.getLocation()) // optionalBody
- );
- defaultConstructor.setDeclaringType(this);
- return new ConstructorDeclarator[] { defaultConstructor };
- }
-
- return (ConstructorDeclarator[]) this.constructors.toArray(new ConstructorDeclarator[this.constructors.size()]);
- }
-
- // All field names start with "this$" or "val$".
- final SortedMap syntheticFields = new TreeMap(); // String name => IClass.IField
- }
-
- public static final class AnonymousClassDeclaration extends ClassDeclaration implements InnerClassDeclaration {
- public final Type baseType; // Base class or interface
-
- public AnonymousClassDeclaration(
- Location location,
- Type baseType
- ) {
- super(
- location, // location
- (short) (Mod.PRIVATE | Mod.FINAL) // modifiers
- );
- (this.baseType = baseType).setEnclosingScope(new EnclosingScopeOfTypeDeclaration(this));
- }
-
- public final void accept(Visitor.TypeDeclarationVisitor visitor) {
- visitor.visitAnonymousClassDeclaration(this);
- }
-
- // Implement TypeDeclaration.
- public String getClassName() {
- if (this.myName == null) {
- Scope s = this.getEnclosingScope();
- for (; !(s instanceof TypeDeclaration); s = s.getEnclosingScope());
- this.myName = ((TypeDeclaration) s).createAnonymousClassName();
- }
- return this.myName;
- }
- private String myName = null;
- public String toString() { return this.getClassName(); }
- }
-
- public abstract static class NamedClassDeclaration extends ClassDeclaration implements NamedTypeDeclaration, DocCommentable {
- private final String optionalDocComment;
- public final String name;
- public final Type optionalExtendedType;
- public final Type[] implementedTypes;
-
- public NamedClassDeclaration(
- Location location,
- String optionalDocComment,
- short modifiers,
- String name,
- Type optionalExtendedType,
- Type[] implementedTypes
- ) {
- super(location, modifiers);
- this.optionalDocComment = optionalDocComment;
- this.name = name;
- this.optionalExtendedType = optionalExtendedType;
- if (optionalExtendedType != null) optionalExtendedType.setEnclosingScope(new EnclosingScopeOfTypeDeclaration(this));
- this.implementedTypes = implementedTypes;
- for (int i = 0; i < implementedTypes.length; ++i) implementedTypes[i].setEnclosingScope(new EnclosingScopeOfTypeDeclaration(this));
- }
-
- public String toString() { return this.name; }
-
- // Implement NamedTypeDeclaration.
- public String getName() { return this.name; }
-
- // Implement DocCommentable.
- public String getDocComment() { return this.optionalDocComment; }
- public boolean hasDeprecatedDocTag() { return this.optionalDocComment != null && this.optionalDocComment.indexOf("@deprecated") != -1; }
- }
-
- /**
- * Lazily determines and returns the enclosing
- * {@link org.codehaus.janino.Java.Scope} of the given
- * {@link org.codehaus.janino.Java.TypeDeclaration}.
- */
- public static final class EnclosingScopeOfTypeDeclaration implements Scope {
- public final TypeDeclaration typeDeclaration;
- public EnclosingScopeOfTypeDeclaration(TypeDeclaration typeDeclaration) {
- this.typeDeclaration = typeDeclaration;
- }
- public Scope getEnclosingScope() { return this.typeDeclaration.getEnclosingScope(); }
- }
-
- public static final class MemberClassDeclaration extends NamedClassDeclaration implements MemberTypeDeclaration, InnerClassDeclaration {
- public MemberClassDeclaration(
- Location location,
- String optionalDocComment,
- short modifiers,
- String name,
- Type optionalExtendedType,
- Type[] implementedTypes
- ) {
- super(
- location, // location
- optionalDocComment, // optionalDocComment
- modifiers, // modifiers
- name, // name
- optionalExtendedType, // optionalExtendedType
- implementedTypes // implementedTypes
- );
- }
-
- // Implement TypeBodyDeclaration.
- public void setDeclaringType(TypeDeclaration declaringType) {
- this.setEnclosingScope(declaringType);
- }
- public TypeDeclaration getDeclaringType() {
- return (TypeDeclaration) this.getEnclosingScope();
- }
- public boolean isStatic() {
- return (this.modifiers & Mod.STATIC) != 0;
- }
-
- // Implement TypeDeclaration.
- public String getClassName() {
- return (
- this.getDeclaringType().getClassName()
- + '$'
- + this.getName()
- );
- }
-
- public void accept(Visitor.TypeDeclarationVisitor visitor) { visitor.visitMemberClassDeclaration(this); }
- public void accept(Visitor.TypeBodyDeclarationVisitor visitor) { visitor.visitMemberClassDeclaration(this); }
- }
-
- public static final class LocalClassDeclaration extends NamedClassDeclaration implements InnerClassDeclaration {
- public LocalClassDeclaration(
- Location location,
- String optionalDocComment,
- short modifiers,
- String name,
- Type optionalExtendedType,
- Type[] implementedTypes
- ) {
- super(
- location, // location
- optionalDocComment, // optionalDocComment
- modifiers, // modifiers
- name, // name
- optionalExtendedType, // optionalExtendedType
- implementedTypes // implementedTypes
- );
- }
-
- // Implement ClassDeclaration.
- protected IClass getOuterIClass2() {
- Scope s = this.getEnclosingScope();
- for (; !(s instanceof FunctionDeclarator); s = s.getEnclosingScope());
- boolean isStaticMethod = (s instanceof MethodDeclarator) && (((FunctionDeclarator) s).modifiers & Mod.STATIC) != 0;
- for (; !(s instanceof TypeDeclaration); s = s.getEnclosingScope());
- TypeDeclaration immediatelyEnclosingTypeDeclaration = (TypeDeclaration) s;
- return (
- immediatelyEnclosingTypeDeclaration instanceof ClassDeclaration &&
- !isStaticMethod
- ) ? (IClass) immediatelyEnclosingTypeDeclaration : null;
- }
-
- // Implement TypeDeclaration.
- public String getClassName() {
- for (Scope s = this.getEnclosingScope();; s = s.getEnclosingScope()) {
- if (s instanceof Java.TypeDeclaration) return ((Java.TypeDeclaration) s).getClassName() + '$' + this.name;
- }
- }
-
- public final void accept(Visitor.TypeDeclarationVisitor visitor) { visitor.visitLocalClassDeclaration(this); }
- }
-
- public static final class PackageMemberClassDeclaration extends NamedClassDeclaration implements PackageMemberTypeDeclaration {
- public PackageMemberClassDeclaration(
- Location location,
- String optionalDocComment,
- short modifiers,
- String name,
- Type optionalExtendedType,
- Type[] implementedTypes
- ) throws Parser.ParseException {
- super(
- location, // location
- optionalDocComment, // optionalDocComment
- modifiers, // modifiers
- name, // name
- optionalExtendedType, // optionalExtendedType
- implementedTypes // implementedTypes
- );
-
- // Check for forbidden modifiers (JLS 7.6).
- if ((modifiers & (
- Mod.PROTECTED |
- Mod.PRIVATE |
- Mod.STATIC
- )) != 0) this.throwParseException("Modifiers \"protected\", \"private\" and \"static\" not allowed in package member class declaration");
- }
-
- // Implement PackageMemberTypeDeclaration.
- public void setDeclaringCompilationUnit(CompilationUnit declaringCompilationUnit) {
- this.setEnclosingScope(declaringCompilationUnit);
- }
- public CompilationUnit getDeclaringCompilationUnit() {
- return (CompilationUnit) this.getEnclosingScope();
- }
-
- // Implement ClassDeclaration.
- protected IClass getOuterIClass2() {
- return null;
- }
-
- // Implement TypeDeclaration.
- public String getClassName() {
- String className = this.getName();
-
- CompilationUnit compilationUnit = (CompilationUnit) this.getEnclosingScope();
- if (compilationUnit.optionalPackageDeclaration != null) className = compilationUnit.optionalPackageDeclaration.packageName + '.' + className;
-
- return className;
- }
-
- public final void accept(Visitor.TypeDeclarationVisitor visitor) { visitor.visitPackageMemberClassDeclaration(this); }
- }
-
- public abstract static class InterfaceDeclaration extends AbstractTypeDeclaration implements NamedTypeDeclaration, DocCommentable {
- private final String optionalDocComment;
- public /*final*/ String name;
-
- protected InterfaceDeclaration(
- Location location,
- String optionalDocComment,
- short modifiers,
- String name,
- Type[] extendedTypes
- ) {
- super(location, modifiers);
- this.optionalDocComment = optionalDocComment;
- this.name = name;
- this.extendedTypes = extendedTypes;
- for (int i = 0; i < extendedTypes.length; ++i) extendedTypes[i].setEnclosingScope(new EnclosingScopeOfTypeDeclaration(this));
- }
-
- public String toString() { return this.name; }
-
- public void addConstantDeclaration(FieldDeclaration fd) {
- this.constantDeclarations.add(fd);
- fd.setDeclaringType(this);
-
- // Clear resolved type cache.
- if (this.resolvedType != null) this.resolvedType.clearIFieldCaches();
- }
-
- public /*final*/ Type[] extendedTypes;
- public final List constantDeclarations = new ArrayList(); // FieldDeclaration
-
- // Set during "compile()".
- IClass[] interfaces = null;
-
- // Implement NamedTypeDeclaration.
- public String getName() { return this.name; }
-
- // Implement DocCommentable.
- public String getDocComment() { return this.optionalDocComment; }
- public boolean hasDeprecatedDocTag() { return this.optionalDocComment != null && this.optionalDocComment.indexOf("@deprecated") != -1; }
- }
-
- public static final class MemberInterfaceDeclaration extends InterfaceDeclaration implements MemberTypeDeclaration {
- public MemberInterfaceDeclaration(
- Location location,
- String optionalDocComment,
- short modifiers,
- String name,
- Type[] extendedTypes
- ) {
- super(
- location, // location
- optionalDocComment, // optionalDocComment
- modifiers, // modifiers
- name, // name
- extendedTypes // extendedTypes
- );
- }
-
- // Implement TypeDeclaration.
- public String getClassName() {
- NamedTypeDeclaration declaringType = (NamedTypeDeclaration) this.getEnclosingScope();
- return (
- declaringType.getClassName()
- + '$'
- + this.getName()
- );
- }
-
- // Implement TypeBodyDeclaration.
- public void setDeclaringType(TypeDeclaration declaringType) { this.setEnclosingScope(declaringType); }
- public TypeDeclaration getDeclaringType() {
- return (TypeDeclaration) this.getEnclosingScope();
- }
- public boolean isStatic() {
- return (this.modifiers & Mod.STATIC) != 0;
- }
-
- public final void accept(Visitor.TypeDeclarationVisitor visitor) { visitor.visitMemberInterfaceDeclaration(this); }
- public final void accept(Visitor.TypeBodyDeclarationVisitor visitor) { visitor.visitMemberInterfaceDeclaration(this); }
- }
-
- public static final class PackageMemberInterfaceDeclaration extends InterfaceDeclaration implements PackageMemberTypeDeclaration {
- public PackageMemberInterfaceDeclaration(
- Location location,
- String optionalDocComment,
- short modifiers,
- String name,
- Type[] extendedTypes
- ) throws Parser.ParseException {
- super(
- location, // location
- optionalDocComment, // optionalDocComment
- modifiers, // modifiers
- name, // name
- extendedTypes // extendedTypes
- );
-
- // Check for forbidden modifiers (JLS 7.6).
- if ((modifiers & (
- Mod.PROTECTED |
- Mod.PRIVATE |
- Mod.STATIC
- )) != 0) this.throwParseException("Modifiers \"protected\", \"private\" and \"static\" not allowed in package member interface declaration");
- }
-
- // Implement PackageMemberTypeDeclaration.
- public void setDeclaringCompilationUnit(CompilationUnit declaringCompilationUnit) {
- this.setEnclosingScope(declaringCompilationUnit);
- }
-
- public CompilationUnit getDeclaringCompilationUnit() {
- return (CompilationUnit) this.getEnclosingScope();
- }
-
- // Implement TypeDeclaration.
- public String getClassName() {
- String className = this.getName();
-
- CompilationUnit compilationUnit = (CompilationUnit) this.getEnclosingScope();
- if (compilationUnit.optionalPackageDeclaration != null) className = compilationUnit.optionalPackageDeclaration.packageName + '.' + className;
-
- return className;
- }
-
- public final void accept(Visitor.TypeDeclarationVisitor visitor) { visitor.visitPackageMemberInterfaceDeclaration(this); }
- }
-
- /**
- * Representation of a "ClassBodyDeclaration" or an "InterfaceMemberDeclaration". These are:
- * <ul>
- * <li>Field declarators
- * <li>Method declarators
- * <li>Static and non-static initializers
- * <li>Member type declarations
- * </ul>
- */
- public interface TypeBodyDeclaration extends Locatable, Scope {
- void setDeclaringType(TypeDeclaration declaringType);
- TypeDeclaration getDeclaringType();
- boolean isStatic();
- void accept(Visitor.TypeBodyDeclarationVisitor visitor);
- }
-
- public abstract static class AbstractTypeBodyDeclaration extends Located implements TypeBodyDeclaration {
- private TypeDeclaration declaringType;
- public final boolean statiC;
-
- protected AbstractTypeBodyDeclaration(
- Location location,
- boolean statiC
- ) {
- super(location);
- this.statiC = statiC;
- }
-
- // Implement TypeBodyDeclaration.
- public void setDeclaringType(TypeDeclaration declaringType) {
- if (this.declaringType != null && declaringType != null) throw new RuntimeException("Declaring type for type body declaration \"" + this.toString() + "\"at " + this.getLocation() + " is already set");
- this.declaringType = declaringType;
- }
- public TypeDeclaration getDeclaringType() {
- return this.declaringType;
- }
-
- public boolean isStatic() {
- return this.statiC;
- }
-
- // Implement BlockStatement.
- public void setEnclosingScope(Scope enclosingScope) {
- this.declaringType = (TypeDeclaration) enclosingScope;
- }
- public Scope getEnclosingScope() {
- return this.declaringType;
- }
- }
-
- /**
- * Representation of an instance (JLS2 8.6) or static initializer (JLS2 8.7).
- */
- public final static class Initializer extends AbstractTypeBodyDeclaration implements BlockStatement {
- public final Block block;
-
- public Initializer(
- Location location,
- boolean statiC,
- Block block
- ) {
- super(location, statiC);
- (this.block = block).setEnclosingScope(this);
- }
- public String toString() {
- return this.statiC ? "static " + this.block : this.block.toString();
- }
-
- // Implement BlockStatement.
-
- public final void accept(Visitor.TypeBodyDeclarationVisitor visitor) { visitor.visitInitializer(this); }
- public final void accept(Visitor.BlockStatementVisitor visitor) { visitor.visitInitializer(this); }
-
- public Java.LocalVariable findLocalVariable(String name) {
- return this.block.findLocalVariable(name);
- }
- }
-
- /**
- * Abstract base class for {@link Java.ConstructorDeclarator} and
- * {@link Java.MethodDeclarator}.
- */
- public abstract static class FunctionDeclarator extends AbstractTypeBodyDeclaration implements DocCommentable {
- private final String optionalDocComment;
- public final short modifiers;
- public final Type type;
- public final String name;
- public final FormalParameter[] formalParameters;
- public final Type[] thrownExceptions;
- public final Block optionalBody;
-
- public FunctionDeclarator(
- Location location,
- String optionalDocComment,
- short modifiers,
- Type type,
- String name,
- FormalParameter[] formalParameters,
- Type[] thrownExceptions,
- Block optionalBody
- ) {
- super(location, (modifiers & Mod.STATIC) != 0);
- this.optionalDocComment = optionalDocComment;
- this.modifiers = modifiers;
- (this.type = type).setEnclosingScope(this);
- this.name = name;
- this.formalParameters = formalParameters;
- for (int i = 0; i < formalParameters.length; ++i) formalParameters[i].type.setEnclosingScope(this);
- this.thrownExceptions = thrownExceptions;
- for (int i = 0; i < thrownExceptions.length; ++i) thrownExceptions[i].setEnclosingScope(this);
- this.optionalBody = optionalBody;
- if (optionalBody != null) optionalBody.setEnclosingScope(this);
- }
-
- // Implement "Scope".
- public Scope getEnclosingScope() {
- return this.getDeclaringType();
- }
-
- // Set by "compile()".
- IClass returnType = null;
-
- // Implement DocCommentable.
- public String getDocComment() { return this.optionalDocComment; }
- public boolean hasDeprecatedDocTag() { return this.optionalDocComment != null && this.optionalDocComment.indexOf("@deprecated") != -1; }
-
- public static final class FormalParameter extends Java.Located {
- public final boolean finaL;
- public final Type type;
- public final String name;
-
- public FormalParameter(
- Location location,
- boolean finaL,
- Type type,
- String name
- ) {
- super(location);
- this.finaL = finaL;
- this.type = type;
- this.name = name;
- }
-
- public String toString() {
- return this.type.toString() + ' ' + this.name;
- }
-
- // Compile time members.
-
- public Java.LocalVariable localVariable = null;
- }
-
- // Compile time members
- public Map localVariables = null; // String name => Java.LocalVariable
- }
-
- public static final class ConstructorDeclarator extends FunctionDeclarator {
- IClass.IConstructor iConstructor = null;
- public ConstructorInvocation optionalConstructorInvocation = null;
-
- public ConstructorDeclarator(
- Location location,
- String optionalDocComment,
- short modifiers,
- FunctionDeclarator.FormalParameter[] formalParameters,
- Type[] thrownExceptions,
- ConstructorInvocation optionalConstructorInvocation,
- Block optionalBody
- ) {
- super(
- location, // location
- optionalDocComment, // optionalDocComment
- modifiers, // modifiers
- new BasicType(location, BasicType.VOID), // type
- "<init>", // name
- formalParameters, // formalParameters
- thrownExceptions, // thrownExceptions
- optionalBody // optionalBody
- );
- this.optionalConstructorInvocation = optionalConstructorInvocation;
- if (optionalConstructorInvocation != null) optionalConstructorInvocation.setEnclosingScope(this);
- }
-
- public ClassDeclaration getDeclaringClass() {
- return (ClassDeclaration) this.getEnclosingScope();
- }
-
- // Compile time members.
-
- Map syntheticParameters = new HashMap(); // String name => LocalVariable
-
- // Implement "FunctionDeclarator":
-
- public String toString() {
- StringBuffer sb = new StringBuffer(this.getDeclaringClass().getClassName());
- sb.append('(');
- FunctionDeclarator.FormalParameter[] fps = this.formalParameters;
- for (int i = 0; i < fps.length; ++i) {
- if (i > 0) sb.append(", ");
- sb.append(fps[i].toString());
- }
- sb.append(')');
- return sb.toString();
- }
-
- public final void accept(Visitor.TypeBodyDeclarationVisitor visitor) { visitor.visitConstructorDeclarator(this); }
- }
-
- public final static class MethodDeclarator extends FunctionDeclarator {
- public MethodDeclarator(
- Location location,
- String optionalDocComment,
- short modifiers,
- Type type,
- String name,
- FunctionDeclarator.FormalParameter[] formalParameters,
- Type[] thrownExceptions,
- Block optionalBody
- ) {
- super(
- location, // location
- optionalDocComment, // optionalDocComment
- modifiers, // modifiers
- type, // type
- name, // name
- formalParameters, // formalParameters
- thrownExceptions, // thrownExceptions
- optionalBody
- );
- }
-
- public String toString() {
- StringBuffer sb = new StringBuffer(this.name);
- sb.append('(');
- FunctionDeclarator.FormalParameter[] fps = this.formalParameters;
- for (int i = 0; i < fps.length; ++i) {
- if (i > 0) sb.append(", ");
- sb.append(fps[i].toString());
- }
- sb.append(')');
- return sb.toString();
- }
-
- public final void accept(Visitor.TypeBodyDeclarationVisitor visitor) { visitor.visitMethodDeclarator(this); }
-
- IClass.IMethod iMethod = null;
- }
-
- /**
- * This class is derived from "Statement", because it provides for the
- * initialization of the field. In other words, "compile()" generates the
- * code that initializes the field.
- */
- public static final class FieldDeclaration extends Statement implements TypeBodyDeclaration, DocCommentable {
- private final String optionalDocComment;
- public final short modifiers;
- public final Type type;
- public final VariableDeclarator[] variableDeclarators;
-
- public FieldDeclaration(
- Location location,
- String optionalDocComment,
- short modifiers,
- Type type,
- VariableDeclarator[] variableDeclarators
- ) {
- super(location);
- this.optionalDocComment = optionalDocComment;
- this.modifiers = modifiers;
- (this.type = type).setEnclosingScope(this);
- this.variableDeclarators = variableDeclarators;
- for (int i = 0; i < variableDeclarators.length; ++i) {
- VariableDeclarator vd = variableDeclarators[i];
- if (vd.optionalInitializer != null) Java.setEnclosingBlockStatement(vd.optionalInitializer, this);
- }
- }
-
- // Implement TypeBodyDeclaration.
- public void setDeclaringType(TypeDeclaration declaringType) {
- this.setEnclosingScope(declaringType);
- }
- public TypeDeclaration getDeclaringType() {
- return (TypeDeclaration) this.getEnclosingScope();
- }
- public boolean isStatic() {
- return (this.modifiers & Mod.STATIC) != 0;
- }
-
- public String toString() {
- StringBuffer sb = new StringBuffer();
- sb.append(Mod.shortToString(this.modifiers)).append(' ').append(this.type).append(' ').append(this.variableDeclarators[0]);
- for (int i = 1; i < this.variableDeclarators.length; ++i) {
- sb.append(", ").append(this.variableDeclarators[i]);
- }
- return sb.toString();
- }
-
- public final void accept(Visitor.TypeBodyDeclarationVisitor visitor) { visitor.visitFieldDeclaration(this); }
- public final void accept(Visitor.BlockStatementVisitor visitor) { visitor.visitFieldDeclaration(this); }
-
- // Implement DocCommentable.
- public String getDocComment() { return this.optionalDocComment; }
- public boolean hasDeprecatedDocTag() { return this.optionalDocComment != null && this.optionalDocComment.indexOf("@deprecated") != -1; }
- }
- private static void setEnclosingBlockStatement(
- ArrayInitializerOrRvalue aiorv,
- BlockStatement enclosingBlockStatement
- ) {
- if (aiorv instanceof Rvalue) {
- ((Rvalue) aiorv).setEnclosingBlockStatement(enclosingBlockStatement);
- } else
- if (aiorv instanceof ArrayInitializer) {
- ArrayInitializerOrRvalue[] values = ((ArrayInitializer) aiorv).values;
- for (int i = 0; i < values.length; ++i) Java.setEnclosingBlockStatement(values[i], enclosingBlockStatement);
- } else
- {
- throw new RuntimeException("Unexpected array or initializer class " + aiorv.getClass().getName());
- }
- }
-
- // Used by FieldDeclaration and LocalVariableDeclarationStatement.
- public final static class VariableDeclarator extends Located {
- public final String name;
- public final int brackets;
- public final ArrayInitializerOrRvalue optionalInitializer;
-
- public VariableDeclarator(
- Location location,
- String name,
- int brackets,
- ArrayInitializerOrRvalue optionalInitializer
- ) {
- super(location);
- this.name = name;
- this.brackets = brackets;
- this.optionalInitializer = optionalInitializer;
-
- // Used both by field declarations an local variable declarations, so naming
- // conventions checking (JLS2 6.8) cannot be done here.
- }
-
- public String toString() {
- StringBuffer sb = new StringBuffer();
- sb.append(this.name);
- for (int i = 0; i < this.brackets; ++i) sb.append("[]");
- if (this.optionalInitializer != null) sb.append(" = ").append(this.optionalInitializer);
- return sb.toString();
- }
-
- // Compile time members.
-
- // Used only if the variable declarator declares a local variable.
- public LocalVariable localVariable = null;
- }
-
- /**
- * Base of all statements that can appear in a block.
- */
- public interface BlockStatement extends Locatable, Scope {
- void setEnclosingScope(Scope enclosingScope);
- Scope getEnclosingScope();
-
- void accept(Visitor.BlockStatementVisitor visitor);
- Java.LocalVariable findLocalVariable(String name);
- }
-
- public static abstract class Statement extends Located implements BlockStatement {
- private Scope enclosingScope = null;
-
- protected Statement(Location location) {
- super(location);
- }
-
- // Implement "BlockStatement".
- public void setEnclosingScope(Scope enclosingScope) {
- if (this.enclosingScope != null && enclosingScope != this.enclosingScope) throw new RuntimeException("Enclosing scope is already set for statement \"" + this.toString() + "\" at " + this.getLocation());
- this.enclosingScope = enclosingScope;
- }
- public Scope getEnclosingScope() { return this.enclosingScope; }
-
- // Compile time members
- public Map localVariables = null; // String name => Java.LocalVariable
- public Java.LocalVariable findLocalVariable(String name) {
- if (this.localVariables == null) { return null; }
- return (LocalVariable) this.localVariables.get(name);
- }
- }
-
- public final static class LabeledStatement extends BreakableStatement {
- public final String label;
- public final Statement body;
-
- public LabeledStatement(
- Location location,
- String label,
- Statement body
- ) {
- super(location);
- this.label = label;
- (this.body = body).setEnclosingScope(this);
- }
- public String toString() {
- return this.label + ": " + this.body;
- }
-
- // Compile time members:
-
- public final void accept(Visitor.BlockStatementVisitor visitor) { visitor.visitLabeledStatement(this); }
- }
-
- /**
- * Representation of a Java<sup>TM</sup> "block" (JLS 14.2).
- * <p>
- * The statements that the block defines are executed in sequence.
- */
- public final static class Block extends Statement {
- public final List statements = new ArrayList(); // BlockStatement
-
- public Block(Location location) {
- super(location);
- }
-
- public void addStatement(BlockStatement statement) {
- this.statements.add(statement);
- statement.setEnclosingScope(this);
- }
- // This one's for some very special compiler trickery...
- void addButDontEncloseStatement(BlockStatement statement) {
- this.statements.add(statement);
- }
- public void addStatements(
- List statements // BlockStatement
- ) {
- this.statements.addAll(statements);
- for (Iterator it = statements.iterator(); it.hasNext();) ((BlockStatement) it.next()).setEnclosingScope(this);
- }
- public void addButDontEncloseStatements(
- List statements // BlockStatement
- ) {
- this.statements.addAll(statements);
- }
- public BlockStatement[] getStatements() {
- return (BlockStatement[]) this.statements.toArray(new BlockStatement[this.statements.size()]);
- }
-
- // Compile time members.
- public final void accept(Visitor.BlockStatementVisitor visitor) { visitor.visitBlock(this); }
-
- public String toString() {
- return "{ ... }";
- }
- }
-
- /**
- * Base class for statements that can be terminated abnormally with a
- * "break" statement.
- * <p>
- * According to the JLS, statements that can be terminated abnormally with
- * a "break" statement are: "COntinuable" statements ("for", "do" and
- * "while"), labeled statements, and the "switch" statement.
- */
- public static abstract class BreakableStatement extends Statement {
- protected BreakableStatement(Location location) {
- super(location);
- }
-
- CodeContext.Offset whereToBreak = null;
- }
-
- public static abstract class ContinuableStatement extends BreakableStatement {
- protected ContinuableStatement(Location location) {
- super(location);
- }
-
- protected CodeContext.Offset whereToContinue = null;
- protected boolean bodyHasContinue = false;
- }
-
- public final static class ExpressionStatement extends Statement {
- public final Rvalue rvalue;
-
- public ExpressionStatement(Rvalue rvalue) throws Parser.ParseException {
- super(rvalue.getLocation());
- if (!(
- rvalue instanceof Java.Assignment
- || rvalue instanceof Java.Crement
- || rvalue instanceof Java.MethodInvocation
- || rvalue instanceof Java.SuperclassMethodInvocation
- || rvalue instanceof Java.NewClassInstance
- || rvalue instanceof Java.NewAnonymousClassInstance
- )) this.throwParseException("This kind of expression is not allowed in an expression statement");
- (this.rvalue = rvalue).setEnclosingBlockStatement(this);
- }
-
- public String toString() {
- return this.rvalue.toString() + ';';
- }
-
- // Compile time members:
-
- public final void accept(Visitor.BlockStatementVisitor visitor) { visitor.visitExpressionStatement(this); }
- }
-
- public final static class LocalClassDeclarationStatement extends Statement {
- public final LocalClassDeclaration lcd;
-
- public LocalClassDeclarationStatement(Java.LocalClassDeclaration lcd) {
- super(lcd.getLocation());
- (this.lcd = lcd).setEnclosingScope(this);
- }
- public String toString() {
- return this.lcd.toString();
- }
-
- public final void accept(Visitor.BlockStatementVisitor visitor) { visitor.visitLocalClassDeclarationStatement(this); }
- }
-
- public final static class IfStatement extends Statement {
- public final Rvalue condition;
- public final BlockStatement thenStatement;
- public final BlockStatement optionalElseStatement;
-
- /**
- * Notice that the <code>elseStatement</code> is mandatory; for an if statement without
- * an "else" clause, a dummy {@link Java.EmptyStatement} should be passed.
- */
- public IfStatement(
- Location location,
- Rvalue condition,
- BlockStatement thenStatement,
- BlockStatement optionalElseStatement
- ) {
- super(location);
- (this.condition = condition).setEnclosingBlockStatement(this);
- (this.thenStatement = thenStatement).setEnclosingScope(this);
- this.optionalElseStatement = optionalElseStatement;
- if (optionalElseStatement != null) optionalElseStatement.setEnclosingScope(this);
- }
-
- public String toString() {
- return this.optionalElseStatement == null ? "if" : "if ... else";
- }
-
- // Compile time members:
-
- public final void accept(Visitor.BlockStatementVisitor visitor) { visitor.visitIfStatement(this); }
- }
-
- public final static class ForStatement extends ContinuableStatement {
- public final BlockStatement optionalInit;
- public final Rvalue optionalCondition;
- public final Rvalue[] optionalUpdate;
- public final BlockStatement body;
-
- public ForStatement(
- Location location,
- BlockStatement optionalInit,
- Rvalue optionalCondition,
- Rvalue[] optionalUpdate,
- BlockStatement body
- ) {
- super(location);
- this.optionalInit = optionalInit;
- if (optionalInit != null) optionalInit.setEnclosingScope(this);
- this.optionalCondition = optionalCondition;
- if (optionalCondition != null) optionalCondition.setEnclosingBlockStatement(this);
- this.optionalUpdate = optionalUpdate;
- if (optionalUpdate != null) {
- for (int i = 0; i < optionalUpdate.length; ++i) optionalUpdate[i].setEnclosingBlockStatement(this);
- }
- (this.body = body).setEnclosingScope(this);
- }
- public String toString() {
- return "for (...; ...; ...) ...";
- }
-
- // Compile time members:
-
- public final void accept(Visitor.BlockStatementVisitor visitor) { visitor.visitForStatement(this); }
- }
-
- public final static class WhileStatement extends ContinuableStatement {
- public final Rvalue condition;
- public final BlockStatement body;
-
- public WhileStatement(
- Location location,
- Rvalue condition,
- BlockStatement body
- ) {
- super(location);
- (this.condition = condition).setEnclosingBlockStatement(this);
- (this.body = body).setEnclosingScope(this);
- }
- public String toString() {
- return "while (" + this.condition + ") " + this.body + ';';
- }
-
- // Compile time members:
-
- public final void accept(Visitor.BlockStatementVisitor visitor) { visitor.visitWhileStatement(this); }
- }
-
- public final static class TryStatement extends Statement {
- public final BlockStatement body;
- public final List catchClauses; // CatchClause
- public final Block optionalFinally;
-
- public TryStatement(
- Location location,
- BlockStatement body,
- List catchClauses, // CatchClause
- Block optionalFinally
- ) {
- super(location);
- (this.body = body).setEnclosingScope(this);
- this.catchClauses = catchClauses;
- for (Iterator it = catchClauses.iterator(); it.hasNext();) ((CatchClause) it.next()).setEnclosingTryStatement(this);
- this.optionalFinally = optionalFinally;
- if (optionalFinally != null) optionalFinally.setEnclosingScope(this);
- }
- public String toString() {
- return "try ... " + this.catchClauses.size() + (this.optionalFinally == null ? " catches" : " catches ... finally");
- }
-
- // Compile time members:
-
- public final void accept(Visitor.BlockStatementVisitor visitor) { visitor.visitTryStatement(this); }
-
- CodeContext.Offset finallyOffset = null;
- }
-
- public static class CatchClause extends Located implements Scope {
- public final FunctionDeclarator.FormalParameter caughtException;
- public final Block body;
- private TryStatement enclosingTryStatement = null;
-
- public CatchClause(
- Location location,
- FunctionDeclarator.FormalParameter caughtException,
- Block body
- ) {
- super(location);
- (this.caughtException = caughtException).type.setEnclosingScope(this);
- (this.body = body).setEnclosingScope(this);
- }
-
- public void setEnclosingTryStatement(TryStatement enclosingTryStatement) {
- if (this.enclosingTryStatement != null && enclosingTryStatement != this.enclosingTryStatement) throw new RuntimeException("Enclosing TYR statement already set for catch clause " + this.toString() + " at " + this.getLocation());
- this.enclosingTryStatement = enclosingTryStatement;
- }
- public Scope getEnclosingScope() { return this.enclosingTryStatement; }
- }
-
- /**
- * 14.10 The "switch" Statement
- */
- public static final class SwitchStatement extends BreakableStatement {
- public final Rvalue condition;
- public final List sbsgs; // SwitchBlockStatementGroup
-
- public SwitchStatement(
- Location location,
- Rvalue condition,
- List sbsgs
- ) {
- super(location);
- (this.condition = condition).setEnclosingBlockStatement(this);
- this.sbsgs = sbsgs;
- for (Iterator it = sbsgs.iterator(); it.hasNext();) {
- SwitchBlockStatementGroup sbsg = ((SwitchBlockStatementGroup) it.next());
- for (Iterator it2 = sbsg.caseLabels.iterator(); it2.hasNext();) {
- ((Rvalue) (it2.next())).setEnclosingBlockStatement(this);
- }
- for (Iterator it2 = sbsg.blockStatements.iterator(); it2.hasNext();) {
- ((BlockStatement) (it2.next())).setEnclosingScope(this);
- }
- }
- }
- public String toString() {
- return "switch (" + this.condition + ") { (" + this.sbsgs.size() + " statement groups) }";
- }
-
- public static class SwitchBlockStatementGroup extends Java.Located {
- public final List caseLabels; // Rvalue
- public final boolean hasDefaultLabel;
- public final List blockStatements; // BlockStatement
-
- public SwitchBlockStatementGroup(
- Location location,
- List caseLabels, // Rvalue
- boolean hasDefaultLabel,
- List blockStatements // BlockStatement
- ) {
- super(location);
- this.caseLabels = caseLabels;
- this.hasDefaultLabel = hasDefaultLabel;
- this.blockStatements = blockStatements;
- }
- public String toString() {
- return this.caseLabels.size() + (this.hasDefaultLabel ? " case label(s) plus DEFAULT" : " case label(s)");
- }
- }
-
- // Compile time members:
-
- public final void accept(Visitor.BlockStatementVisitor visitor) { visitor.visitSwitchStatement(this); }
- }
- static class Padder extends CodeContext.Inserter implements CodeContext.FixUp {
- public Padder(CodeContext codeContext) {
- codeContext.super();
- }
- public void fixUp() {
- int x = this.offset % 4;
- if (x != 0) {
- CodeContext ca = this.getCodeContext();
- ca.pushInserter(this); {
- ca.makeSpace((short) -1, 4 - x);
- } ca.popInserter();
- }
- }
- }
-
- public final static class SynchronizedStatement extends Statement {
- public final Rvalue expression;
- public final BlockStatement body;
-
- public SynchronizedStatement(
- Location location,
- Rvalue expression,
- BlockStatement body
- ) {
- super(location);
- (this.expression = expression).setEnclosingBlockStatement(this);
- (this.body = body).setEnclosingScope(this);
- }
- public String toString() {
- return "synchronized(" + this.expression + ") " + this.body;
- }
-
- // Compile time members:
-
- public final void accept(Visitor.BlockStatementVisitor visitor) { visitor.visitSynchronizedStatement(this); }
-
- short monitorLvIndex = -1;
- }
-
- public final static class DoStatement extends ContinuableStatement {
- public final BlockStatement body;
- public final Rvalue condition;
-
- public DoStatement(
- Location location,
- BlockStatement body,
- Rvalue condition
- ) {
- super(location);
- (this.body = body).setEnclosingScope(this);
- (this.condition = condition).setEnclosingBlockStatement(this);
- }
- public String toString() {
- return "do " + this.body + " while(" + this.condition + ");";
- }
-
- // Compile time members:
-
- public final void accept(Visitor.BlockStatementVisitor visitor) { visitor.visitDoStatement(this); }
- }
-
- public final static class LocalVariableDeclarationStatement extends Statement {
- public final short modifiers;
- public final Type type;
- public final VariableDeclarator[] variableDeclarators;
-
- /**
- * @param modifiers Only "final" allowed.
- */
- public LocalVariableDeclarationStatement(
- Location location,
- short modifiers,
- Type type,
- VariableDeclarator[] variableDeclarators
- ) {
- super(location);
- this.modifiers = modifiers;
- (this.type = type).setEnclosingScope(this);
- this.variableDeclarators = variableDeclarators;
- for (int i = 0; i < variableDeclarators.length; ++i) {
- VariableDeclarator vd = variableDeclarators[i];
- if (vd.optionalInitializer != null) Java.setEnclosingBlockStatement(vd.optionalInitializer, this);
- }
- }
-
- // Compile time members:
-
- public final void accept(Visitor.BlockStatementVisitor visitor) { visitor.visitLocalVariableDeclarationStatement(this); }
-
- public String toString() {
- StringBuffer sb = new StringBuffer();
- if (this.modifiers != 0) sb.append(Mod.shortToString(this.modifiers)).append(' ');
- sb.append(this.type).append(' ').append(this.variableDeclarators[0].toString());
- for (int i = 1; i < this.variableDeclarators.length; ++i) {
- sb.append(", ").append(this.variableDeclarators[i].toString());
- }
- return sb.append(';').toString();
- }
- }
-
- public final static class ReturnStatement extends Statement {
- public final Rvalue optionalReturnValue;
-
- public ReturnStatement(
- Location location,
- Rvalue optionalReturnValue
- ) {
- super(location);
- this.optionalReturnValue = optionalReturnValue;
- if (optionalReturnValue != null) optionalReturnValue.setEnclosingBlockStatement(this);
- }
-
- public String toString() {
- return this.optionalReturnValue == null ? "return;" : "return " + this.optionalReturnValue + ';';
- }
-
- // Compile time members:
-
- public final void accept(Visitor.BlockStatementVisitor visitor) { visitor.visitReturnStatement(this); }
- }
-
- public final static class ThrowStatement extends Statement {
- public final Rvalue expression;
-
- public ThrowStatement(
- Location location,
- Rvalue expression
- ) {
- super(location);
- (this.expression = expression).setEnclosingBlockStatement(this);
- }
- public String toString() {
- return "throw " + this.expression + ';';
- }
-
- // Compile time members:
-
- public final void accept(Visitor.BlockStatementVisitor visitor) { visitor.visitThrowStatement(this); }
- }
-
- /**
- * Representation of the Java<sup>TM</sup> "break" statement (JLS 14.14).
- */
- public final static class BreakStatement extends Statement {
- public final String optionalLabel;
-
- public BreakStatement(
- Location location,
- String optionalLabel
- ) {
- super(location);
- this.optionalLabel = optionalLabel;
- }
- public String toString() {
- return this.optionalLabel == null ? "break;" : "break " + this.optionalLabel + ';';
- }
-
- // Compile time members:
-
- public final void accept(Visitor.BlockStatementVisitor visitor) { visitor.visitBreakStatement(this); }
- }
-
- /**
- * Representation of the Java<sup>TM</sup> "continue" statement (JLS
- * 14.15).
- */
- public final static class ContinueStatement extends Statement {
- public final String optionalLabel;
-
- public ContinueStatement(
- Location location,
- String optionalLabel
- ) {
- super(location);
- this.optionalLabel = optionalLabel;
- }
- public String toString() {
- return this.optionalLabel == null ? "continue;" : "continue " + this.optionalLabel + ';';
- }
-
- // Compile time members:
-
- public final void accept(Visitor.BlockStatementVisitor visitor) { visitor.visitContinueStatement(this); }
- }
-
- /**
- * Represents the "empty statement", i.e. the blank semicolon.
- */
- public final static class EmptyStatement extends Statement {
- public EmptyStatement(Location location) {
- super(location);
- }
- public String toString() {
- return ";";
- }
-
- public final void accept(Visitor.BlockStatementVisitor visitor) { visitor.visitEmptyStatement(this); }
- }
-
- /**
- * Abstract base class for {@link Java.Type}, {@link Java.Rvalue} and
- * {@link Java.Lvalue}.
- */
- public static abstract class Atom extends Located {
- public Atom(Location location) {
- super(location);
- }
-
- public Type toType() { return null; }
- public Rvalue toRvalue() { return null; }
- public Lvalue toLvalue() { return null; }
-
- public abstract String toString();
-
- // Parse time members:
-
- public final Type toTypeOrPE() throws Parser.ParseException {
- Type result = this.toType();
- if (result == null) this.throwParseException("Expression \"" + this.toString() + "\" is not a type");
- return result;
- }
- public final Rvalue toRvalueOrPE() throws Parser.ParseException {
- Rvalue result = this.toRvalue();
- if (result == null) this.throwParseException("Expression \"" + this.toString() + "\" is not an rvalue");
- return result;
- }
- public final Lvalue toLvalueOrPE() throws Parser.ParseException {
- Lvalue result = this.toLvalue();
- if (result == null) this.throwParseException("Expression \"" + this.toString() + "\" is not an lvalue");
- return result;
- }
-
- public abstract void accept(Visitor.AtomVisitor visitor);
- }
-
- /**
- * Representation of a Java<sup>TM</sup> type.
- */
- public static abstract class Type extends Atom {
- private Scope enclosingScope = null;
-
- protected Type(Location location) {
- super(location);
- }
-
- /**
- * Sets the enclosing scope for this object and all subordinate
- * {@link org.codehaus.janino.Java.Type} objects.
- */
- public void setEnclosingScope(final Scope enclosingScope) {
- if (this.enclosingScope != null && enclosingScope != this.enclosingScope) throw new RuntimeException("Enclosing scope already set for type \"" + this.toString() + "\" at " + this.getLocation());
- this.enclosingScope = enclosingScope;
- }
- public Scope getEnclosingScope() {
- return this.enclosingScope;
- }
- public Type toType() { return this; }
-
- public abstract void accept(Visitor.TypeVisitor visitor);
- }
-
- public static final class SimpleType extends Type {
- public final IClass iClass;
-
- public SimpleType(Location location, IClass iClass) {
- super(location);
- this.iClass = iClass;
- }
- public String toString() { return this.iClass.toString(); }
-
- public final void accept(Visitor.AtomVisitor visitor) { visitor.visitSimpleType(this); }
- public final void accept(Visitor.TypeVisitor visitor) { visitor.visitSimpleType(this); }
- };
-
- /**
- * Representation of a Java<sup>TM</sup> "basic type" (obviously
- * equaivalent to a "primitive type") (JLS 4.2).
- */
- public static final class BasicType extends Type {
- public /*final*/ int index;
-
- public BasicType(Location location, int index) {
- super(location);
- this.index = index;
- }
-
- public String toString() {
- switch (this.index) {
- case BasicType.VOID: return "void";
- case BasicType.BYTE: return "byte";
- case BasicType.SHORT: return "short";
- case BasicType.CHAR: return "char";
- case BasicType.INT: return "int";
- case BasicType.LONG: return "long";
- case BasicType.FLOAT: return "float";
- case BasicType.DOUBLE: return "double";
- case BasicType.BOOLEAN: return "boolean";
- default: throw new RuntimeException("Invalid index " + this.index);
- }
- }
-
- public final void accept(Visitor.TypeVisitor visitor) { visitor.visitBasicType(this); }
- public final void accept(Visitor.AtomVisitor visitor) { visitor.visitBasicType(this); }
-
- public static final int VOID = 0;
- public static final int BYTE = 1;
- public static final int SHORT = 2;
- public static final int CHAR = 3;
- public static final int INT = 4;
- public static final int LONG = 5;
- public static final int FLOAT = 6;
- public static final int DOUBLE = 7;
- public static final int BOOLEAN = 8;
- }
-
- public static final class ReferenceType extends Type {
- public final String[] identifiers;
-
- public ReferenceType(
- Location location,
- String[] identifiers
- ) {
- super(location);
- this.identifiers = identifiers;
- }
-
- public String toString() { return Java.join(this.identifiers, "."); }
-
- public final void accept(Visitor.AtomVisitor visitor) { visitor.visitReferenceType(this); }
- public final void accept(Visitor.TypeVisitor visitor) { visitor.visitReferenceType(this); }
- }
-
- // Helper class for JLS 15.9.1
- public static final class RvalueMemberType extends Type {
- public final Rvalue rvalue;
- public final String identifier;
-
- /**
- * Notice: The <code>rvalue</code> is not a subordinate object!
- */
- public RvalueMemberType(
- Location location,
- Rvalue rvalue,
- String identifier
- ) {
- super(location);
- this.rvalue = rvalue;
- this.identifier = identifier;
- }
-
- public String toString() { return this.identifier; }
-
- public final void accept(Visitor.AtomVisitor visitor) { visitor.visitRvalueMemberType(this); }
- public final void accept(Visitor.TypeVisitor visitor) { visitor.visitRvalueMemberType(this); }
- }
-
-
- /**
- * Representation of a Java<sup>TM</sup> array type (JLS 10.1).
- */
- public static final class ArrayType extends Type {
- public final Type componentType;
-
- public ArrayType(Type componentType) {
- super(componentType.getLocation());
- this.componentType = componentType;
- }
-
- public void setEnclosingScope(final Scope enclosingScope) {
- super.setEnclosingScope(enclosingScope);
- this.componentType.setEnclosingScope(enclosingScope);
- }
- public String toString() {
- return this.componentType.toString() + "[]";
- }
-
- public final void accept(Visitor.AtomVisitor visitor) { visitor.visitArrayType(this); }
- public final void accept(Visitor.TypeVisitor visitor) { visitor.visitArrayType(this); }
- }
-
- /**
- * Representation of an "rvalue", i.e. an expression that has a type and
- * a value, but cannot be assigned to: An expression that can be the
- * right-hand-side of an assignment.
- */
- public static abstract class Rvalue extends Atom implements ArrayInitializerOrRvalue {
- private Java.BlockStatement enclosingBlockStatement = null;
-
- protected Rvalue(Location location) {
- super(location);
- }
-
- /**
- * Sets enclosing block statement for this object and all subordinate
- * {@link org.codehaus.janino.Java.Rvalue} objects.
- */
- public final void setEnclosingBlockStatement(final Java.BlockStatement enclosingBlockStatement) {
- this.accept((Visitor.RvalueVisitor) new Traverser() {
- public void traverseRvalue(Java.Rvalue rv) {
- if (rv.enclosingBlockStatement != null && enclosingBlockStatement != rv.enclosingBlockStatement) throw new RuntimeException("Enclosing block statement for rvalue \"" + rv + "\" at " + rv.getLocation() + " is already set");
- rv.enclosingBlockStatement = enclosingBlockStatement;
- super.traverseRvalue(rv);
- }
- public void traverseAnonymousClassDeclaration(Java.AnonymousClassDeclaration acd) {
- acd.setEnclosingScope(enclosingBlockStatement);
- ;
- }
- public void traverseType(Java.Type t) {
- if (t.enclosingScope != null && enclosingBlockStatement != t.enclosingScope) throw new RuntimeException("Enclosing scope already set for type \"" + this.toString() + "\" at " + t.getLocation());
- t.enclosingScope = enclosingBlockStatement;
-// t.setEnclosingScope(enclosingBlockStatement);
- super.traverseType(t);
- }
- }.comprehensiveVisitor());
- }
- public Java.BlockStatement getEnclosingBlockStatement() {
- return this.enclosingBlockStatement;
- }
- public Rvalue toRvalue() { return this; }
-
- static final Object CONSTANT_VALUE_UNKNOWN = new Object();
- Object constantValue = Java.Rvalue.CONSTANT_VALUE_UNKNOWN;
- public static final Object CONSTANT_VALUE_NULL = new Throwable();
-
- public abstract void accept(Visitor.RvalueVisitor rvv);
-
- public final static boolean JUMP_IF_TRUE = true;
- public final static boolean JUMP_IF_FALSE = false;
- }
-
- /**
- * Base class for {@link Java.Rvalue}s that compile better as conditional
- * branches.
- */
- public static abstract class BooleanRvalue extends Rvalue {
- protected BooleanRvalue(Location location) {
- super(location);
- }
- }
-
- /**
- * Representation of an "lvalue", i.e. an expression that has a type and
- * a value, and can be assigned to: An expression that can be the
- * left-hand-side of an assignment.
- */
- public static abstract class Lvalue extends Rvalue {
- protected Lvalue(Location location) {
- super(location);
- }
-
- public Lvalue toLvalue() { return this; }
-
- public abstract void accept(Visitor.LvalueVisitor lvv);
- }
-
- /**
- * This class is special: It does not extend/implement the Atom subclasses,
- * but overrides Atom's "to...()" methods.
- */
- public static final class AmbiguousName extends Lvalue {
- public final String[] identifiers;
- public final int n;
-
- public AmbiguousName(
- Location location,
- String[] identifiers
- ) {
- this(location, identifiers, identifiers.length);
- }
- public AmbiguousName(
- Location location,
- String[] identifiers,
- int n
- ) {
- super(location);
- this.identifiers = identifiers;
- this.n = n;
- }
-
- // Override "Atom.toType()".
- private Type type = null;
- public Type toType() {
- if (this.type == null) {
- String[] is = new String[this.n];
- System.arraycopy(this.identifiers, 0, is, 0, this.n);
- this.type = new ReferenceType(this.getLocation(), is);
- this.type.setEnclosingScope(this.getEnclosingBlockStatement());
- }
- return this.type;
- }
-
- // Compile time members.
-
- public String toString() {
- return Java.join(this.identifiers, ".", 0, this.n);
- }
-
- Atom reclassified = null;
-
- public final void accept(Visitor.AtomVisitor visitor) { visitor.visitAmbiguousName(this); }
- public final void accept(Visitor.RvalueVisitor visitor) { visitor.visitAmbiguousName(this); }
- public final void accept(Visitor.LvalueVisitor visitor) { visitor.visitAmbiguousName(this); }
- }
-
- // Helper class for 6.5.2.1.7, 6.5.2.2.1
- public static final class Package extends Atom {
- public final String name;
-
- public Package(Location location, String name) {
- super(location);
- this.name = name;
- }
- public String toString() { return this.name; }
-
- public final void accept(Visitor.AtomVisitor visitor) { visitor.visitPackage(this); }
- }
-
- /**
- * Representation of a local variable access -- used during compilation.
- */
- public static final class LocalVariableAccess extends Lvalue {
- public /*final*/ LocalVariable localVariable;
-
- public LocalVariableAccess(
- Location location,
- LocalVariable localVariable
- ) {
- super(location);
- this.localVariable = localVariable;
- }
-
- // Compile time members.
-
- public String toString() { return this.localVariable.toString(); }
-
- public final void accept(Visitor.LvalueVisitor visitor) { visitor.visitLocalVariableAccess(this); }
- public final void accept(Visitor.RvalueVisitor visitor) { visitor.visitLocalVariableAccess(this); }
- public final void accept(Visitor.AtomVisitor visitor) { visitor.visitLocalVariableAccess(this); }
- }
-
- /**
- * Representation of an access to a field of a class or an interface. (Does not implement the
- * "array length" expression, e.g. "ia.length".)
- */
- public static final class FieldAccess extends Lvalue {
- public final Atom lhs;
- public final IClass.IField field;
-
- public FieldAccess(
- Location location,
- Atom lhs,
- IClass.IField field
- ) {
- super(location);
- this.lhs = lhs;
- this.field = field;
- }
-
- // Compile time members.
-
- // Implement "Atom".
- public String toString() { return this.lhs.toString() + '.' + this.field.toString(); }
-
- public final void accept(Visitor.AtomVisitor visitor) { visitor.visitFieldAccess(this); }
- public final void accept(Visitor.RvalueVisitor visitor) { visitor.visitFieldAccess(this); }
- public final void accept(Visitor.LvalueVisitor visitor) { visitor.visitFieldAccess(this); }
- }
-
- public static final class ArrayLength extends Rvalue {
- public final Rvalue lhs;
-
- public ArrayLength(
- Location location,
- Rvalue lhs
- ) {
- super(location);
- this.lhs = lhs;
- }
-
- // Compile time members.
-
- // Implement "Atom".
- public String toString() { return this.lhs.toString() + ".length"; }
-
- public final void accept(Visitor.AtomVisitor visitor) { visitor.visitArrayLength(this); }
- public final void accept(Visitor.RvalueVisitor visitor) { visitor.visitArrayLength(this); }
- }
-
- /**
- * Representation of an access to the innermost enclosing instance.
- */
- public static final class ThisReference extends Rvalue {
-
- /**
- * Access the declaring class.
- */
- public ThisReference(Location location) {
- super(location);
- }
-
- // Compile time members.
-
- IClass iClass = null;
-
- // Implement "Atom".
- public String toString() { return "this"; }
-
- public final void accept(Visitor.AtomVisitor visitor) { visitor.visitThisReference(this); }
- public final void accept(Visitor.RvalueVisitor visitor) { visitor.visitThisReference(this); }
- }
-
- /**
- * Representation of an access to the current object or an enclosing instance.
- */
- public static final class QualifiedThisReference extends Rvalue {
- public final Type qualification;
-
- /**
- * Access the given enclosing instance of the declaring class.
- */
- public QualifiedThisReference(
- Location location,
- Type qualification
- ) {
- super(location);
-
- if (qualification == null) throw new NullPointerException();
- this.qualification = qualification;
- }
-
- // Compile time members.
-
- ClassDeclaration declaringClass = null;
- TypeBodyDeclaration declaringTypeBodyDeclaration = null;
- IClass targetIClass = null;
-
- // Used at compile time.
-// public QualifiedThisReference(
-// Location location,
-// ClassDeclaration declaringClass,
-// TypeBodyDeclaration declaringTypeBodyDeclaration,
-// IClass targetIClass
-// ) {
-// super(location);
-// if (declaringClass == null) throw new NullPointerException();
-// if (declaringTypeBodyDeclaration == null) throw new NullPointerException();
-// if (targetIClass == null) throw new NullPointerException();
-//
-// this.qualification = null;
-// this.declaringClass = declaringClass;
-// this.declaringTypeBodyDeclaration = declaringTypeBodyDeclaration;
-// this.targetIClass = targetIClass;
-// }
-
- // Implement "Atom".
- public String toString() {
- return this.qualification.toString() + ".this";
- }
-
- public final void accept(Visitor.AtomVisitor visitor) { visitor.visitQualifiedThisReference(this); }
- public final void accept(Visitor.RvalueVisitor visitor) { visitor.visitQualifiedThisReference(this); }
- }
-
- public static final class ClassLiteral extends Rvalue {
- public final Type type;
-
- public ClassLiteral(
- Location location,
- Type type
- ) {
- super(location);
- this.type = type;
- }
-
- // Compile time members.
-
- //Implement "Atom".
- public String toString() { return this.type.toString() + ".class"; }
-
- public final void accept(Visitor.AtomVisitor visitor) { visitor.visitClassLiteral(this); }
- public final void accept(Visitor.RvalueVisitor visitor) { visitor.visitClassLiteral(this); }
- }
-
- public static final class Assignment extends Rvalue {
- public final Lvalue lhs;
- public final String operator;
- public final Rvalue rhs;
-
- public Assignment(
- Location location,
- Lvalue lhs,
- String operator,
- Rvalue rhs
- ) {
- super(location);
- this.lhs = lhs;
- this.operator = operator;
- this.rhs = rhs;
- }
-
- // Compile time members.
-
- // Implement "Atom".
- public String toString() { return this.lhs.toString() + ' ' + this.operator + ' ' + this.rhs.toString(); }
-
- public final void accept(Visitor.AtomVisitor visitor) { visitor.visitAssignment(this); }
- public final void accept(Visitor.RvalueVisitor visitor) { visitor.visitAssignment(this); }
- }
-
- public static final class ConditionalExpression extends Rvalue {
- public final Rvalue lhs, mhs, rhs;
-
- public ConditionalExpression(
- Location location,
- Rvalue lhs,
- Rvalue mhs,
- Rvalue rhs
- ) {
- super(location);
- this.lhs = lhs;
- this.mhs = mhs;
- this.rhs = rhs;
- }
-
- // Implement "Atom".
- public String toString() { return this.lhs.toString() + " ? " + this.mhs.toString() + " : " + this.rhs.toString(); }
-
- public final void accept(Visitor.AtomVisitor visitor) { visitor.visitConditionalExpression(this); }
- public final void accept(Visitor.RvalueVisitor visitor) { visitor.visitConditionalExpression(this); }
- }
-
- /**
- * Objects of this class represent represent one pre- or post-increment
- * or decrement.
- */
- public static final class Crement extends Rvalue {
- public final boolean pre;
- public final String operator; // "++" or "--"
- public final Lvalue operand;
-
- public Crement(Location location, String operator, Lvalue operand) {
- super(location);
- this.pre = true;
- this.operator = operator;
- this.operand = operand;
- }
- public Crement(Location location, Lvalue operand, String operator) {
- super(location);
- this.pre = false;
- this.operator = operator;
- this.operand = operand;
- }
-
- // Compile time members.
-
- // Implement "Atom".
- public String toString() {
- return (
- this.pre ?
- this.operator + this.operand :
- this.operand + this.operator
- );
- }
-
- public final void accept(Visitor.AtomVisitor visitor) { visitor.visitCrement(this); }
- public final void accept(Visitor.RvalueVisitor visitor) { visitor.visitCrement(this); }
- }
-
- /**
- * This class implements an array access.
- */
- public static final class ArrayAccessExpression extends Lvalue {
- public final Rvalue lhs;
- public final Rvalue index;
-
- public ArrayAccessExpression(
- Location location,
- Rvalue lhs,
- Rvalue index
- ) {
- super(location);
- this.lhs = lhs;
- this.index = index;
- }
-
- // Compile time members:
-
- // Implement "Atom".
- public String toString() { return this.lhs.toString() + '[' + this.index + ']'; }
-
- public final void accept(Visitor.AtomVisitor visitor) { visitor.visitArrayAccessExpression(this); }
- public final void accept(Visitor.RvalueVisitor visitor) { visitor.visitArrayAccessExpression(this); }
- public final void accept(Visitor.LvalueVisitor visitor) { visitor.visitArrayAccessExpression(this); }
- }
-
- /**
- * This class implements class or interface field access, and also the "array length"
- * expression "xy.length".
- */
- public static final class FieldAccessExpression extends Lvalue {
- public final Atom lhs;
- public final String fieldName;
-
- public FieldAccessExpression(
- Location location,
- Atom lhs,
- String fieldName
- ) {
- super(location);
- this.lhs = lhs;
- this.fieldName = fieldName;
- }
-
- // Compile time members:
-
- // Implement "Atom".
- public String toString() { return this.lhs.toString() + '.' + this.fieldName; }
-
- public final void accept(Visitor.AtomVisitor visitor) { visitor.visitFieldAccessExpression(this); }
- public final void accept(Visitor.RvalueVisitor visitor) { visitor.visitFieldAccessExpression(this); }
- public final void accept(Visitor.LvalueVisitor visitor) { visitor.visitFieldAccessExpression(this); }
-
- Rvalue value = null;
- }
-
- /**
- * Representation of "super.fld" and "Type.super.fld".
- */
- public static final class SuperclassFieldAccessExpression extends Lvalue {
- public final Type optionalQualification;
- public final String fieldName;
-
- public SuperclassFieldAccessExpression(
- Location location,
- Type optionalQualification,
- String fieldName
- ) {
- super(location);
- this.optionalQualification = optionalQualification;
- this.fieldName = fieldName;
- }
-
- // Compile time members.
-
- // Implement "Atom".
- public String toString() { return (this.optionalQualification == null ? "super." : this.optionalQualification.toString() + ".super.") + this.fieldName; }
-
- public final void accept(Visitor.AtomVisitor visitor) { visitor.visitSuperclassFieldAccessExpression(this); }
- public final void accept(Visitor.RvalueVisitor visitor) { visitor.visitSuperclassFieldAccessExpression(this); }
- public final void accept(Visitor.LvalueVisitor visitor) { visitor.visitSuperclassFieldAccessExpression(this); }
-
- Rvalue value = null;
- }
-
- /**
- * This class implements the unary operators "+", "-", "~" and "!".
- */
- public static final class UnaryOperation extends BooleanRvalue {
- public final String operator;
- public final Rvalue operand;
-
- public UnaryOperation(
- Location location,
- String operator,
- Rvalue operand
- ) {
- super(location);
- this.operator = operator;
- this.operand = operand;
- }
-
- // Implement "Atom".
- public String toString() { return this.operator + this.operand.toString(); }
-
- public final void accept(Visitor.AtomVisitor visitor) { visitor.visitUnaryOperation(this); }
- public final void accept(Visitor.RvalueVisitor visitor) { visitor.visitUnaryOperation(this); }
- }
-
- public static final class Instanceof extends Rvalue {
- public final Rvalue lhs;
- public final Type rhs;
-
- public Instanceof(
- Location location,
- Rvalue lhs,
- Type rhs // ReferenceType or ArrayType
- ) {
- super(location);
- this.lhs = lhs;
- this.rhs = rhs;
- }
-
- // Compile time members.
-
- // Implement "Atom".
- public String toString() { return this.lhs.toString() + " instanceof " + this.rhs.toString(); }
-
- public final void accept(Visitor.AtomVisitor visitor) { visitor.visitInstanceof(this); }
- public final void accept(Visitor.RvalueVisitor visitor) { visitor.visitInstanceof(this); }
- }
-
- /**
- * Representation of all non-operand-modifying Java<sup>TM</sup> binary
- * operations.
- * <p>
- * Operations with boolean result:<br>
- * <tt>|| && == != < > <= >=</tt>
- * <p>
- * Operations with non-boolean result:<br>
- * <tt>| ^ & * / % + - << >> >>></tt>
- */
- public static final class BinaryOperation extends BooleanRvalue {
- public final Rvalue lhs;
- public final String op;
- public final Rvalue rhs;
-
- public BinaryOperation(
- Location location,
- Rvalue lhs,
- String op,
- Rvalue rhs
- ) {
- super(location);
- this.lhs = lhs;
- this.op = op;
- this.rhs = rhs;
- }
-
- // Compile time members.
-
- // Implement "Atom".
- public String toString() {
- return this.lhs.toString() + ' ' + this.op + ' ' + this.rhs.toString();
- }
-
- /**
- * Returns an {@link Iterator} over a left-to-right sequence of {@link Java.Rvalue}s.
- */
- public Iterator unrollLeftAssociation() {
- List operands = new ArrayList();
- BinaryOperation x = this;
- for (;;) {
- operands.add(x.rhs);
- Rvalue lhs = x.lhs;
- if (
- lhs instanceof BinaryOperation &&
- ((BinaryOperation) lhs).op == this.op
- ) {
- x = (BinaryOperation) lhs;
- } else {
- operands.add(lhs);
- break;
- }
- }
- return new ReverseListIterator(operands.listIterator(operands.size()));
- }
-
- public final void accept(Visitor.AtomVisitor visitor) { visitor.visitBinaryOperation(this); }
- public final void accept(Visitor.RvalueVisitor visitor) { visitor.visitBinaryOperation(this); }
- }
-
- public static final class Cast extends Rvalue {
- public final Type targetType;
- public final Rvalue value;
-
- public Cast(
- Location location,
- Type targetType,
- Rvalue value
- ) {
- super(location);
- this.targetType = targetType;
- this.value = value;
- }
-
- // Compile time members.
-
- // Implement "Atom".
- public String toString() { return '(' + this.targetType.toString() + ") " + this.value.toString(); }
-
- public final void accept(Visitor.AtomVisitor visitor) { visitor.visitCast(this); }
- public final void accept(Visitor.RvalueVisitor visitor) { visitor.visitCast(this); }
- }
-
- public final static class ParenthesizedExpression extends Lvalue {
- public final Rvalue value;
-
- public ParenthesizedExpression(Location location, Rvalue value) {
- super(location);
- this.value = value;
- }
-
- public String toString() {
- return '(' + this.value.toString() + ')';
- }
- public void accept(Visitor.AtomVisitor visitor) { visitor.visitParenthesizedExpression(this); }
- public void accept(Visitor.RvalueVisitor visitor) { visitor.visitParenthesizedExpression(this); }
- public void accept(Visitor.LvalueVisitor visitor) { visitor.visitParenthesizedExpression(this); }
- }
-
- public static abstract class ConstructorInvocation extends Atom implements BlockStatement {
- public final Rvalue[] arguments;
- private Scope enclosingScope = null;
-
- protected ConstructorInvocation(
- Location location,
- Rvalue[] arguments
- ) {
- super(location);
- this.arguments = arguments;
- for (int i = 0; i < arguments.length; ++i) arguments[i].setEnclosingBlockStatement(this);
- }
-
- // Implement BlockStatement
- public void setEnclosingScope(Scope enclosingScope) {
- if (this.enclosingScope != null && enclosingScope != null) throw new RuntimeException("Enclosing scope is already set for statement \"" + this.toString() + "\" at " + this.getLocation());
- this.enclosingScope = enclosingScope;
- }
- public Scope getEnclosingScope() { return this.enclosingScope; }
-
- // Compile time members
- public Map localVariables = null; // String name => Java.LocalVariable
- public Java.LocalVariable findLocalVariable(String name) {
- if (this.localVariables == null) { return null; }
- return (LocalVariable) this.localVariables.get(name);
- }
- }
-
- public final static class AlternateConstructorInvocation extends ConstructorInvocation {
- public AlternateConstructorInvocation(
- Location location,
- Rvalue[] arguments
- ) {
- super(location, arguments);
- }
-
- // Implement Atom.
- public String toString() { return "this()"; }
- public void accept(Visitor.AtomVisitor visitor) { ((Visitor.BlockStatementVisitor) visitor).visitAlternateConstructorInvocation(this); }
-
- // Implement BlockStatement.
- public void accept(Visitor.BlockStatementVisitor visitor) { visitor.visitAlternateConstructorInvocation(this); }
- }
-
- public final static class SuperConstructorInvocation extends ConstructorInvocation {
- public final Rvalue optionalQualification;
-
- public SuperConstructorInvocation(
- Location location,
- Rvalue optionalQualification,
- Rvalue[] arguments
- ) {
- super(location, arguments);
- this.optionalQualification = optionalQualification;
- if (optionalQualification != null) optionalQualification.setEnclosingBlockStatement(this);
- }
-
- // Implement Atom.
- public String toString() { return "super()"; }
- public void accept(Visitor.AtomVisitor visitor) { ((Visitor.BlockStatementVisitor) visitor).visitSuperConstructorInvocation(this); }
-
- // Implement BlockStatement.
- public void accept(Visitor.BlockStatementVisitor visitor) { visitor.visitSuperConstructorInvocation(this); }
- }
-
- public static final class MethodInvocation extends Invocation {
- public final Atom optionalTarget; // null == simple method name.
- public final String methodName;
-
- public MethodInvocation(
- Location location,
- Atom optionalTarget,
- String methodName,
- Rvalue[] arguments
- ) {
- super(location, arguments);
- this.optionalTarget = optionalTarget;
- this.methodName = methodName;
- }
-
- // Implement "Atom".
- IClass.IMethod iMethod;
- public String toString() {
- StringBuffer sb = new StringBuffer();
- if (this.optionalTarget != null) sb.append(this.optionalTarget.toString()).append('.');
- sb.append(this.methodName).append('(');
- for (int i = 0; i < this.arguments.length; ++i) {
- if (i > 0) sb.append(", ");
- sb.append(this.arguments[i].toString());
- }
- sb.append(')');
- return sb.toString();
- }
-
- public final void accept(Visitor.AtomVisitor visitor) { visitor.visitMethodInvocation(this); }
- public final void accept(Visitor.RvalueVisitor visitor) { visitor.visitMethodInvocation(this); }
- }
-
- public static final class SuperclassMethodInvocation extends Invocation {
- public final String methodName;
-
- public SuperclassMethodInvocation(
- Location location,
- String methodName,
- Rvalue[] arguments
- ) {
- super(location, arguments);
- this.methodName = methodName;
- }
-
- // Implement "Atom".
- public String toString() { return "super." + this.methodName + "()"; }
-
- public final void accept(Visitor.AtomVisitor visitor) { visitor.visitSuperclassMethodInvocation(this); }
- public final void accept(Visitor.RvalueVisitor visitor) { visitor.visitSuperclassMethodInvocation(this); }
- }
-
- public static abstract class Invocation extends Rvalue {
- public final Rvalue[] arguments;
-
- protected Invocation(
- Location location,
- Rvalue[] arguments
- ) {
- super(location);
- this.arguments = arguments;
- }
- }
-
- public static final class NewClassInstance extends Rvalue {
- public final Rvalue optionalQualification;
- public final Type type;
- public final Rvalue[] arguments;
-
- public NewClassInstance(
- Location location,
- Rvalue optionalQualification,
- Type type,
- Rvalue[] arguments
- ) {
- super(location);
- this.optionalQualification = optionalQualification;
- this.type = type;
- this.arguments = arguments;
- }
-
- // Compile time members.
-
- protected IClass iClass = null;
-
- public NewClassInstance(
- Location location,
- Rvalue optionalQualification,
- IClass iClass,
- Rvalue[] arguments
- ) {
- super(location);
- this.optionalQualification = optionalQualification;
- this.type = null;
- this.arguments = arguments;
- this.iClass = iClass;
- }
-
- // Implement "Atom".
- public String toString() {
- StringBuffer sb = new StringBuffer();
- if (this.optionalQualification != null) sb.append(this.optionalQualification.toString()).append('.');
- sb.append("new ");
- if (this.type != null) {
- sb.append(this.type.toString());
- } else
- if (this.iClass != null) {
- sb.append(this.iClass.toString());
- } else {
- sb.append("???");
- }
- sb.append('(');
- for (int i = 0; i < this.arguments.length; ++i) {
- if (i > 0) sb.append(", ");
- sb.append(this.arguments[i].toString());
- }
- sb.append(')');
- return sb.toString();
- }
-
- public final void accept(Visitor.AtomVisitor visitor) { visitor.visitNewClassInstance(this); }
- public final void accept(Visitor.RvalueVisitor visitor) { visitor.visitNewClassInstance(this); }
- }
-
- public static final class NewAnonymousClassInstance extends Rvalue {
- public final Rvalue optionalQualification;
- public final AnonymousClassDeclaration anonymousClassDeclaration;
- public final Rvalue[] arguments;
-
- public NewAnonymousClassInstance(
- Location location,
- Rvalue optionalQualification,
- AnonymousClassDeclaration anonymousClassDeclaration,
- Rvalue[] arguments
- ) {
- super(location);
- this.optionalQualification = optionalQualification;
- this.anonymousClassDeclaration = anonymousClassDeclaration;
- this.arguments = arguments;
- }
-
- // Implement "Atom".
- public String toString() {
- StringBuffer sb = new StringBuffer();
- if (this.optionalQualification != null) sb.append(this.optionalQualification.toString()).append('.');
- sb.append("new ").append(this.anonymousClassDeclaration.baseType.toString()).append("() { ... }");
- return sb.toString();
- }
-
- public final void accept(Visitor.AtomVisitor visitor) { visitor.visitNewAnonymousClassInstance(this); }
- public final void accept(Visitor.RvalueVisitor visitor) { visitor.visitNewAnonymousClassInstance(this); }
- }
-
- // Used during compile-time.
- public static final class ParameterAccess extends Rvalue {
- public final FunctionDeclarator.FormalParameter formalParameter;
-
- public ParameterAccess(
- Location location,
- FunctionDeclarator.FormalParameter formalParameter
- ) {
- super(location);
- this.formalParameter = formalParameter;
- }
-
- // Implement Atom
- public String toString() { return this.formalParameter.name; }
-
- public final void accept(Visitor.AtomVisitor visitor) { visitor.visitParameterAccess(this); }
- public final void accept(Visitor.RvalueVisitor visitor) { visitor.visitParameterAccess(this); }
- }
-
- public static final class NewArray extends Rvalue {
- public final Type type;
- public final Rvalue[] dimExprs;
- public final int dims;
-
- /**
- * Create a new array with dimension dimExprs.length + dims
- * <p>
- * e.g. byte[12][][] is created with
- * new NewArray(
- * null,
- * Java.BasicType(NULL, Java.BasicType.BYTE),
- * new Rvalue[] {
- * new Java.Literal(null, Integer.valueOf(12)
- * },
- * 2
- * )
- * @param location the location of this element
- * @param type the base type of the array
- * @param dimExprs sizes for dimensions being allocated with specific sizes
- * @param dims the number of dimensions that are not yet allocated
- */
- public NewArray(
- Location location,
- Type type,
- Rvalue[] dimExprs,
- int dims
- ) {
- super(location);
- this.type = type;
- this.dimExprs = dimExprs;
- this.dims = dims;
- }
-
- // Implement "Atom".
- public String toString() { return "new " + this.type.toString() + "[]..."; }
- public final void accept(Visitor.AtomVisitor visitor) { visitor.visitNewArray(this); }
-
- // Implement "Rvalue".
- public final void accept(Visitor.RvalueVisitor visitor) { visitor.visitNewArray(this); }
- }
-
- public static final class NewInitializedArray extends Rvalue {
- public final ArrayType arrayType;
- public final ArrayInitializer arrayInitializer;
-
- public NewInitializedArray(
- Location location,
- ArrayType arrayType,
- ArrayInitializer arrayInitializer
- ) {
- super(location);
- this.arrayType = arrayType;
- this.arrayInitializer = arrayInitializer;
- }
-
- // Implement "Atom".
- public String toString() { return "new " + this.arrayType.toString() + " { ... }"; }
- public final void accept(Visitor.AtomVisitor visitor) { visitor.visitNewInitializedArray(this); }
-
- // Implement "Rvalue".
- public final void accept(Visitor.RvalueVisitor visitor) { visitor.visitNewInitializedArray(this); }
- }
-
- /**
- * Represents a Java<sup>TM</sup> array initializer (JLS 10.6).
- * <p>
- * Allocates an array and initializes its members with (not necessarily
- * constant) values.
- */
- public static final class ArrayInitializer extends Located implements ArrayInitializerOrRvalue {
- public final ArrayInitializerOrRvalue[] values;
-
- public ArrayInitializer(
- Location location,
- ArrayInitializerOrRvalue[] values
- ) {
- super(location);
- this.values = values;
- }
- public String toString() {
- return " { (" + this.values.length + " values) }";
- }
- }
-
- public interface ArrayInitializerOrRvalue {
- }
-
- public static final class Literal extends Rvalue {
- public final Object value; // The "null" literal has "value == null".
-
- /**
- * @param value An {@link Integer}, {@link Long}, {@link Float}, {@link Double}, {@link String}, {@link Character}, {@link Boolean}, or <code>null</code>
- */
- public Literal(Location location, Object value) {
- super(location);
- if (!(
- value instanceof Integer
- || value instanceof Long
- || value instanceof Float
- || value instanceof Double
- || value instanceof String
- || value instanceof Character
- || value instanceof Boolean
- || value == null
- )) throw new IllegalArgumentException(value.getClass().getName());
- this.value = value;
- }
-
- // Implement "Atom".
- public String toString() { return Scanner.literalValueToString(this.value); }
-
- public final void accept(Visitor.AtomVisitor visitor) { visitor.visitLiteral(this); }
- public final void accept(Visitor.RvalueVisitor visitor) { visitor.visitLiteral(this); }
- }
-
- /**
- * Used during resolution.
- */
- public static class LocalVariable {
- public final boolean finaL;
- public final IClass type;
- public short localVariableArrayIndex = -1; // Used during compilation
-
- public LocalVariable(
- boolean finaL,
- IClass type
- ) {
- this.finaL = finaL;
- this.type = type;
- }
- }
-
- public static String join(Object[] a, String separator) {
- return Java.join(a, separator, 0, a.length);
- }
-
- public static String join(Object[] a, String separator, int off, int len) {
- if (a == null) return ("(null)");
- if (off >= len) return "";
- StringBuffer sb = new StringBuffer(a[off].toString());
- for (++off; off < len; ++off) {
- sb.append(separator);
- sb.append(a[off]);
- }
- return sb.toString();
- }
-}
diff --git a/src/org/codehaus/janino/JavaSourceClassLoader.java b/src/org/codehaus/janino/JavaSourceClassLoader.java
deleted file mode 100644
index 98e125b..0000000
--- a/src/org/codehaus/janino/JavaSourceClassLoader.java
+++ /dev/null
@@ -1,412 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino;
-
-import java.io.*;
-import java.lang.reflect.*;
-import java.util.*;
-
-import java.security.ProtectionDomain;
-
-import org.codehaus.janino.tools.Disassembler;
-import org.codehaus.janino.util.*;
-import org.codehaus.janino.util.enumerator.*;
-import org.codehaus.janino.util.resource.*;
-
-
-/**
- * A {@link ClassLoader} that, unlike usual {@link ClassLoader}s,
- * does not load byte code, but reads Java<sup>TM</sup> source code and then scans, parses,
- * compiles and loads it into the virtual machine.
- * <p>
- * As with any {@link ClassLoader}, it is not possible to "update" classes after they've been
- * loaded. The way to achieve this is to give up on the {@link JavaSourceClassLoader} and create
- * a new one.
- */
-public class JavaSourceClassLoader extends ClassLoader {
- private final static boolean DEBUG = false;
-
- public interface ProtectionDomainFactory {
- ProtectionDomain getProtectionDomain(String name);
- }
-
- /**
- * Read Java<sup>TM</sup> 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 args.
- * <p>
- * Usage is as follows:
- * <pre>
- * java [ <i>java-option</i> ] org.codehaus.janino.JavaSourceClassLoader [ <i>option</i> ] ... <i>class-name</i> [ <i>arg</i> ] ...
- * <i>java-option</i> Any valid option for the Java Virtual Machine (e.g. "-classpath <i>colon-separated-list-of-class-directories</i>")
- * <i>option</i>:
- * -sourcepath <i>colon-separated-list-of-source-directories</i>
- * -encoding <i>character-encoding</i>
- * -g Generate all debugging info");
- * -g:none Generate no debugging info");
- * -g:{lines,vars,source} Generate only some debugging info");
- * -cache <i>dir</i> Cache compiled classes here");
-
- * </pre>
- */
- public static void main(String[] args) {
- File[] optionalSourcePath = null;
- String optionalCharacterEncoding = null;
- EnumeratorSet debuggingInformation = DebuggingInformation.DEFAULT_DEBUGGING_INFORMATION;
- String optionalCacheDirName = null;
-
- // 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 = PathResourceFinder.parsePath(args[++i]);
- } else
- if ("-encoding".equals(arg)) {
- optionalCharacterEncoding = args[++i];
- } else
- if (arg.equals("-g")) {
- debuggingInformation = DebuggingInformation.ALL;
- } else
- if (arg.equals("-g:none")) {
- debuggingInformation = DebuggingInformation.NONE;
- } else
- if (arg.startsWith("-g:")) {
- try {
- debuggingInformation = new EnumeratorSet(DebuggingInformation.class, arg.substring(3));
- } catch (EnumeratorFormatException ex) {
- debuggingInformation = DebuggingInformation.NONE;
- }
- } else
- if ("-cache".equals(arg)) {
- optionalCacheDirName = args[++i];
- } else
- if ("-help".equals(arg)) {
- System.out.println("Usage:");
- System.out.println(" java [ <java-option> ] " + JavaSourceClassLoader.class.getName() + " { <option> } <class-name> { <argument> }");
- System.out.println("Load the named class by name and invoke its \"main(String[])\" method,");
- System.out.println("passing the given <argument>s.");
- System.out.println(" <java-option> Any valid option for the Java Virtual Machine (e.g. \"-classpath <dir>\")");
- System.out.println(" <option>:");
- System.out.println(" -sourcepath <" + File.pathSeparator + "-separated-list-of-source-directories>");
- System.out.println(" -encoding <character-encoding>");
- System.out.println(" -g Generate all debugging info");
- System.out.println(" -g:none Generate no debugging info");
- System.out.println(" -g:{lines,vars,source} Generate only some debugging info");
- System.out.println(" -cache <dir> Cache compiled classes here");
- System.exit(0);
- } else
- {
- System.err.println("Invalid command line option \"" + arg + "\"; try \"-help\"");
- System.exit(1);
- }
- }
-
- // Determine class name.
- if (i == args.length) {
- System.err.println("No class name given, try \"-help\"");
- System.exit(1);
- }
- String className = args[i++];
-
- // Determine arguments passed to "main()".
- String[] mainArgs = new String[args.length - i];
- System.arraycopy(args, i, mainArgs, 0, args.length - i);
-
- // Set up a JavaSourceClassLoader or a CachingJavaSourceClassLoader.
- ClassLoader cl;
- if (optionalCacheDirName == null) {
- cl = new JavaSourceClassLoader(
- ClassLoader.getSystemClassLoader(), // parentClassLoader
- optionalSourcePath, // optionalSourcePath
- optionalCharacterEncoding, // optionalCharacterEncoding
- debuggingInformation // debuggingInformation
- );
- } else {
- cl = new CachingJavaSourceClassLoader(
- SimpleCompiler.BOOT_CLASS_LOADER, // parentClassLoader
- optionalSourcePath, // optionalSourcePath
- optionalCharacterEncoding, // optionalCharacterEncoding
- new File(optionalCacheDirName), // cacheDirectory
- debuggingInformation // debuggingInformation
- );
- }
-
- // Load the given class.
- Class clazz;
- try {
- clazz = cl.loadClass(className);
- } catch (ClassNotFoundException ex) {
- System.err.println("Loading class \"" + className + "\": " + ex.getMessage());
- System.exit(1);
- return; // NEVER REACHED
- }
-
- // Find its "main" method.
- Method mainMethod;
- try {
- mainMethod = clazz.getMethod("main", new Class[] { String[].class });
- } catch (NoSuchMethodException ex) {
- System.err.println("Class \"" + className + "\" has not public method \"main(String[])\".");
- System.exit(1);
- return; // NEVER REACHED
- }
-
- // Invoke the "main" method.
- try {
- mainMethod.invoke(null, new Object[] { mainArgs });
- } catch (IllegalArgumentException e) {
- e.printStackTrace();
- System.exit(1);
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- System.exit(1);
- } catch (InvocationTargetException e) {
- e.printStackTrace();
- System.exit(1);
- }
- }
-
- /**
- * Set up a {@link JavaSourceClassLoader} that finds Java<sup>TM</sup> source code in a file
- * that resides in either of the directories specified by the given source path.
- * <p>
- * You can specify to include certain debugging information in the generated class files, which
- * is useful if you want to debug through the generated classes (see
- * {@link Scanner#Scanner(String, Reader)}).
- *
- * @param parentClassLoader See {@link ClassLoader}
- * @param optionalSourcePath A collection of directories that are searched for Java<sup>TM</sup> source files in the given order
- * @param optionalCharacterEncoding The encoding of the Java<sup>TM</sup> source files (<code>null</code> for platform default encoding)
- * @param debuggingInformation What kind of debugging information to generate, see {@link DebuggingInformation}
- */
- public JavaSourceClassLoader(
- ClassLoader parentClassLoader,
- File[] optionalSourcePath,
- String optionalCharacterEncoding,
- EnumeratorSet debuggingInformation
- ) {
- this(
- parentClassLoader, // parentClassLoader
- ( // sourceFinder
- optionalSourcePath == null ?
- (ResourceFinder) new DirectoryResourceFinder(new File(".")) :
- (ResourceFinder) new PathResourceFinder(optionalSourcePath)
- ),
- optionalCharacterEncoding, // optionalCharacterEncoding
- debuggingInformation // debuggingInformation
- );
- }
-
- /**
- * Set up a {@link JavaSourceClassLoader} that finds Java<sup>TM</sup> source code through
- * a given {@link ResourceFinder}.
- * <p>
- * You can specify to include certain debugging information in the generated class files, which
- * is useful if you want to debug through the generated classes (see
- * {@link Scanner#Scanner(String, Reader)}).
- *
- * @param parentClassLoader See {@link ClassLoader}
- * @param sourceFinder Used to locate additional source files
- * @param optionalCharacterEncoding The encoding of the Java<sup>TM</sup> source files (<code>null</code> for platform default encoding)
- * @param debuggingInformation What kind of debugging information to generate, see {@link DebuggingInformation}
- */
- public JavaSourceClassLoader(
- ClassLoader parentClassLoader,
- ResourceFinder sourceFinder,
- String optionalCharacterEncoding,
- EnumeratorSet debuggingInformation
- ) {
- super(parentClassLoader);
-
- this.iClassLoader = new JavaSourceIClassLoader(
- sourceFinder, // sourceFinder
- optionalCharacterEncoding, // optionalCharacterEncoding
- this.unitCompilers, // unitCompilers
- new ClassLoaderIClassLoader(parentClassLoader) // optionalParentIClassLoader
- );
-
- this.debuggingInformation = debuggingInformation;
- }
-
- /**
- * @see UnitCompiler#setCompileErrorHandler
- */
- public void setCompileErrorHandler(UnitCompiler.ErrorHandler optionalCompileErrorHandler) {
- this.iClassLoader.setCompileErrorHandler(optionalCompileErrorHandler);
- }
-
- /**
- * @see Parser#setWarningHandler(WarningHandler)
- * @see UnitCompiler#setCompileErrorHandler
- */
- public void setWarningHandler(WarningHandler optionalWarningHandler) {
- this.iClassLoader.setWarningHandler(optionalWarningHandler);
- }
-
- /**
- * Implementation of {@link ClassLoader#findClass(String)}.
- *
- * @throws ClassNotFoundException
- */
- protected Class findClass(String name) throws ClassNotFoundException {
-
- // Check if the bytecode for that class was generated already.
- byte[] bytecode = (byte[]) this.precompiledClasses.remove(name);
- if (bytecode == null) {
-
- // Read, scan, parse and compile the right compilation unit.
- {
- Map bytecodes = this.generateBytecodes(name);
- if (bytecodes == null) throw new ClassNotFoundException(name);
- this.precompiledClasses.putAll(bytecodes);
- }
-
- // Now the bytecode for our class should be available.
- bytecode = (byte[]) this.precompiledClasses.remove(name);
- if (bytecode == null) throw new RuntimeException("SNO: Scanning, parsing and compiling class \"" + name + "\" did not create a class file!?");
- }
-
- return this.defineBytecode(name, bytecode);
- }
-
- /**
- * This {@link Map} keeps those classes which were already compiled, but not
- * yet defined i.e. which were not yet passed to
- * {@link ClassLoader#defineClass(java.lang.String, byte[], int, int)}.
- */
- Map precompiledClasses = new HashMap(); // String name => byte[] bytecode
-
- /**
- * Find, scan, parse the right compilation unit. Compile the parsed compilation unit to
- * bytecode. This may cause more compilation units being scanned and parsed. Continue until
- * all compilation units are compiled.
- *
- * @return String name => byte[] bytecode, or <code>null</code> if no source code could be found
- * @throws ClassNotFoundException on compilation problems
- */
- protected Map generateBytecodes(String name) throws ClassNotFoundException {
- if (this.iClassLoader.loadIClass(Descriptor.fromClassName(name)) == null) return null;
-
- Map bytecodes = new HashMap(); // String name => byte[] bytecode
- Set compiledUnitCompilers = new HashSet();
- COMPILE_UNITS:
- for (;;) {
- for (Iterator it = this.unitCompilers.iterator(); it.hasNext();) {
- UnitCompiler uc = (UnitCompiler) it.next();
- if (!compiledUnitCompilers.contains(uc)) {
- ClassFile[] cfs;
- try {
- cfs = uc.compileUnit(this.debuggingInformation);
- } catch (CompileException ex) {
- throw new ClassNotFoundException("Compiling unit \"" + uc.compilationUnit.optionalFileName + "\"", ex);
- }
- for (int i = 0; i < cfs.length; ++i) {
- ClassFile cf = cfs[i];
- bytecodes.put(cf.getThisClassName(), cf.toByteArray());
- }
- compiledUnitCompilers.add(uc);
- continue COMPILE_UNITS;
- }
- }
- return bytecodes;
- }
- }
-
- /**
- * Define a set of classes, like
- * {@link java.lang.ClassLoader#defineClass(java.lang.String, byte[], int, int)}.
- * If the <code>bytecodes</code> contains an entry for <code>name</code>, then the
- * {@link Class} defined for that name is returned.
- *
- * @param bytecodes String name => byte[] bytecode
- */
- protected Class defineBytecodes(String name, Map bytecodes) throws ClassFormatError {
- Class clazz = null;
- for (Iterator it = bytecodes.entrySet().iterator(); it.hasNext();) {
- Map.Entry me = (Map.Entry) it.next();
- String name2 = (String) me.getKey();
- byte[] ba = (byte[]) me.getValue();
-
- Class c = this.defineBytecode(name2, ba);
- if (name2.equals(name)) clazz = c;
- }
- return clazz;
- }
-
- /**
- * Calls {@link java.lang.ClassLoader#defineClass(java.lang.String, byte[], int, int)}
- * or {@link java.lang.ClassLoader#defineClass(java.lang.String, byte[], int, int, java.security.ProtectionDomain)},
- * depending on whether or not a {@link ProtectionDomainFactory} was set.
- *
- * @see #setProtectionDomainFactory
- */
- protected Class defineBytecode(String className, byte[] ba) throws ClassFormatError {
-
- // Disassemble the the class bytecode(for debugging).
- if (JavaSourceClassLoader.DEBUG) {
- System.out.println("*** Disassembly of class \"" + className + "\":");
- try {
- new Disassembler().disasm(new ByteArrayInputStream(ba));
- System.out.flush();
- } catch (IOException ex) {
- throw new RuntimeException("SNO: IOException despite ByteArrayInputStream");
- }
- }
-
- if (this.protectionDomainFactory == null) {
- return this.defineClass(className, ba, 0, ba.length);
- } else
- {
- String sourceName = ClassFile.getSourceResourceName(className);
- ProtectionDomain domain = this.protectionDomainFactory.getProtectionDomain(sourceName);
- return this.defineClass(className, ba, 0, ba.length, domain);
- }
- }
-
- public void setProtectionDomainFactory(ProtectionDomainFactory protectionDomainFactory) {
- this.protectionDomainFactory = protectionDomainFactory;
- }
-
- private final JavaSourceIClassLoader iClassLoader;
- private final EnumeratorSet debuggingInformation;
- private ProtectionDomainFactory protectionDomainFactory;
-
- /**
- * Collection of parsed, but uncompiled compilation units.
- */
- private final Set unitCompilers = new HashSet(); // UnitCompiler
-}
diff --git a/src/org/codehaus/janino/JavaSourceIClassLoader.java b/src/org/codehaus/janino/JavaSourceIClassLoader.java
deleted file mode 100644
index 461215c..0000000
--- a/src/org/codehaus/janino/JavaSourceIClassLoader.java
+++ /dev/null
@@ -1,173 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino;
-
-import java.io.*;
-import java.util.*;
-
-import org.codehaus.janino.util.*;
-import org.codehaus.janino.util.resource.*;
-
-
-/**
- * This {@link org.codehaus.janino.IClassLoader} finds, scans and parses compilation units.
- * <p>
- * Notice that it does not compile them!
- */
-public final class JavaSourceIClassLoader extends IClassLoader {
- private static final boolean DEBUG = false;
-
- private final ResourceFinder sourceFinder;
- private final String optionalCharacterEncoding;
- private final Set unitCompilers; // UnitCompiler
- private UnitCompiler.ErrorHandler optionalCompileErrorHandler = null;
- private WarningHandler optionalWarningHandler = null;
-
- /**
- * Notice that the <code>unitCompilers</code> set is both read and written
- * by the {@link JavaSourceIClassLoader}: As it searches for {@link IClass}es, it looks
- * into <code>unitCompilers</code> for class declarations, and as it opens,
- * scans and parses compilation units on-the-fly, it adds them to
- * <code>unitCompilers</code>.
- */
- public JavaSourceIClassLoader(
- ResourceFinder sourceFinder,
- String optionalCharacterEncoding,
- Set unitCompilers, // UnitCompiler
- IClassLoader optionalParentIClassLoader
- ) {
- super(optionalParentIClassLoader);
-
- this.sourceFinder = sourceFinder;
- this.optionalCharacterEncoding = optionalCharacterEncoding;
- this.unitCompilers = unitCompilers;
- super.postConstruct();
- }
-
- /**
- * @see UnitCompiler#setCompileErrorHandler(ErrorHandler)
- */
- public void setCompileErrorHandler(UnitCompiler.ErrorHandler optionalCompileErrorHandler) {
- this.optionalCompileErrorHandler = optionalCompileErrorHandler;
- }
-
- /**
- * @see Parser#setWarningHandler(WarningHandler)
- * @see UnitCompiler#setCompileErrorHandler(ErrorHandler)
- */
- public void setWarningHandler(WarningHandler optionalWarningHandler) {
- this.optionalWarningHandler = optionalWarningHandler;
- }
-
- /**
- * @param type field descriptor of the {@link IClass} to load, e.g. "Lpkg1/pkg2/Outer$Inner;"
- * @throws ClassNotFoundException if an exception was raised while loading the {@link IClass}
- */
- public IClass findIClass(final String type) throws ClassNotFoundException {
- if (JavaSourceIClassLoader.DEBUG) System.out.println("type = " + type);
-
- // Class type.
- String className = Descriptor.toClassName(type); // E.g. "pkg1.pkg2.Outer$Inner"
- if (JavaSourceIClassLoader.DEBUG) System.out.println("2 className = \"" + className + "\"");
-
- // Do not attempt to load classes from package "java".
- if (className.startsWith("java.")) return null;
-
- // Determine the name of the top-level class.
- String topLevelClassName;
- {
- int idx = className.indexOf('$');
- topLevelClassName = idx == -1 ? className : className.substring(0, idx);
- }
-
- // Check the already-parsed compilation units.
- for (Iterator it = this.unitCompilers.iterator(); it.hasNext();) {
- UnitCompiler uc = (UnitCompiler) it.next();
- IClass res = uc.findClass(topLevelClassName);
- if (res != null) {
- if (!className.equals(topLevelClassName)) {
- res = uc.findClass(className);
- if (res == null) return null;
- }
- this.defineIClass(res);
- return res;
- }
- }
-
- // Find source file.
- Resource sourceResource = this.sourceFinder.findResource(ClassFile.getSourceResourceName(className));
- if (sourceResource == null) return null;
- if (JavaSourceIClassLoader.DEBUG) System.out.println("sourceURL=" + sourceResource);
-
- try {
-
- // Scan and parse the source file.
- InputStream inputStream = sourceResource.open();
- Java.CompilationUnit cu;
- try {
- Scanner scanner = new Scanner(sourceResource.getFileName(), inputStream, this.optionalCharacterEncoding);
- scanner.setWarningHandler(this.optionalWarningHandler);
- Parser parser = new Parser(scanner);
- parser.setWarningHandler(this.optionalWarningHandler);
- cu = parser.parseCompilationUnit();
- } finally {
- try { inputStream.close(); } catch (IOException ex) {}
- }
- UnitCompiler uc = new UnitCompiler(cu, this);
- uc.setCompileErrorHandler(this.optionalCompileErrorHandler);
- uc.setWarningHandler(this.optionalWarningHandler);
-
- // Remember compilation unit for later compilation.
- this.unitCompilers.add(uc);
-
- // Find the class/interface declaration in the compiled unit.
- IClass res = uc.findClass(className);
- if (res == null) {
- if (className.equals(topLevelClassName)) throw new Parser.ParseException("Source file \"" + sourceResource.getFileName() + "\" does not declare class \"" + className + "\"", (Location) null);
- return null;
- }
- this.defineIClass(res);
- return res;
- } catch (Scanner.ScanException e) {
- throw new ClassNotFoundException("Parsing compilation unit \"" + sourceResource + "\"", e);
- } catch (Parser.ParseException e) {
- throw new ClassNotFoundException("Parsing compilation unit \"" + sourceResource + "\"", e);
- } catch (IOException e) {
- throw new ClassNotFoundException("Parsing compilation unit \"" + sourceResource + "\"", e);
- } catch (CompileException e) {
- throw new ClassNotFoundException("Parsing compilation unit \"" + sourceResource + "\"", e);
- }
- }
-}
\ No newline at end of file
diff --git a/src/org/codehaus/janino/Location.java b/src/org/codehaus/janino/Location.java
deleted file mode 100644
index dfe899c..0000000
--- a/src/org/codehaus/janino/Location.java
+++ /dev/null
@@ -1,69 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino;
-
-/**
- * Represents the location of a character in a file, as defined by
- * file name, line number and column number.
- */
-public class Location {
- public Location(String optionalFileName, short lineNumber, short columnNumber) {
- this.optionalFileName = optionalFileName;
- this.lineNumber = lineNumber;
- this.columnNumber = columnNumber;
- }
-
- public String getFileName() { return this.optionalFileName; }
- public short getLineNumber() { return this.lineNumber; }
- public short getColumnNumber() { return this.columnNumber; }
-
- /**
- * Converts this {@link Location} into an english text, like<pre>
- * File Main.java, Line 23, Column 79</pre>
- */
- public String toString() {
- StringBuffer sb = new StringBuffer();
- if (this.optionalFileName != null) {
- sb.append("File ").append(this.optionalFileName).append(", ");
- }
- sb.append("Line ").append(this.lineNumber).append(", ");
- sb.append("Column ").append(this.columnNumber);
- return sb.toString();
- }
-
- private /*final*/ String optionalFileName;
- private /*final*/ short lineNumber;
- private /*final*/ short columnNumber;
-}
\ No newline at end of file
diff --git a/src/org/codehaus/janino/MethodDescriptor.java b/src/org/codehaus/janino/MethodDescriptor.java
deleted file mode 100644
index d2c312c..0000000
--- a/src/org/codehaus/janino/MethodDescriptor.java
+++ /dev/null
@@ -1,98 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino;
-
-import java.util.*;
-
-/**
- * Representation of a "method descriptor" (JVMS 4.3.3).
- */
-public class MethodDescriptor {
-
- /** The field descriptors of the method parameters. */
- public final String[] parameterFDs;
-
- /** The field descriptor of the method return value. */
- public final String returnFD;
-
- /** */
- public MethodDescriptor(String[] parameterFDs, String returnFD) {
- this.parameterFDs = parameterFDs;
- this.returnFD = returnFD;
- }
-
- /**
- * Parse a method descriptor into parameter FDs and return FDs.
- */
- public MethodDescriptor(String s) {
- if (s.charAt(0) != '(') throw new RuntimeException();
-
- int from = 1;
- List parameterFDs = new ArrayList(); // String
- while (s.charAt(from) != ')') {
- int to = from;
- while (s.charAt(to) =='[') ++to;
- if ("BCDFIJSZ".indexOf(s.charAt(to)) != -1) {
- ++to;
- } else
- if (s.charAt(to) == 'L') {
- for (++to; s.charAt(to) != ';'; ++to);
- ++to;
- } else {
- throw new RuntimeException();
- }
- parameterFDs.add(s.substring(from, to));
- from = to;
- }
- this.parameterFDs = (String[]) parameterFDs.toArray(new String[parameterFDs.size()]);
- this.returnFD = s.substring(++from);
- }
-
- /**
- * Returns the "method descriptor" (JVMS 4.3.3).
- */
- public String toString() {
- StringBuffer sb = new StringBuffer("(");
- for (int i = 0; i < this.parameterFDs.length; ++i) sb.append(this.parameterFDs[i]);
- return sb.append(')').append(this.returnFD).toString();
- }
-
- /**
- * Patch an additional parameter into a given method descriptor.
- */
- public static String prependParameter(String md, String parameterFD) {
- return '(' + parameterFD + md.substring(1);
- }
-}
diff --git a/src/org/codehaus/janino/Mod.java b/src/org/codehaus/janino/Mod.java
deleted file mode 100644
index fd5af52..0000000
--- a/src/org/codehaus/janino/Mod.java
+++ /dev/null
@@ -1,104 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino;
-
-/**
- * This class defines constants and convenience methods for the handling of
- * modifiers as defined by the JVM.
- * <p>
- * Notice: This class should be named <code>IClass.IModifier</code>, but changing the name would
- * break existing client code. Thus it won't be renamed until there's a really good reason to
- * do it (maybe with a major desing change).
- */
-public class Mod {
- private Mod() {} // Don't instantiate me!
-
- public final static short NONE = 0x0000;
-
- public final static short PUBLIC = 0x0001;
- public final static short PRIVATE = 0x0002;
- public final static short PROTECTED = 0x0004;
- public final static short PACKAGE = 0x0000;
- public final static short PPP = 0x0007;
-
- public static boolean isPublicAccess(short sh) { return (sh & Mod.PPP) == Mod.PUBLIC; }
- public static boolean isPrivateAccess(short sh) { return (sh & Mod.PPP) == Mod.PRIVATE; }
- public static boolean isProtectedAccess(short sh) { return (sh & Mod.PPP) == Mod.PROTECTED; }
- public static boolean isPackageAccess(short sh) { return (sh & Mod.PPP) == Mod.PACKAGE; }
- public static short changeAccess(short sh, short newAccess) { return (short) ((sh & ~Mod.PPP) | newAccess); }
-
- public final static short STATIC = 0x0008;
- public final static short FINAL = 0x0010;
- public final static short SUPER = 0x0020;
- public final static short SYNCHRONIZED = 0x0020;
- public final static short VOLATILE = 0x0040;
- public final static short TRANSIENT = 0x0080;
- public final static short NATIVE = 0x0100;
- public final static short INTERFACE = 0x0200;
- public final static short ABSTRACT = 0x0400;
- public final static short STRICTFP = 0x0800;
-
- // Poorly documented JDK 1.5 modifiers:
- public final static short SYNTHETIC = 0x1000;
- public final static short ANNOTATION = 0x2000;
- public final static short ENUM = 0x4000;
-
- public static String shortToString(short sh) {
- String res = "";
- for (int i = 0; i < Mod.mappings.length; i += 2) {
- if ((sh & ((Short) Mod.mappings[i + 1]).shortValue()) == 0) continue;
- if (res.length() > 0) res += ' ';
- res += (String) Mod.mappings[i];
- }
- return res;
- }
-
- private final static Object[] mappings = {
- "public", new Short(Mod.PUBLIC),
- "private", new Short(Mod.PRIVATE),
- "protected", new Short(Mod.PROTECTED),
- "static", new Short(Mod.STATIC),
- "final", new Short(Mod.FINAL),
-// "super", new Short(Mod.SUPER),
- "synchronized", new Short(Mod.SYNCHRONIZED),
- "volatile", new Short(Mod.VOLATILE),
- "transient", new Short(Mod.TRANSIENT),
- "native", new Short(Mod.NATIVE),
- "interface", new Short(Mod.INTERFACE),
- "abstract", new Short(Mod.ABSTRACT),
- "strictfp", new Short(Mod.STRICTFP),
- };
-}
-
diff --git a/src/org/codehaus/janino/Opcode.java b/src/org/codehaus/janino/Opcode.java
deleted file mode 100644
index 0f627c8..0000000
--- a/src/org/codehaus/janino/Opcode.java
+++ /dev/null
@@ -1,612 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino;
-
-/**
- * Definitions of Java bytecode opcodes.
- */
-
-/*package*/ interface Opcode {
- public final static byte AALOAD = 50;
- public final static byte AASTORE = 83;
- public final static byte ACONST_NULL = 1;
- public final static byte ALOAD = 25;
- public final static byte ALOAD_0 = 42;
- public final static byte ALOAD_1 = 43;
- public final static byte ALOAD_2 = 44;
- public final static byte ALOAD_3 = 45;
- public final static byte ANEWARRAY = (byte) 189;
- public final static byte ARETURN = (byte) 176;
- public final static byte ARRAYLENGTH = (byte) 190;
- public final static byte ASTORE = 58;
- public final static byte ASTORE_0 = 75;
- public final static byte ASTORE_1 = 76;
- public final static byte ASTORE_2 = 77;
- public final static byte ASTORE_3 = 78;
- public final static byte ATHROW = (byte) 191;
- public final static byte BALOAD = 51;
- public final static byte BASTORE = 84;
- public final static byte BIPUSH = 16;
- public final static byte CALOAD = 52;
- public final static byte CASTORE = 85;
- public final static byte CHECKCAST = (byte) 192;
- public final static byte D2F = (byte) 144;
- public final static byte D2I = (byte) 142;
- public final static byte D2L = (byte) 143;
- public final static byte DADD = 99;
- public final static byte DALOAD = 49;
- public final static byte DASTORE = 82;
- public final static byte DCMPG = (byte) 152;
- public final static byte DCMPL = (byte) 151;
- public final static byte DCONST_0 = 14;
- public final static byte DCONST_1 = 15;
- public final static byte DDIV = 111;
- public final static byte DLOAD = 24;
- public final static byte DLOAD_0 = 38;
- public final static byte DLOAD_1 = 39;
- public final static byte DLOAD_2 = 40;
- public final static byte DLOAD_3 = 41;
- public final static byte DMUL = 107;
- public final static byte DNEG = 119;
- public final static byte DREM = 115;
- public final static byte DRETURN = (byte) 175;
- public final static byte DSTORE = 57;
- public final static byte DSTORE_0 = 71;
- public final static byte DSTORE_1 = 72;
- public final static byte DSTORE_2 = 73;
- public final static byte DSTORE_3 = 74;
- public final static byte DSUB = 103;
- public final static byte DUP = 89;
- public final static byte DUP_X1 = 90;
- public final static byte DUP_X2 = 91;
- public final static byte DUP2 = 92;
- public final static byte DUP2_X1 = 93;
- public final static byte DUP2_X2 = 94;
- public final static byte F2D = (byte) 141;
- public final static byte F2I = (byte) 139;
- public final static byte F2L = (byte) 140;
- public final static byte FADD = 98;
- public final static byte FALOAD = 48;
- public final static byte FASTORE = 81;
- public final static byte FCMPG = (byte) 150;
- public final static byte FCMPL = (byte) 149;
- public final static byte FCONST_0 = 11;
- public final static byte FCONST_1 = 12;
- public final static byte FCONST_2 = 13;
- public final static byte FDIV = 110;
- public final static byte FLOAD = 23;
- public final static byte FLOAD_0 = 34;
- public final static byte FLOAD_1 = 35;
- public final static byte FLOAD_2 = 36;
- public final static byte FLOAD_3 = 37;
- public final static byte FMUL = 106;
- public final static byte FNEG = 118;
- public final static byte FREM = 114;
- public final static byte FRETURN = (byte) 174;
- public final static byte FSTORE = 56;
- public final static byte FSTORE_0 = 67;
- public final static byte FSTORE_1 = 68;
- public final static byte FSTORE_2 = 69;
- public final static byte FSTORE_3 = 70;
- public final static byte FSUB = 102;
- public final static byte GETFIELD = (byte) 180;
- public final static byte GETSTATIC = (byte) 178;
- public final static byte GOTO = (byte) 167;
- public final static byte GOTO_W = (byte) 200;
- public final static byte I2B = (byte) 145;
- public final static byte I2C = (byte) 146;
- public final static byte I2D = (byte) 135;
- public final static byte I2F = (byte) 134;
- public final static byte I2L = (byte) 133;
- public final static byte I2S = (byte) 147;
- public final static byte IADD = 96;
- public final static byte IALOAD = 46;
- public final static byte IAND = 126;
- public final static byte IASTORE = 79;
- public final static byte ICONST_M1 = 2;
- public final static byte ICONST_0 = 3;
- public final static byte ICONST_1 = 4;
- public final static byte ICONST_2 = 5;
- public final static byte ICONST_3 = 6;
- public final static byte ICONST_4 = 7;
- public final static byte ICONST_5 = 8;
- public final static byte IDIV = 108;
- public final static byte IF_ACMPEQ = (byte) 165;
- public final static byte IF_ACMPNE = (byte) 166;
- public final static byte IF_ICMPEQ = (byte) 159;
- public final static byte IF_ICMPNE = (byte) 160;
- public final static byte IF_ICMPLT = (byte) 161;
- public final static byte IF_ICMPGE = (byte) 162;
- public final static byte IF_ICMPGT = (byte) 163;
- public final static byte IF_ICMPLE = (byte) 164;
- public final static byte IFEQ = (byte) 153;
- public final static byte IFNE = (byte) 154;
- public final static byte IFLT = (byte) 155;
- public final static byte IFGE = (byte) 156;
- public final static byte IFGT = (byte) 157;
- public final static byte IFLE = (byte) 158;
- public final static byte IFNONNULL = (byte) 199;
- public final static byte IFNULL = (byte) 198;
- public final static byte IINC = (byte) 132;
- public final static byte ILOAD = 21;
- public final static byte ILOAD_0 = 26;
- public final static byte ILOAD_1 = 27;
- public final static byte ILOAD_2 = 28;
- public final static byte ILOAD_3 = 29;
- public final static byte IMUL = 104;
- public final static byte INEG = 116;
- public final static byte INSTANCEOF = (byte) 193;
- public final static byte INVOKEINTERFACE = (byte) 185;
- public final static byte INVOKESPECIAL = (byte) 183;
- public final static byte INVOKESTATIC = (byte) 184;
- public final static byte INVOKEVIRTUAL = (byte) 182;
- public final static byte IOR = (byte) 128;
- public final static byte IREM = 112;
- public final static byte IRETURN = (byte) 172;
- public final static byte ISHL = 120;
- public final static byte ISHR = 122;
- public final static byte ISTORE = 54;
- public final static byte ISTORE_0 = 59;
- public final static byte ISTORE_1 = 60;
- public final static byte ISTORE_2 = 61;
- public final static byte ISTORE_3 = 62;
- public final static byte ISUB = 100;
- public final static byte IUSHR = 124;
- public final static byte IXOR = (byte) 130;
- public final static byte JSR = (byte) 168;
- public final static byte JSR_W = (byte) 201;
- public final static byte L2D = (byte) 138;
- public final static byte L2F = (byte) 137;
- public final static byte L2I = (byte) 136;
- public final static byte LADD = 97;
- public final static byte LALOAD = 47;
- public final static byte LAND = 127;
- public final static byte LASTORE = 80;
- public final static byte LCMP = (byte) 148;
- public final static byte LCONST_0 = 9;
- public final static byte LCONST_1 = 10;
- public final static byte LDC = 18;
- public final static byte LDC_W = 19;
- public final static byte LDC2_W = 20;
- public final static byte LDIV = 109;
- public final static byte LLOAD = 22;
- public final static byte LLOAD_0 = 30;
- public final static byte LLOAD_1 = 31;
- public final static byte LLOAD_2 = 32;
- public final static byte LLOAD_3 = 33;
- public final static byte LMUL = 105;
- public final static byte LNEG = 117;
- public final static byte LOOKUPSWITCH = (byte) 171;
- public final static byte LOR = (byte) 129;
- public final static byte LREM = 113;
- public final static byte LRETURN = (byte) 173;
- public final static byte LSHL = 121;
- public final static byte LSHR = 123;
- public final static byte LSTORE = 55;
- public final static byte LSTORE_0 = 63;
- public final static byte LSTORE_1 = 64;
- public final static byte LSTORE_2 = 65;
- public final static byte LSTORE_3 = 66;
- public final static byte LSUB = 101;
- public final static byte LUSHR = 125;
- public final static byte LXOR = (byte) 131;
- public final static byte MONITORENTER = (byte) 194;
- public final static byte MONITOREXIT = (byte) 195;
- public final static byte MULTIANEWARRAY = (byte) 197;
- public final static byte NEW = (byte) 187;
- public final static byte NEWARRAY = (byte) 188;
- public final static byte NOP = 0;
- public final static byte POP = 87;
- public final static byte POP2 = 88;
- public final static byte PUTFIELD = (byte) 181;
- public final static byte PUTSTATIC = (byte) 179;
- public final static byte RET = (byte) 169;
- public final static byte RETURN = (byte) 177;
- public final static byte SALOAD = 53;
- public final static byte SASTORE = 86;
- public final static byte SIPUSH = 17;
- public final static byte SWAP = 95;
- public final static byte TABLESWITCH = (byte) 170;
- public final static byte WIDE = (byte) 196;
-
- /**
- * Constants for the "OPCODE_PROPERTIES" array.
- */
- public static final short INVALID_OPCODE = -1;
-
- // "Stack delta" constants.
- public static final short SD_MASK = 31;
- public static final short SD_M4 = 0;
- public static final short SD_M3 = 1;
- public static final short SD_M2 = 2;
- public static final short SD_M1 = 3;
- public static final short SD_P0 = 4;
- public static final short SD_P1 = 5;
- public static final short SD_P2 = 6;
- public static final short SD_0 = 7;
- public static final short SD_GETFIELD = 9;
- public static final short SD_GETSTATIC = 10;
- public static final short SD_PUTFIELD = 11;
- public static final short SD_PUTSTATIC = 12;
- public static final short SD_INVOKEVIRTUAL = 13;
- public static final short SD_INVOKESPECIAL = 14;
- public static final short SD_INVOKESTATIC = 15;
- public static final short SD_INVOKEINTERFACE = 16;
- public static final short SD_MULTIANEWARRAY = 18;
-
- // Operand 1 types.
- public static final short OP1_MASK = 15 * 32;
- public static final short OP1_SB = 1 * 32;
- public static final short OP1_UB = 2 * 32;
- public static final short OP1_SS = 3 * 32;
- public static final short OP1_CP1 = 4 * 32;
- public static final short OP1_CP2 = 5 * 32;
- public static final short OP1_LV1 = 6 * 32;
- public static final short OP1_LV2 = 7 * 32;
- public static final short OP1_BO2 = 8 * 32;
- public static final short OP1_BO4 = 9 * 32;
- public static final short OP1_LOOKUPSWITCH = 10 * 32;
- public static final short OP1_TABLESWITCH = 11 * 32;
- public static final short OP1_JSR = 12 * 32;
-
- // Operand 2 types.
- public static final short OP2_MASK = 3 * 512;
- public static final short OP2_SB = 1 * 512;
- public static final short OP2_SS = 2 * 512;
-
- // Operand 3 types.
- public static final short OP3_MASK = 1 * 2048;
- public static final short OP3_SB = 1 * 2048;
-
- // Implicit operands.
- public static final short IO_MASK = 7 * 4096;
- public static final short IO_LV_0 = 1 * 4096;
- public static final short IO_LV_1 = 2 * 4096;
- public static final short IO_LV_2 = 3 * 4096;
- public static final short IO_LV_3 = 4 * 4096;
-
- public static final short NO_FALLTHROUGH = (short) 32768;
-
- public static final short[] OPCODE_PROPERTIES = {
-/* 0*/ /*NOP*/ Opcode.SD_P0,
- /*ACONST_NULL*/ Opcode.SD_P1,
- /*ICONST_M1*/ Opcode.SD_P1,
- /*ICONST_0*/ Opcode.SD_P1,
- /*ICONST_1*/ Opcode.SD_P1,
- /*ICONST_2*/ Opcode.SD_P1,
- /*ICONST_3*/ Opcode.SD_P1,
- /*ICONST_4*/ Opcode.SD_P1,
- /*ICONST_5*/ Opcode.SD_P1,
- /*LCONST_0*/ Opcode.SD_P2,
-/* 10*/ /*LCONST_1*/ Opcode.SD_P2,
- /*FCONST_0*/ Opcode.SD_P1,
- /*FCONST_1*/ Opcode.SD_P1,
- /*FCONST_2*/ Opcode.SD_P1,
- /*DCONST_0*/ Opcode.SD_P2,
- /*DCONST_1*/ Opcode.SD_P2,
- /*BIPUSH*/ Opcode.SD_P1 | Opcode.OP1_SB,
- /*SIPUSH*/ Opcode.SD_P1 | Opcode.OP1_SS,
- /*LDC*/ Opcode.SD_P1 | Opcode.OP1_CP1,
- /*LDC_W*/ Opcode.SD_P1 | Opcode.OP1_CP2,
-/* 20*/ /*LDC2_W*/ Opcode.SD_P2 | Opcode.OP1_CP2,
- /*ILOAD*/ Opcode.SD_P1 | Opcode.OP1_LV1,
- /*LLOAD*/ Opcode.SD_P2 | Opcode.OP1_LV1,
- /*FLOAD*/ Opcode.SD_P1 | Opcode.OP1_LV1,
- /*DLOAD*/ Opcode.SD_P2 | Opcode.OP1_LV1,
- /*ALOAD*/ Opcode.SD_P1 | Opcode.OP1_LV1,
- /*ILOAD_0*/ Opcode.SD_P1 | Opcode.IO_LV_0,
- /*ILOAD_1*/ Opcode.SD_P1 | Opcode.IO_LV_1,
- /*ILOAD_2*/ Opcode.SD_P1 | Opcode.IO_LV_2,
- /*ILOAD_3*/ Opcode.SD_P1 | Opcode.IO_LV_3,
-/* 30*/ /*LLOAD_0*/ Opcode.SD_P2 | Opcode.IO_LV_0,
- /*LLOAD_1*/ Opcode.SD_P2 | Opcode.IO_LV_1,
- /*LLOAD_2*/ Opcode.SD_P2 | Opcode.IO_LV_2,
- /*LLOAD_3*/ Opcode.SD_P2 | Opcode.IO_LV_3,
- /*FLOAD_0*/ Opcode.SD_P1 | Opcode.IO_LV_0,
- /*FLOAD_1*/ Opcode.SD_P1 | Opcode.IO_LV_1,
- /*FLOAD_2*/ Opcode.SD_P1 | Opcode.IO_LV_2,
- /*FLOAD_3*/ Opcode.SD_P1 | Opcode.IO_LV_3,
- /*DLOAD_0*/ Opcode.SD_P2 | Opcode.IO_LV_0,
- /*DLOAD_1*/ Opcode.SD_P2 | Opcode.IO_LV_1,
-/* 40*/ /*DLOAD_2*/ Opcode.SD_P2 | Opcode.IO_LV_2,
- /*DLOAD_3*/ Opcode.SD_P2 | Opcode.IO_LV_3,
- /*ALOAD_0*/ Opcode.SD_P1 | Opcode.IO_LV_0,
- /*ALOAD_1*/ Opcode.SD_P1 | Opcode.IO_LV_1,
- /*ALOAD_2*/ Opcode.SD_P1 | Opcode.IO_LV_2,
- /*ALOAD_3*/ Opcode.SD_P1 | Opcode.IO_LV_3,
- /*IALOAD*/ Opcode.SD_M1,
- /*LALOAD*/ Opcode.SD_P0,
- /*FALOAD*/ Opcode.SD_M1,
- /*DALOAD*/ Opcode.SD_P0,
-/* 50*/ /*AALOAD*/ Opcode.SD_M1,
- /*BALOAD*/ Opcode.SD_M1,
- /*CALOAD*/ Opcode.SD_M1,
- /*SALOAD*/ Opcode.SD_M1,
- /*ISTORE*/ Opcode.SD_M1 | Opcode.OP1_LV1,
- /*LSTORE*/ Opcode.SD_M2 | Opcode.OP1_LV1,
- /*FSTORE*/ Opcode.SD_M1 | Opcode.OP1_LV1,
- /*DSTORE*/ Opcode.SD_M2 | Opcode.OP1_LV1,
- /*ASTORE*/ Opcode.SD_M1 | Opcode.OP1_LV1,
- /*ISTORE_0*/ Opcode.SD_M1 | Opcode.IO_LV_0,
-/* 60*/ /*ISTORE_1*/ Opcode.SD_M1 | Opcode.IO_LV_1,
- /*ISTORE_2*/ Opcode.SD_M1 | Opcode.IO_LV_2,
- /*ISTORE_3*/ Opcode.SD_M1 | Opcode.IO_LV_3,
- /*LSTORE_0*/ Opcode.SD_M2 | Opcode.IO_LV_0,
- /*LSTORE_1*/ Opcode.SD_M2 | Opcode.IO_LV_1,
- /*LSTORE_2*/ Opcode.SD_M2 | Opcode.IO_LV_2,
- /*LSTORE_3*/ Opcode.SD_M2 | Opcode.IO_LV_3,
- /*FSTORE_0*/ Opcode.SD_M1 | Opcode.IO_LV_0,
- /*FSTORE_1*/ Opcode.SD_M1 | Opcode.IO_LV_1,
- /*FSTORE_2*/ Opcode.SD_M1 | Opcode.IO_LV_2,
-/* 70*/ /*FSTORE_3*/ Opcode.SD_M1 | Opcode.IO_LV_3,
- /*DSTORE_0*/ Opcode.SD_M2 | Opcode.IO_LV_0,
- /*DSTORE_1*/ Opcode.SD_M2 | Opcode.IO_LV_1,
- /*DSTORE_2*/ Opcode.SD_M2 | Opcode.IO_LV_2,
- /*DSTORE_3*/ Opcode.SD_M2 | Opcode.IO_LV_3,
- /*ASTORE_0*/ Opcode.SD_M1 | Opcode.IO_LV_0,
- /*ASTORE_1*/ Opcode.SD_M1 | Opcode.IO_LV_1,
- /*ASTORE_2*/ Opcode.SD_M1 | Opcode.IO_LV_2,
- /*ASTORE_3*/ Opcode.SD_M1 | Opcode.IO_LV_3,
- /*IASTORE*/ Opcode.SD_M3,
-/* 80*/ /*LASTORE*/ Opcode.SD_M4,
- /*FASTORE*/ Opcode.SD_M3,
- /*DASTORE*/ Opcode.SD_M4,
- /*AASTORE*/ Opcode.SD_M3,
- /*BASTORE*/ Opcode.SD_M3,
- /*CASTORE*/ Opcode.SD_M3,
- /*SASTORE*/ Opcode.SD_M3,
- /*POP*/ Opcode.SD_M1,
- /*POP2*/ Opcode.SD_M2,
- /*DUP*/ Opcode.SD_P1,
-/* 90*/ /*DUP_X1*/ Opcode.SD_P1,
- /*DUP_X2*/ Opcode.SD_P1,
- /*DUP2*/ Opcode.SD_P2,
- /*DUP2_X1*/ Opcode.SD_P2,
- /*DUP2_X2*/ Opcode.SD_P2,
- /*SWAP*/ Opcode.SD_P0,
- /*IADD*/ Opcode.SD_M1,
- /*LADD*/ Opcode.SD_M2,
- /*FADD*/ Opcode.SD_M1,
- /*DADD*/ Opcode.SD_M2,
-/*100*/ /*ISUB*/ Opcode.SD_M1,
- /*LSUB*/ Opcode.SD_M2,
- /*FSUB*/ Opcode.SD_M1,
- /*DSUB*/ Opcode.SD_M2,
- /*IMUL*/ Opcode.SD_M1,
- /*LMUL*/ Opcode.SD_M2,
- /*FMUL*/ Opcode.SD_M1,
- /*DMUL*/ Opcode.SD_M2,
- /*IDIV*/ Opcode.SD_M1,
- /*LDIV*/ Opcode.SD_M2,
-/*110*/ /*FDIV*/ Opcode.SD_M1,
- /*DDIV*/ Opcode.SD_M2,
- /*IREM*/ Opcode.SD_M1,
- /*LREM*/ Opcode.SD_M2,
- /*FREM*/ Opcode.SD_M1,
- /*DREM*/ Opcode.SD_M2,
- /*INEG*/ Opcode.SD_P0,
- /*LNEG*/ Opcode.SD_P0,
- /*FNEG*/ Opcode.SD_P0,
- /*DNEG*/ Opcode.SD_P0,
-/*120*/ /*ISHL*/ Opcode.SD_M1,
- /*LSHL*/ Opcode.SD_M1,
- /*ISHR*/ Opcode.SD_M1,
- /*LSHR*/ Opcode.SD_M1,
- /*IUSHR*/ Opcode.SD_M1,
- /*LUSHR*/ Opcode.SD_M1,
- /*IAND*/ Opcode.SD_M1,
- /*LAND*/ Opcode.SD_M2,
- /*IOR*/ Opcode.SD_M1,
- /*LOR*/ Opcode.SD_M2,
-/*130*/ /*IXOR*/ Opcode.SD_M1,
- /*LXOR*/ Opcode.SD_M2,
- /*IINC*/ Opcode.SD_P0 | Opcode.OP1_LV1 | Opcode.OP2_SB,
- /*I2L*/ Opcode.SD_P1,
- /*I2F*/ Opcode.SD_P0,
- /*I2D*/ Opcode.SD_P1,
- /*L2I*/ Opcode.SD_M1,
- /*L2F*/ Opcode.SD_M1,
- /*L2D*/ Opcode.SD_P0,
- /*F2I*/ Opcode.SD_P0,
-/*140*/ /*F2L*/ Opcode.SD_P1,
- /*F2D*/ Opcode.SD_P1,
- /*D2I*/ Opcode.SD_M1,
- /*D2L*/ Opcode.SD_P0,
- /*D2F*/ Opcode.SD_M1,
- /*I2B*/ Opcode.SD_P0,
- /*I2C*/ Opcode.SD_P0,
- /*I2S*/ Opcode.SD_P0,
- /*LCMP*/ Opcode.SD_M3,
- /*FCMPL*/ Opcode.SD_M1,
-/*150*/ /*FCMPG*/ Opcode.SD_M1,
- /*DCMPL*/ Opcode.SD_M3,
- /*DCMPG*/ Opcode.SD_M3,
- /*IFEQ*/ Opcode.SD_M1 | Opcode.OP1_BO2,
- /*IFNE*/ Opcode.SD_M1 | Opcode.OP1_BO2,
- /*IFLT*/ Opcode.SD_M1 | Opcode.OP1_BO2,
- /*IFGE*/ Opcode.SD_M1 | Opcode.OP1_BO2,
- /*IFGT*/ Opcode.SD_M1 | Opcode.OP1_BO2,
- /*IFLE*/ Opcode.SD_M1 | Opcode.OP1_BO2,
- /*IF_ICMPEQ*/ Opcode.SD_M2 | Opcode.OP1_BO2,
-/*160*/ /*IF_ICMPNE*/ Opcode.SD_M2 | Opcode.OP1_BO2,
- /*IF_ICMPLT*/ Opcode.SD_M2 | Opcode.OP1_BO2,
- /*IF_ICMPGE*/ Opcode.SD_M2 | Opcode.OP1_BO2,
- /*IF_ICMPGT*/ Opcode.SD_M2 | Opcode.OP1_BO2,
- /*IF_ICMPLE*/ Opcode.SD_M2 | Opcode.OP1_BO2,
- /*IF_ACMPEQ*/ Opcode.SD_M2 | Opcode.OP1_BO2,
- /*IF_ACMPNE*/ Opcode.SD_M2 | Opcode.OP1_BO2,
- /*GOTO*/ Opcode.SD_P0 | Opcode.OP1_BO2 | Opcode.NO_FALLTHROUGH,
- /*JSR*/ Opcode.SD_P0 | Opcode.OP1_JSR,
- /*RET*/ Opcode.SD_P0 | Opcode.OP1_LV1 | Opcode.NO_FALLTHROUGH,
-/*170*/ /*TABLESWITCH*/ Opcode.SD_M1 | Opcode.OP1_TABLESWITCH,
- /*LOOKUPSWITCH*/ Opcode.SD_M1 | Opcode.OP1_LOOKUPSWITCH,
- /*IRETURN*/ Opcode.SD_0 | Opcode.NO_FALLTHROUGH,
- /*LRETURN*/ Opcode.SD_0 | Opcode.NO_FALLTHROUGH,
- /*FRETURN*/ Opcode.SD_0 | Opcode.NO_FALLTHROUGH,
- /*DRETURN*/ Opcode.SD_0 | Opcode.NO_FALLTHROUGH,
- /*ARETURN*/ Opcode.SD_M1 | Opcode.NO_FALLTHROUGH,
- /*RETURN*/ Opcode.SD_0 | Opcode.NO_FALLTHROUGH,
- /*GETSTATIC*/ Opcode.SD_GETSTATIC | Opcode.OP1_CP2,
- /*PUTSTATIC*/ Opcode.SD_PUTSTATIC | Opcode.OP1_CP2,
-/*180*/ /*GETFIELD*/ Opcode.SD_GETFIELD | Opcode.OP1_CP2,
- /*PUTFIELD*/ Opcode.SD_PUTFIELD | Opcode.OP1_CP2,
- /*INVOKEVIRTUAL*/ Opcode.SD_INVOKEVIRTUAL | Opcode.OP1_CP2,
- /*INVOKESPECIAL*/ Opcode.SD_INVOKESPECIAL | Opcode.OP1_CP2,
- /*INVOKESTATIC*/ Opcode.SD_INVOKESTATIC | Opcode.OP1_CP2,
- /*INVOKEINTERFACE*/ Opcode.SD_INVOKEINTERFACE | Opcode.OP1_CP2 | Opcode.OP2_SB | Opcode.OP3_SB,
- /*UNUSED*/ Opcode.INVALID_OPCODE,
- /*NEW*/ Opcode.SD_P1 | Opcode.OP1_CP2,
- /*NEWARRAY*/ Opcode.SD_P0 | Opcode.OP1_UB,
- /*ANEWARRAY*/ Opcode.SD_P0 | Opcode.OP1_CP2,
-/*190*/ /*ARRAYLENGTH*/ Opcode.SD_P0,
- /*ATHROW*/ Opcode.SD_M1 | Opcode.NO_FALLTHROUGH,
- /*CHECKCAST*/ Opcode.SD_P0 | Opcode.OP1_CP2,
- /*INSTANCEOF*/ Opcode.SD_P0 | Opcode.OP1_CP2,
- /*MONITORENTER*/ Opcode.SD_M1,
- /*MONITOREXIT*/ Opcode.SD_M1,
- /*WIDE*/ Opcode.INVALID_OPCODE,
- /*MULTIANEWARRAY*/ Opcode.SD_MULTIANEWARRAY | Opcode.OP1_CP2 | Opcode.OP2_SB,
- /*IFNULL*/ Opcode.SD_M1 | Opcode.OP1_BO2,
- /*IFNONNULL*/ Opcode.SD_M1 | Opcode.OP1_BO2,
-/*200*/ /*GOTO_W*/ Opcode.SD_P0 | Opcode.OP1_BO4 | Opcode.NO_FALLTHROUGH,
- /*JSR_W*/ Opcode.SD_P1 | Opcode.OP1_BO4,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/*210*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/*220*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/*230*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/*240*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/*250*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- };
-
- public static final short[] WIDE_OPCODE_PROPERTIES = {
-/* 0*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/*010*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/*020*/ Opcode.INVALID_OPCODE,
- /*ILOAD*/ Opcode.SD_P1 | Opcode.OP1_LV2,
- /*LLOAD*/ Opcode.SD_P2 | Opcode.OP1_LV2,
- /*FLOAD*/ Opcode.SD_P1 | Opcode.OP1_LV2,
- /*DLOAD*/ Opcode.SD_P2 | Opcode.OP1_LV2,
- /*ALOAD*/ Opcode.SD_P1 | Opcode.OP1_LV2,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/* 30*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/* 40*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/* 50*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- /*ISTORE*/ Opcode.SD_M1 | Opcode.OP1_LV2,
- /*LSTORE*/ Opcode.SD_M2 | Opcode.OP1_LV2,
- /*FSTORE*/ Opcode.SD_M1 | Opcode.OP1_LV2,
- /*DSTORE*/ Opcode.SD_M2 | Opcode.OP1_LV2,
- /*ASTORE*/ Opcode.SD_M1 | Opcode.OP1_LV2,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/* 60*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/* 70*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/* 80*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/* 90*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/*100*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/*110*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/*120*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/*130*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- /*IINC*/ Opcode.SD_P0 | Opcode.OP1_LV2 | Opcode.OP2_SS,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/*140*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/*150*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/*160*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE,
- /*RET*/ Opcode.SD_P0 | Opcode.OP1_LV2,
-/*170*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/*180*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/*190*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/*200*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/*210*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/*220*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/*230*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/*240*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/*250*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
- };
-}
diff --git a/src/org/codehaus/janino/Parser.java b/src/org/codehaus/janino/Parser.java
deleted file mode 100644
index 929333f..0000000
--- a/src/org/codehaus/janino/Parser.java
+++ /dev/null
@@ -1,2540 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino;
-
-import java.io.*;
-import java.util.*;
-
-import org.codehaus.janino.Java.CompilationUnit.ImportDeclaration;
-import org.codehaus.janino.util.LocatedException;
-import org.codehaus.janino.util.enumerator.Enumerator;
-
-/**
- * A parser for the Java<sup>TM</sup> programming language.
- */
-public class Parser {
- private final Scanner scanner;
-
- public Parser(Scanner scanner) {
- this.scanner = scanner;
- }
-
- public Scanner getScanner() {
- return this.scanner;
- }
-
- /**
- * <pre>
- * CompilationUnit := [ PackageDeclaration ]
- * { ImportDeclaration }
- * { TypeDeclaration }
- * </pre>
- */
- public Java.CompilationUnit parseCompilationUnit() throws ParseException, Scanner.ScanException, IOException {
- Java.CompilationUnit compilationUnit = new Java.CompilationUnit(this.location().getFileName());
-
- if (this.peekKeyword("package")) {
- compilationUnit.setPackageDeclaration(this.parsePackageDeclaration());
- }
-
- while (this.peekKeyword("import")) {
- compilationUnit.addImportDeclaration(this.parseImportDeclaration());
- }
-
- while (!this.scanner.peek().isEOF()) {
- if (this.peekOperator(";")) {
- this.eatToken();
- } else
- {
- compilationUnit.addPackageMemberTypeDeclaration(this.parsePackageMemberTypeDeclaration());
- }
- }
-
- return compilationUnit;
- }
-
- /**
- * <pre>
- * PackageDeclaration := 'package' QualifiedIdentifier ';'
- * </pre>
- */
- public Java.PackageDeclaration parsePackageDeclaration() throws Parser.ParseException, Scanner.ScanException, IOException {
- this.readKeyword("package");
- Location loc = this.location();
- String packageName = Parser.join(this.parseQualifiedIdentifier(), ".");
- this.readOperator(";");
- this.verifyStringIsConventionalPackageName(packageName, loc);
- return new Java.PackageDeclaration(loc, packageName);
- }
-
- /**
- * <pre>
- * ImportDeclaration := 'import' ImportDeclarationBody ';'
- * </pre>
- */
- public Java.CompilationUnit.ImportDeclaration parseImportDeclaration() throws ParseException, Scanner.ScanException, IOException {
- this.readKeyword("import");
- Java.CompilationUnit.ImportDeclaration importDeclaration = this.parseImportDeclarationBody();
- this.readOperator(";");
- return importDeclaration;
- }
-
- /**
- * <pre>
- * ImportDeclarationBody := [ 'static' ] Identifier { '.' Identifier } [ '.' '*' ]
- * </pre>
- */
- public Java.CompilationUnit.ImportDeclaration parseImportDeclarationBody() throws ParseException, Scanner.ScanException, IOException {
- Location loc = this.location();
- boolean isStatic;
- if (this.peekKeyword("static")) {
- isStatic = true;
- this.eatToken();
- } else
- {
- isStatic = false;
- }
- List l = new ArrayList();
- l.add(this.readIdentifier());
- for (;;) {
- if (!this.peekOperator(".")) {
- String[] identifiers = (String[]) l.toArray(new String[l.size()]);
- return (
- isStatic
- ? (ImportDeclaration) new Java.CompilationUnit.SingleStaticImportDeclaration(loc, identifiers)
- : (ImportDeclaration) new Java.CompilationUnit.SingleTypeImportDeclaration(loc, identifiers)
- );
- }
- this.readOperator(".");
- if (this.peekOperator("*")) {
- this.eatToken();
- String[] identifiers = (String[]) l.toArray(new String[l.size()]);
- return (
- isStatic
- ? (ImportDeclaration) new Java.CompilationUnit.StaticImportOnDemandDeclaration(loc, identifiers)
- : (ImportDeclaration) new Java.CompilationUnit.TypeImportOnDemandDeclaration(loc, identifiers)
- );
- }
- l.add(this.readIdentifier());
- }
- }
-
- /**
- * QualifiedIdentifier := Identifier { '.' Identifier }
- */
- public String[] parseQualifiedIdentifier() throws ParseException, Scanner.ScanException, IOException {
- if (!this.scanner.peek().isIdentifier()) this.throwParseException("Identifier expected");
- List l = new ArrayList();
- l.add(this.readIdentifier());
- while (this.peekOperator(".") && this.scanner.peekNextButOne().isIdentifier()) {
- this.eatToken();
- l.add(this.readIdentifier());
- }
- return (String[]) l.toArray(new String[l.size()]);
- }
-
- /**
- * <pre>
- * PackageMemberTypeDeclaration :=
- * ModifiersOpt 'class' ClassDeclarationRest |
- * ModifiersOpt 'interface' InterfaceDeclarationRest
- * </pre>
- */
- public Java.PackageMemberTypeDeclaration parsePackageMemberTypeDeclaration() throws ParseException, Scanner.ScanException, IOException {
- String optionalDocComment = this.scanner.doc();
-
- short modifiers = this.parseModifiersOpt();
-
- Java.PackageMemberTypeDeclaration res;
- if (this.peekKeyword("class")) {
- if (optionalDocComment == null) this.warning("CDCM", "Class doc comment missing", this.location());
- this.eatToken();
- res = (Java.PackageMemberClassDeclaration) this.parseClassDeclarationRest(
- optionalDocComment, // optionalDocComment
- modifiers, // modifiers
- ClassDeclarationContext.COMPILATION_UNIT // context
- );
- } else
- if (this.peekKeyword("interface")) {
- if (optionalDocComment == null) this.warning("IDCM", "Interface doc comment missing", this.location());
- this.eatToken();
- res = (Java.PackageMemberInterfaceDeclaration) this.parseInterfaceDeclarationRest(
- optionalDocComment, // optionalDocComment
- modifiers, // modifiers
- InterfaceDeclarationContext.COMPILATION_UNIT // context
- );
- } else
- {
- this.throwParseException("Unexpected token \"" + this.scanner.peek() + "\" in class or interface declaration");
- /* NEVER REACHED */ return null;
- }
- return res;
- }
-
- /**
- * <pre>
- * ModifiersOpt := { 'public' | 'protected' | 'private' | 'static' |
- * 'abstract' | 'final' | 'native' | 'synchronized' |
- * 'transient' | 'volatile' | 'strictfp'
- * </pre>
- */
- public short parseModifiersOpt() throws ParseException, Scanner.ScanException, IOException {
- short mod = 0;
- while (this.peekKeyword()) {
- String kw = this.scanner.peek().getKeyword();
- short x = (short) (
- kw == "public" ? Mod.PUBLIC :
- kw == "protected" ? Mod.PROTECTED :
- kw == "private" ? Mod.PRIVATE :
- kw == "static" ? Mod.STATIC :
- kw == "abstract" ? Mod.ABSTRACT :
- kw == "final" ? Mod.FINAL :
- kw == "native" ? Mod.NATIVE :
- kw == "synchronized" ? Mod.SYNCHRONIZED :
- kw == "transient" ? Mod.TRANSIENT :
- kw == "volatile" ? Mod.VOLATILE :
- kw == "strictfp" ? Mod.STRICTFP :
- -1
- );
- if (x == -1) break;
-
- this.eatToken();
- if ((mod & x) != 0) this.throwParseException("Duplicate modifier \"" + kw + "\"");
- for (int i = 0; i < Parser.MUTUALS.length; ++i) {
- short m = Parser.MUTUALS[i];
- if ((x & m) != 0 && (mod & m) != 0) {
- this.throwParseException("Only one of \"" + Mod.shortToString(m) + "\" allowed");
- }
- }
- mod |= x;
- }
- return mod;
- }
- private static final short[] MUTUALS = {
- Mod.PUBLIC | Mod.PROTECTED | Mod.PRIVATE,
- };
-
- /**
- * <pre>
- * ClassDeclarationRest :=
- * Identifier
- * [ 'extends' ReferenceType ]
- * [ 'implements' ReferenceTypeList ]
- * ClassBody
- * </pre>
- */
- public Java.NamedClassDeclaration parseClassDeclarationRest(
- String optionalDocComment,
- short modifiers,
- ClassDeclarationContext context
- ) throws ParseException, Scanner.ScanException, IOException {
- Location location = this.location();
- String className = this.readIdentifier();
- this.verifyIdentifierIsConventionalClassOrInterfaceName(className, location);
-
- Java.ReferenceType optionalExtendedType = null;
- if (this.peekKeyword("extends")) {
- this.eatToken();
- optionalExtendedType = this.parseReferenceType();
- }
-
- Java.ReferenceType[] implementedTypes = new Java.ReferenceType[0];
- if (this.peekKeyword("implements")) {
- this.eatToken();
- implementedTypes = this.parseReferenceTypeList();
- }
-
- Java.NamedClassDeclaration namedClassDeclaration;
- if (context == ClassDeclarationContext.COMPILATION_UNIT) {
- namedClassDeclaration = new Java.PackageMemberClassDeclaration(
- location, // location
- optionalDocComment, // optionalDocComment
- modifiers, // modifiers
- className, // name
- optionalExtendedType, // optinalExtendedType
- implementedTypes // implementedTypes
- );
- } else
- if (context == ClassDeclarationContext.TYPE_DECLARATION) {
- namedClassDeclaration = new Java.MemberClassDeclaration(
- location, // location
- optionalDocComment, // optionalDocComment
- modifiers, // modifiers
- className, // name
- optionalExtendedType, // optionalExtendedType
- implementedTypes // implementedTypes
- );
- } else
- if (context == ClassDeclarationContext.BLOCK) {
- namedClassDeclaration = new Java.LocalClassDeclaration(
- location, // location
- optionalDocComment, // optionalDocComment
- modifiers, // modifiers
- className, // name
- optionalExtendedType, // optionalExtendedType
- implementedTypes // implementedTypes
- );
- } else
- {
- throw new RuntimeException("SNO: Class declaration in unexpected context " + context);
- }
-
- this.parseClassBody(namedClassDeclaration);
- return namedClassDeclaration;
- }
- public static class ClassDeclarationContext extends Enumerator {
- public static final ClassDeclarationContext BLOCK = new ClassDeclarationContext("block");
- public static final ClassDeclarationContext TYPE_DECLARATION = new ClassDeclarationContext("type_declaration");
- public static final ClassDeclarationContext COMPILATION_UNIT = new ClassDeclarationContext("compilation_unit");
- private ClassDeclarationContext(String name) { super(name); }
- }
-
- /**
- * <pre>
- * ClassBody := '{' { ClassBodyDeclaration } '}'
- * </pre>
- */
- public void parseClassBody(
- Java.ClassDeclaration classDeclaration
- ) throws ParseException, Scanner.ScanException, IOException {
- if (!this.peekOperator("{")) this.throwParseException("\"{\" expected at start of class body");
- this.eatToken();
-
- for (;;) {
- if (this.peekOperator("}")) {
- this.eatToken();
- return;
- }
-
- this.parseClassBodyDeclaration(classDeclaration);
- }
- }
-
- /**
- * <pre>
- * ClassBodyDeclaration :=
- * ';' |
- * ModifiersOpt (
- * Block | // Instance (JLS2 8.6) or static initializer (JLS2 8.7)
- * 'void' Identifier MethodDeclarationRest |
- * 'class' ClassDeclarationRest |
- * 'interface' InterfaceDeclarationRest |
- * ConstructorDeclarator |
- * Type Identifier (
- * MethodDeclarationRest |
- * FieldDeclarationRest ';'
- * )
- * )
- *
- * </pre>
- */
- public void parseClassBodyDeclaration(
- Java.ClassDeclaration classDeclaration
- ) throws ParseException, Scanner.ScanException, IOException {
- if (this.peekOperator(";")) {
- this.eatToken();
- return;
- }
-
- String optionalDocComment = this.scanner.doc();
- short modifiers = this.parseModifiersOpt();
-
- // Initializer?
- if (this.peekOperator("{")) {
- if ((modifiers & ~Mod.STATIC) != 0) this.throwParseException("Only modifier \"static\" allowed on initializer");
-
- Java.Initializer initializer = new Java.Initializer(
- this.location(), // location
- (modifiers & Mod.STATIC) != 0, // statiC
- this.parseBlock() // block
- );
-
- classDeclaration.addVariableDeclaratorOrInitializer(initializer);
- return;
- }
-
- // "void" method declaration.
- if (this.peekKeyword("void")) {
- Location location = this.location();
- this.eatToken();
- if (optionalDocComment == null) this.warning("MDCM", "Method doc comment missing", location);
- String name = this.readIdentifier();
- classDeclaration.addDeclaredMethod(this.parseMethodDeclarationRest(
- optionalDocComment, // declaringType
- modifiers, // optionalDocComment
- new Java.BasicType(location, Java.BasicType.VOID), // modifiers
- name // name
- ));
- return;
- }
-
- // Member class.
- if (this.peekKeyword("class")) {
- if (optionalDocComment == null) this.warning("MCDCM", "Member class doc comment missing", this.location());
- this.eatToken();
- classDeclaration.addMemberTypeDeclaration((Java.MemberTypeDeclaration) this.parseClassDeclarationRest(
- optionalDocComment, // optionalDocComment
- modifiers, // modifiers
- ClassDeclarationContext.TYPE_DECLARATION // context
- ));
- return;
- }
-
- // Member interface.
- if (this.peekKeyword("interface")) {
- if (optionalDocComment == null) this.warning("MIDCM", "Member interface doc comment missing", this.location());
- this.eatToken();
- classDeclaration.addMemberTypeDeclaration((Java.MemberTypeDeclaration) this.parseInterfaceDeclarationRest(
- optionalDocComment, // optionalDocComment
- (short) (modifiers | Mod.STATIC), // modifiers
- InterfaceDeclarationContext.NAMED_TYPE_DECLARATION // context
- ));
- return;
- }
-
- // Constructor.
- if (
- classDeclaration instanceof Java.NamedClassDeclaration &&
- this.scanner.peek().isIdentifier(((Java.NamedClassDeclaration) classDeclaration).getName()) &&
- this.scanner.peekNextButOne().isOperator("(")
- ) {
- if (optionalDocComment == null) this.warning("CDCM", "Constructor doc comment missing", this.location());
- classDeclaration.addConstructor(this.parseConstructorDeclarator(
- optionalDocComment, // declaringClass
- modifiers // modifiers
- ));
- return;
- }
-
- // Member method or field.
- Java.Type memberType = this.parseType();
- Location location = this.location();
- String memberName = this.readIdentifier();
-
- // Method declarator.
- if (this.peekOperator("(")) {
- if (optionalDocComment == null) this.warning("MDCM", "Method doc comment missing", this.location());
- classDeclaration.addDeclaredMethod(this.parseMethodDeclarationRest(
- optionalDocComment, // declaringType
- modifiers, // optionalDocComment
- memberType, // modifiers
- memberName // name
- ));
- return;
- }
-
- // Field declarator.
- if (optionalDocComment == null) this.warning("FDCM", "Field doc comment missing", this.location());
- Java.FieldDeclaration fd = new Java.FieldDeclaration(
- location, // location
- optionalDocComment, // optionalDocComment
- modifiers, // modifiers
- memberType, // type
- this.parseFieldDeclarationRest(memberName) // variableDeclarators
- );
- this.readOperator(";");
- classDeclaration.addVariableDeclaratorOrInitializer(fd);
- }
-
- /**
- * <pre>
- * InterfaceDeclarationRest :=
- * Identifier
- * [ 'extends' ReferenceTypeList ]
- * InterfaceBody
- * </pre>
- */
- public Java.InterfaceDeclaration parseInterfaceDeclarationRest(
- String optionalDocComment,
- short modifiers,
- InterfaceDeclarationContext context
- ) throws ParseException, Scanner.ScanException, IOException {
- Location location = this.location();
- String interfaceName = this.readIdentifier();
- this.verifyIdentifierIsConventionalClassOrInterfaceName(interfaceName, location);
-
- Java.ReferenceType[] extendedTypes = new Java.ReferenceType[0];
- if (this.peekKeyword("extends")) {
- this.eatToken();
- extendedTypes = this.parseReferenceTypeList();
- }
-
- Java.InterfaceDeclaration interfaceDeclaration;
- if (context == InterfaceDeclarationContext.COMPILATION_UNIT) {
- interfaceDeclaration = new Java.PackageMemberInterfaceDeclaration(
- location, // location
- optionalDocComment, // optionalDocComment
- modifiers, // modifiers
- interfaceName, // name
- extendedTypes // extendedTypes
- );
- } else
- if (context == InterfaceDeclarationContext.NAMED_TYPE_DECLARATION) {
- interfaceDeclaration = new Java.MemberInterfaceDeclaration(
- location, // location
- optionalDocComment, // optionalDocComment
- modifiers, // modifiers
- interfaceName, // name
- extendedTypes // extendedTypes
- );
- } else
- {
- throw new RuntimeException("SNO: Interface declaration in unexpected context " + context);
- }
-
- this.parseInterfaceBody(interfaceDeclaration);
- return interfaceDeclaration;
- }
- public static class InterfaceDeclarationContext extends Enumerator {
- public static final InterfaceDeclarationContext NAMED_TYPE_DECLARATION = new InterfaceDeclarationContext("named_type_declaration");
- public static final InterfaceDeclarationContext COMPILATION_UNIT = new InterfaceDeclarationContext("compilation_unit");
- private InterfaceDeclarationContext(String name) { super(name); }
- }
-
- /**
- * <pre>
- * InterfaceBody := '{' {
- * ';' |
- * ModifiersOpt (
- * 'void' Identifier MethodDeclarationRest |
- * 'class' ClassDeclarationRest |
- * 'interface' InterfaceDeclarationRest |
- * Type Identifier (
- * MethodDeclarationRest |
- * FieldDeclarationRest
- * )
- * )
- * } '}'
- * </pre>
- */
- public void parseInterfaceBody(
- Java.InterfaceDeclaration interfaceDeclaration
- ) throws ParseException, Scanner.ScanException, IOException {
- this.readOperator("{");
-
- for (;;) {
- if (this.peekOperator("}")) {
- this.eatToken();
- break;
- }
-
- if (this.peekOperator(";")) {
- this.eatToken();
- continue;
- }
-
- String optionalDocComment = this.scanner.doc();
- short modifiers = this.parseModifiersOpt();
-
- // "void" method declaration.
- if (this.peekKeyword("void")) {
- if (optionalDocComment == null) this.warning("MDCM", "Method doc comment missing", this.location());
- Location location = this.location();
- this.eatToken();
- String name = this.readIdentifier();
- interfaceDeclaration.addDeclaredMethod(this.parseMethodDeclarationRest(
- optionalDocComment, // declaringType
- (short) (modifiers | Mod.ABSTRACT | Mod.PUBLIC), // optionalDocComment
- new Java.BasicType(location, Java.BasicType.VOID), // modifiers
- name // name
- ));
- } else
-
- // Member class.
- if (this.peekKeyword("class")) {
- if (optionalDocComment == null) this.warning("MCDCM", "Member class doc comment missing", this.location());
- this.eatToken();
- interfaceDeclaration.addMemberTypeDeclaration((Java.MemberTypeDeclaration) this.parseClassDeclarationRest(
- optionalDocComment, // optionalDocComment
- (short) (modifiers | Mod.STATIC | Mod.PUBLIC), // modifiers
- ClassDeclarationContext.TYPE_DECLARATION // context
- ));
- } else
-
- // Member interface.
- if (this.peekKeyword("interface")) {
- if (optionalDocComment == null) this.warning("MIDCM", "Member interface doc comment missing", this.location());
- this.eatToken();
- interfaceDeclaration.addMemberTypeDeclaration((Java.MemberTypeDeclaration) this.parseInterfaceDeclarationRest(
- optionalDocComment, // optionalDocComment
- (short) (modifiers | Mod.STATIC | Mod.PUBLIC), // modifiers
- InterfaceDeclarationContext.NAMED_TYPE_DECLARATION // context
- ));
- } else
-
- // Member method or field.
- {
- Java.Type memberType = this.parseType();
- if (!this.scanner.peek().isIdentifier()) this.throwParseException("Identifier expected in member declaration");
- Location location = this.location();
- String memberName = this.readIdentifier();
-
- // Method declarator.
- if (this.peekOperator("(")) {
- if (optionalDocComment == null) this.warning("MDCM", "Method doc comment missing", this.location());
- interfaceDeclaration.addDeclaredMethod(this.parseMethodDeclarationRest(
- optionalDocComment, // declaringType
- (short) (modifiers | Mod.ABSTRACT | Mod.PUBLIC), // optionalDocComment
- memberType, // modifiers
- memberName // name
- ));
- } else
-
- // Field declarator.
- {
- if (optionalDocComment == null) this.warning("FDCM", "Field doc comment missing", this.location());
- Java.FieldDeclaration fd = new Java.FieldDeclaration(
- location, // location
- optionalDocComment, // optionalDocComment
- (short) ( // modifiers
- modifiers |
- Mod.PUBLIC | Mod.STATIC | Mod.FINAL
- ),
- memberType, // type
- this.parseFieldDeclarationRest(memberName) // variableDeclarators
- );
- interfaceDeclaration.addConstantDeclaration(fd);
- }
- }
- }
- }
-
- /**
- * <pre>
- * ConstructorDeclarator :=
- * Identifier
- * FormalParameters
- * [ 'throws' ReferenceTypeList ]
- * '{'
- * [ 'this' Arguments ';' | 'super' Arguments ';' | Primary '.' 'super' Arguments ';' ]
- * BlockStatements
- * '}'
- * </pre>
- */
- public Java.ConstructorDeclarator parseConstructorDeclarator(
- String optionalDocComment,
- short modifiers
- ) throws ParseException, Scanner.ScanException, IOException {
- Location location = this.location();
- this.readIdentifier(); // Class name
-
- // Parse formal parameters.
- Java.FunctionDeclarator.FormalParameter[] formalParameters = this.parseFormalParameters(
- );
-
- // Parse "throws" clause.
- Java.ReferenceType[] thrownExceptions;
- if (this.peekKeyword("throws")) {
- this.eatToken();
- thrownExceptions = this.parseReferenceTypeList();
- } else {
- thrownExceptions = new Java.ReferenceType[0];
- }
-
- // Parse constructor body.
- location = this.location();
- this.readOperator("{");
-
- // Special treatment for the first statement of the constructor body: If this is surely an
- // expression statement, and if it could be a "ConstructorInvocation", then parse the
- // expression and check if it IS a ConstructorInvocation.
- Java.ConstructorInvocation optionalConstructorInvocation = null;
- Java.Block body = new Java.Block(location);
- if (
- this.peekKeyword(new String[] {
- "this", "super", "new", "void",
- "byte", "char", "short", "int", "long", "float", "double", "boolean",
- } ) ||
- this.scanner.peek().isLiteral() ||
- this.scanner.peek().isIdentifier()
- ) {
- Java.Atom a = this.parseExpression();
- if (a instanceof Java.ConstructorInvocation) {
- this.readOperator(";");
- optionalConstructorInvocation = (Java.ConstructorInvocation) a;
- } else {
- Java.Statement s;
- if (this.scanner.peek().isIdentifier()) {
- Java.Type variableType = a.toTypeOrPE();
- s = new Java.LocalVariableDeclarationStatement(
- a.getLocation(), // location
- (short) 0, // modifiers
- variableType, // type
- this.parseLocalVariableDeclarators() // variableDeclarators
- );
- this.readOperator(";");
- } else {
- s = new Java.ExpressionStatement(a.toRvalueOrPE());
- this.readOperator(";");
- }
- body.addStatement(s);
- }
- }
- body.addStatements(this.parseBlockStatements());
-
- this.readOperator("}");
-
- return new Java.ConstructorDeclarator(
- location, // location
- optionalDocComment, // optionalDocComment
- modifiers, // modifiers
- formalParameters, // formalParameters
- thrownExceptions, // thrownExceptions
- optionalConstructorInvocation, // optionalConstructorInvocationStatement
- body // body
- );
- }
-
- /**
- * <pre>
- * MethodDeclarationRest :=
- * FormalParameters
- * { '[' ']' }
- * [ 'throws' ReferenceTypeList ]
- * ( ';' | MethodBody )
- * </pre>
- */
- public Java.MethodDeclarator parseMethodDeclarationRest(
- String optionalDocComment,
- short modifiers,
- Java.Type type,
- String name
- ) throws ParseException, Scanner.ScanException, IOException {
- Location location = this.location();
-
- this.verifyIdentifierIsConventionalMethodName(name, location);
-
- Java.FunctionDeclarator.FormalParameter[] formalParameters = this.parseFormalParameters(
- );
-
- for (int i = this.parseBracketsOpt(); i > 0; --i) type = new Java.ArrayType(type);
-
- Java.ReferenceType[] thrownExceptions;
- if (this.peekKeyword("throws")) {
- this.eatToken();
- thrownExceptions = this.parseReferenceTypeList();
- } else {
- thrownExceptions = new Java.ReferenceType[0];
- }
-
- Java.Block optionalBody;
- if (this.peekOperator(";")) {
- if ((modifiers & (Mod.ABSTRACT | Mod.NATIVE)) == 0) this.throwParseException("Non-abstract, non-native method must have a body");
- this.eatToken();
- optionalBody = null;
- } else {
- if ((modifiers & (Mod.ABSTRACT | Mod.NATIVE)) != 0) this.throwParseException("Abstract or native method must not have a body");
- optionalBody = this.parseMethodBody();
- }
- return new Java.MethodDeclarator(
- location, // location
- optionalDocComment, // optionalDocComment
- modifiers, // modifiers
- type, // type
- name, // name
- formalParameters, // formalParameters
- thrownExceptions, // thrownExceptions
- optionalBody // optionalBody
- );
- }
-
- /**
- * <pre>
- * VariableInitializer :=
- * ArrayInitializer |
- * Expression
- * </pre>
- */
- public Java.ArrayInitializerOrRvalue parseVariableInitializer() throws ParseException, Scanner.ScanException, IOException {
- if (this.peekOperator("{")) {
- return this.parseArrayInitializer();
- } else
- {
- return this.parseExpression().toRvalueOrPE();
- }
- }
-
- /**
- * <pre>
- * ArrayInitializer :=
- * '{' [ VariableInitializer { ',' VariableInitializer } [ ',' ] '}'
- * </pre>
- */
- public Java.ArrayInitializer parseArrayInitializer() throws ParseException, Scanner.ScanException, IOException {
- Location location = this.location();
- this.readOperator("{");
- List l = new ArrayList(); // ArrayInitializerOrRvalue
- while (!this.peekOperator("}")) {
- l.add(this.parseVariableInitializer());
- if (this.peekOperator("}")) break;
- if (!this.peekOperator(",")) this.throwParseException("\",\" or \"}\" expected");
- this.eatToken();
- }
- this.eatToken();
- return new Java.ArrayInitializer(
- location,
- (Java.ArrayInitializerOrRvalue[]) l.toArray(new Java.ArrayInitializerOrRvalue[l.size()])
- );
- }
-
- /**
- * <pre>
- * FormalParameters := '(' [ FormalParameter { ',' FormalParameter } ] ')'
- * </pre>
- */
- public Java.FunctionDeclarator.FormalParameter[] parseFormalParameters()
- throws ParseException, Scanner.ScanException, IOException {
- this.readOperator("(");
- if (this.peekOperator(")")) {
- this.eatToken();
- return new Java.FunctionDeclarator.FormalParameter[0];
- }
-
- List l = new ArrayList(); // Java.FormalParameter
- for (;;) {
- l.add(this.parseFormalParameter());
- if (!this.peekOperator(",")) break;
- this.eatToken();
- }
- this.readOperator(")");
- return (Java.FunctionDeclarator.FormalParameter[]) l.toArray(new Java.FunctionDeclarator.FormalParameter[l.size()]);
- }
-
- /**
- * <pre>
- * FormalParameter := [ 'final' ] Type Identifier BracketsOpt
- * </pre>
- */
- public Java.FunctionDeclarator.FormalParameter parseFormalParameter() throws ParseException, Scanner.ScanException, IOException {
- boolean finaL = this.peekKeyword("final");
- if (finaL) this.eatToken();
-
- Java.Type type = this.parseType();
-
- Location location = this.location();
- String name = this.readIdentifier();
- this.verifyIdentifierIsConventionalLocalVariableOrParameterName(name, location);
-
- for (int i = this.parseBracketsOpt(); i > 0; --i) type = new Java.ArrayType(type);
- return new Java.FunctionDeclarator.FormalParameter(location, finaL, type, name);
- }
-
- /**
- * <pre>
- * BracketsOpt := { '[' ']' }
- * </pre>
- */
- int parseBracketsOpt() throws Scanner.ScanException, IOException {
- int res = 0;
- while (
- this.scanner.peek(). isOperator("[") &&
- this.scanner.peekNextButOne().isOperator("]")
- ) {
- this.eatToken();
- this.eatToken();
- ++res;
- }
- return res;
- }
-
- /**
- * <pre>
- * MethodBody := Block
- * </pre>
- */
- public Java.Block parseMethodBody() throws ParseException, Scanner.ScanException, IOException {
- return this.parseBlock();
- }
-
- /**
- * <pre>
- * '{' BlockStatements '}'
- * </pre>
- */
- public Java.Block parseBlock() throws ParseException, Scanner.ScanException, IOException {
- Java.Block block = new Java.Block(this.location());
- this.readOperator("{");
- block.addStatements(this.parseBlockStatements());
- this.readOperator("}");
- return block;
- }
-
- /**
- * <pre>
- * BlockStatements := { BlockStatement }
- * </pre>
- */
- public List parseBlockStatements() throws ParseException, Scanner.ScanException, IOException {
- List l = new ArrayList();
- while (
- !this.peekOperator("}") &&
- !this.peekKeyword("case") &&
- !this.peekKeyword("default")
- ) l.add(this.parseBlockStatement());
- return l;
- }
-
- /**
- * <pre>
- * BlockStatement := { Identifier ':' } (
- * ( Modifiers Type | ModifiersOpt BasicType ) LocalVariableDeclarators ';' |
- * 'class' ... |
- * Statement |
- * 'final' Type LocalVariableDeclarators ';' |
- * Expression ';' |
- * Expression LocalVariableDeclarators ';' (1)
- * )
- * </pre>
- *
- * (1) "Expression" must pose a type, and has optional trailing brackets.
- */
- public Java.BlockStatement parseBlockStatement() throws ParseException, Scanner.ScanException, IOException {
-
- // Statement?
- if (
- (
- this.scanner.peek().isIdentifier() &&
- this.scanner.peekNextButOne().isOperator(":")
- ) ||
- this.peekKeyword(new String[] {
- "if", "for", "while", "do", "try", "switch", "synchronized",
- "return", "throw", "break", "continue"
- }) ||
- this.peekOperator(new String[] { "{", ";" })
- ) return this.parseStatement();
-
- // Local class declaration?
- if (this.peekKeyword("class")) {
- // JAVADOC[TM] ignores doc comments for local classes, but we
- // don't...
- String optionalDocComment = this.scanner.doc();
- if (optionalDocComment == null) this.warning("LCDCM", "Local class doc comment missing", this.location());
-
- this.eatToken();
- final Java.LocalClassDeclaration lcd = (Java.LocalClassDeclaration) this.parseClassDeclarationRest(
- optionalDocComment, // optionalDocComment
- Mod.NONE, // modifiers
- ClassDeclarationContext.BLOCK // context
- );
- return new Java.LocalClassDeclarationStatement(lcd);
- }
-
- // 'final' Type LocalVariableDeclarators ';'
- if (this.peekKeyword("final")) {
- Location location = this.location();
- this.eatToken();
- Java.Type variableType = this.parseType();
- Java.LocalVariableDeclarationStatement lvds = new Java.LocalVariableDeclarationStatement(
- location, // location
- Mod.FINAL, // modifiers
- variableType, // type
- this.parseLocalVariableDeclarators() // variableDeclarators
- );
- this.readOperator(";");
- return lvds;
- }
-
- // It's either a non-final local variable declaration or an expression statement. We can
- // only tell after parsing an expression.
- Java.Atom a = this.parseExpression();
-
- // Expression ';'
- if (this.peekOperator(";")) {
- this.eatToken();
- return new Java.ExpressionStatement(a.toRvalueOrPE());
- }
-
- // Expression LocalVariableDeclarators ';'
- Java.Type variableType = a.toTypeOrPE();
- Java.LocalVariableDeclarationStatement lvds = new Java.LocalVariableDeclarationStatement(
- a.getLocation(), // location
- Mod.NONE, // modifiers
- variableType, // type
- this.parseLocalVariableDeclarators() // variableDeclarators
- );
- this.readOperator(";");
- return lvds;
- }
-
- /**
- * <pre>
- * LocalVariableDeclarators := VariableDeclarator { ',' VariableDeclarator }
- * </pre>
- */
- public Java.VariableDeclarator[] parseLocalVariableDeclarators() throws ParseException, Scanner.ScanException, IOException {
- List l = new ArrayList();
- for (;;) {
- Java.VariableDeclarator vd = this.parseVariableDeclarator();
- this.verifyIdentifierIsConventionalLocalVariableOrParameterName(vd.name, vd.getLocation());
- l.add(vd);
- if (!this.peekOperator(",")) break;
- this.eatToken();
- }
- return (Java.VariableDeclarator[]) l.toArray(new Java.VariableDeclarator[l.size()]);
- }
-
- /**
- * <pre>
- * FieldDeclarationRest :=
- * VariableDeclaratorRest
- * { ',' VariableDeclarator }
- * </pre>
- */
- public Java.VariableDeclarator[] parseFieldDeclarationRest(String name) throws ParseException, Scanner.ScanException, IOException {
- List l = new ArrayList();
-
- Java.VariableDeclarator vd = this.parseVariableDeclaratorRest(name);
- this.verifyIdentifierIsConventionalFieldName(vd.name, vd.getLocation());
- l.add(vd);
-
- while (this.peekOperator(",")) {
- this.eatToken();
-
- vd = this.parseVariableDeclarator();
- this.verifyIdentifierIsConventionalFieldName(vd.name, vd.getLocation());
- l.add(vd);
- }
- return (Java.VariableDeclarator[]) l.toArray(new Java.VariableDeclarator[l.size()]);
- }
-
- /**
- * <pre>
- * VariableDeclarator := Identifier VariableDeclaratorRest
- * </pre>
- */
- public Java.VariableDeclarator parseVariableDeclarator() throws ParseException, Scanner.ScanException, IOException {
- return this.parseVariableDeclaratorRest(this.readIdentifier());
- }
-
- /**
- * <pre>
- * VariableDeclaratorRest := { '[' ']' } [ '=' VariableInitializer ]
- * </pre>
- * Used by field declarations and local variable declarations.
- */
- public Java.VariableDeclarator parseVariableDeclaratorRest(String name) throws ParseException, Scanner.ScanException, IOException {
- Location loc = this.location();
- int brackets = this.parseBracketsOpt();
- Java.ArrayInitializerOrRvalue initializer = null;
- if (this.peekOperator("=")) {
- this.eatToken();
- initializer = this.parseVariableInitializer();
- }
- return new Java.VariableDeclarator(loc, name, brackets, initializer);
- }
-
- /**
- * <pre>
- * Statement :=
- * LabeledStatement |
- * Block |
- * IfStatement |
- * ForStatement |
- * WhileStatement |
- * DoStatement |
- * TryStatement |
- * 'switch' ... |
- * 'synchronized' ... |
- * ReturnStatement |
- * ThrowStatement |
- * BreakStatement |
- * ContinueStatement |
- * EmptyStatement |
- * ExpressionStatement
- * </pre>
- */
- public Java.Statement parseStatement() throws ParseException, Scanner.ScanException, IOException {
- if (
- this.scanner.peek().isIdentifier() &&
- this.scanner.peekNextButOne().isOperator(":")
- ) {
- return this.parseLabeledStatement();
- }
-
- Scanner.Token t = this.scanner.peek();
- Java.Statement stmt = (
- t.isOperator("{") ? this.parseBlock() :
- t.isKeyword("if") ? this.parseIfStatement() :
- t.isKeyword("for") ? this.parseForStatement() :
- t.isKeyword("while") ? this.parseWhileStatement() :
- t.isKeyword("do") ? this.parseDoStatement() :
- t.isKeyword("try") ? this.parseTryStatement() :
- t.isKeyword("switch") ? this.parseSwitchStatement() :
- t.isKeyword("synchronized") ? this.parseSynchronizedStatement() :
- t.isKeyword("return") ? this.parseReturnStatement() :
- t.isKeyword("throw") ? this.parseThrowStatement() :
- t.isKeyword("break") ? this.parseBreakStatement() :
- t.isKeyword("continue") ? this.parseContinueStatement() :
- t.isOperator(";") ? this.parseEmptyStatement() :
- this.parseExpressionStatement()
- );
- if (stmt == null) this.throwParseException("\"" + t.getKeyword() + "\" NYI");
-
- return stmt;
- }
-
- /**
- * <pre>
- * LabeledStatement := Identifier ':' Statement
- * </pre>
- */
- public Java.Statement parseLabeledStatement() throws ParseException, Scanner.ScanException, IOException {
- String label = this.readIdentifier();
- this.readOperator(":");
- return new Java.LabeledStatement(
- this.location(), // location
- label, // label
- this.parseStatement() // body
- );
- }
-
- /**
- * <pre>
- * IfStatement := 'if' '(' Expression ')' Statement [ 'else' Statement ]
- * </pre>
- */
- public Java.Statement parseIfStatement() throws ParseException, Scanner.ScanException, IOException {
- Location location = this.location();
- this.readKeyword("if");
- this.readOperator("(");
- final Java.Rvalue condition = this.parseExpression().toRvalueOrPE();
- this.readOperator(")");
-
- Java.Statement thenStatement = this.parseStatement();
-
- Java.Statement optionalElseStatement = null;
- if (this.peekKeyword("else")) {
- this.eatToken();
- optionalElseStatement = this.parseStatement();
- }
-
- return new Java.IfStatement(
- location, // location
- condition, // condition
- thenStatement, // thenStatement
- optionalElseStatement // optionalElseStatement
- );
- }
-
- /**
- * <pre>
- * ForStatement :=
- * 'for' '('
- * [ ForInit ] ';'
- * [ Expression ] ';'
- * [ ExpressionList ]
- * ')' Statement
- * </pre>
- */
- public Java.Statement parseForStatement() throws ParseException, Scanner.ScanException, IOException {
- Location location = this.location();
- this.readKeyword("for");
-
- this.readOperator("(");
-
- Java.BlockStatement optionalInit = null;
- if (!this.peekOperator(";")) optionalInit = this.parseForInit();
-
- this.readOperator(";");
-
- Java.Rvalue optionalCondition = null;
- if (!this.peekOperator(";")) optionalCondition = this.parseExpression().toRvalueOrPE();
-
- this.readOperator(";");
-
- Java.Rvalue[] optionalUpdate = null;
- if (!this.peekOperator(")")) optionalUpdate = this.parseExpressionList();
-
- this.readOperator(")");
-
- // KLUDGE: Insert an implicit Block here.
-// Java.Block implicitBlock = new Java.Block(location);
- return /*Java.ForStatement forStatement =*/ new Java.ForStatement(
- location, // location
- optionalInit, // optionalInit
- optionalCondition, // optionalCondition
- optionalUpdate, // optionalUpdate
- this.parseStatement() // body
- );
-// implicitBlock.addStatement(forStatement);
-
-// return implicitBlock;
- }
-
- /**
- * <pre>
- * ForInit :=
- * Modifiers Type LocalVariableDeclarators |
- * ModifiersOpt BasicType LocalVariableDeclarators |
- * Expression (
- * LocalVariableDeclarators | (1)
- * { ',' Expression }
- * )
- * </pre>
- *
- * (1) "Expression" must pose a type.
- */
- private Java.BlockStatement parseForInit() throws ParseException, Scanner.ScanException, IOException {
-
- // Modifiers Type LocalVariableDeclarators
- // ModifiersOpt BasicType LocalVariableDeclarators
- if (this.peekKeyword(new String[] { "final", "byte", "short", "char", "int", "long", "float", "double", "boolean" })) {
- short modifiers = this.parseModifiersOpt();
- Java.Type variableType = this.parseType();
- return new Java.LocalVariableDeclarationStatement(
- this.location(), // location
- modifiers, // modifiers
- variableType, // type
- this.parseLocalVariableDeclarators() // variableDeclarators
- );
- }
-
- Java.Atom a = this.parseExpression();
-
- // Expression LocalVariableDeclarators
- if (this.scanner.peek().isIdentifier()) {
- Java.Type variableType = a.toTypeOrPE();
- return new Java.LocalVariableDeclarationStatement(
- a.getLocation(), // location
- Mod.NONE, // modifiers
- variableType, // type
- this.parseLocalVariableDeclarators() // variableDeclarators
- );
- }
-
- // Expression { ',' Expression }
- if (!this.peekOperator(",")) {
- return new Java.ExpressionStatement(a.toRvalueOrPE());
- }
- this.eatToken();
- List l = new ArrayList();
- l.add(new Java.ExpressionStatement(a.toRvalueOrPE()));
- for (;;) {
- l.add(new Java.ExpressionStatement(this.parseExpression().toRvalueOrPE()));
- if (!this.peekOperator(",")) break;
- this.eatToken();
- }
-
- Java.Block b = new Java.Block(a.getLocation());
- b.addStatements(l);
- return b;
- }
-
- /**
- * <pre>
- * WhileStatement := 'while' '(' Expression ')' Statement
- * </pre>
- */
- public Java.Statement parseWhileStatement() throws ParseException, Scanner.ScanException, IOException {
- Location location = this.location();
- this.readKeyword("while");
-
- this.readOperator("(");
- Java.Rvalue condition = this.parseExpression().toRvalueOrPE();
- this.readOperator(")");
-
- return new Java.WhileStatement(
- location, // location
- condition, // condition
- this.parseStatement() // body
- );
- }
-
- /**
- * <pre>
- * DoStatement := 'do' Statement 'while' '(' Expression ')' ';'
- * </pre>
- */
- public Java.Statement parseDoStatement() throws ParseException, Scanner.ScanException, IOException {
- Location location = this.location();
- this.readKeyword("do");
-
- Java.Statement body = this.parseStatement();
-
- this.readKeyword("while");
- this.readOperator("(");
- Java.Rvalue condition = this.parseExpression().toRvalueOrPE();
- this.readOperator(")");
- this.readOperator(";");
-
- return new Java.DoStatement(
- location, // location
- body, // body
- condition // condition
- );
- }
-
- /**
- * <pre>
- * TryStatement :=
- * 'try' Block Catches [ Finally ] |
- * 'try' Block Finally
- *
- * Catches := CatchClause { CatchClause }
- *
- * CatchClause := 'catch' '(' FormalParameter ')' Block
- *
- * Finally := 'finally' Block
- * </pre>
- */
- public Java.Statement parseTryStatement() throws ParseException, Scanner.ScanException, IOException {
- Location location = this.location();
- this.readKeyword("try");
-
- Java.Block body = this.parseBlock();
-
- // { CatchClause }
- List ccs = new ArrayList();
- while (this.peekKeyword("catch")) {
- Location loc = this.location();
- this.eatToken();
- this.readOperator("(");
- Java.FunctionDeclarator.FormalParameter caughtException = this.parseFormalParameter();
- this.readOperator(")");
- ccs.add(new Java.CatchClause(
- loc, // location
- caughtException, // caughtException
- this.parseBlock() // body
- ));
- }
- Java.Block optionalFinally = null;
- if (this.peekKeyword("finally")) {
- this.eatToken();
- optionalFinally = this.parseBlock();
- }
- if (ccs.size() == 0 && optionalFinally == null) this.throwParseException("\"try\" statement must have at least one \"catch\" clause or a \"finally\" clause");
-
- return new Java.TryStatement(
- location, // location
- body, // body
- ccs, // catchClauses
- optionalFinally // optionalFinally
- );
- }
-
- /**
- * <pre>
- * SwitchStatement :=
- * 'switch' '(' Expression ')' '{' { SwitchLabels BlockStatements } '}'
- *
- * SwitchLabels := SwitchLabels { SwitchLabels }
- *
- * SwitchLabel := 'case' Expression ':' | 'default' ':'
- * </pre>
- */
- public Java.Statement parseSwitchStatement() throws ParseException, Scanner.ScanException, IOException {
- Location location = this.location();
- this.readKeyword("switch");
-
- this.readOperator("(");
- Java.Rvalue condition = this.parseExpression().toRvalueOrPE();
- this.readOperator(")");
-
- this.readOperator("{");
- List sbsgs = new ArrayList();
- while (!this.peekOperator("}")) {
- Location location2 = this.location();
- boolean hasDefaultLabel = false;
- List caseLabels = new ArrayList();
- do {
- if (this.peekKeyword("case")) {
- this.eatToken();
- caseLabels.add(this.parseExpression().toRvalueOrPE());
- } else
- if (this.peekKeyword("default")) {
- this.eatToken();
- if (hasDefaultLabel) this.throwParseException("Duplicate \"default\" label");
- hasDefaultLabel = true;
- } else {
- this.throwParseException("\"case\" or \"default\" expected");
- }
- this.readOperator(":");
- } while (this.peekKeyword(new String[] { "case", "default" }));
-
- Java.SwitchStatement.SwitchBlockStatementGroup sbsg = new Java.SwitchStatement.SwitchBlockStatementGroup(
- location2, // location
- caseLabels, // caseLabels
- hasDefaultLabel, // hasDefaultLabel
- this.parseBlockStatements() // blockStatements
- );
- sbsgs.add(sbsg);
- }
- this.eatToken();
- return new Java.SwitchStatement(
- location, // location
- condition, // condition
- sbsgs // sbsgs
- );
- }
-
- /**
- * <pre>
- * SynchronizedStatement :=
- * 'synchronized' '(' expression ')' Block
- * </pre>
- */
- public Java.Statement parseSynchronizedStatement() throws ParseException, Scanner.ScanException, IOException {
- Location location = this.location();
- this.readKeyword("synchronized");
- this.readOperator("(");
- Java.Rvalue expression = this.parseExpression().toRvalueOrPE();
- this.readOperator(")");
- return new Java.SynchronizedStatement(
- location, // location
- expression, // expression
- this.parseBlock() // body
- );
- }
-
- /**
- * <pre>
- * ReturnStatement := 'return' [ Expression ] ';'
- * </pre>
- */
- public Java.Statement parseReturnStatement() throws ParseException, Scanner.ScanException, IOException {
- Location location = this.location();
- this.readKeyword("return");
- Java.Rvalue returnValue = this.peekOperator(";") ? null : this.parseExpression().toRvalueOrPE();
- this.readOperator(";");
- return new Java.ReturnStatement(location, returnValue);
- }
-
- /**
- * <pre>
- * ThrowStatement := 'throw' Expression ';'
- * </pre>
- */
- public Java.Statement parseThrowStatement() throws ParseException, Scanner.ScanException, IOException {
- Location location = this.location();
- this.readKeyword("throw");
- final Java.Rvalue expression = this.parseExpression().toRvalueOrPE();
- this.readOperator(";");
-
- return new Java.ThrowStatement(location, expression);
- }
-
- /**
- * <pre>
- * BreakStatement := 'break' [ Identifier ] ';'
- * </pre>
- */
- public Java.Statement parseBreakStatement() throws ParseException, Scanner.ScanException, IOException {
- Location location = this.location();
- this.readKeyword("break");
- String optionalLabel = null;
- if (this.scanner.peek().isIdentifier()) optionalLabel = this.readIdentifier();
- this.readOperator(";");
- return new Java.BreakStatement(location, optionalLabel);
- }
-
- /**
- * <pre>
- * ContinueStatement := 'continue' [ Identifier ] ';'
- * </pre>
- */
- public Java.Statement parseContinueStatement() throws ParseException, Scanner.ScanException, IOException {
- Location location = this.location();
- this.readKeyword("continue");
- String optionalLabel = null;
- if (this.scanner.peek().isIdentifier()) optionalLabel = this.readIdentifier();
- this.readOperator(";");
- return new Java.ContinueStatement(location, optionalLabel);
- }
-
- /**
- * <pre>
- * EmptyStatement := ';'
- * </pre>
- */
- public Java.Statement parseEmptyStatement() throws ParseException, Scanner.ScanException, IOException {
- Location location = this.location();
- this.readOperator(";");
- return new Java.EmptyStatement(location);
- }
-
- /**
- * <pre>
- * ExpressionList := Expression { ',' Expression }
- * </pre>
- */
- public Java.Rvalue[] parseExpressionList() throws ParseException, Scanner.ScanException, IOException {
- List l = new ArrayList();
- for (;;) {
- l.add(this.parseExpression().toRvalueOrPE());
- if (!this.peekOperator(",")) break;
- this.eatToken();
- }
- return (Java.Rvalue[]) l.toArray(new Java.Rvalue[l.size()]);
- }
-
- /**
- * <pre>
- * Type := (
- * 'byte' | 'short' | 'char' | 'int' | 'long' |
- * 'float' | 'double' | 'boolean' |
- * ReferenceType
- * ) { '[' ']' }
- * </pre>
- */
- public Java.Type parseType() throws ParseException, Scanner.ScanException, IOException {
- Scanner.Token t = this.scanner.peek();
- int bt = -1;
- if (t.isKeyword("byte" )) { bt = Java.BasicType.BYTE ; } else
- if (t.isKeyword("short" )) { bt = Java.BasicType.SHORT ; } else
- if (t.isKeyword("char" )) { bt = Java.BasicType.CHAR ; } else
- if (t.isKeyword("int" )) { bt = Java.BasicType.INT ; } else
- if (t.isKeyword("long" )) { bt = Java.BasicType.LONG ; } else
- if (t.isKeyword("float" )) { bt = Java.BasicType.FLOAT ; } else
- if (t.isKeyword("double" )) { bt = Java.BasicType.DOUBLE ; } else
- if (t.isKeyword("boolean")) { bt = Java.BasicType.BOOLEAN; }
- Java.Type res;
- if (bt != -1) {
- res = new Java.BasicType(t.getLocation(), bt);
- this.eatToken();
- } else {
- res = this.parseReferenceType();
- }
- for (int i = this.parseBracketsOpt(); i > 0; --i) res = new Java.ArrayType(res);
- return res;
- }
-
- /**
- * <pre>
- * ReferenceType := QualifiedIdentifier
- * </pre>
- */
- public Java.ReferenceType parseReferenceType() throws ParseException, Scanner.ScanException, IOException {
- return new Java.ReferenceType(
- this.location(), // location
- this.parseQualifiedIdentifier() // identifiers
- );
- }
-
- /**
- * <pre>
- * ReferenceTypeList := ReferenceType { ',' ReferenceType }
- * </pre>
- */
- public Java.ReferenceType[] parseReferenceTypeList() throws ParseException, Scanner.ScanException, IOException {
- List l = new ArrayList();
- l.add(this.parseReferenceType());
- while (this.peekOperator(",")) {
- this.eatToken();
- l.add(this.parseReferenceType());
- }
- return (Java.ReferenceType[]) l.toArray(new Java.ReferenceType[l.size()]);
- }
-
- /**
- * <pre>
- * Expression := AssignmentExpression
- * </pre>
- */
- public Java.Atom parseExpression() throws ParseException, Scanner.ScanException, IOException {
- return this.parseAssignmentExpression();
- }
-
- /**
- * <pre>
- * AssignmentExpression :=
- * ConditionalExpression [ AssignmentOperator AssignmentExpression ]
- *
- * AssignmentOperator :=
- * '=' | '*=' | '/=' | '%=' | '+=' | '-=' | '<<=' |
- * '>>=' | '>>>=' | '&=' | '^=' | '|='
- * </pre>
- */
- public Java.Atom parseAssignmentExpression() throws ParseException, Scanner.ScanException, IOException {
- Java.Atom a = this.parseConditionalExpression();
- if (this.peekOperator(new String[] { "=", "+=", "-=", "*=", "/=", "&=", "|=", "^=", "%=", "<<=", ">>=", ">>>=" })) {
- Location location = this.location();
- String operator = this.readOperator();
- final Java.Lvalue lhs = a.toLvalueOrPE();
- final Java.Rvalue rhs = this.parseAssignmentExpression().toRvalueOrPE();
- return new Java.Assignment(location, lhs, operator, rhs);
- }
- return a;
- }
-
- /**
- * <pre>
- * ConditionalExpression :=
- * ConditionalOrExpression [ '?' Expression ':' ConditionalExpression ]
- * </pre>
- */
- public Java.Atom parseConditionalExpression() throws ParseException, Scanner.ScanException, IOException {
- Java.Atom a = this.parseConditionalOrExpression();
- if (!this.peekOperator("?")) return a;
- Location location = this.location();
- this.eatToken();
-
- Java.Rvalue lhs = a.toRvalueOrPE();
- Java.Rvalue mhs = this.parseExpression().toRvalueOrPE();
- this.readOperator(":");
- Java.Rvalue rhs = this.parseConditionalExpression().toRvalueOrPE();
- return new Java.ConditionalExpression(location, lhs, mhs, rhs);
- }
-
- /**
- * <pre>
- * ConditionalOrExpression :=
- * ConditionalAndExpression { '||' ConditionalAndExpression ]
- * </pre>
- */
- public Java.Atom parseConditionalOrExpression() throws ParseException, Scanner.ScanException, IOException {
- Java.Atom a = this.parseConditionalAndExpression();
- while (this.peekOperator("||")) {
- Location location = this.location();
- this.eatToken();
- a = new Java.BinaryOperation(
- location,
- a.toRvalueOrPE(),
- "||",
- this.parseConditionalAndExpression().toRvalueOrPE()
- );
- }
- return a;
- }
-
- /**
- * <pre>
- * ConditionalAndExpression :=
- * InclusiveOrExpression { '&&' InclusiveOrExpression }
- * </pre>
- */
- public Java.Atom parseConditionalAndExpression() throws ParseException, Scanner.ScanException, IOException {
- Java.Atom a = this.parseInclusiveOrExpression();
- while (this.peekOperator("&&")) {
- Location location = this.location();
- this.eatToken();
- a = new Java.BinaryOperation(
- location,
- a.toRvalueOrPE(),
- "&&",
- this.parseInclusiveOrExpression().toRvalueOrPE()
- );
- }
- return a;
- }
-
- /**
- * <pre>
- * InclusiveOrExpression :=
- * ExclusiveOrExpression { '|' ExclusiveOrExpression }
- * </pre>
- */
- public Java.Atom parseInclusiveOrExpression() throws ParseException, Scanner.ScanException, IOException {
- Java.Atom a = this.parseExclusiveOrExpression();
- while (this.peekOperator("|")) {
- Location location = this.location();
- this.eatToken();
- a = new Java.BinaryOperation(
- location,
- a.toRvalueOrPE(),
- "|",
- this.parseExclusiveOrExpression().toRvalueOrPE()
- );
- }
- return a;
- }
-
- /**
- * <pre>
- * ExclusiveOrExpression :=
- * AndExpression { '^' AndExpression }
- * </pre>
- */
- public Java.Atom parseExclusiveOrExpression() throws ParseException, Scanner.ScanException, IOException {
- Java.Atom a = this.parseAndExpression();
- while (this.peekOperator("^")) {
- Location location = this.location();
- this.eatToken();
- a = new Java.BinaryOperation(
- location,
- a.toRvalueOrPE(),
- "^",
- this.parseAndExpression().toRvalueOrPE()
- );
- }
- return a;
- }
-
- /**
- * <pre>
- * AndExpression :=
- * EqualityExpression { '&' EqualityExpression }
- * </pre>
- */
- public Java.Atom parseAndExpression() throws ParseException, Scanner.ScanException, IOException {
- Java.Atom a = this.parseEqualityExpression();
- while (this.peekOperator("&")) {
- Location location = this.location();
- this.eatToken();
- a = new Java.BinaryOperation(
- location,
- a.toRvalueOrPE(),
- "&",
- this.parseEqualityExpression().toRvalueOrPE()
- );
- }
- return a;
- }
-
- /**
- * <pre>
- * EqualityExpression :=
- * RelationalExpression { ( '==' | '!=' ) RelationalExpression }
- * </pre>
- */
- public Java.Atom parseEqualityExpression() throws ParseException, Scanner.ScanException, IOException {
- Java.Atom a = this.parseRelationalExpression();
-
- while (this.peekOperator(new String[] { "==", "!=" })) {
- a = new Java.BinaryOperation(
- this.location(), // location
- a.toRvalueOrPE(), // lhs
- this.readOperator(), // op
- this.parseRelationalExpression().toRvalueOrPE() // rhs
- );
- }
- return a;
- }
-
- /**
- * <pre>
- * RelationalExpression :=
- * ShiftExpression {
- * ( ( '<' | '>' | '<=' | '>=' ) ShiftExpression ) |
- * ( 'instanceof' ReferenceType )
- * }
- * </pre>
- */
- public Java.Atom parseRelationalExpression() throws ParseException, Scanner.ScanException, IOException {
- Java.Atom a = this.parseShiftExpression();
-
- for (;;) {
- if (this.peekKeyword("instanceof")) {
- Location location = this.location();
- this.eatToken();
- a = new Java.Instanceof(
- location,
- a.toRvalueOrPE(),
- this.parseType()
- );
- } else
- if (this.peekOperator(new String[] { "<", ">", "<=", ">=" })) {
- a = new Java.BinaryOperation(
- this.location(), // location
- a.toRvalueOrPE(), // lhs
- this.readOperator(), // op
- this.parseShiftExpression().toRvalueOrPE() // rhs
- );
- } else {
- return a;
- }
- }
- }
-
- /**
- * <pre>
- * ShiftExpression :=
- * AdditiveExpression { ( '<<' | '>>' | '>>>' ) AdditiveExpression }
- * </pre>
- */
- public Java.Atom parseShiftExpression() throws ParseException, Scanner.ScanException, IOException {
- Java.Atom a = this.parseAdditiveExpression();
-
- while (this.peekOperator(new String[] { "<<", ">>", ">>>" })) {
- a = new Java.BinaryOperation(
- this.location(), // location
- a.toRvalueOrPE(), // lhs
- this.readOperator(), // op
- this.parseAdditiveExpression().toRvalueOrPE() // rhs
- );
- }
- return a;
- }
-
- /**
- * <pre>
- * AdditiveExpression :=
- * MultiplicativeExpression { ( '+' | '-' ) MultiplicativeExpression }
- * </pre>
- */
- public Java.Atom parseAdditiveExpression() throws ParseException, Scanner.ScanException, IOException {
- Java.Atom a = this.parseMultiplicativeExpression();
-
- while (this.peekOperator(new String[] { "+", "-" })) {
- a = new Java.BinaryOperation(
- this.location(), // location
- a.toRvalueOrPE(), // lhs
- this.readOperator(), // op
- this.parseMultiplicativeExpression().toRvalueOrPE() // rhs
- );
- }
- return a;
- }
-
- /**
- * <pre>
- * MultiplicativeExpression :=
- * UnaryExpression { ( '*' | '/' | '%' ) UnaryExpression }
- * </pre>
- */
- public Java.Atom parseMultiplicativeExpression() throws ParseException, Scanner.ScanException, IOException {
- Java.Atom a = this.parseUnaryExpression();
-
- while (this.peekOperator(new String[] { "*", "/", "%" })) {
- a = new Java.BinaryOperation(
- this.location(), // location
- a.toRvalueOrPE(), // lhs
- this.readOperator(), // op
- this.parseUnaryExpression().toRvalueOrPE() // rhs
- );
- }
- return a;
- }
-
- /**
- * <pre>
- * UnaryExpression :=
- * { PrefixOperator } Primary { Selector } { PostfixOperator }
- *
- * PrefixOperator := '++' | '--' | '+' | '-' | '~' | '!'
- *
- * PostfixOperator := '++' | '--'
- * </pre>
- */
- public Java.Atom parseUnaryExpression() throws ParseException, Scanner.ScanException, IOException {
- if (this.peekOperator(new String[] { "++", "--" })) {
- return new Java.Crement(
- this.location(), // location
- this.readOperator(), // operator
- this.parseUnaryExpression().toLvalueOrPE() // operand
- );
- }
-
- if (this.peekOperator(new String[] { "+", "-", "~", "!" })) {
- return new Java.UnaryOperation(
- this.location(), // location
- this.readOperator(), // operator
- this.parseUnaryExpression().toRvalueOrPE() // operand
- );
- }
-
- Java.Atom a = this.parsePrimary();
-
- while (this.peekOperator(new String[] { ".", "[" })) {
- a = this.parseSelector(a);
- }
-
- while (this.peekOperator(new String[] { "++", "--" })) {
- a = new Java.Crement(
- this.location(), // location
- a.toLvalueOrPE(), // operand
- this.readOperator() // operator
- );
- }
-
- return a;
- }
-
- /**
- * <pre>
- * Primary :=
- * CastExpression | // CastExpression 15.16
- * '(' Expression ')' | // ParenthesizedExpression 15.8.5
- * Literal | // Literal 15.8.1
- * Name | // AmbiguousName
- * Name Arguments | // MethodInvocation
- * Name '[]' { '[]' } | // ArrayType 10.1
- * Name '[]' { '[]' } '.' 'class' | // ClassLiteral 15.8.2
- * 'this' | // This 15.8.3
- * 'this' Arguments | // Alternate constructor invocation 8.8.5.1
- * 'super' Arguments | // Unqualified superclass constructor invocation 8.8.5.1
- * 'super' '.' Identifier | // SuperclassFieldAccess 15.11.2
- * 'super' '.' Identifier Arguments | // SuperclassMethodInvocation 15.12.4.9
- * NewClassInstance |
- * NewAnonymousClassInstance | // ClassInstanceCreationExpression 15.9
- * NewArray | // ArrayCreationExpression 15.10
- * NewInitializedArray | // ArrayInitializer 10.6
- * BasicType { '[]' } | // Type
- * BasicType { '[]' } '.' 'class' | // ClassLiteral 15.8.2
- * 'void' '.' 'class' // ClassLiteral 15.8.2
- *
- * CastExpression :=
- * '(' PrimitiveType { '[]' } ')' UnaryExpression |
- * '(' Expression ')' UnaryExpression
- *
- * NewClassInstance := 'new' ReferenceType Arguments
- *
- * NewAnonymousClassInstance := 'new' ReferenceType Arguments [ ClassBody ]
- *
- * NewArray := 'new' Type DimExprs { '[]' }
- *
- * NewInitializedArray := 'new' ArrayType ArrayInitializer
- * </pre>
- */
- public Java.Atom parsePrimary() throws ParseException, Scanner.ScanException, IOException {
- if (this.peekOperator("(")) {
- this.eatToken();
- if (this.peekKeyword(new String[] { "boolean", "char", "byte", "short", "int", "long", "float", "double", })) {
- // '(' PrimitiveType { '[]' } ')' UnaryExpression
- Java.Type type = this.parseType();
- int brackets = this.parseBracketsOpt();
- this.readOperator(")");
- for (int i = 0; i < brackets; ++i) type = new Java.ArrayType(type);
- return new Java.Cast(
- this.location(), // location
- type, // targetType
- this.parseUnaryExpression().toRvalueOrPE() // value
- );
- }
- Java.Atom a = this.parseExpression();
- this.readOperator(")");
-
- if (
- this.scanner.peek().isLiteral() ||
- this.scanner.peek().isIdentifier() ||
- this.peekOperator(new String[] { "(", "~", "!", }) ||
- this.peekKeyword(new String[] { "this", "super", "new", } )
- ) {
- // '(' Expression ')' UnaryExpression
- return new Java.Cast(
- this.location(), // location
- a.toTypeOrPE(), // targetType
- this.parseUnaryExpression().toRvalueOrPE() // value
- );
- }
-
- // '(' Expression ')'
- return new Java.ParenthesizedExpression(a.getLocation(), a.toRvalueOrPE());
- }
-
- if (this.scanner.peek().isLiteral()) {
- // Literal
- return this.parseLiteral();
- }
-
- if (this.scanner.peek().isIdentifier()) {
- Location location = this.location();
- String[] qi = this.parseQualifiedIdentifier();
- if (this.peekOperator("(")) {
- // Name Arguments
- return new Java.MethodInvocation(
- this.location(), // location
- qi.length == 1 ? null : new Java.AmbiguousName( // optionalTarget
- location, // location
- qi, // identifiers
- qi.length - 1 // n
- ),
- qi[qi.length - 1], // methodName
- this.parseArguments() // arguments
- );
- }
- if (
- this.peekOperator("[")
- && this.scanner.peekNextButOne().isOperator("]")
- ) {
- // Name '[]' { '[]' }
- // Name '[]' { '[]' } '.' 'class'
- Java.Type res = new Java.ReferenceType(
- location, // location
- qi // identifiers
- );
- int brackets = this.parseBracketsOpt();
- for (int i = 0; i < brackets; ++i) res = new Java.ArrayType(res);
- if (
- this.peekOperator(".")
- && this.scanner.peekNextButOne().isKeyword("class")
- ) {
- this.eatToken();
- Location location2 = this.location();
- this.eatToken();
- return new Java.ClassLiteral(location2, res);
- } else {
- return res;
- }
- }
- // Name
- return new Java.AmbiguousName(
- this.location(), // location
- qi // identifiers
- );
- }
-
- if (this.peekKeyword("this")) {
- Location location = this.location();
- this.eatToken();
- if (this.peekOperator("(")) {
-
- // 'this' Arguments
- // Alternate constructor invocation (JLS 8.8.5.1)
- return new Java.AlternateConstructorInvocation(
- location, // location
- this.parseArguments() // arguments
- );
- } else
- {
-
- // 'this'
- return new Java.ThisReference(location);
- }
- }
-
- if (this.peekKeyword("super")) {
- this.eatToken();
- if (this.peekOperator("(")) {
-
- // 'super' Arguments
- // Unqualified superclass constructor invocation (JLS 8.8.5.1)
- return new Java.SuperConstructorInvocation(
- this.location(), // location
- (Java.Rvalue) null, // optionalQualification
- this.parseArguments() // arguments
- );
- }
- this.readOperator(".");
- String name = this.readIdentifier();
- if (this.peekOperator("(")) {
-
- // 'super' '.' Identifier Arguments
- return new Java.SuperclassMethodInvocation(
- this.location(), // location
- name, // methodName
- this.parseArguments() // arguments
- );
- } else {
-
- // 'super' '.' Identifier
- return new Java.SuperclassFieldAccessExpression(
- this.location(), // location
- (Java.Type) null, // optionalQualification
- name // fieldName
- );
- }
- }
-
- // 'new'
- if (this.peekKeyword("new")) {
- Location location = this.location();
- this.eatToken();
- Java.Type type = this.parseType();
- if (type instanceof Java.ArrayType) {
- // 'new' ArrayType ArrayInitializer
- return new Java.NewInitializedArray(location, (Java.ArrayType) type, this.parseArrayInitializer());
- }
- if (
- type instanceof Java.ReferenceType
- && this.peekOperator("(")
- ) {
- // 'new' ReferenceType Arguments [ ClassBody ]
- Java.Rvalue[] arguments = this.parseArguments();
- if (this.peekOperator("{")) {
- // 'new' ReferenceType Arguments ClassBody
- final Java.AnonymousClassDeclaration anonymousClassDeclaration = new Java.AnonymousClassDeclaration(
- this.location(), // location
- type // baseType
- );
- this.parseClassBody(anonymousClassDeclaration);
- return new Java.NewAnonymousClassInstance(
- location, // location
- (Java.Rvalue) null, // optionalQualification
- anonymousClassDeclaration, // anonymousClassDeclaration
- arguments // arguments
- );
- } else {
- // 'new' ReferenceType Arguments
- return new Java.NewClassInstance(
- location, // location
- (Java.Rvalue) null, // optionalQualification
- type, // type
- arguments // arguments
- );
- }
- }
- // 'new' Type DimExprs { '[]' }
- return new Java.NewArray(
- location, // location
- type, // type
- this.parseDimExprs(), // dimExprs
- this.parseBracketsOpt() // dims
- );
- }
-
- // BasicType
- if (this.peekKeyword(new String[] { "boolean", "char", "byte", "short", "int", "long", "float", "double", })) {
- Java.Type res = this.parseType();
- int brackets = this.parseBracketsOpt();
- for (int i = 0; i < brackets; ++i) res = new Java.ArrayType(res);
- if (
- this.peekOperator(".")
- && this.scanner.peekNextButOne().isKeyword("class")
- ) {
- // BasicType { '[]' } '.' 'class'
- this.eatToken();
- Location location = this.location();
- this.eatToken();
- return new Java.ClassLiteral(location, res);
- }
- // BasicType { '[]' }
- return res;
- }
-
- // 'void'
- if (this.peekKeyword("void")) {
- this.eatToken();
- if (
- this.peekOperator(".")
- && this.scanner.peekNextButOne().isKeyword("class")
- ) {
- // 'void' '.' 'class'
- this.eatToken();
- Location location = this.location();
- this.eatToken();
- return new Java.ClassLiteral(location, new Java.BasicType(location, Java.BasicType.VOID));
- }
- this.throwParseException("\"void\" encountered in wrong context");
- }
-
- this.throwParseException("Unexpected token \"" + this.scanner.peek() + "\" in primary");
- /* NEVER REACHED */ return null;
- }
-
- /**
- * <pre>
- * Selector :=
- * '.' Identifier | // FieldAccess 15.11.1
- * '.' Identifier Arguments | // MethodInvocation
- * '.' 'this' // QualifiedThis 15.8.4
- * '.' 'super' Arguments // Qualified superclass constructor invocation (JLS 8.8.5.1)
- * '.' 'super' '.' Identifier | // SuperclassFieldReference (JLS 15.11.2)
- * '.' 'super' '.' Identifier Arguments | // SuperclassMethodInvocation (JLS 15.12.4.9)
- * '.' 'new' Identifier Arguments [ ClassBody ] | // QualifiedClassInstanceCreationExpression 15.9
- * '.' 'class'
- * '[' Expression ']' // ArrayAccessExpression 15.13
- * </pre>
- */
- public Java.Atom parseSelector(Java.Atom atom) throws ParseException, Scanner.ScanException, IOException {
- if (this.peekOperator(".")) {
- this.eatToken();
- if (this.scanner.peek().isIdentifier()) {
- String identifier = this.readIdentifier();
- if (this.peekOperator("(")) {
- // '.' Identifier Arguments
- return new Java.MethodInvocation(
- this.location(), // location
- atom.toRvalueOrPE(), // optionalTarget
- identifier, // methodName
- this.parseArguments() // arguments
- );
- }
- // '.' Identifier
- return new Java.FieldAccessExpression(
- this.location(), // location
- atom.toRvalueOrPE(), // lhs
- identifier // fieldName
- );
- }
- if (this.peekKeyword("this")) {
- // '.' 'this'
- Location location = this.location();
- this.eatToken();
- return new Java.QualifiedThisReference(
- location, // location
- atom.toTypeOrPE() // qualification
- );
- }
- if (this.peekKeyword("super")) {
- Location location = this.location();
- this.eatToken();
- if (this.peekOperator("(")) {
-
- // '.' 'super' Arguments
- // Qualified superclass constructor invocation (JLS 8.8.5.1) (LHS is an Rvalue)
- return new Java.SuperConstructorInvocation(
- location, // location
- atom.toRvalueOrPE(), // optionalQualification
- this.parseArguments() // arguments
- );
- }
- this.readOperator(".");
- String identifier = this.readIdentifier();
-
- if (this.peekOperator("(")) {
-
- // '.' 'super' '.' Identifier Arguments
- // Qualified superclass method invocation (JLS 15.12) (LHS is a ClassName)
- // TODO: Qualified superclass method invocation
- this.throwParseException("Qualified superclass method invocation NYI");
- } else {
-
- // '.' 'super' '.' Identifier
- // Qualified superclass field access (JLS 15.11.2) (LHS is an Rvalue)
- return new Java.SuperclassFieldAccessExpression(
- location, // location
- atom.toTypeOrPE(), // optionalQualification
- identifier // fieldName
- );
- }
- }
- if (this.peekKeyword("new")) {
- // '.' 'new' Identifier Arguments [ ClassBody ]
- Java.Rvalue lhs = atom.toRvalue();
- Location location = this.location();
- this.eatToken();
- String identifier = this.readIdentifier();
- Java.Type type = new Java.RvalueMemberType(
- location, // location
- lhs, // rValue
- identifier // identifier
- );
- Java.Rvalue[] arguments = this.parseArguments();
- if (this.peekOperator("{")) {
- // '.' 'new' Identifier Arguments ClassBody (LHS is an Rvalue)
- final Java.AnonymousClassDeclaration anonymousClassDeclaration = new Java.AnonymousClassDeclaration(
- this.location(), // location
- type // baseType
- );
- this.parseClassBody(anonymousClassDeclaration);
- return new Java.NewAnonymousClassInstance(
- location, // location
- lhs, // optionalQualification
- anonymousClassDeclaration, // anonymousClassDeclaration
- arguments // arguments
- );
- } else {
- // '.' 'new' Identifier Arguments (LHS is an Rvalue)
- return new Java.NewClassInstance(
- location, // location
- lhs, // optionalQualification
- type, // referenceType
- arguments // arguments
- );
- }
- }
- if (this.peekKeyword("class")) {
- // '.' 'class'
- Location location = this.location();
- this.eatToken();
- return new Java.ClassLiteral(location, atom.toTypeOrPE());
- }
- this.throwParseException("Unexpected selector \"" + this.scanner.peek() + "\" after \".\"");
- }
- if (this.peekOperator("[")) {
- // '[' Expression ']'
- Location location = this.location();
- this.eatToken();
- Java.Rvalue index = this.parseExpression().toRvalueOrPE();
- this.readOperator("]");
- return new Java.ArrayAccessExpression(
- location, // location
- atom.toRvalueOrPE(), // lhs
- index // index
- );
- }
- this.throwParseException("Unexpected token \"" + this.scanner.peek() + "\" in selector");
- /* NEVER REACHED */ return null;
- }
-
- /**
- * <pre>
- * DimExprs := DimExpr { DimExpr }
- * </pre>
- */
- public Java.Rvalue[] parseDimExprs() throws ParseException, Scanner.ScanException, IOException {
- List l = new ArrayList();
- l.add(this.parseDimExpr());
- while (
- this.peekOperator("[")
- && !this.scanner.peekNextButOne().isOperator("]")
- ) l.add(this.parseDimExpr());
- return (Java.Rvalue[]) l.toArray(new Java.Rvalue[l.size()]);
- }
-
- /**
- * <pre>
- * DimExpr := '[' Expression ']'
- * </pre>
- */
- public Java.Rvalue parseDimExpr() throws Scanner.ScanException, ParseException, IOException {
- this.readOperator("[");
- Java.Rvalue res = this.parseExpression().toRvalueOrPE();
- this.readOperator("]");
- return res;
- }
-
- /**
- * <pre>
- * Arguments := '(' [ ArgumentList ] ')'
- * </pre>
- */
- public Java.Rvalue[] parseArguments() throws ParseException, Scanner.ScanException, IOException {
- this.readOperator("(");
- if (this.peekOperator(")")) {
- this.eatToken();
- return new Java.Rvalue[0];
- }
- Java.Rvalue[] arguments = this.parseArgumentList();
- this.readOperator(")");
- return arguments;
- }
-
- /**
- * <pre>
- * ArgumentList := Expression { ',' Expression }
- * </pre>
- */
- public Java.Rvalue[] parseArgumentList() throws ParseException, Scanner.ScanException, IOException {
- List l = new ArrayList();
- for (;;) {
- l.add(this.parseExpression().toRvalueOrPE());
- if (!this.peekOperator(",")) break;
- this.eatToken();
- }
- return (Java.Rvalue[]) l.toArray(new Java.Rvalue[l.size()]);
- }
-
- public Java.Atom parseLiteral() throws ParseException, Scanner.ScanException, IOException {
- Scanner.Token t = this.scanner.read();
- if (!t.isLiteral()) this.throwParseException("Literal expected");
- return new Java.Literal(t.getLocation(), t.getLiteralValue());
- }
-
- // Simplified access to the scanner.
-
- public Location location() { return this.scanner.location(); }
- public void eatToken() throws Scanner.ScanException, IOException { this.scanner.read(); }
- // Keyword-related.
- public boolean peekKeyword() { return this.scanner.peek().isKeyword(); }
- public boolean peekKeyword(String keyword) { return this.scanner.peek().isKeyword(keyword); }
- public boolean peekKeyword(String[] keywords) { return this.scanner.peek().isKeyword(keywords); }
- public void readKeyword(String keyword) throws ParseException, Scanner.ScanException, IOException {
- if (!this.scanner.read().isKeyword(keyword)) this.throwParseException("\"" + keyword + "\" expected"); // We want a ParseException, not a ScanException
- }
- // Operator-related.
- public boolean peekOperator(String operator) { return this.scanner.peek().isOperator(operator); }
- public boolean peekOperator(String[] operators) { return this.scanner.peek().isOperator(operators); }
- public String readOperator() throws ParseException, Scanner.ScanException, IOException {
- Scanner.Token t = this.scanner.read();
- if (!t.isOperator()) this.throwParseException("Operator expected"); // We want a ParseException, not a ScanException
- return t.getOperator();
- }
- public void readOperator(String operator) throws ParseException, Scanner.ScanException, IOException {
- if (!this.scanner.read().isOperator(operator)) this.throwParseException("Operator \"" + operator + "\" expected"); // We want a ParseException, not a ScanException
- }
- // Identifier-related.
- public boolean peekIdentifier() { return this.scanner.peek().isIdentifier(); }
- public String readIdentifier() throws ParseException, Scanner.ScanException, IOException {
- Scanner.Token t = this.scanner.read();
- if (!t.isIdentifier()) this.throwParseException("Identifier expected"); // We want a ParseException, not a ScanException
- return t.getIdentifier();
- }
-
- /**
- * <pre>
- * ExpressionStatement := Expression ';'
- * </pre>
- */
- public Java.Statement parseExpressionStatement() throws ParseException, Scanner.ScanException, IOException {
- Java.Rvalue rv = this.parseExpression().toRvalueOrPE();
- this.readOperator(";");
-
- return new Java.ExpressionStatement(rv);
- }
-
- /**
- * Issue a warning if the given string does not comply with the package naming conventions
- * (JLS2 6.8.1).
- */
- private void verifyStringIsConventionalPackageName(String s, Location loc) {
- if (!Character.isLowerCase(s.charAt(0))) {
- this.warning("UPN", "Package name \"" + s + "\" does not begin with a lower-case letter (see JLS2 6.8.1)", loc);
- return;
- }
-
- for (int i = 0; i < s.length(); ++i) {
- char c = s.charAt(i);
- if (!Character.isLowerCase(c) && c != '_' && c != '.') {
- this.warning("PPN", "Poorly chosen package name \"" + s + "\" contains bad character '" + c + "'", loc);
- return;
- }
- }
- }
-
- /**
- * Issue a warning if the given identifier does not comply with the class and interface type
- * naming conventions (JLS2 6.8.2).
- */
- private void verifyIdentifierIsConventionalClassOrInterfaceName(String id, Location loc) {
- if (!Character.isUpperCase(id.charAt(0))) {
- this.warning("UCOIN1", "Class or interface name \"" + id + "\" does not begin with an upper-case letter (see JLS2 6.8.2)", loc);
- return;
- }
- for (int i = 0; i < id.length(); ++i) {
- char c = id.charAt(i);
- if (!Character.isLetter(c) && !Character.isDigit(c)) {
- this.warning("UCOIN", "Class or interface name \"" + id + "\" contains unconventional character \"" + c + "\" (see JLS2 6.8.2)", loc);
- return;
- }
- }
- }
-
- /**
- * Issue a warning if the given identifier does not comply with the method naming conventions
- * (JLS2 6.8.3).
- */
- private void verifyIdentifierIsConventionalMethodName(String id, Location loc) {
- if (!Character.isLowerCase(id.charAt(0))) {
- this.warning("UMN1", "Method name \"" + id + "\" does not begin with a lower-case letter (see JLS2 6.8.3)", loc);
- return;
- }
- for (int i = 0; i < id.length(); ++i) {
- char c = id.charAt(i);
- if (!Character.isLetter(c) && !Character.isDigit(c)) {
- this.warning("UMN", "Method name \"" + id + "\" contains unconventional character \"" + c + "\" (see JLS2 6.8.3)", loc);
- return;
- }
- }
- }
-
- /**
- * Issue a warning if the given identifier does not comply with the field naming conventions
- * (JLS2 6.8.4) and constant naming conventions (JLS2 6.8.5).
- */
- private void verifyIdentifierIsConventionalFieldName(String id, Location loc) {
-
- // In practice, a field is not always a constant iff it is static-final. So let's
- // always tolerate both field and constant names.
-
- if (Character.isUpperCase(id.charAt(0))) {
- for (int i = 0; i < id.length(); ++i) {
- char c = id.charAt(i);
- if (!Character.isUpperCase(c) && !Character.isDigit(c) && c != '_') {
- this.warning("UCN", "Constant name \"" + id + "\" contains unconventional character \"" + c + "\" (see JLS2 6.8.5)", loc);
- return;
- }
- }
- } else
- if (Character.isLowerCase(id.charAt(0))) {
- for (int i = 0; i < id.length(); ++i) {
- char c = id.charAt(i);
- if (!Character.isLetter(c) && !Character.isDigit(c)) {
- this.warning("UFN", "Field name \"" + id + "\" contains unconventional character \"" + c + "\" (see JLS2 6.8.4)", loc);
- return;
- }
- }
- } else {
- this.warning("UFN1", "\"" + id + "\" is neither a conventional field name (JLS2 6.8.4) nor a conventional constant name (JLS2 6.8.5)", loc);
- }
- }
-
- /**
- * Issue a warning if the given identifier does not comply with the local variable and
- * parameter naming conventions (JLS2 6.8.6).
- */
- private void verifyIdentifierIsConventionalLocalVariableOrParameterName(String id, Location loc) {
- if (!Character.isLowerCase(id.charAt(0))) {
- this.warning("ULVN1", "Local variable name \"" + id + "\" does not begin with a lower-case letter (see JLS2 6.8.6)", loc);
- return;
- }
- for (int i = 0; i < id.length(); ++i) {
- char c = id.charAt(i);
- if (!Character.isLetter(c) && !Character.isDigit(c)) {
- this.warning("ULVN", "Local variable name \"" + id + "\" contains unconventional character \"" + c + "\" (see JLS2 6.8.6)", loc);
- return;
- }
- }
- }
-
- /**
- * By default, warnings are discarded, but an application my install a
- * {@link WarningHandler}.
- * <p>
- * Notice that there is no <code>Parser.setErrorHandler()</code> method, but parse errors
- * always throw a {@link ParseException}. The reason being is that there is no reasonable
- * way to recover from parse errors and continue parsing, so there is no need to install
- * a custom parse error handler.
- *
- * @param optionalWarningHandler <code>null</code> to indicate that no warnings be issued
- */
- public void setWarningHandler(WarningHandler optionalWarningHandler) {
- this.optionalWarningHandler = optionalWarningHandler;
- }
-
- // Used for elaborate warning handling.
- private WarningHandler optionalWarningHandler = null;
-
- /**
- * Issues a warning with the given message and location and returns. This is done through
- * a {@link WarningHandler} that was installed through
- * {@link #setWarningHandler(WarningHandler)}.
- * <p>
- * The <code>handle</code> argument qulifies the warning and is typically used by
- * the {@link WarningHandler} to suppress individual warnings.
- */
- private void warning(String handle, String message, Location optionalLocation) {
- if (this.optionalWarningHandler != null) this.optionalWarningHandler.handleWarning(handle, message, optionalLocation);
- }
-
- /**
- * An exception that reflects an error during parsing.
- *
- * This exception is associated with a particular {@link Location
- * Location} in the source code.
- */
- public static class ParseException extends LocatedException {
- public ParseException(String message, Location location) {
- super(message, location);
- }
- }
-
- /**
- * Convenience method for throwing a ParseException.
- */
- protected final void throwParseException(String message) throws ParseException {
- throw new ParseException(message, this.location());
- }
-
- private static String join(String[] sa, String separator) {
- if (sa == null) return ("(null)");
- if (sa.length == 0) return ("(zero length array)");
- StringBuffer sb = new StringBuffer(sa[0]);
- for (int i = 1; i < sa.length; ++i) {
- sb.append(separator).append(sa[i]);
- }
- return sb.toString();
- }
-}
diff --git a/src/org/codehaus/janino/ReflectionIClass.java b/src/org/codehaus/janino/ReflectionIClass.java
deleted file mode 100644
index eaf8196..0000000
--- a/src/org/codehaus/janino/ReflectionIClass.java
+++ /dev/null
@@ -1,314 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino;
-
-import java.util.*;
-import java.lang.reflect.*;
-
-/**
- * Wraps a {@link java.lang.Class} in an {@link org.codehaus.janino.IClass}.
- */
-class ReflectionIClass extends IClass {
- private /*final*/ Class clazz;
- private /*final*/ IClassLoader iClassLoader;
-
- /**
- * @param iClassLoader required to load other {@link IClass}es on <code>get...()</code>.
- */
- public ReflectionIClass(Class clazz, IClassLoader iClassLoader) {
- this.clazz = clazz;
- this.iClassLoader = iClassLoader;
- }
-
- protected IConstructor[] getDeclaredIConstructors2() {
- Constructor[] constructors = this.clazz.getDeclaredConstructors();
- IConstructor[] result = new IConstructor[constructors.length];
- for (int i = 0; i < constructors.length; ++i) {
- result[i] = new ReflectionIConstructor(constructors[i]);
- }
- return result;
- }
-
- protected IMethod[] getDeclaredIMethods2() {
- Method[] methods = this.clazz.getDeclaredMethods();
- List iMethods = new ArrayList();
- for (int i = 0; i < methods.length; ++i) {
- Method m = methods[i];
-
- // Skip JDK 1.5 synthetic methods (e.g. those generated for
- // covariant return values).
- if ((m.getModifiers() & Mod.SYNTHETIC) != 0) continue;
-
- // Wrap java.reflection.Method in an IMethod.
- iMethods.add(new ReflectionIMethod(m));
- }
- if (methods.length == 0 && this.clazz.isArray()) {
- iMethods.add(new IMethod() {
- public String getName() { return "clone"; }
- public IClass getReturnType() throws CompileException { return ReflectionIClass.this.iClassLoader.OBJECT; }
- public boolean isAbstract() { return false; }
- public boolean isStatic() { return false; }
- public Access getAccess() { return Access.PUBLIC; }
- public IClass[] getParameterTypes() throws CompileException { return new IClass[0]; }
- public IClass[] getThrownExceptions() throws CompileException { return new IClass[0]; }
- });
- }
- return (IMethod[]) iMethods.toArray(new IMethod[iMethods.size()]);
- }
-
- protected IField[] getDeclaredIFields2() {
- Field[] fields = this.clazz.getDeclaredFields();
- IField[] result = new IField[fields.length];
- for (int i = 0; i < fields.length; ++i) {
- result[i] = new ReflectionIField(fields[i]);
- }
- return result;
- }
-
- protected IClass[] getDeclaredIClasses2() {
- return this.classesToIClasses(this.clazz.getDeclaredClasses());
- }
-
- protected IClass getDeclaringIClass2() {
- Class declaringClass = this.clazz.getDeclaringClass();
- if (declaringClass == null) return null;
- return this.classToIClass(declaringClass);
- }
- protected IClass getOuterIClass2() throws CompileException {
- if (Modifier.isStatic(this.clazz.getModifiers())) return null;
- return this.getDeclaringIClass();
- }
- protected IClass getSuperclass2() {
- Class superclass = this.clazz.getSuperclass();
- return superclass == null ? null : this.classToIClass(superclass);
- }
- protected IClass[] getInterfaces2() {
- return this.classesToIClasses(this.clazz.getInterfaces());
- }
- protected String getDescriptor2() {
- return Descriptor.fromClassName(this.clazz.getName());
- }
- public Access getAccess() { return ReflectionIClass.modifiers2Access(this.clazz.getModifiers()); }
- public boolean isFinal() { return Modifier.isFinal(this.clazz.getModifiers()); }
- public boolean isInterface() { return this.clazz.isInterface(); }
- public boolean isAbstract() { return Modifier.isAbstract(this.clazz.getModifiers()); }
- public boolean isArray() { return this.clazz.isArray(); }
- protected IClass getComponentType2() {
- Class componentType = this.clazz.getComponentType();
- return componentType == null ? null : this.classToIClass(componentType);
- }
- public boolean isPrimitive() {
- return this.clazz.isPrimitive();
- }
- public boolean isPrimitiveNumeric() {
- return (
- this.clazz == byte.class ||
- this.clazz == short.class ||
- this.clazz == int.class ||
- this.clazz == long.class ||
- this.clazz == char.class ||
- this.clazz == float.class ||
- this.clazz == double.class
- );
- }
-
- /**
- * @return E.g. "int", "int[][]", "pkg1.pkg2.Outer$Inner[]"
- */
- public String toString() {
- int brackets = 0;
- Class c = this.clazz;
- while (c.isArray()) {
- ++brackets;
- c = c.getComponentType();
- }
- String s = c.getName();
- while (brackets-- > 0) s += "[]";
- return s;
- }
-
- private class ReflectionIConstructor extends IConstructor {
- public ReflectionIConstructor(Constructor constructor) { this.constructor = constructor; }
-
- // Implement IMember.
- public Access getAccess() {
- int mod = this.constructor.getModifiers();
- return ReflectionIClass.modifiers2Access(mod);
- }
-
- // Implement "IConstructor".
- public IClass[] getParameterTypes() throws CompileException {
- IClass[] parameterTypes = ReflectionIClass.this.classesToIClasses(this.constructor.getParameterTypes());
-
- // The JAVADOC of java.lang.reflect.Constructor does not document it, but
- // "getParameterTypes()" includes the synthetic "enclosing instance" parameter.
- IClass outerClass = ReflectionIClass.this.getOuterIClass();
- if (outerClass != null) {
- if (parameterTypes.length < 1) throw new CompileException("Constructor \"" + this.constructor + "\" lacks synthetic enclosing instance parameter", null);
- if (parameterTypes[0] != outerClass) throw new CompileException("Enclosing instance parameter of constructor \"" + this.constructor + "\" has wrong type -- \"" + parameterTypes[0] + "\" vs. \"" + outerClass + "\"", null);
- IClass[] tmp = new IClass[parameterTypes.length - 1];
- System.arraycopy(parameterTypes, 1, tmp, 0, tmp.length);
- parameterTypes = tmp;
- }
-
- return parameterTypes;
- }
- public String getDescriptor() {
- Class[] parameterTypes = this.constructor.getParameterTypes();
- String[] parameterDescriptors = new String[parameterTypes.length];
- for (int i = 0; i < parameterDescriptors.length; ++i) {
- parameterDescriptors[i] = Descriptor.fromClassName(parameterTypes[i].getName());
- }
- return new MethodDescriptor(parameterDescriptors, Descriptor.VOID_).toString();
- }
- public IClass[] getThrownExceptions() {
- return ReflectionIClass.this.classesToIClasses(this.constructor.getExceptionTypes());
- }
-
- final Constructor constructor;
- };
- private class ReflectionIMethod extends IMethod {
- public ReflectionIMethod(Method method) { this.method = method; }
-
- // Implement IMember.
- public Access getAccess() {
- return ReflectionIClass.modifiers2Access(this.method.getModifiers());
- }
-
- // Implement "IMethod".
- public String getName() { return this.method.getName(); }
- public IClass[] getParameterTypes() {
- return ReflectionIClass.this.classesToIClasses(this.method.getParameterTypes());
- }
- public boolean isStatic() { return Modifier.isStatic(this.method.getModifiers()); }
- public boolean isAbstract() { return Modifier.isAbstract(this.method.getModifiers()); }
- public IClass getReturnType() {
- return ReflectionIClass.this.classToIClass(this.method.getReturnType());
- }
- public IClass[] getThrownExceptions() {
- return ReflectionIClass.this.classesToIClasses(this.method.getExceptionTypes());
- }
-
- final Method method;
- };
- private class ReflectionIField extends IField {
- public ReflectionIField(Field field) { this.field = field; }
-
- // Implement IMember.
- public Access getAccess() {
- return ReflectionIClass.modifiers2Access(this.field.getModifiers());
- }
-
- // Implement "IField".
- public String getName() { return this.field.getName(); }
- public boolean isStatic() {
- return Modifier.isStatic(this.field.getModifiers());
- }
- public IClass getType() {
- return ReflectionIClass.this.classToIClass(this.field.getType());
- }
- public String toString() {
- return (
- Descriptor.toString(this.getDeclaringIClass().getDescriptor()) +
- "." +
- this.getName()
- );
- }
- /**
- * This implementation of {@link IClass.IField#getConstantValue()} is
- * not completely correct:
- * <ul>
- * <li>
- * It treats non-static fields as non-constant
- * <li>
- * Even fields with a <i>non-constant</i> initializer are identified
- * as constant. (The value of that field may be different in a
- * different JVM instance -- the classical example is
- * {@link java.io.File#separator}.)
- * </ul>
- */
- public Object getConstantValue() throws CompileException {
- int mod = this.field.getModifiers();
- Class clazz = this.field.getType();
- if (
- Modifier.isStatic(mod) &&
- Modifier.isFinal(mod) &&
- (clazz.isPrimitive() || clazz == String.class)
- ) {
- try {
- return this.field.get(null);
- } catch (IllegalAccessException ex) {
- throw new CompileException("Field \"" + this.field.getName() + "\" is not accessible", (Location) null);
- }
- }
- return null;
- }
-
- final Field field;
- }
-
- /**
- * Load {@link Class} through {@link IClassLoader} to
- * ensure unique {@link IClass}es.
- */
- private IClass classToIClass(Class c) {
- IClass iClass;
- try {
- iClass = this.iClassLoader.loadIClass(Descriptor.fromClassName(c.getName()));
- } catch (ClassNotFoundException ex) {
- throw new RuntimeException("Loading IClass \"" + c.getName() + "\": " + ex);
- }
- if (iClass == null) throw new RuntimeException("Cannot load class \"" + c.getName() + "\" through the given ClassLoader");
- return iClass;
- }
-
- /**
- * @see #classToIClass(Class)
- */
- private IClass[] classesToIClasses(Class[] cs) {
- IClass[] result = new IClass[cs.length];
- for (int i = 0; i < cs.length; ++i) result[i] = this.classToIClass(cs[i]);
- return result;
- }
-
- private static Access modifiers2Access(int modifiers) {
- return (
- Modifier.isPrivate(modifiers) ? Access.PRIVATE :
- Modifier.isProtected(modifiers) ? Access.PROTECTED :
- Modifier.isPublic(modifiers) ? Access.PUBLIC :
- Access.DEFAULT
- );
- }
-}
diff --git a/src/org/codehaus/janino/ResourceFinderIClassLoader.java b/src/org/codehaus/janino/ResourceFinderIClassLoader.java
deleted file mode 100644
index 1ec79f2..0000000
--- a/src/org/codehaus/janino/ResourceFinderIClassLoader.java
+++ /dev/null
@@ -1,89 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino;
-
-import java.io.*;
-
-import org.codehaus.janino.util.ClassFile;
-import org.codehaus.janino.util.resource.*;
-
-
-/**
- * This {@link org.codehaus.janino.IClassLoader} loads IClasses through a
- * a {@link org.codehaus.janino.util.resource.ResourceFinder} that designates
- * {@link org.codehaus.janino.util.ClassFile}s.
- */
-public class ResourceFinderIClassLoader extends IClassLoader {
- private final ResourceFinder resourceFinder;
-
- public ResourceFinderIClassLoader(
- ResourceFinder resourceFinder,
- IClassLoader optionalParentIClassLoader
- ) {
- super(optionalParentIClassLoader);
- this.resourceFinder = resourceFinder;
- this.postConstruct();
- }
-
- protected IClass findIClass(String descriptor) throws ClassNotFoundException {
- String className = Descriptor.toClassName(descriptor);
-
- // Find the class file resource.
- Resource classFileResource = this.resourceFinder.findResource(ClassFile.getClassFileResourceName(className));
- if (classFileResource == null) return null;
-
- // Open the class file resource.
- InputStream is;
- try {
- is = classFileResource.open();
- } catch (IOException ex) {
- throw new ClassNotFoundException("Opening resource \"" + classFileResource.getFileName() + "\"", ex);
- }
-
- // Load the IClass from the class file.
- ClassFile cf;
- try {
- cf = new ClassFile(is);
- } catch (IOException e) {
- throw new ClassNotFoundException("Reading resource \"" + classFileResource.getFileName() + "\"", e);
- } finally {
- try { is.close(); } catch (IOException e) {}
- }
- IClass iClass = new ClassFileIClass(cf, this);
- this.defineIClass(iClass);
- return iClass;
- }
-
-}
diff --git a/src/org/codehaus/janino/Scanner.java b/src/org/codehaus/janino/Scanner.java
deleted file mode 100644
index 03251e8..0000000
--- a/src/org/codehaus/janino/Scanner.java
+++ /dev/null
@@ -1,1276 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino;
-
-import java.io.*;
-import java.util.*;
-
-import org.codehaus.janino.util.LocatedException;
-import org.codehaus.janino.util.TeeReader;
-
-
-/**
- * Splits up a character stream into tokens and returns them as
- * {@link java.lang.String String} objects.
- * <p>
- * The <code>optionalFileName</code> parameter passed to many
- * constructors should point
- */
-
-public class Scanner {
-
- // Public Scanners that read from a file.
-
- /**
- * Set up a scanner that reads tokens from the given file in the default charset.
- * <p>
- * <b>This method is deprecated because it leaves the input file open.</b>
- *
- * @deprecated
- */
- public Scanner(String fileName) throws ScanException, IOException {
- this(
- fileName, // optionalFileName
- new FileInputStream(fileName) // is
- );
- }
-
- /**
- * Set up a scanner that reads tokens from the given file in the given encoding.
- * <p>
- * <b>This method is deprecated because it leaves the input file open.</b>
- *
- * @deprecated
- */
- public Scanner(String fileName, String encoding) throws ScanException, IOException {
- this(
- fileName, // optionalFileName
- new FileInputStream(fileName), // is
- encoding // optionalEncoding
- );
- }
-
- /**
- * Set up a scanner that reads tokens from the given file in the platform
- * default encoding.
- * <p>
- * <b>This method is deprecated because it leaves the input file open.</b>
- *
- * @deprecated
- */
- public Scanner(File file) throws ScanException, IOException {
- this(
- file.getAbsolutePath(), // optionalFileName
- new FileInputStream(file), // is
- null // optionalEncoding
- );
- }
-
- /**
- * Set up a scanner that reads tokens from the given file in the given encoding.
- * <p>
- * <b>This method is deprecated because it leaves the input file open.</b>
- *
- * @deprecated
- */
- public Scanner(File file, String optionalEncoding) throws ScanException, IOException {
- this(
- file.getAbsolutePath(), // optionalFileName
- new FileInputStream(file), // fis
- optionalEncoding // optionalEncoding
- );
- }
-
- // Public Scanners that read from an InputStream
-
- /**
- * Set up a scanner that reads tokens from the given
- * {@link InputStream} in the platform default encoding.
- * <p>
- * The <code>fileName</code> is solely used for reporting in thrown
- * exceptions.
- */
- public Scanner(String optionalFileName, InputStream is) throws ScanException, IOException {
- this(
- optionalFileName,
- new InputStreamReader(is), // in
- (short) 1, (short) 0 // initialLineNumber, initialColumnNumber
- );
- }
-
- /**
- * Set up a scanner that reads tokens from the given
- * {@link InputStream} with the given <code>optionalEncoding</code>
- * (<code>null</code> means platform default encoding).
- * <p>
- * The <code>optionalFileName</code> is used for reporting errors during
- * compilation and for source level debugging, and should name an existing
- * file. If <code>null</code> is passed, and the system property
- * <code>org.codehaus.janino.source_debugging.enable</code> is set to "true", then
- * a temporary file in <code>org.codehaus.janino.source_debugging.dir</code> or the
- * system's default temp dir is created in order to make the source code
- * available to a debugger.
- */
- public Scanner(
- String optionalFileName,
- InputStream is,
- String optionalEncoding
- ) throws ScanException, IOException {
- this(
- optionalFileName, // optionalFileName
- ( // in
- optionalEncoding == null ?
- new InputStreamReader(is) :
- new InputStreamReader(is, optionalEncoding)
- ),
- (short) 1, (short) 0 // initialLineNumber, initialColumnNumber
- );
- }
-
- // Public Scanners that read from a Reader.
-
- /**
- * Set up a scanner that reads tokens from the given
- * {@link Reader}.
- * <p>
- * The <code>optionalFileName</code> is used for reporting errors during
- * compilation and for source level debugging, and should name an existing
- * file. If <code>null</code> is passed, and the system property
- * <code>org.codehaus.janino.source_debugging.enable</code> is set to "true", then
- * a temporary file in <code>org.codehaus.janino.source_debugging.dir</code> or the
- * system's default temp dir is created in order to make the source code
- * available to a debugger.
- */
- public Scanner(String optionalFileName, Reader in) throws ScanException, IOException {
- this(
- optionalFileName, // optionalFileName
- in, // in
- (short) 1, // initialLineNumber
- (short) 0 // initialColumnNumber
- );
- }
-
- /**
- * Creates a {@link Scanner} that counts lines and columns from non-default initial
- * values.
- */
- public Scanner(
- String optionalFileName,
- Reader in,
- short initialLineNumber, // "1" is a good idea
- short initialColumnNumber // "0" is a good idea
- ) throws ScanException, IOException {
-
- // Debugging on source code level is only possible if the code comes from
- // a "real" Java source file which the debugger can read. If this is not the
- // case, and we absolutely want source code level debugging, then we write
- // a verbatim copy of the source code into a temporary file in the system
- // temp directory.
- // This behavior is controlled by the two system properties
- // org.codehaus.janino.source_debugging.enable
- // org.codehaus.janino.source_debugging.dir
- // JANINO is designed to compile in memory to save the overhead of disk
- // I/O, so writing this file is only recommended for source code level
- // debugging purposes.
- if (optionalFileName == null && Boolean.getBoolean("org.codehaus.janino.source_debugging.enable")) {
- String dirName = System.getProperty("org.codehaus.janino.source_debugging.dir");
- File dir = dirName == null ? null : new File(dirName);
- File temporaryFile = File.createTempFile("janino", ".java", dir);
- temporaryFile.deleteOnExit();
- in = new TeeReader(
- in, // in
- new FileWriter(temporaryFile), // out
- true // closeWriterOnEOF
- );
- optionalFileName = temporaryFile.getAbsolutePath();
- }
-
- this.optionalFileName = optionalFileName;
- this.in = new UnicodeUnescapeReader(in);
- this.nextCharLineNumber = initialLineNumber;
- this.nextCharColumnNumber = initialColumnNumber;
-
- this.readNextChar();
- this.nextToken = this.internalRead();
- this.nextButOneToken = null;
- }
-
- /**
- * Return the file name optionally passed to the constructor.
- */
- public String getFileName() {
- return this.optionalFileName;
- }
-
- /**
- * Closes the character source (file, {@link InputStream}, {@link Reader}) associated
- * with this object. The results of future calls to {@link #peek()} and
- * {@link #read()} are undefined.
- * <p>
- * <b>This method is deprecated, because the concept described above is confusing. An
- * application should close the underlying {@link InputStream} or {@link Reader} itself.</b>
- *
- * @deprecated
- */
- public void close() throws IOException {
- this.in.close();
- }
-
- /**
- * Read the next token from the input.
- */
- public Token read() throws ScanException, IOException {
- Token res = this.nextToken;
- if (this.nextButOneToken != null) {
- this.nextToken = this.nextButOneToken;
- this.nextButOneToken = null;
- } else {
- this.nextToken = this.internalRead();
- }
- return res;
- }
-
- /**
- * Peek the next token, but don't remove it from the input.
- */
- public Token peek() {
- if (Scanner.DEBUG) System.err.println("peek() => \"" + this.nextToken + "\"");
- return this.nextToken;
- }
-
- /**
- * Peek the next but one token, neither remove the next nor the next but one token from the
- * input.
- * <p>
- * This makes parsing so much easier, e.g. for class literals like
- * <code>Map.class</code>.
- */
- public Token peekNextButOne() throws ScanException, IOException {
- if (this.nextButOneToken == null) this.nextButOneToken = this.internalRead();
- return this.nextButOneToken;
- }
-
- /**
- * Get the text of the doc comment (a.k.a. "JAVADOC comment") preceeding
- * the next token.
- * @return <code>null</code> if the next token is not preceeded by a doc comment
- */
- public String doc() {
- String s = this.docComment;
- this.docComment = null;
- return s;
- }
-
- /**
- * Returns the {@link Location} of the next token.
- */
- public Location location() {
- return this.nextToken.getLocation();
- }
-
- public abstract class Token {
- private /*final*/ String optionalFileName;
- private /*final*/ short lineNumber;
- private /*final*/ short columnNumber;
- private Location location = null;
-
- private Token() {
- this.optionalFileName = Scanner.this.optionalFileName;
- this.lineNumber = Scanner.this.tokenLineNumber;
- this.columnNumber = Scanner.this.tokenColumnNumber;
- }
-
- public Location getLocation() {
- if (this.location == null) this.location = new Location(this.optionalFileName, this.lineNumber, this.columnNumber);
- return this.location;
- }
-
- public boolean isKeyword() { return false; }
- public boolean isKeyword(String k) { return false; }
- public boolean isKeyword(String[] ks) { return false; }
- public String getKeyword() throws ScanException { throw new ScanException("Not a keyword token"); }
-
- public boolean isIdentifier() { return false; }
- public boolean isIdentifier(String id) { return false; }
- public String getIdentifier() throws ScanException { throw new ScanException("Not an identifier token"); }
-
- public boolean isLiteral() { return false; }
- public Object getLiteralValue() throws ScanException { throw new ScanException("Not a literal token"); }
-
- public boolean isOperator() { return false; }
- public boolean isOperator(String o) { return false; }
- public boolean isOperator(String[] os) { return false; }
- public String getOperator() throws ScanException { throw new ScanException("Not an operator token"); }
-
- public boolean isEOF() { return false; }
- }
-
- public class KeywordToken extends Token {
- private final String keyword;
-
- /**
- * @param keyword Must be in interned string!
- */
- private KeywordToken(String keyword) {
- this.keyword = keyword;
- }
-
- public boolean isKeyword() { return true; }
- public boolean isKeyword(String k) { return this.keyword == k; }
- public boolean isKeyword(String[] ks) {
- for (int i = 0; i < ks.length; ++i) {
- if (this.keyword == ks[i]) return true;
- }
- return false;
- }
- public String getKeyword() { return this.keyword; }
-
- public String toString() { return this.keyword; }
- }
-
- public class IdentifierToken extends Token {
- private final String identifier;
-
- private IdentifierToken(String identifier) {
- this.identifier = identifier;
- }
-
- public boolean isIdentifier() { return true; }
- public boolean isIdentifier(String id) { return this.identifier.equals(id); }
- public String getIdentifier() { return this.identifier; }
-
- public String toString() { return this.identifier; }
- }
-
- /**
- * This reference represents the "magic" literal "2147483648" which is only
- * allowed in a negated context.
- */
- public static final Integer MAGIC_INTEGER = new Integer(Integer.MIN_VALUE);
-
- /**
- * This reference represents the "magic" literal "9223372036854775808L" which is only
- * allowed in a negated context.
- */
- public static final Long MAGIC_LONG = new Long(Long.MIN_VALUE);
-
- /**
- * The type of the <code>value</code> parameter determines the type of the literal
- * token:
- * <table>
- * <tr><th>Type/value returned by {@link #getLiteralValue()}</th><th>Literal</th></tr>
- * <tr><td>{@link String}</td><td>STRING literal</td></tr>
- * <tr><td>{@link Character}</td><td>CHAR literal</td></tr>
- * <tr><td>{@link Integer}</td><td>INT literal</td></tr>
- * <tr><td>{@link Long}</td><td>LONG literal</td></tr>
- * <tr><td>{@link Float}</td><td>FLOAT literal</td></tr>
- * <tr><td>{@link Double}</td><td>DOUBLE literal</td></tr>
- * <tr><td>{@link Boolean}</td><td>BOOLEAN literal</td></tr>
- * <tr><td><code>null</code></td><td>NULL literal</td></tr>
- * </table>
- */
- public final class LiteralToken extends Token {
- private final Object value;
-
- /**
- * @param value A {@link Boolean}, {@link String}, {@link Double}, {@link Float}, {@link Character}, or <code>null</code>
- */
- public LiteralToken(Object value) {
- this.value = value;
- }
-
- // Implement {@link Literal}.
- public final boolean isLiteral() { return true; }
- public Object getLiteralValue() { return this.value; }
-
- public String toString() {
- return Scanner.literalValueToString(this.value);
- }
- }
- public static String literalValueToString(Object v) {
- if (v instanceof String) {
- StringBuffer sb = new StringBuffer();
- sb.append('"');
- String s = (String) v;
- for (int i = 0; i < s.length(); ++i) {
- char c = s.charAt(i);
-
- if (c == '"') {
- sb.append("\\\"");
- } else {
- Scanner.escapeCharacter(c, sb);
- }
- }
- sb.append('"');
- return sb.toString();
- }
- if (v instanceof Character) {
- char c = ((Character) v).charValue();
- if (c == '\'') return "'\\''";
- StringBuffer sb = new StringBuffer("'");
- Scanner.escapeCharacter(c, sb);
- return sb.append('\'').toString();
- }
- if (v instanceof Integer) {
- if (v == Scanner.MAGIC_INTEGER) return "2147483648";
- int iv = ((Integer) v).intValue();
- return iv < 0 ? "0x" + Integer.toHexString(iv) : Integer.toString(iv);
- }
- if (v instanceof Long) {
- if (v == Scanner.MAGIC_LONG) return "9223372036854775808L";
- long lv = ((Long) v).longValue();
- return lv < 0L ? "0x" + Long.toHexString(lv) + 'L' : Long.toString(lv) + 'L';
- }
- if (v instanceof Float) {
- return v.toString() + 'F';
- }
- if (v instanceof Double) {
- return v.toString() + 'D';
- }
- if (v instanceof Boolean) {
- return v.toString();
- }
- if (v == null) {
- return "null";
- }
- throw new RuntimeException("Unexpected value type \"" + v.getClass().getName() + "\"");
- }
-
- public class OperatorToken extends Token {
- private final String operator;
-
- /**
- *
- * @param operator Must be an interned string!
- */
- private OperatorToken(String operator) {
- this.operator = operator;
- }
-
- public boolean isOperator() { return true; }
- public boolean isOperator(String o) { return this.operator == o; }
- public boolean isOperator(String[] os) {
- for (int i = 0; i < os.length; ++i) {
- if (this.operator == os[i]) return true;
- }
- return false;
- }
- public String getOperator() { return this.operator; }
-
- public String toString() { return this.operator; }
- }
-
- public class EOFToken extends Token {
- public boolean isEOF() { return true; }
- public String toString() { return "End-Of-File"; }
- }
-
- /**
- * Escape unprintable characters appropriately, i.e. as
- * backslash-letter or backslash-U-four-hex-digits.
- * <p>
- * Notice: Single and double quotes are not escaped!
- */
- private static void escapeCharacter(char c, StringBuffer sb) {
-
- // Backslash escape sequences.
- int idx = "\b\t\n\f\r\\".indexOf(c);
- if (idx != -1) {
- sb.append('\\').append("btnfr\\".charAt(idx));
- } else
-
- // Printable characters.
- if (c >= ' ' && c < 255 && c != 127) {
- sb.append(c);
- } else
-
- // Backslash-U escape sequences.
- {
- sb.append("\\u");
- String hs = Integer.toHexString(0xffff & c);
- for (int j = hs.length(); j < 4; ++j) sb.append('0');
- sb.append(hs);
- }
- }
-
- private Token internalRead() throws ScanException, IOException {
- if (this.docComment != null) {
- this.warning("MDC", "Misplaced doc comment", this.nextToken.getLocation());
- this.docComment = null;
- }
-
- // Skip whitespace and process comments.
- int state = 0;
- StringBuffer dcsb = null; // For doc comment
-
- PROCESS_COMMENTS:
- for (;;) {
- switch (state) {
-
- case 0: // Outside any comment
- if (this.nextChar == -1) {
- return new EOFToken();
- } else
- if (Character.isWhitespace((char) this.nextChar)) {
- ;
- } else
- if (this.nextChar == '/') {
- state = 1;
- } else
- {
- break PROCESS_COMMENTS;
- }
- break;
-
- case 1: // After "/"
- if (this.nextChar == -1) {
- return new OperatorToken("/");
- } else
- if (this.nextChar == '=') {
- this.readNextChar();
- return new OperatorToken("/=");
- } else
- if (this.nextChar == '/') {
- state = 2;
- } else
- if (this.nextChar == '*') {
- state = 3;
- } else
- {
- return new OperatorToken("/");
- }
- break;
-
- case 2: // After "//..."
- if (this.nextChar == -1) {
- return new EOFToken();
- } else
- if (this.nextChar == '\r' || this.nextChar == '\n') {
- state = 0;
- } else
- {
- ;
- }
- break;
-
- case 3: // After "/*"
- if (this.nextChar == -1) {
- throw new ScanException("EOF in traditional comment");
- } else
- if (this.nextChar == '*') {
- state = 4;
- } else
- {
- state = 9;
- }
- break;
-
- case 4: // After "/**"
- if (this.nextChar == -1) {
- throw new ScanException("EOF in doc comment");
- } else
- if (this.nextChar == '/') {
- state = 0;
- } else
- {
- if (this.docComment != null) this.warning("MDC", "Multiple doc comments", new Location(this.optionalFileName, this.nextCharLineNumber, this.nextCharColumnNumber));
- dcsb = new StringBuffer();
- dcsb.append((char) this.nextChar);
- state = (
- (this.nextChar == '\r' || this.nextChar == '\n') ? 6
- : this.nextChar == '*' ? 8
- : 5
- );
- }
- break;
-
- case 5: // After "/**..."
- if (this.nextChar == -1) {
- throw new ScanException("EOF in doc comment");
- } else
- if (this.nextChar == '*') {
- state = 8;
- } else
- if (this.nextChar == '\r' || this.nextChar == '\n') {
- dcsb.append((char) this.nextChar);
- state = 6;
- } else
- {
- dcsb.append((char) this.nextChar);
- }
- break;
-
- case 6: // After "/**...\n"
- if (this.nextChar == -1) {
- throw new ScanException("EOF in doc comment");
- } else
- if (this.nextChar == '*') {
- state = 7;
- } else
- if (this.nextChar == '\r' || this.nextChar == '\n') {
- dcsb.append((char) this.nextChar);
- } else
- if (this.nextChar == ' ' || this.nextChar == '\t') {
- ;
- } else
- {
- dcsb.append((char) this.nextChar);
- state = 5;
- }
- break;
-
- case 7: // After "/**...\n *"
- if (this.nextChar == -1) {
- throw new ScanException("EOF in doc comment");
- } else
- if (this.nextChar == '*') {
- ;
- } else
- if (this.nextChar == '/') {
- this.docComment = dcsb.toString();
- state = 0;
- } else
- {
- dcsb.append((char) this.nextChar);
- state = 5;
- }
- break;
-
- case 8: // After "/**...*"
- if (this.nextChar == -1) {
- throw new ScanException("EOF in doc comment");
- } else
- if (this.nextChar == '/') {
- this.docComment = dcsb.toString();
- state = 0;
- } else
- if (this.nextChar == '*') {
- dcsb.append('*');
- } else
- {
- dcsb.append('*');
- dcsb.append((char) this.nextChar);
- state = 5;
- }
- break;
-
- case 9: // After "/*..."
- if (this.nextChar == -1) {
- throw new ScanException("EOF in traditional comment");
- } else
- if (this.nextChar == '*') {
- state = 10;
- } else
- {
- ;
- }
- break;
-
- case 10: // After "/*...*"
- if (this.nextChar == -1) {
- throw new ScanException("EOF in traditional comment");
- } else
- if (this.nextChar == '/') {
- state = 0;
- } else
- if (this.nextChar == '*') {
- ;
- } else
- {
- state = 9;
- }
- }
- this.readNextChar();
- }
-
- /*
- * Whitespace and comments are now skipped; "nextChar" is definitely
- * the first character of the token.
- */
- this.tokenLineNumber = this.nextCharLineNumber;
- this.tokenColumnNumber = this.nextCharColumnNumber;
-
- // Scan identifier.
- if (Character.isJavaIdentifierStart((char) this.nextChar)) {
- StringBuffer sb = new StringBuffer();
- sb.append((char) this.nextChar);
- for (;;) {
- this.readNextChar();
- if (
- this.nextChar == -1 ||
- !Character.isJavaIdentifierPart((char) this.nextChar)
- ) break;
- sb.append((char) this.nextChar);
- }
- String s = sb.toString();
- if (s.equals("true")) return new LiteralToken(Boolean.TRUE);
- if (s.equals("false")) return new LiteralToken(Boolean.FALSE);
- if (s.equals("null")) return new LiteralToken(null);
- {
- String v = (String) Scanner.JAVA_KEYWORDS.get(s);
- if (v != null) return new KeywordToken(v);
- }
- return new IdentifierToken(s);
- }
-
- // Scan numeric literal.
- if (Character.isDigit((char) this.nextChar)) {
- return this.scanNumericLiteral(0);
- }
-
- // A "." is special: Could either be a floating-point constant like ".001", or the "."
- // operator.
- if (this.nextChar == '.') {
- this.readNextChar();
- if (Character.isDigit((char) this.nextChar)) {
- return this.scanNumericLiteral(2);
- } else {
- return new OperatorToken(".");
- }
- }
-
- // Scan string literal.
- if (this.nextChar == '"') {
- StringBuffer sb = new StringBuffer("");
- this.readNextChar();
- if (this.nextChar == -1) throw new ScanException("EOF in string literal");
- if (this.nextChar == '\r' || this.nextChar == '\n') throw new ScanException("Line break in string literal");
- while (this.nextChar != '"') {
- sb.append(this.unescapeCharacterLiteral());
- }
- this.readNextChar();
- return new LiteralToken(sb.toString());
- }
-
- // Scan character literal.
- if (this.nextChar == '\'') {
- this.readNextChar();
- if (this.nextChar == '\'') throw new ScanException("Single quote must be backslash-escaped in character literal");
- char lit = this.unescapeCharacterLiteral();
- if (this.nextChar != '\'') throw new ScanException("Closing single quote missing");
- this.readNextChar();
-
- return new LiteralToken(new Character(lit));
- }
-
- // Scan separator / operator.
- {
- String v = (String) Scanner.JAVA_OPERATORS.get(
- new String(new char[] { (char) this.nextChar })
- );
- if (v != null) {
- for (;;) {
- this.readNextChar();
- String v2 = (String) Scanner.JAVA_OPERATORS.get(v + (char) this.nextChar);
- if (v2 == null) return new OperatorToken(v);
- v = v2;
- }
- }
- }
-
- throw new ScanException("Invalid character input \"" + (char) this.nextChar + "\" (character code " + this.nextChar + ")");
- }
-
- private Token scanNumericLiteral(int initialState) throws ScanException, IOException {
- StringBuffer sb = (initialState == 2) ? new StringBuffer("0.") : new StringBuffer();
- int state = initialState;
- for (;;) {
- switch (state) {
-
- case 0: // First character.
- if (this.nextChar == '0') {
- state = 6;
- } else
- /* if (Character.isDigit((char) this.nextChar)) */ {
- sb.append((char) this.nextChar);
- state = 1;
- }
- break;
-
- case 1: // Decimal digits.
- if (Character.isDigit((char) this.nextChar)) {
- sb.append((char) this.nextChar);
- } else
- if (this.nextChar == 'l' || this.nextChar == 'L') {
- this.readNextChar();
- return this.stringToLongLiteralToken(sb.toString(), 10);
- } else
- if (this.nextChar == 'f' || this.nextChar == 'F') {
- this.readNextChar();
- return this.stringToFloatLiteralToken(sb.toString());
- } else
- if (this.nextChar == 'd' || this.nextChar == 'D') {
- this.readNextChar();
- return this.stringToDoubleLiteralToken(sb.toString());
- } else
- if (this.nextChar == '.') {
- sb.append('.');
- state = 2;
- } else
- if (this.nextChar == 'E' || this.nextChar == 'e') {
- sb.append('E');
- state = 3;
- } else
- {
- return this.stringToIntegerLiteralToken(sb.toString(), 10);
- }
- break;
-
- case 2: // After decimal point.
- if (Character.isDigit((char) this.nextChar)) {
- sb.append((char) this.nextChar);
- } else
- if (this.nextChar == 'e' || this.nextChar == 'E') {
- sb.append('E');
- state = 3;
- } else
- if (this.nextChar == 'f' || this.nextChar == 'F') {
- this.readNextChar();
- return this.stringToFloatLiteralToken(sb.toString());
- } else
- if (this.nextChar == 'd' || this.nextChar == 'D') {
- this.readNextChar();
- return this.stringToDoubleLiteralToken(sb.toString());
- } else
- {
- return this.stringToDoubleLiteralToken(sb.toString());
- }
- break;
-
- case 3: // Read exponent.
- if (Character.isDigit((char) this.nextChar)) {
- sb.append((char) this.nextChar);
- state = 5;
- } else
- if (this.nextChar == '-' || this.nextChar == '+') {
- sb.append((char) this.nextChar);
- state = 4;
- } else
- {
- throw new ScanException("Exponent missing after \"E\"");
- }
- break;
-
- case 4: // After exponent sign.
- if (Character.isDigit((char) this.nextChar)) {
- sb.append((char) this.nextChar);
- state = 5;
- } else
- {
- throw new ScanException("Exponent missing after \"E\" and sign");
- }
- break;
-
- case 5: // After first exponent digit.
- if (Character.isDigit((char) this.nextChar)) {
- sb.append((char) this.nextChar);
- } else
- if (this.nextChar == 'f' || this.nextChar == 'F') {
- this.readNextChar();
- return this.stringToFloatLiteralToken(sb.toString());
- } else
- if (this.nextChar == 'd' || this.nextChar == 'D') {
- this.readNextChar();
- return this.stringToDoubleLiteralToken(sb.toString());
- } else
- {
- return this.stringToDoubleLiteralToken(sb.toString());
- }
- break;
-
- case 6: // After leading zero
- if ("01234567".indexOf(this.nextChar) != -1) {
- sb.append((char) this.nextChar);
- state = 7;
- } else
- if (this.nextChar == 'l' || this.nextChar == 'L') {
- this.readNextChar();
- return this.stringToLongLiteralToken("0", 10);
- } else
- if (this.nextChar == 'f' || this.nextChar == 'F') {
- this.readNextChar();
- return this.stringToFloatLiteralToken("0");
- } else
- if (this.nextChar == 'd' || this.nextChar == 'D') {
- this.readNextChar();
- return this.stringToDoubleLiteralToken("0");
- } else
- if (this.nextChar == '.') {
- sb.append("0.");
- state = 2;
- } else
- if (this.nextChar == 'E' || this.nextChar == 'e') {
- sb.append('E');
- state = 3;
- } else
- if (this.nextChar == 'x' || this.nextChar == 'X') {
- state = 8;
- } else
- {
- return this.stringToIntegerLiteralToken("0", 10);
- }
- break;
-
- case 7: // In octal literal.
- if ("01234567".indexOf(this.nextChar) != -1) {
- sb.append((char) this.nextChar);
- } else
- if (this.nextChar == 'l' || this.nextChar == 'L') {
- // Octal long literal.
- this.readNextChar();
- return this.stringToLongLiteralToken(sb.toString(), 8);
- } else
- {
- // Octal int literal
- return this.stringToIntegerLiteralToken(sb.toString(), 8);
- }
- break;
-
- case 8: // First hex digit
- if (Character.digit((char) this.nextChar, 16) != -1) {
- sb.append((char) this.nextChar);
- state = 9;
- } else
- {
- throw new ScanException("Hex digit expected after \"0x\"");
- }
- break;
-
- case 9:
- if (Character.digit((char) this.nextChar, 16) != -1) {
- sb.append((char) this.nextChar);
- } else
- if (this.nextChar == 'l' || this.nextChar == 'L') {
- // Hex long literal
- this.readNextChar();
- return this.stringToLongLiteralToken(sb.toString(), 16);
- } else
- {
- // Hex long literal
- return this.stringToIntegerLiteralToken(sb.toString(), 16);
- }
- break;
- }
- this.readNextChar();
- }
- }
-
- private LiteralToken stringToIntegerLiteralToken(final String s, int radix) throws ScanException {
- int x;
- switch (radix) {
-
- case 10:
- // Special case: Decimal literal 2^31 must only appear in "negated" context, i.e.
- // "-2147483648" is a valid long literal, but "2147483648" is not.
- if (s.equals("2147483648")) return new LiteralToken(Scanner.MAGIC_INTEGER);
- try {
- x = Integer.parseInt(s);
- } catch (NumberFormatException e) {
- throw new ScanException("Value of decimal integer literal \"" + s + "\" is out of range");
- }
- break;
-
- case 8:
- // Cannot use "Integer.parseInt(s, 8)" because that parses SIGNED values.
- x = 0;
- for (int i = 0; i < s.length(); ++i) {
- if ((x & 0xe0000000) != 0) throw new ScanException("Value of octal integer literal \"" + s + "\" is out of range");
- x = (x << 3) + Character.digit(s.charAt(i), 8);
- }
- break;
-
- case 16:
- // Cannot use "Integer.parseInt(s, 16)" because that parses SIGNED values.
- x = 0;
- for (int i = 0; i < s.length(); ++i) {
- if ((x & 0xf0000000) != 0) throw new ScanException("Value of hexadecimal integer literal \"" + s + "\" is out of range");
- x = (x << 4) + Character.digit(s.charAt(i), 16);
- }
- break;
-
- default:
- throw new RuntimeException("Illegal radix " + radix);
- }
- return new LiteralToken(new Integer(x));
- }
-
- private LiteralToken stringToLongLiteralToken(final String s, int radix) throws ScanException {
- long x;
- switch (radix) {
-
- case 10:
- // Special case: Decimal literal 2^63 must only appear in "negated" context, i.e.
- // "-9223372036854775808" is a valid long literal, but "9223372036854775808" is not.
- if (s.equals("9223372036854775808")) return new LiteralToken(Scanner.MAGIC_LONG);
-
- try {
- x = Long.parseLong(s);
- } catch (NumberFormatException e) {
- throw new ScanException("Value of decimal long literal \"" + s + "\" is out of range");
- }
- break;
-
- case 8:
- // Cannot use "Long.parseLong(s, 8)" because that parses SIGNED values.
- x = 0L;
- for (int i = 0; i < s.length(); ++i) {
- if ((x & 0xe000000000000000L) != 0L) throw new ScanException("Value of octal long literal \"" + s + "\" is out of range");
- x = (x << 3) + Character.digit(s.charAt(i), 8);
- }
- break;
-
- case 16:
- // Cannot use "Long.parseLong(s, 16)" because that parses SIGNED values.
- x = 0L;
- for (int i = 0; i < s.length(); ++i) {
- if ((x & 0xf000000000000000L) != 0L) throw new ScanException("Value of hexadecimal long literal \"" + s + "\" is out of range");
- x = (x << 4) + (long) Character.digit(s.charAt(i), 16);
- }
- break;
-
- default:
- throw new RuntimeException("Illegal radix " + radix);
- }
- return new LiteralToken(new Long(x));
- }
-
- private LiteralToken stringToFloatLiteralToken(final String s) throws ScanException {
- float f;
- try {
- f = Float.parseFloat(s);
- } catch (NumberFormatException e) {
- throw new RuntimeException("SNO: parsing float literal \"" + s + "\" throws a \"NumberFormatException\"");
- }
- if (Float.isInfinite(f)) throw new ScanException("Value of float literal \"" + s + "\" is out of range");
- if (Float.isNaN(f)) throw new RuntimeException("SNO: parsing float literal \"" + s + "\" results is NaN");
-
- // Check for FLOAT underrun.
- if (f == 0.0F) {
- for (int i = 0; i < s.length(); ++i) {
- char c = s.charAt(i);
- if ("123456789".indexOf(c) != -1) throw new ScanException("Literal \"" + s + "\" is too small to be represented as a float");
- if ("0.".indexOf(c) == -1) break;
- }
- }
-
- return new LiteralToken(new Float(f));
- }
-
- private LiteralToken stringToDoubleLiteralToken(final String s) throws ScanException {
- double d;
- try {
- d = Double.parseDouble(s);
- } catch (NumberFormatException e) {
- throw new RuntimeException("SNO: parsing double literal \"" + s + "\" throws a \"NumberFormatException\"");
- }
- if (Double.isInfinite(d)) throw new ScanException("Value of double literal \"" + s + "\" is out of range");
- if (Double.isNaN(d)) throw new RuntimeException("SNO: parsing double literal \"" + s + "\" results is NaN");
-
-
- // Check for DOUBLE underrun.
- if (d == 0.0D) {
- for (int i = 0; i < s.length(); ++i) {
- char c = s.charAt(i);
- if ("123456789".indexOf(c) != -1) throw new ScanException("Literal \"" + s + "\" is too small to be represented as a double");
- if ("0.".indexOf(c) == -1) break;
- }
- }
-
- return new LiteralToken(new Double(d));
- }
-
- /**
- * Consume characters until a literal character is complete.
- */
- private char unescapeCharacterLiteral() throws ScanException, IOException {
- if (this.nextChar == -1) throw new ScanException("EOF in character literal");
-
- if (this.nextChar == '\r' || this.nextChar == '\n') throw new ScanException("Line break in literal not allowed");
-
- if (this.nextChar != '\\') {
- char res = (char) this.nextChar;
- this.readNextChar();
- return res;
- }
- this.readNextChar();
- int idx = "btnfr".indexOf(this.nextChar);
- if (idx != -1) {
- char res = "\b\t\n\f\r".charAt(idx);
- this.readNextChar();
- return res;
- }
- idx = "01234567".indexOf(this.nextChar);
- if (idx != -1) {
- int code = idx;
- this.readNextChar();
- idx = "01234567".indexOf(this.nextChar);
- if (idx == -1) return (char) code;
- code = 8 * code + idx;
- this.readNextChar();
- idx = "01234567".indexOf(this.nextChar);
- if (idx == -1) return (char) code;
- code = 8 * code + idx;
- if (code > 255) throw new ScanException("Invalid octal escape");
- this.readNextChar();
- return (char) code;
- }
-
- char res = (char) this.nextChar;
- this.readNextChar();
- return res;
- }
-
- // Read one character and store in "nextChar".
- private void readNextChar() throws IOException, ScanException {
- try {
- this.nextChar = this.in.read();
- } catch (UnicodeUnescapeException ex) {
- throw new ScanException(ex.getMessage(), ex);
- }
- if (this.nextChar == '\r') {
- ++this.nextCharLineNumber;
- this.nextCharColumnNumber = 0;
- this.crLfPending = true;
- } else
- if (this.nextChar == '\n') {
- if (this.crLfPending) {
- this.crLfPending = false;
- } else {
- ++this.nextCharLineNumber;
- this.nextCharColumnNumber = 0;
- }
- } else
- {
- ++this.nextCharColumnNumber;
- }
-//System.out.println("'" + (char) nextChar + "' = " + (int) nextChar);
- }
-
- private static final boolean DEBUG = false;
-
- private /*final*/ String optionalFileName;
- private /*final*/ Reader in;
- private int nextChar = -1; // Always valid (one character read-ahead).
- private boolean crLfPending = false;
- private short nextCharLineNumber;
- private short nextCharColumnNumber;
-
- private Token nextToken; // Is always non-null (one token read-ahead).
- private Token nextButOneToken; // Is only non-null after "peekNextButOne()".
- private short tokenLineNumber; // Line number of "nextToken" (typically starting at one).
- private short tokenColumnNumber; // Column number of first character of "nextToken" (1 if token is immediately preceeded by a line break).
- private String docComment = null; // The optional JAVADOC comment preceeding the "nextToken".
-
- private static final Map JAVA_KEYWORDS = new HashMap();
- static {
- String[] ks = {
- "abstract", "boolean", "break", "byte", "case", "catch", "char",
- "class", "const", "continue", "default", "do", "double", "else",
- "extends", "final", "finally", "float", "for", "goto", "if",
- "implements", "import", "instanceof", "int", "interface", "long",
- "native", "new", "package", "private", "protected", "public",
- "return", "short", "static", "strictfp", "super", "switch",
- "synchronized", "this", "throw", "throws", "transient", "try",
- "void", "volatile", "while"
- };
- for (int i = 0; i < ks.length; ++i) Scanner.JAVA_KEYWORDS.put(ks[i], ks[i]);
- }
- private static final Map JAVA_OPERATORS = new HashMap();
- static {
- String[] ops = {
- // Separators:
- "(", ")", "{", "}", "[", "]", ";", ",", ".",
- // Operators:
- "=", ">", "<", "!", "~", "?", ":",
- "==", "<=", ">=", "!=", "&&", "||", "++", "--",
- "+", "-", "*", "/", "&", "|", "^", "%", "<<", ">>", ">>>",
- "+=", "-=", "*=", "/=", "&=", "|=", "^=", "%=", "<<=", ">>=", ">>>=",
- };
- for (int i = 0; i < ops.length; ++i) Scanner.JAVA_OPERATORS.put(ops[i], ops[i]);
- }
-
-
- /**
- * An exception that reflects an error during parsing.
- */
- public class ScanException extends LocatedException {
-
- public ScanException(String message) {
- super(message, new Location(
- Scanner.this.optionalFileName,
- Scanner.this.nextCharLineNumber,
- Scanner.this.nextCharColumnNumber
- ));
- }
-
- public ScanException(String message, Throwable cause) {
- super(message, new Location(
- Scanner.this.optionalFileName,
- Scanner.this.nextCharLineNumber,
- Scanner.this.nextCharColumnNumber
- ), cause);
- }
- }
-
- /**
- * By default, warnings are discarded, but an application my install a
- * {@link WarningHandler}.
- * <p>
- * Notice that there is no <code>Scanner.setErrorHandler()</code> method, but scan errors
- * always throw a {@link ScanException}. The reason being is that there is no reasonable
- * way to recover from scan errors and continue scanning, so there is no need to install
- * a custom scan error handler.
- *
- * @param optionalWarningHandler <code>null</code> to indicate that no warnings be issued
- */
- public void setWarningHandler(WarningHandler optionalWarningHandler) {
- this.optionalWarningHandler = optionalWarningHandler;
- }
-
- // Used for elaborate warning handling.
- private WarningHandler optionalWarningHandler = null;
-
- /**
- * Issues a warning with the given message and location and returns. This is done through
- * a {@link WarningHandler} that was installed through
- * {@link #setWarningHandler(WarningHandler)}.
- * <p>
- * The <code>handle</code> argument qulifies the warning and is typically used by
- * the {@link WarningHandler} to suppress individual warnings.
- */
- private void warning(String handle, String message, Location optionalLocation) {
- if (this.optionalWarningHandler != null) this.optionalWarningHandler.handleWarning(handle, message, optionalLocation);
- }
-}
diff --git a/src/org/codehaus/janino/ScriptEvaluator.java b/src/org/codehaus/janino/ScriptEvaluator.java
deleted file mode 100644
index efa93e7..0000000
--- a/src/org/codehaus/janino/ScriptEvaluator.java
+++ /dev/null
@@ -1,1045 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino;
-
-import java.io.*;
-import java.lang.reflect.*;
-import java.util.*;
-
-import org.codehaus.janino.Java.AmbiguousName;
-import org.codehaus.janino.Java.LocalVariableDeclarationStatement;
-import org.codehaus.janino.Parser.ParseException;
-import org.codehaus.janino.Scanner.ScanException;
-import org.codehaus.janino.util.Traverser;
-
-/**
- * An engine that executes a script in Java<sup>TM</sup> bytecode.
- * <p>
- * The syntax of the script to compile is a sequence of import declarations (not allowed if you
- * compile many scripts at a time, see below) followed by a
- * sequence of statements, as defined in the
- * <a href="http://java.sun.com/docs/books/jls/second_edition">Java Language Specification, 2nd
- * edition</a>, sections
- * <a href="http://java.sun.com/docs/books/jls/second_edition/html/packages.doc.html#70209">7.5</a>
- * and
- * <a href="http://java.sun.com/docs/books/jls/second_edition/html/statements.doc.html#101241">14</a>.
- * <p>
- * Example:
- * <pre>
- * import java.text.*;
- *
- * System.out.println("HELLO");
- * System.out.println(new DecimalFormat("####,###.##").format(a));
- * </pre>
- * (Notice that this expression refers to a parameter "a", as explained below.)
- * <p>
- * The script may complete abnormally, e.g. through a RETURN statement:
- * <pre>
- * if (a == null) {
- * System.out.println("Oops!");
- * return;
- * }
- * </pre>
- * Optionally, the script may be declared with a non-void return type. In this case, the last
- * statement of the script must be a RETURN statement (or a THROW statement), and all RETURN
- * statements in the script must return a value with the given type.
- * <p>
- * The script evaluator is implemented by creating and compiling a temporary compilation unit
- * defining one class with one method the body of which consists of the statements of the
- * script.
- * <p>
- * To set up a {@link ScriptEvaluator} object, proceed as follows:
- * <ol>
- * <li>
- * Create the {@link ScriptEvaluator} using {@link #ScriptEvaluator()}
- * <li>
- * Configure the {@link ScriptEvaluator} by calling any of the following methods:
- * <ul>
- * <li>{@link #setReturnType(Class)}
- * <li>{@link #setParameters(String[], Class[])}
- * <li>{@link #setThrownExceptions(Class[])}
- * <li>{@link org.codehaus.janino.SimpleCompiler#setParentClassLoader(ClassLoader)}
- * <li>{@link org.codehaus.janino.ClassBodyEvaluator#setDefaultImports(String[])}
- * </ul>
- * <li>
- * Call any of the {@link org.codehaus.janino.Cookable#cook(Scanner)} methods to scan,
- * parse, compile and load the script into the JVM.
- * </ol>
- * After the {@link ScriptEvaluator} object is created, the script can be executed as often with
- * different parameter values (see {@link #evaluate(Object[])}). This execution is very fast,
- * compared to the compilation.
- * <p>
- * Less common methods exist that allow for the specification of the name of the generated class,
- * the class it extends, the interfaces it implements, the name of the method that executes the
- * script, the exceptions that this method (i.e. the script) is allowed to throw, and the
- * {@link ClassLoader} that is used to define the generated class and to load classes referenced by
- * the script.
- * <p>
- * Alternatively, a number of "convenience constructors" exist that execute the steps described
- * above instantly. Their use is discouraged.
- * <p>
- * If you want to compile many scripts at the same time, you have the option to cook an
- * <i>array</i> of scripts in one {@link ScriptEvaluator} by using the following methods:
- * <ul>
- * <li>{@link #setMethodNames(String[])}
- * <li>{@link #setParameters(String[][], Class[][])}
- * <li>{@link #setReturnTypes(Class[])}
- * <li>{@link #setStaticMethod(boolean[])}
- * <li>{@link #setThrownExceptions(Class[][])}
- * <li>{@link #cook(Scanner[])}
- * <li>{@link #evaluate(int, Object[])}
- * </ul>
- * Notice that these methods have array parameters in contrast to their one-script brethren.
- */
-public class ScriptEvaluator extends ClassBodyEvaluator {
-
- protected boolean[] optionalStaticMethod = null;
- protected Class[] optionalReturnTypes = null;
- protected String[] optionalMethodNames = null;
- protected String[][] optionalParameterNames = null;
- protected Class[][] optionalParameterTypes = null;
- protected Class[][] optionalThrownExceptions = null;
-
- private Method[] result = null; // null=uncooked
-
- /**
- * Equivalent to<pre>
- * ScriptEvaluator se = new ScriptEvaluator();
- * se.cook(script);</pre>
- *
- * @see #ScriptEvaluator()
- * @see Cookable#cook(String)
- */
- public ScriptEvaluator(
- String script
- ) throws CompileException, Parser.ParseException, Scanner.ScanException {
- this.cook(script);
- }
-
- /**
- * Equivalent to<pre>
- * ScriptEvaluator se = new ScriptEvaluator();
- * se.setReturnType(returnType);
- * se.cook(script);</pre>
- *
- * @see #ScriptEvaluator()
- * @see #setReturnType(Class)
- * @see Cookable#cook(String)
- */
- public ScriptEvaluator(
- String script,
- Class returnType
- ) throws CompileException, Parser.ParseException, Scanner.ScanException {
- this.setReturnType(returnType);
- this.cook(script);
- }
-
- /**
- * Equivalent to<pre>
- * ScriptEvaluator se = new ScriptEvaluator();
- * se.setReturnType(returnType);
- * se.setParameters(parameterNames, parameterTypes);
- * se.cook(script);</pre>
- *
- * @see #ScriptEvaluator()
- * @see #setReturnType(Class)
- * @see #setParameters(String[], Class[])
- * @see Cookable#cook(String)
- */
- public ScriptEvaluator(
- String script,
- Class returnType,
- String[] parameterNames,
- Class[] parameterTypes
- ) throws CompileException, Parser.ParseException, Scanner.ScanException {
- this.setReturnType(returnType);
- this.setParameters(parameterNames, parameterTypes);
- this.cook(script);
- }
-
- /**
- * Equivalent to<pre>
- * ScriptEvaluator se = new ScriptEvaluator();
- * se.setReturnType(returnType);
- * se.setParameters(parameterNames, parameterTypes);
- * se.setThrownExceptions(thrownExceptions);
- * se.cook(script);</pre>
- *
- * @see #ScriptEvaluator()
- * @see #setReturnType(Class)
- * @see #setParameters(String[], Class[])
- * @see #setThrownExceptions(Class[])
- * @see Cookable#cook(String)
- */
- public ScriptEvaluator(
- String script,
- Class returnType,
- String[] parameterNames,
- Class[] parameterTypes,
- Class[] thrownExceptions
- ) throws CompileException, Parser.ParseException, Scanner.ScanException {
- this.setReturnType(returnType);
- this.setParameters(parameterNames, parameterTypes);
- this.setThrownExceptions(thrownExceptions);
- this.cook(script);
- }
-
- /**
- * Equivalent to<pre>
- * ScriptEvaluator se = new ScriptEvaluator();
- * se.setReturnType(returnType);
- * se.setParameters(parameterNames, parameterTypes);
- * se.setThrownExceptions(thrownExceptions);
- * se.setParentClassLoader(optionalParentClassLoader);
- * se.cook(optionalFileName, is);</pre>
- *
- * @see #ScriptEvaluator()
- * @see #setReturnType(Class)
- * @see #setParameters(String[], Class[])
- * @see #setThrownExceptions(Class[])
- * @see SimpleCompiler#setParentClassLoader(ClassLoader)
- * @see Cookable#cook(String, InputStream)
- */
- public ScriptEvaluator(
- String optionalFileName,
- InputStream is,
- Class returnType,
- String[] parameterNames,
- Class[] parameterTypes,
- Class[] thrownExceptions,
- ClassLoader optionalParentClassLoader // null = use current thread's context class loader
- ) throws CompileException, Parser.ParseException, Scanner.ScanException, IOException {
- this.setReturnType(returnType);
- this.setParameters(parameterNames, parameterTypes);
- this.setThrownExceptions(thrownExceptions);
- this.setParentClassLoader(optionalParentClassLoader);
- this.cook(optionalFileName, is);
- }
-
- /**
- * Equivalent to<pre>
- * ScriptEvaluator se = new ScriptEvaluator();
- * se.setReturnType(returnType);
- * se.setParameters(parameterNames, parameterTypes);
- * se.setThrownExceptions(thrownExceptions);
- * se.setParentClassLoader(optionalParentClassLoader);
- * se.cook(reader);</pre>
- *
- * @see #ScriptEvaluator()
- * @see #setReturnType(Class)
- * @see #setParameters(String[], Class[])
- * @see #setThrownExceptions(Class[])
- * @see SimpleCompiler#setParentClassLoader(ClassLoader)
- * @see Cookable#cook(String, Reader)
- */
- public ScriptEvaluator(
- String optionalFileName,
- Reader reader,
- Class returnType,
- String[] parameterNames,
- Class[] parameterTypes,
- Class[] thrownExceptions,
- ClassLoader optionalParentClassLoader // null = use current thread's context class loader
- ) throws CompileException, Parser.ParseException, Scanner.ScanException, IOException {
- this.setReturnType(returnType);
- this.setParameters(parameterNames, parameterTypes);
- this.setThrownExceptions(thrownExceptions);
- this.setParentClassLoader(optionalParentClassLoader);
- this.cook(optionalFileName, reader);
- }
-
- /**
- * Equivalent to<pre>
- * ScriptEvaluator se = new ScriptEvaluator();
- * se.setReturnType(returnType);
- * se.setParameters(parameterNames, parameterTypes);
- * se.setThrownExceptions(thrownExceptions);
- * se.setParentClassLoader(optionalParentClassLoader);
- * se.cook(scanner);</pre>
- *
- * @see #ScriptEvaluator()
- * @see #setReturnType(Class)
- * @see #setParameters(String[], Class[])
- * @see #setThrownExceptions(Class[])
- * @see SimpleCompiler#setParentClassLoader(ClassLoader)
- * @see Cookable#cook(Scanner)
- */
- public ScriptEvaluator(
- Scanner scanner,
- Class returnType,
- String[] parameterNames,
- Class[] parameterTypes,
- Class[] thrownExceptions,
- ClassLoader optionalParentClassLoader // null = use current thread's context class loader
- ) throws CompileException, Parser.ParseException, Scanner.ScanException, IOException {
- this.setReturnType(returnType);
- this.setParameters(parameterNames, parameterTypes);
- this.setThrownExceptions(thrownExceptions);
- this.setParentClassLoader(optionalParentClassLoader);
- this.cook(scanner);
- }
-
- /**
- * Equivalent to<pre>
- * ScriptEvaluator se = new ScriptEvaluator();
- * se.setExtendedType(optionalExtendedType);
- * se.setImplementedTypes(implementedTypes);
- * se.setReturnType(returnType);
- * se.setParameters(parameterNames, parameterTypes);
- * se.setThrownExceptions(thrownExceptions);
- * se.setParentClassLoader(optionalParentClassLoader);
- * se.cook(scanner);</pre>
- *
- * @see #ScriptEvaluator()
- * @see ClassBodyEvaluator#setExtendedType(Class)
- * @see ClassBodyEvaluator#setImplementedTypes(Class[])
- * @see #setReturnType(Class)
- * @see #setParameters(String[], Class[])
- * @see #setThrownExceptions(Class[])
- * @see SimpleCompiler#setParentClassLoader(ClassLoader)
- * @see Cookable#cook(Scanner)
- */
- public ScriptEvaluator(
- Scanner scanner,
- Class optionalExtendedType,
- Class[] implementedTypes,
- Class returnType,
- String[] parameterNames,
- Class[] parameterTypes,
- Class[] thrownExceptions,
- ClassLoader optionalParentClassLoader // null = use current thread's context class loader
- ) throws CompileException, Parser.ParseException, Scanner.ScanException, IOException {
- this.setExtendedType(optionalExtendedType);
- this.setImplementedTypes(implementedTypes);
- this.setReturnType(returnType);
- this.setParameters(parameterNames, parameterTypes);
- this.setThrownExceptions(thrownExceptions);
- this.setParentClassLoader(optionalParentClassLoader);
- this.cook(scanner);
- }
-
- /**
- * Equivalent to<pre>
- * ScriptEvaluator se = new ScriptEvaluator();
- * se.setClassName(className);
- * se.setExtendedType(optionalExtendedType);
- * se.setImplementedTypes(implementedTypes);
- * se.setStaticMethod(staticMethod);
- * se.setReturnType(returnType);
- * se.setMethodName(methodName);
- * se.setParameters(parameterNames, parameterTypes);
- * se.setThrownExceptions(thrownExceptions);
- * se.setParentClassLoader(optionalParentClassLoader);
- * se.cook(scanner);</pre>
- *
- * @see #ScriptEvaluator()
- * @see ClassBodyEvaluator#setClassName(String)
- * @see ClassBodyEvaluator#setExtendedType(Class)
- * @see ClassBodyEvaluator#setImplementedTypes(Class[])
- * @see #setStaticMethod(boolean)
- * @see #setReturnType(Class)
- * @see #setMethodName(String)
- * @see #setParameters(String[], Class[])
- * @see #setThrownExceptions(Class[])
- * @see SimpleCompiler#setParentClassLoader(ClassLoader)
- * @see Cookable#cook(Scanner)
- */
- public ScriptEvaluator(
- Scanner scanner,
- String className,
- Class optionalExtendedType,
- Class[] implementedTypes,
- boolean staticMethod,
- Class returnType,
- String methodName,
- String[] parameterNames,
- Class[] parameterTypes,
- Class[] thrownExceptions,
- ClassLoader optionalParentClassLoader // null = use current thread's context class loader
- ) throws Scanner.ScanException, Parser.ParseException, CompileException, IOException {
- this.setClassName(className);
- this.setExtendedType(optionalExtendedType);
- this.setImplementedTypes(implementedTypes);
- this.setStaticMethod(staticMethod);
- this.setReturnType(returnType);
- this.setMethodName(methodName);
- this.setParameters(parameterNames, parameterTypes);
- this.setThrownExceptions(thrownExceptions);
- this.setParentClassLoader(optionalParentClassLoader);
- this.cook(scanner);
- }
-
- public ScriptEvaluator() {}
-
- /**
- * Define whether the generated method should be STATIC or not. Defaults to <code>true</code>.
- */
- public void setStaticMethod(boolean staticMethod) {
- this.setStaticMethod(new boolean[] { staticMethod });
- }
-
- /**
- * Define the return type of the generated method. Defaults to <code>void.class</code>.
- */
- public void setReturnType(Class returnType) {
- this.setReturnTypes(new Class[] { returnType });
- }
-
- /**
- * Define the name of the generated method. Defaults to an unspecified name.
- */
- public void setMethodName(String methodName) {
- this.setMethodNames(new String[] { methodName });
- }
-
- /**
- * Define the names and types of the parameters of the generated method.
- */
- public void setParameters(String[] parameterNames, Class[] parameterTypes) {
- this.setParameters(new String[][] { parameterNames }, new Class[][] {parameterTypes });
- }
-
- /**
- * Define the exceptions that the generated method may throw.
- */
- public void setThrownExceptions(Class[] thrownExceptions) {
- this.setThrownExceptions(new Class[][] { thrownExceptions });
- }
-
- public final void cook(Scanner scanner)
- throws CompileException, Parser.ParseException, Scanner.ScanException, IOException {
- this.cook(new Scanner[] { scanner });
- }
-
- /**
- * Calls the generated method with concrete parameter values.
- * <p>
- * Each parameter value must have the same type as specified through
- * the "parameterTypes" parameter of
- * {@link #setParameters(String[], Class[])}.
- * <p>
- * Parameters of primitive type must passed with their wrapper class
- * objects.
- * <p>
- * The object returned has the class as specified through
- * {@link #setReturnType(Class)}.
- * <p>
- * This method is thread-safe.
- *
- * @param parameterValues The concrete parameter values.
- */
- public Object evaluate(Object[] parameterValues) throws InvocationTargetException {
- return this.evaluate(0, parameterValues);
- }
-
- /**
- * Returns the loaded {@link java.lang.reflect.Method}.
- * <p>
- * This method must only be called after {@link #cook(Scanner)}.
- * <p>
- * This method must not be called for instances of derived classes.
- */
- public Method getMethod() {
- return this.getMethod(0);
- }
-
- /**
- * Define whether the methods implementing each script should be STATIC or not. By default
- * all scripts are compiled into STATIC methods.
- */
- public void setStaticMethod(boolean[] staticMethod) {
- assertNotCooked();
- this.optionalStaticMethod = (boolean[]) staticMethod.clone();
- }
-
- /**
- * Define the return types of the scripts. By default all scripts have VOID return type.
- */
- public void setReturnTypes(Class[] returnTypes) {
- assertNotCooked();
- this.optionalReturnTypes = (Class[]) returnTypes.clone();
- }
-
- /**
- * Define the names of the generated methods. By default the methods have distinct and
- * implementation-specific names.
- * <p>
- * If two scripts have the same name, then they must have different parameter types
- * (see {@link #setParameters(String[][], Class[][])}).
- */
- public void setMethodNames(String[] methodNames) {
- assertNotCooked();
- this.optionalMethodNames = (String[]) methodNames.clone();
- }
-
- /**
- * Define the names and types of the parameters of the generated methods.
- */
- public void setParameters(String[][] parameterNames, Class[][] parameterTypes) {
- assertNotCooked();
- this.optionalParameterNames = (String[][]) parameterNames.clone();
- this.optionalParameterTypes = (Class[][]) parameterTypes.clone();
- }
-
- /**
- * Define the exceptions that the generated methods may throw.
- */
- public void setThrownExceptions(Class[][] thrownExceptions) {
- assertNotCooked();
- this.optionalThrownExceptions = (Class[][]) thrownExceptions.clone();
- }
-
- /**
- * Like {@link #cook(Scanner)}, but cooks a <i>set</i> of scripts into one class. Notice that
- * if <i>any</i> of the scripts causes trouble, the entire compilation will fail. If you
- * need to report <i>which</i> of the scripts causes the exception, you may want to use the
- * <code>optionalFileName</code> argument of {@link Scanner#Scanner(String, Reader)} to
- * distinguish between the individual token sources.
- * <p>
- * On a 2 GHz Intel Pentium Core Duo under Windows XP with an IBM 1.4.2 JDK, compiling
- * 10000 expressions "a + b" (integer) takes about 4 seconds and 56 MB of main memory.
- * The generated class file is 639203 bytes large.
- * <p>
- * The number and the complexity of the scripts is restricted by the
- * <a href="http://java.sun.com/docs/books/vmspec/2nd-edition/html/ClassFile.doc.html#88659">Limitations
- * of the Java Virtual Machine</a>, where the most limiting factor is the 64K entries limit
- * of the constant pool. Since every method with a distinct name requires one entry there,
- * you can define at best 32K (very simple) scripts.
- *
- * If and only if the number of scanners is one, then that single script may contain leading
- * IMPORT directives.
- *
- * @throws IllegalStateException if any of the preceeding <code>set...()</code> had an array size different from that of <code>scanners</code>
- */
- public final void cook(Scanner[] scanners)
- throws CompileException, Parser.ParseException, Scanner.ScanException, IOException {
- if (scanners == null) throw new NullPointerException();
-
- // The "dimension" of this ScriptEvaluator, i.e. how many scripts are cooked at the same
- // time.
- int count = scanners.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.optionalStaticMethod != null && this.optionalStaticMethod.length != count) throw new IllegalStateException("staticMethod");
- if (this.optionalThrownExceptions != null && this.optionalThrownExceptions.length != count) throw new IllegalStateException("thrownExceptions");
-
- this.setUpClassLoaders();
-
- // Create compilation unit.
- Java.CompilationUnit compilationUnit = this.makeCompilationUnit(count == 1 ? scanners[0] : null);
-
- // Create class declaration.
- Java.ClassDeclaration cd = this.addPackageMemberClassDeclaration(scanners[0].location(), compilationUnit);
-
- // Determine method names.
- String[] methodNames;
- if (this.optionalMethodNames == null) {
- methodNames = new String[count];
- for (int i = 0; i < count; ++i) methodNames[i] = "eval" + i;
- } else
- {
- methodNames = this.optionalMethodNames;
- }
-
- // Create methods with one block each.
- for (int i = 0; i < count; ++i) {
- Scanner scanner = scanners[i];
-
- Java.Block block = this.makeBlock(i, scanner);
-
- // Determine the following script properties AFTER the call to "makeBlock()",
- // because "makeBlock()" may modify these script properties on-the-fly.
- boolean staticMethod = this.optionalStaticMethod == null ? true : 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];
-
- cd.addDeclaredMethod(this.makeMethodDeclaration(
- scanner.location(), // location
- staticMethod, // staticMethod
- returnType, // returnType
- methodNames[i], // methodName
- parameterTypes, // parameterTypes
- parameterNames, // parameterNames
- thrownExceptions, // thrownExceptions
- block // optionalBody
- ));
- }
-
- // Compile and load the compilation unit.
- Class c = this.compileToClass(
- compilationUnit, // compilationUnit
- DebuggingInformation.DEFAULT_DEBUGGING_INFORMATION, // debuggingInformation
- this.className
- );
-
- // 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] + "\"");
- }
- }
- } else
- {
- class MethodWrapper {
- private final String name;
- private final Class[] parameterTypes;
- MethodWrapper(String name, Class[] parameterTypes) {
- this.name = name;
- this.parameterTypes = parameterTypes;
- }
- public boolean equals(Object o) {
- if (!(o instanceof MethodWrapper)) return false;
- MethodWrapper that = (MethodWrapper) o;
- if (!this.name.equals(that.name)) return false;
- int cnt = this.parameterTypes.length;
- if (cnt != that.parameterTypes.length) return false;
- for (int i = 0; i < cnt; ++i) {
- if (!this.parameterTypes[i].equals(that.parameterTypes[i])) return false;
- }
- return true;
- }
- public int hashCode() {
- int hc = this.name.hashCode();
- for (int i = 0; i < this.parameterTypes.length; ++i) {
- hc ^= this.parameterTypes[i].hashCode();
- }
- return hc;
- }
- }
- 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 = (Method) 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;
- }
- }
- }
-
- public final void cook(Reader[] readers)
- throws CompileException, Parser.ParseException, Scanner.ScanException, IOException {
- this.cook(new String[readers.length], readers);
- }
-
- /**
- * @param optionalFileNames Used when reporting errors and warnings.
- */
- public final void cook(String[] optionalFileNames, Reader[] readers)
- throws CompileException, Parser.ParseException, Scanner.ScanException, IOException {
- Scanner[] scanners = new Scanner[readers.length];
- for (int i = 0; i < readers.length; ++i) scanners[i] = new Scanner(optionalFileNames[i], readers[i]);
- this.cook(scanners);
- }
-
- /**
- * Cook tokens from {@link java.lang.String}s.
- */
- public final void cook(String[] strings)
- throws CompileException, Parser.ParseException, Scanner.ScanException {
- Reader[] readers = new Reader[strings.length];
- for (int i = 0; i < strings.length; ++i) readers[i] = new StringReader(strings[i]);
- try {
- this.cook(readers);
- } catch (IOException ex) {
- throw new RuntimeException("SNO: IOException despite StringReader");
- }
- }
-
- protected Class getDefaultReturnType() {
- return void.class;
- }
-
- /**
- * Fill the given <code>block</code> by parsing statements until EOF and adding
- * them to the block.
- */
- protected Java.Block makeBlock(int idx, Scanner scanner) throws ParseException, ScanException, IOException {
- Java.Block block = new Java.Block(scanner.location());
- Parser parser = new Parser(scanner);
- while (!scanner.peek().isEOF()) {
- block.addStatement(parser.parseBlockStatement());
- }
-
- return block;
- }
-
- protected void compileToMethods(
- Java.CompilationUnit compilationUnit,
- String[] methodNames,
- Class[][] parameterTypes
- ) throws CompileException {
-
- // Compile and load the compilation unit.
- Class c = this.compileToClass(
- compilationUnit, // compilationUnit
- DebuggingInformation.DEFAULT_DEBUGGING_INFORMATION, // debuggingInformation
- this.className
- );
-
- // Find the script method by name.
- this.result = new Method[methodNames.length];
- for (int i = 0; i < this.result.length; ++i) {
- try {
- this.result[i] = c.getMethod(methodNames[i], parameterTypes[i]);
- } catch (NoSuchMethodException ex) {
- throw new RuntimeException("SNO: Loaded class does not declare method \"" + this.optionalMethodNames[i] + "\"");
- }
- }
- }
-
- /**
- * To the given {@link Java.ClassDeclaration}, add
- * <ul>
- * <li>A public method declaration with the given return type, name, parameter
- * names and values and thrown exceptions
- * <li>A block
- * </ul>
- *
- * @param returnType Return type of the declared method
- */
- protected Java.MethodDeclarator makeMethodDeclaration(
- Location location,
- boolean staticMethod,
- Class returnType,
- String methodName,
- Class[] parameterTypes,
- String[] parameterNames,
- Class[] thrownExceptions,
- Java.Block optionalBody
- ) {
- if (parameterNames.length != parameterTypes.length) throw new RuntimeException("Lengths of \"parameterNames\" (" + parameterNames.length + ") and \"parameterTypes\" (" + parameterTypes.length + ") do not match");
-
- Java.FunctionDeclarator.FormalParameter[] fps = new Java.FunctionDeclarator.FormalParameter[parameterNames.length];
- for (int i = 0; i < fps.length; ++i) {
- fps[i] = new Java.FunctionDeclarator.FormalParameter(
- location, // location
- true, // finaL
- this.classToType(location, parameterTypes[i]), // type
- parameterNames[i] // name
- );
- }
-
- return new Java.MethodDeclarator(
- location, // location
- null, // optionalDocComment
- ( // modifiers
- staticMethod ?
- (short) (Mod.PUBLIC | Mod.STATIC) :
- (short) Mod.PUBLIC
- ),
- this.classToType(location, returnType), // type
- methodName, // name
- fps, // formalParameters
- this.classesToTypes(location, thrownExceptions), // thrownExceptions
- optionalBody // optionalBody
- );
- }
-
- /**
- * Simplified version of
- * {@link #createFastScriptEvaluator(Scanner, Class, String[], ClassLoader)}.
- *
- * @param script Contains the sequence of script tokens
- * @param interfaceToImplement Must declare exactly the one method that defines the expression's signature
- * @param parameterNames The expression references the parameters through these names
- * @return an object that implements the given interface and extends the <code>optionalExtendedType</code>
- */
- public static Object createFastScriptEvaluator(
- String script,
- Class interfaceToImplement,
- String[] parameterNames
- ) throws CompileException, Parser.ParseException, Scanner.ScanException {
- ScriptEvaluator se = new ScriptEvaluator();
- return ScriptEvaluator.createFastEvaluator(se, script, parameterNames, interfaceToImplement);
- }
-
- /**
- * If the parameter and return types of the expression are known at compile time,
- * then a "fast" script evaluator can be instantiated through this method.
- * <p>
- * Script evaluation is faster than through {@link #evaluate(Object[])}, because
- * it is not done through reflection but through direct method invocation.
- * <p>
- * Example:
- * <pre>
- * public interface Foo {
- * int bar(int a, int b);
- * }
- * ...
- * Foo f = (Foo) ScriptEvaluator.createFastScriptEvaluator(
- * new Scanner(null, new StringReader("return a + b;")),
- * Foo.class,
- * new String[] { "a", "b" },
- * (ClassLoader) null // Use current thread's context class loader
- * );
- * System.out.println("1 + 2 = " + f.bar(1, 2));
- * </pre>
- * Notice: The <code>interfaceToImplement</code> must either be declared <code>public</code>,
- * or with package scope in the root package (i.e. "no" package).
- *
- * @param scanner Source of script tokens
- * @param interfaceToImplement Must declare exactly one method
- * @param parameterNames
- * @param optionalParentClassLoader
- * @return an object that implements the given interface
- */
- public static Object createFastScriptEvaluator(
- Scanner scanner,
- Class interfaceToImplement,
- String[] parameterNames,
- ClassLoader optionalParentClassLoader
- ) throws CompileException, Parser.ParseException, Scanner.ScanException, IOException {
- ScriptEvaluator se = new ScriptEvaluator();
- se.setParentClassLoader(optionalParentClassLoader);
- return ScriptEvaluator.createFastEvaluator(se, scanner, parameterNames, interfaceToImplement);
- }
-
- /**
- * Like {@link #createFastScriptEvaluator(Scanner, Class, String[], ClassLoader)},
- * but gives you more control over the generated class (rarely needed in practice).
- * <p>
- * Notice: The <code>interfaceToImplement</code> must either be declared <code>public</code>,
- * or with package scope in the same package as <code>className</code>.
- *
- * @param scanner Source of script tokens
- * @param className Name of generated class
- * @param optionalExtendedType Class to extend
- * @param interfaceToImplement Must declare exactly the one method that defines the expression's signature
- * @param parameterNames The expression references the parameters through these names
- * @param optionalParentClassLoader Used to load referenced classes, defaults to the current thread's "context class loader"
- * @return an object that implements the given interface and extends the <code>optionalExtendedType</code>
- */
- public static Object createFastScriptEvaluator(
- Scanner scanner,
- String className,
- Class optionalExtendedType,
- Class interfaceToImplement,
- String[] parameterNames,
- ClassLoader optionalParentClassLoader
- ) throws CompileException, Parser.ParseException, Scanner.ScanException, IOException {
- ScriptEvaluator se = new ScriptEvaluator();
- se.setClassName(className);
- se.setExtendedType(optionalExtendedType);
- se.setParentClassLoader(optionalParentClassLoader);
- return ScriptEvaluator.createFastEvaluator(se, scanner, parameterNames, interfaceToImplement);
- }
-
- public static Object createFastScriptEvaluator(
- Scanner scanner,
- String[] optionalDefaultImports,
- String className,
- Class optionalExtendedType,
- Class interfaceToImplement,
- String[] parameterNames,
- ClassLoader optionalParentClassLoader
- ) throws CompileException, Parser.ParseException, Scanner.ScanException, IOException {
- ScriptEvaluator se = new ScriptEvaluator();
- se.setClassName(className);
- se.setExtendedType(optionalExtendedType);
- se.setDefaultImports(optionalDefaultImports);
- se.setParentClassLoader(optionalParentClassLoader);
- return ScriptEvaluator.createFastEvaluator(se, scanner, parameterNames, interfaceToImplement);
- }
-
- public static Object createFastEvaluator(
- ScriptEvaluator se,
- String s,
- String[] parameterNames,
- Class interfaceToImplement
- ) throws CompileException, Parser.ParseException, Scanner.ScanException {
- try {
- return ScriptEvaluator.createFastEvaluator(
- se,
- new Scanner(null, new StringReader(s)),
- parameterNames,
- interfaceToImplement
- );
- } catch (IOException ex) {
- throw new RuntimeException("IOException despite StringReader");
- }
- }
-
- /**
- * Create and return an object that implements the exactly one method of the given
- * <code>interfaceToImplement</code>.
- *
- * @param se A pre-configured {@link ScriptEvaluator} object
- * @param scanner Source of tokens to read
- * @param parameterNames The names of the parameters of the one abstract method of <code>interfaceToImplement</code>
- * @param interfaceToImplement A type with exactly one abstract method
- * @return an instance of the created {@link Object}
- */
- public static Object createFastEvaluator(
- ScriptEvaluator se,
- Scanner scanner,
- String[] parameterNames,
- Class interfaceToImplement
- ) throws CompileException, Parser.ParseException, Scanner.ScanException, 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];
-
- se.setImplementedTypes(new Class[] { interfaceToImplement });
- se.setStaticMethod(false);
- se.setReturnType(methodToImplement.getReturnType());
- se.setMethodName(methodToImplement.getName());
- se.setParameters(parameterNames, methodToImplement.getParameterTypes());
- se.setThrownExceptions(methodToImplement.getExceptionTypes());
- se.cook(scanner);
- Class c = se.getMethod().getDeclaringClass();
- try {
- return c.newInstance();
- } catch (InstantiationException e) {
- // SNO - Declared class is always non-abstract.
- throw new RuntimeException(e.toString());
- } catch (IllegalAccessException e) {
- // SNO - interface methods are always PUBLIC.
- throw new RuntimeException(e.toString());
- }
- }
-
- /**
- * Guess the names of the parameters used in the given expression. The strategy is to look
- * at all "ambiguous names" in the expression (e.g. in "a.b.c.d()", the ambiguous name
- * is "a.b.c"), and then at the components of the ambiguous name.
- * <ul>
- * <li>If any component starts with an upper-case letter, then ambiguous name is assumed to
- * be a type name.
- * <li>Otherwise, if the first component of the ambiguous name matches the name of a
- * previously defined local variable, then the first component of the ambiguous name is
- * assumed to be a local variable name. (Notice that this strategy does not consider that
- * the scope of a local variable declaration may end before the end of the script.)
- * <li>Otherwise, the first component of the ambiguous name is assumed to be a parameter name.
- * </ul>
- *
- * @see Scanner#Scanner(String, Reader)
- */
- public static String[] guessParameterNames(Scanner scanner) throws ParseException, ScanException, IOException {
- Parser parser = new Parser(scanner);
-
- // Eat optional leading import declarations.
- while (scanner.peek().isKeyword("import")) parser.parseImportDeclaration();
-
- // Parse the script statements into a block.
- Java.Block block = new Java.Block(scanner.location());
- while (!scanner.peek().isEOF()) block.addStatement(parser.parseBlockStatement());
-
- // Traverse the block for ambiguous names and guess which of them are parameter names.
- final Set localVariableNames = new HashSet();
- final Set parameterNames = new HashSet();
- new Traverser() {
- public void traverseLocalVariableDeclarationStatement(LocalVariableDeclarationStatement lvds) {
- for (int i = 0; i < lvds.variableDeclarators.length; ++i) {
- localVariableNames.add(lvds.variableDeclarators[i].name);
- }
- super.traverseLocalVariableDeclarationStatement(lvds);
- }
-
- public void traverseAmbiguousName(AmbiguousName an) {
-
- // If any of the components starts with an upper-case letter, then the ambiguous
- // name is most probably a type name, e.g. "System.out" or "java.lang.System.out".
- for (int i = 0; i < an.identifiers.length; ++i) {
- if (Character.isUpperCase(an.identifiers[i].charAt(0))) return;
- }
-
- // Is it a local variable's name?
- if (localVariableNames.contains(an.identifiers[0])) return;
-
- // It's most probably a parameter name (although it could be a field name as well).
- parameterNames.add(an.identifiers[0]);
- }
- }.traverseBlock(block);
-
- return (String[]) parameterNames.toArray(new String[parameterNames.size()]);
- }
-
- /**
- * Calls the generated method with concrete parameter values.
- * <p>
- * Each parameter value must have the same type as specified through
- * the "parameterTypes" parameter of
- * {@link #setParameters(String[], Class[])}.
- * <p>
- * Parameters of primitive type must passed with their wrapper class
- * objects.
- * <p>
- * The object returned has the class as specified through
- * {@link #setReturnType(Class)}.
- * <p>
- * This method is thread-safe.
- *
- * @param idx The index of the script (0 ... <code>scripts.length - 1</code>)
- * @param parameterValues The concrete parameter values.
- */
- public Object evaluate(int idx, Object[] parameterValues) throws InvocationTargetException {
- if (this.result == null) throw new IllegalStateException("Must only be called after \"cook()\"");
- try {
- return this.result[idx].invoke(null, parameterValues);
- } catch (IllegalAccessException ex) {
- throw new RuntimeException(ex.toString());
- }
- }
-
- /**
- * Returns the loaded {@link java.lang.reflect.Method}.
- * <p>
- * This method must only be called after {@link #cook(Scanner)}.
- * <p>
- * This method must not be called for instances of derived classes.
- *
- * @param idx The index of the script (0 ... <code>scripts.length - 1</code>)
- */
- public Method getMethod(int idx) {
- if (this.result == null) throw new IllegalStateException("Must only be called after \"cook()\"");
- return this.result[idx];
- }
-}
diff --git a/src/org/codehaus/janino/SimpleCompiler.java b/src/org/codehaus/janino/SimpleCompiler.java
deleted file mode 100644
index f3fd349..0000000
--- a/src/org/codehaus/janino/SimpleCompiler.java
+++ /dev/null
@@ -1,462 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino;
-
-import java.io.*;
-import java.lang.reflect.*;
-import java.util.*;
-
-import org.codehaus.janino.tools.Disassembler;
-import org.codehaus.janino.util.*;
-import org.codehaus.janino.util.enumerator.*;
-
-/**
- * A simplified version of {@link Compiler} that can compile only a single
- * compilation unit. (A "compilation unit" is the characters stored in a
- * ".java" file.)
- * <p>
- * Opposed to a normal ".java" file, you can declare multiple public classes
- * here.
- * <p>
- * To set up a {@link SimpleCompiler} object, proceed as follows:
- * <ol>
- * <li>
- * Create the {@link SimpleCompiler} using {@link #SimpleCompiler()}
- * <li>
- * Optionally set an alternate parent class loader through
- * {@link #setParentClassLoader(ClassLoader)}.
- * <li>
- * Call any of the {@link org.codehaus.janino.Cookable#cook(Scanner)} methods to scan,
- * parse, compile and load the compilation unit into the JVM.
- * </ol>
- * Alternatively, a number of "convenience constructors" exist that execute the steps described
- * above instantly.
- */
-public class SimpleCompiler extends Cookable {
- private final static boolean DEBUG = false;
-
- private ClassLoader parentClassLoader = Thread.currentThread().getContextClassLoader();
- private Class[] optionalAuxiliaryClasses = null;
-
- // Set when "cook()"ing.
- private AuxiliaryClassLoader classLoader = null;
- private IClassLoader iClassLoader = null;
-
- private ClassLoader result = null;
-
- public static void main(String[] args) throws Exception {
- if (args.length >= 1 && args[0].equals("-help")) {
- System.out.println("Usage:");
- System.out.println(" org.codehaus.janino.SimpleCompiler <source-file> <class-name> { <argument> }");
- System.out.println("Reads a compilation unit from the given <source-file> and invokes method");
- System.out.println("\"public static void main(String[])\" of class <class-name>, passing the.");
- System.out.println("given <argument>s.");
- System.exit(1);
- }
-
- if (args.length < 2) {
- System.err.println("Source file and/or class name missing; try \"-help\".");
- System.exit(1);
- }
-
- // Get source file.
- String sourceFileName = args[0];
-
- // Get class name.
- String className = args[1];
-
- // Get arguments.
- String[] arguments = new String[args.length - 2];
- System.arraycopy(args, 2, arguments, 0, arguments.length);
-
- // Compile the source file.
- ClassLoader cl = new SimpleCompiler(sourceFileName, new FileInputStream(sourceFileName)).getClassLoader();
-
- // Load the class.
- Class c = cl.loadClass(className);
-
- // Invoke the "public static main(String[])" method.
- Method m = c.getMethod("main", new Class[] { String[].class });
- m.invoke(null, new Object[] { arguments });
- }
-
- /**
- * Equivalent to<pre>
- * SimpleCompiler sc = new SimpleCompiler();
- * sc.cook(optionalFileName, in);</pre>
- *
- * @see #SimpleCompiler()
- * @see Cookable#cook(String, Reader)
- */
- public SimpleCompiler(
- String optionalFileName,
- Reader in
- ) throws IOException, Scanner.ScanException, Parser.ParseException, CompileException {
- this.cook(optionalFileName, in);
- }
-
- /**
- * Equivalent to<pre>
- * SimpleCompiler sc = new SimpleCompiler();
- * sc.cook(optionalFileName, is);</pre>
- *
- * @see #SimpleCompiler()
- * @see Cookable#cook(String, InputStream)
- */
- public SimpleCompiler(
- String optionalFileName,
- InputStream is
- ) throws IOException, Scanner.ScanException, Parser.ParseException, CompileException {
- this.cook(optionalFileName, is);
- }
-
- /**
- * Equivalent to<pre>
- * SimpleCompiler sc = new SimpleCompiler();
- * sc.cook(fileName);</pre>
- *
- * @see #SimpleCompiler()
- * @see Cookable#cookFile(String)
- */
- public SimpleCompiler(
- String fileName
- ) throws IOException, Scanner.ScanException, Parser.ParseException, CompileException {
- this.cookFile(fileName);
- }
-
- /**
- * Equivalent to<pre>
- * SimpleCompiler sc = new SimpleCompiler();
- * sc.setParentClassLoader(optionalParentClassLoader);
- * sc.cook(scanner);</pre>
- *
- * @see #SimpleCompiler()
- * @see #setParentClassLoader(ClassLoader)
- * @see Cookable#cook(Scanner)
- */
- public SimpleCompiler(
- Scanner scanner,
- ClassLoader optionalParentClassLoader
- ) throws IOException, Scanner.ScanException, Parser.ParseException, CompileException {
- this.setParentClassLoader(optionalParentClassLoader);
- this.cook(scanner);
- }
-
- public SimpleCompiler() {}
-
- /**
- * The "parent class loader" is used to load referenced classes. Useful values are:
- * <table border="1"><tr>
- * <td><code>System.getSystemClassLoader()</code></td>
- * <td>The running JVM's class path</td>
- * </tr><tr>
- * <td><code>Thread.currentThread().getContextClassLoader()</code> or <code>null</code></td>
- * <td>The class loader effective for the invoking thread</td>
- * </tr><tr>
- * <td>{@link #BOOT_CLASS_LOADER}</td>
- * <td>The running JVM's boot class path</td>
- * </tr></table>
- * The parent class loader defaults to the current thread's context class loader.
- */
- public void setParentClassLoader(ClassLoader optionalParentClassLoader) {
- this.setParentClassLoader(optionalParentClassLoader, null);
- }
-
- /**
- * A {@link ClassLoader} that finds the classes on the JVM's <i>boot class path</i> (e.g.
- * <code>java.io.*</code>), but not the classes on the JVM's <i>class path</i>.
- */
- public static final ClassLoader BOOT_CLASS_LOADER = new ClassLoader(null) {};
-
- /**
- * Allow references to the classes loaded through this parent class loader
- * (@see {@link #setParentClassLoader(ClassLoader)}), plus the extra
- * <code>auxiliaryClasses</code>.
- * <p>
- * Notice that the <code>auxiliaryClasses</code> must either be loadable through the
- * <code>optionalParentClassLoader</code> (in which case they have no effect), or
- * <b>no class with the same name</b> must be loadable through the
- * <code>optionalParentClassLoader</code>.
- */
- public void setParentClassLoader(ClassLoader optionalParentClassLoader, Class[] auxiliaryClasses) {
- assertNotCooked();
- this.parentClassLoader = (
- optionalParentClassLoader != null
- ? optionalParentClassLoader
- : Thread.currentThread().getContextClassLoader()
- );
- this.optionalAuxiliaryClasses = auxiliaryClasses;
- }
-
- public void cook(Scanner scanner)
- throws CompileException, Parser.ParseException, Scanner.ScanException, IOException {
- this.setUpClassLoaders();
-
- // Parse the compilation unit.
- Java.CompilationUnit compilationUnit = new Parser(scanner).parseCompilationUnit();
-
- // Compile the classes and load them.
- this.compileToClassLoader(
- compilationUnit,
- DebuggingInformation.DEFAULT_DEBUGGING_INFORMATION
- );
- }
-
- /**
- * Cook this compilation unit directly.
- * See {@link Cookable#cook}
- */
- public void cook(Java.CompilationUnit compilationUnit) throws CompileException {
- this.setUpClassLoaders();
-
- // Compile the classes and load them.
- this.compileToClassLoader(
- compilationUnit,
- DebuggingInformation.DEFAULT_DEBUGGING_INFORMATION
- );
- }
-
- /**
- * Initializes {@link #classLoader} and {@link #iClassLoader} from the configured
- * {@link #parentClassLoader} and {@link #optionalAuxiliaryClasses}. These are needed by
- * {@link #classToType(Location, Class)} and friends which are used when creating the AST.
- */
- protected final void setUpClassLoaders() {
- assertNotCooked();
-
- // Set up the ClassLoader for the compilation and the loading.
- this.classLoader = new AuxiliaryClassLoader(this.parentClassLoader);
- if (this.optionalAuxiliaryClasses != null) {
- for (int i = 0; i < this.optionalAuxiliaryClasses.length; ++i) {
- this.classLoader.addAuxiliaryClass(this.optionalAuxiliaryClasses[i]);
- }
- }
-
- this.iClassLoader = new ClassLoaderIClassLoader(this.classLoader);
- }
-
- /**
- * A {@link ClassLoader} that intermixes that classes loaded by its parent with a map of
- * "auxiliary classes".
- */
- private static final class AuxiliaryClassLoader extends ClassLoader {
- private final Map auxiliaryClasses = new HashMap(); // String name => Class
-
- private AuxiliaryClassLoader(ClassLoader parent) {
- super(parent);
- }
-
- protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
- Class c = (Class) this.auxiliaryClasses.get(name);
- if (c != null) return c;
-
- return super.loadClass(name, resolve);
- }
-
- private void addAuxiliaryClass(Class c) {
- if (this.auxiliaryClasses.containsKey(c.getName())) return;
-
- // Check whether the auxiliary class is conflicting with this ClassLoader.
- try {
- Class c2 = super.loadClass(c.getName(), false);
- if (c2 != c) throw new RuntimeException("Trying to add an auxiliary class \"" + c.getName() + "\" while another class with the same name is already loaded");
- } catch (ClassNotFoundException ex) {
- ;
- }
-
- this.auxiliaryClasses.put(c.getName(), c);
-
- {
- Class sc = c.getSuperclass();
- if (sc != null) this.addAuxiliaryClass(sc);
- }
-
- {
- Class[] ifs = c.getInterfaces();
- for (int i = 0; i < ifs.length; ++i) this.addAuxiliaryClass(ifs[i]);
- }
- }
-
- public boolean equals(Object o) {
- if (!(o instanceof AuxiliaryClassLoader)) return false;
- AuxiliaryClassLoader that = (AuxiliaryClassLoader) o;
-
- {
- final ClassLoader parentOfThis = this.getParent();
- final ClassLoader parentOfThat = that.getParent();
- if (parentOfThis == null ? parentOfThat != null : !parentOfThis.equals(parentOfThat)) return false;
- }
-
- return this.auxiliaryClasses.equals(that.auxiliaryClasses);
- }
-
- public int hashCode() {
- ClassLoader parent = this.getParent();
- return (parent == null ? 0 : parent.hashCode()) ^ this.auxiliaryClasses.hashCode();
- }
- }
-
- /**
- * Returns a {@link ClassLoader} object through which the previously compiled classes can
- * be accessed. This {@link ClassLoader} can be used for subsequent calls to
- * {@link #SimpleCompiler(Scanner, ClassLoader)} in order to compile compilation units that
- * use types (e.g. declare derived types) declared in the previous one.
- * <p>
- * This method must only be called after {@link #cook(Scanner)}.
- * <p>
- * This method must not be called for instances of derived classes.
- */
- public ClassLoader getClassLoader() {
- if (this.getClass() != SimpleCompiler.class) throw new IllegalStateException("Must not be called on derived instances");
- if (this.result == null) throw new IllegalStateException("Must only be called after \"cook()\"");
- return this.result;
- }
-
- /**
- * Two {@link SimpleCompiler}s are regarded equal iff
- * <ul>
- * <li>Both are objects of the same class (e.g. both are {@link ScriptEvaluator}s)
- * <li>Both generated functionally equal classes as seen by {@link ByteArrayClassLoader#equals(Object)}
- * </ul>
- */
- public boolean equals(Object o) {
- if (!(o instanceof SimpleCompiler)) return false;
- SimpleCompiler that = (SimpleCompiler) o;
- if (this.getClass() != that.getClass()) return false;
- if (this.result == null || that.result == null) throw new IllegalStateException("Equality can only be checked after cooking");
- return this.result.equals(that.result);
- }
-
- public int hashCode() {
- return this.classLoader.hashCode();
- }
-
- /**
- * Wrap a reflection {@link Class} in a {@link Java.Type} object.
- */
- protected Java.Type classToType(
- Location location,
- final Class optionalClass
- ) {
- if (optionalClass == null) return null;
-
- this.classLoader.addAuxiliaryClass(optionalClass);
-
- IClass iClass;
- try {
- iClass = this.iClassLoader.loadIClass(Descriptor.fromClassName(optionalClass.getName()));
- } catch (ClassNotFoundException ex) {
- throw new RuntimeException("Loading IClass \"" + optionalClass.getName() + "\": " + ex);
- }
- if (iClass == null) throw new RuntimeException("Cannot load class \"" + optionalClass.getName() + "\" through the given ClassLoader");
-
- return new Java.SimpleType(location, iClass);
- }
-
- /**
- * Convert an array of {@link Class}es into an array of{@link Java.Type}s.
- */
- protected Java.Type[] classesToTypes(
- Location location,
- Class[] classes
- ) {
- Java.Type[] types = new Java.Type[classes.length];
- for (int i = 0; i < classes.length; ++i) {
- types[i] = this.classToType(location, classes[i]);
- }
- return types;
- }
-
- /**
- * Compile the given compilation unit. (A "compilation unit" is typically the contents
- * of a Java<sup>TM</sup> source file.)
- *
- * @param compilationUnit The parsed compilation unit
- * @param debuggingInformation What kind of debugging information to generate in the class file
- * @return The {@link ClassLoader} into which the compiled classes were defined
- * @throws CompileException
- */
- protected final ClassLoader compileToClassLoader(
- Java.CompilationUnit compilationUnit,
- EnumeratorSet debuggingInformation
- ) throws CompileException {
- if (SimpleCompiler.DEBUG) {
- UnparseVisitor.unparse(compilationUnit, new OutputStreamWriter(System.out));
- }
-
- // Compile compilation unit to class files.
- ClassFile[] classFiles = new UnitCompiler(
- compilationUnit,
- this.iClassLoader
- ).compileUnit(debuggingInformation);
-
- // Convert the class files to bytes and store them in a Map.
- Map classes = new HashMap(); // String className => byte[] data
- for (int i = 0; i < classFiles.length; ++i) {
- ClassFile cf = classFiles[i];
- classes.put(cf.getThisClassName(), cf.toByteArray());
- }
-
- // Disassemble all generated classes (for debugging).
- if (SimpleCompiler.DEBUG) {
- for (Iterator it = classes.entrySet().iterator(); it.hasNext();) {
- Map.Entry me = (Map.Entry) it.next();
- String className = (String) me.getKey();
- byte[] bytecode = (byte[]) me.getValue();
- System.out.println("*** Disassembly of class \"" + className + "\":");
- try {
- new Disassembler().disasm(new ByteArrayInputStream(bytecode));
- System.out.flush();
- } catch (IOException ex) {
- throw new RuntimeException("SNO: IOException despite ByteArrayInputStream");
- }
- }
- }
-
- // Create a ClassLoader that loads the generated classes.
- this.result = new ByteArrayClassLoader(
- classes, // classes
- this.classLoader // parent
- );
- return this.result;
- }
-
- /**
- * Throw an {@link IllegalStateException} if this {@link Cookable} is already cooked.
- */
- protected void assertNotCooked() {
- if (this.classLoader != null) throw new IllegalStateException("Already cooked");
- }
-}
diff --git a/src/org/codehaus/janino/UnicodeUnescapeException.java b/src/org/codehaus/janino/UnicodeUnescapeException.java
deleted file mode 100644
index 366419c..0000000
--- a/src/org/codehaus/janino/UnicodeUnescapeException.java
+++ /dev/null
@@ -1,45 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino;
-
-/**
- * Represents a problem that occurred while unescaping a unicode escape
- * sequence through a {@link org.codehaus.janino.UnicodeUnescapeReader}.
- */
-public class UnicodeUnescapeException extends RuntimeException {
- public UnicodeUnescapeException(String message) {
- super(message);
- }
-}
diff --git a/src/org/codehaus/janino/UnicodeUnescapeReader.java b/src/org/codehaus/janino/UnicodeUnescapeReader.java
deleted file mode 100644
index 91e4bc8..0000000
--- a/src/org/codehaus/janino/UnicodeUnescapeReader.java
+++ /dev/null
@@ -1,136 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino;
-
-import java.io.*;
-
-/**
- * A {@link FilterReader} that unescapes the "Unicode Escapes"
- * as described in
- * <a href="http://java.sun.com/docs/books/jls/second_edition/html/lexical.doc.html#100850">the
- * Java Language Specification, 2nd edition</a>.
- * <p>
- * Notice that it is possible to formulate invalid escape sequences, e.g.
- * "\u123g" ("g" is not a valid hex character). This is handled by
- * throwing a {@link java.lang.RuntimeException}-derived
- * {@link org.codehaus.janino.UnicodeUnescapeException}.
- */
-public class UnicodeUnescapeReader extends FilterReader {
-
- /**
- * @param in
- */
- public UnicodeUnescapeReader(Reader in) {
- super(in);
- }
-
- /**
- * Override {@link FilterReader#read()}.
- *
- * @throws UnicodeUnescapeException Invalid escape sequence encountered
- */
- public int read() throws IOException {
- int c;
-
- // Read next character.
- if (this.unreadChar == -1) {
- c = this.in.read();
- } else {
- c = this.unreadChar;
- this.unreadChar = -1;
- }
-
- // Check for backslash-u escape sequence, preceeded with an even number
- // of backslashes.
- if (c != '\\' || this.oddPrecedingBackslashes) {
- this.oddPrecedingBackslashes = false;
- return c;
- }
-
- // Read one character ahead and check if it is a "u".
- c = this.in.read();
- if (c != 'u') {
- this.unreadChar = c;
- this.oddPrecedingBackslashes = true;
- return '\\';
- }
-
- // Skip redundant "u"s.
- do {
- c = this.in.read();
- if (c == -1) throw new UnicodeUnescapeException("Incomplete escape sequence");
- } while (c == 'u');
-
- // Decode escape sequence.
- char[] ca = new char[4];
- ca[0] = (char) c;
- if (this.in.read(ca, 1, 3) != 3) throw new UnicodeUnescapeException("Incomplete escape sequence");
- try {
- return 0xffff & Integer.parseInt(new String(ca), 16);
- } catch (NumberFormatException ex) {
- throw new UnicodeUnescapeException("Invalid escape sequence \"\\u" + new String(ca) + "\"");
- }
- }
-
- /**
- * Override {@link FilterReader#read(char[], int, int)}.
- */
- public int read(char[] cbuf, int off, int len) throws IOException {
- if (len == 0) return 0;
- int res = 0;
- do {
- int c = this.read();
- if (c == -1) break;
- cbuf[off++] = (char) c;
- } while (++res < len);
- return res == 0 ? -1 : res;
- }
-
- /**
- * Simple unit testing.
- */
- public static void main(String[] args) throws IOException {
- Reader r = new UnicodeUnescapeReader(new StringReader(args[0]));
- for (;;) {
- int c = r.read();
- if (c == -1) break;
- System.out.print((char) c);
- }
- System.out.println();
- }
-
- private int unreadChar = -1; // -1 == none
- private boolean oddPrecedingBackslashes = false;
-}
diff --git a/src/org/codehaus/janino/UnitCompiler.java b/src/org/codehaus/janino/UnitCompiler.java
deleted file mode 100644
index 8de3dbc..0000000
--- a/src/org/codehaus/janino/UnitCompiler.java
+++ /dev/null
@@ -1,8378 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino;
-
-import java.io.DataOutputStream;
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.StringTokenizer;
-import java.util.TreeMap;
-
-import org.codehaus.janino.IClass.IField;
-import org.codehaus.janino.IClass.IInvocable;
-import org.codehaus.janino.IClass.IMethod;
-import org.codehaus.janino.Java.AlternateConstructorInvocation;
-import org.codehaus.janino.Java.Block;
-import org.codehaus.janino.Java.BlockStatement;
-import org.codehaus.janino.Java.BreakStatement;
-import org.codehaus.janino.Java.CatchClause;
-import org.codehaus.janino.Java.ConstructorDeclarator;
-import org.codehaus.janino.Java.ConstructorInvocation;
-import org.codehaus.janino.Java.ContinueStatement;
-import org.codehaus.janino.Java.DoStatement;
-import org.codehaus.janino.Java.EmptyStatement;
-import org.codehaus.janino.Java.ExpressionStatement;
-import org.codehaus.janino.Java.FieldAccess;
-import org.codehaus.janino.Java.FieldDeclaration;
-import org.codehaus.janino.Java.ForStatement;
-import org.codehaus.janino.Java.FunctionDeclarator;
-import org.codehaus.janino.Java.IfStatement;
-import org.codehaus.janino.Java.Initializer;
-import org.codehaus.janino.Java.Invocation;
-import org.codehaus.janino.Java.LabeledStatement;
-import org.codehaus.janino.Java.LocalClassDeclarationStatement;
-import org.codehaus.janino.Java.LocalVariable;
-import org.codehaus.janino.Java.LocalVariableDeclarationStatement;
-import org.codehaus.janino.Java.Locatable;
-import org.codehaus.janino.Java.ReturnStatement;
-import org.codehaus.janino.Java.Rvalue;
-import org.codehaus.janino.Java.SimpleType;
-import org.codehaus.janino.Java.Statement;
-import org.codehaus.janino.Java.SuperConstructorInvocation;
-import org.codehaus.janino.Java.SuperclassFieldAccessExpression;
-import org.codehaus.janino.Java.SwitchStatement;
-import org.codehaus.janino.Java.SynchronizedStatement;
-import org.codehaus.janino.Java.ThrowStatement;
-import org.codehaus.janino.Java.TryStatement;
-import org.codehaus.janino.Java.WhileStatement;
-import org.codehaus.janino.Java.CompilationUnit.ImportDeclaration;
-import org.codehaus.janino.Java.CompilationUnit.SingleStaticImportDeclaration;
-import org.codehaus.janino.Java.CompilationUnit.SingleTypeImportDeclaration;
-import org.codehaus.janino.Java.CompilationUnit.StaticImportOnDemandDeclaration;
-import org.codehaus.janino.Java.CompilationUnit.TypeImportOnDemandDeclaration;
-import org.codehaus.janino.Visitor.BlockStatementVisitor;
-import org.codehaus.janino.Visitor.ImportVisitor;
-import org.codehaus.janino.util.ClassFile;
-import org.codehaus.janino.util.enumerator.EnumeratorSet;
-
-/**
- * This class actually implements the Java<sup>TM</sup> compiler. It is
- * associated with exactly one compilation unit which it compiles.
- */
-public class UnitCompiler {
- private static final boolean DEBUG = false;
-
- /**
- * This constant determines the number of operands up to which the
- *
- * a.concat(b).concat(c)
- *
- * strategy is used to implement string concatenation. For more operands, the
- *
- * new StringBuffer(a).append(b).append(c).append(d).toString()
- *
- * strategy is chosen.
- *
- * A very good article from Tom Gibara
- *
- * http://www.tomgibara.com/janino-evaluation/string-concatenation-benchmark
- *
- * analyzes the impact of this decision and recommends a value of three.
- */
- private static final int STRING_CONCAT_LIMIT = 3;
-
- public UnitCompiler(
- Java.CompilationUnit compilationUnit,
- IClassLoader iClassLoader
- ) throws CompileException {
- this.compilationUnit = compilationUnit;
- this.iClassLoader = iClassLoader;
-
- try {
- if (iClassLoader.loadIClass(Descriptor.STRING_BUILDER) != null) {
- this.isStringBuilderAvailable = true;
- } else
- if (iClassLoader.loadIClass(Descriptor.STRING_BUFFER) != null) {
- this.isStringBuilderAvailable = false;
- } else
- {
- throw new RuntimeException("SNO: Could neither load \"StringBuffer\" nor \"StringBuilder\"");
- }
- } catch (ClassNotFoundException ex) {
- throw new RuntimeException("SNO: Error loading \"StringBuffer\" or \"StringBuilder\": " + ex.getMessage());
- }
-
- // Compile non-static import declarations. (Must be done here in the constructor and not
- // down in "compileUnit()" because otherwise "resolve()" cannot resolve type names.)
- this.typeImportsOnDemand = new ArrayList();
- this.typeImportsOnDemand.add(new String[] { "java", "lang" });
- for (Iterator it = this.compilationUnit.importDeclarations.iterator(); it.hasNext();) {
- ImportDeclaration id = (ImportDeclaration) it.next();
- class UCE extends RuntimeException { final CompileException ce; UCE(CompileException ce) { this.ce = ce; } }
- try {
- id.accept(new ImportVisitor() {
- public void visitSingleTypeImportDeclaration(SingleTypeImportDeclaration stid) { try { UnitCompiler.this.import2(stid); } catch (CompileException e) { throw new UCE(e); } }
- public void visitTypeImportOnDemandDeclaration(TypeImportOnDemandDeclaration tiodd) { UnitCompiler.this.import2(tiodd); }
- public void visitSingleStaticImportDeclaration(SingleStaticImportDeclaration ssid) {}
- public void visitStaticImportOnDemandDeclaration(StaticImportOnDemandDeclaration siodd) {}
- });
- } catch (UCE uce) { throw uce.ce; }
- }
- }
-
- private void import2(SingleTypeImportDeclaration stid) throws CompileException {
- String[] ids = stid.identifiers;
- String name = last(ids);
-
- String[] prev = (String[]) UnitCompiler.this.singleTypeImports.put(name, ids);
-
- // Check for re-import of same name.
- if (prev != null && !Arrays.equals(prev, ids)) {
- this.compileError("Class \"" + name + "\" was previously imported as \"" + Java.join(prev, ".") + "\", now as \"" + Java.join(ids, ".") + "\"");
- }
- }
- private void import2(TypeImportOnDemandDeclaration tiodd) {
-
- // Duplicate type-imports-on-demand are not an error, so no checks here.
- UnitCompiler.this.typeImportsOnDemand.add(tiodd.identifiers);
- }
- private void import2(SingleStaticImportDeclaration ssid) throws CompileException {
- String name = last(ssid.identifiers);
- Object importedObject;
-
- FIND_IMPORTED_OBJECT:
- {
-
- // Type?
- {
- IClass iClass = this.loadFullyQualifiedClass(ssid.identifiers);
- if (iClass != null) {
- importedObject = iClass;
- break FIND_IMPORTED_OBJECT;
- }
- }
-
- String[] typeName = allButLast(ssid.identifiers);
- IClass iClass = this.loadFullyQualifiedClass(typeName);
- if (iClass == null) {
- this.compileError("Could not load \"" + Java.join(typeName, ".") + "\"", ssid.getLocation());
- return;
- }
-
- // Static field?
- IField[] flds = iClass.getDeclaredIFields();
- for (int i = 0; i < flds.length; ++i) {
- IField iField = flds[i];
- if (iField.getName().equals(name)) {
- if (!iField.isStatic()) {
- this.compileError("Filed \"" + name + "\" of \"" + Java.join(typeName, ".") + "\" must be static", ssid.getLocation());
- }
- importedObject = iField;
- break FIND_IMPORTED_OBJECT;
- }
- }
-
- // Static method?
- IMethod[] ms = iClass.getDeclaredIMethods(name);
- if (ms.length > 0) {
- importedObject = Arrays.asList(ms);
- break FIND_IMPORTED_OBJECT;
- }
-
- // Give up.
- this.compileError("\"" + Java.join(typeName, ".") + "\" has no static member \"" + name + "\"", ssid.getLocation());
- return;
- }
-
- Object prev = this.singleStaticImports.put(name, importedObject);
-
- // Check for re-import of same name.
- if (prev != null && !prev.equals(importedObject)) {
- UnitCompiler.this.compileError("\"" + name + "\" was previously statically imported as \"" + prev.toString() + "\", now as \"" + importedObject.toString() + "\"", ssid.getLocation());
- }
- }
- private void import2(StaticImportOnDemandDeclaration siodd) throws CompileException {
- IClass iClass = this.loadFullyQualifiedClass(siodd.identifiers);
- if (iClass == null) {
- this.compileError("Could not load \"" + Java.join(siodd.identifiers, ".") + "\"", siodd.getLocation());
- return;
- }
- UnitCompiler.this.staticImportsOnDemand.add(iClass);
- }
-
- /**
- * Generates an array of {@link ClassFile} objects which represent the classes and
- * interfaces defined in the compilation unit.
- */
- public ClassFile[] compileUnit(
- EnumeratorSet debuggingInformation
- ) throws CompileException {
-
- // Compile static import declarations.
- for (Iterator it = this.compilationUnit.importDeclarations.iterator(); it.hasNext();) {
- ImportDeclaration id = (ImportDeclaration) it.next();
- class UCE extends RuntimeException { final CompileException ce; UCE(CompileException ce) { this.ce = ce; } }
- try {
- id.accept(new ImportVisitor() {
- public void visitSingleTypeImportDeclaration(SingleTypeImportDeclaration stid) {}
- public void visitTypeImportOnDemandDeclaration(TypeImportOnDemandDeclaration tiodd) {}
- public void visitSingleStaticImportDeclaration(SingleStaticImportDeclaration ssid) { try { UnitCompiler.this.import2(ssid); } catch (CompileException e) { throw new UCE(e); } }
- public void visitStaticImportOnDemandDeclaration(StaticImportOnDemandDeclaration siodd) { try { UnitCompiler.this.import2(siodd); } catch (CompileException e) { throw new UCE(e); } }
- });
- } catch (UCE uce) { throw uce.ce; }
- }
-
- this.generatedClassFiles = new ArrayList();
- this.debuggingInformation = debuggingInformation;
-
- for (Iterator it = this.compilationUnit.packageMemberTypeDeclarations.iterator(); it.hasNext();) {
- UnitCompiler.this.compile((Java.PackageMemberTypeDeclaration) it.next());
- }
-
- if (this.compileErrorCount > 0) throw new CompileException(this.compileErrorCount + " error(s) while compiling unit \"" + this.compilationUnit.optionalFileName + "\"", null);
-
- List l = this.generatedClassFiles;
- return (ClassFile[]) l.toArray(new ClassFile[l.size()]);
- }
-
- // ------------ TypeDeclaration.compile() -------------
-
- private void compile(Java.TypeDeclaration td) throws CompileException {
- class UCE extends RuntimeException { final CompileException ce; UCE(CompileException ce) { this.ce = ce; } }
- Visitor.TypeDeclarationVisitor tdv = new Visitor.TypeDeclarationVisitor() {
- public void visitAnonymousClassDeclaration (Java.AnonymousClassDeclaration acd) { try { UnitCompiler.this.compile2(acd ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitLocalClassDeclaration (Java.LocalClassDeclaration lcd) { try { UnitCompiler.this.compile2(lcd ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitPackageMemberClassDeclaration (Java.PackageMemberClassDeclaration pmcd) { try { UnitCompiler.this.compile2((Java.PackageMemberTypeDeclaration) pmcd); } catch (CompileException e) { throw new UCE(e); } }
- public void visitMemberInterfaceDeclaration (Java.MemberInterfaceDeclaration mid) { try { UnitCompiler.this.compile2(mid ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitPackageMemberInterfaceDeclaration(Java.PackageMemberInterfaceDeclaration pmid) { try { UnitCompiler.this.compile2((Java.PackageMemberTypeDeclaration) pmid); } catch (CompileException e) { throw new UCE(e); } }
- public void visitMemberClassDeclaration (Java.MemberClassDeclaration mcd) { try { UnitCompiler.this.compile2(mcd ); } catch (CompileException e) { throw new UCE(e); } }
- };
- try {
- td.accept(tdv);
- } catch (UCE uce) {
- throw uce.ce;
- }
- }
- public void compile2(Java.PackageMemberTypeDeclaration pmtd) throws CompileException {
- Java.CompilationUnit declaringCompilationUnit = pmtd.getDeclaringCompilationUnit();
-
- // Check for conflict with single-type-import (7.6).
- {
- String[] ss = this.getSingleTypeImport(pmtd.getName());
- if (ss != null) this.compileError("Package member type declaration \"" + pmtd.getName() + "\" conflicts with single-type-import \"" + Java.join(ss, ".") + "\"", pmtd.getLocation());
- }
-
- // Check for redefinition within compilation unit (7.6).
- {
- Java.PackageMemberTypeDeclaration otherPMTD = declaringCompilationUnit.getPackageMemberTypeDeclaration(pmtd.getName());
- if (otherPMTD != pmtd) this.compileError("Redeclaration of type \"" + pmtd.getName() + "\", previously declared in " + otherPMTD.getLocation(), pmtd.getLocation());
- }
-
- if (pmtd instanceof Java.NamedClassDeclaration) {
- this.compile2((Java.NamedClassDeclaration) pmtd);
- } else
- if (pmtd instanceof Java.InterfaceDeclaration) {
- this.compile2((Java.InterfaceDeclaration) pmtd);
- } else
- {
- throw new RuntimeException("PMTD of unexpected type " + pmtd.getClass().getName());
- }
- }
-
- public void compile2(Java.ClassDeclaration cd) throws CompileException {
- IClass iClass = this.resolve(cd);
-
- // Check that all methods are implemented.
- if ((cd.modifiers & Mod.ABSTRACT) == 0) {
- IMethod[] ms = iClass.getIMethods();
- for (int i = 0; i < ms.length; ++i) {
- if (ms[i].isAbstract()) this.compileError("Non-abstract class \"" + iClass + "\" must implement method \"" + ms[i] + "\"", cd.getLocation());
- }
- }
-
- // Create "ClassFile" object.
- ClassFile cf = new ClassFile(
- (short) (cd.modifiers | Mod.SUPER), // accessFlags
- iClass.getDescriptor(), // thisClassFD
- iClass.getSuperclass().getDescriptor(), // superClassFD
- IClass.getDescriptors(iClass.getInterfaces()) // interfaceFDs
- );
-
- // Add InnerClasses attribute entry for this class declaration.
- if (cd.getEnclosingScope() instanceof Java.CompilationUnit) {
- ;
- } else
- if (cd.getEnclosingScope() instanceof Java.Block) {
- short innerClassInfoIndex = cf.addConstantClassInfo(iClass.getDescriptor());
- short innerNameIndex = (
- this instanceof Java.NamedTypeDeclaration ?
- cf.addConstantUtf8Info(((Java.NamedTypeDeclaration) this).getName()) :
- (short) 0
- );
- cf.addInnerClassesAttributeEntry(new ClassFile.InnerClassesAttribute.Entry(
- innerClassInfoIndex, // innerClassInfoIndex
- (short) 0, // outerClassInfoIndex
- innerNameIndex, // innerNameIndex
- cd.modifiers // innerClassAccessFlags
- ));
- } else
- if (cd.getEnclosingScope() instanceof Java.AbstractTypeDeclaration) {
- short innerClassInfoIndex = cf.addConstantClassInfo(iClass.getDescriptor());
- short outerClassInfoIndex = cf.addConstantClassInfo(this.resolve(((Java.AbstractTypeDeclaration) cd.getEnclosingScope())).getDescriptor());
- short innerNameIndex = cf.addConstantUtf8Info(((Java.MemberTypeDeclaration) cd).getName());
- cf.addInnerClassesAttributeEntry(new ClassFile.InnerClassesAttribute.Entry(
- innerClassInfoIndex, // innerClassInfoIndex
- outerClassInfoIndex, // outerClassInfoIndex
- innerNameIndex, // innerNameIndex
- cd.modifiers // innerClassAccessFlags
- ));
- }
-
- // Set "SourceFile" attribute.
- if (this.debuggingInformation.contains(DebuggingInformation.SOURCE)) {
- String sourceFileName;
- {
- String s = cd.getLocation().getFileName();
- if (s != null) {
- sourceFileName = new File(s).getName();
- } else if (cd instanceof Java.NamedTypeDeclaration) {
- sourceFileName = ((Java.NamedTypeDeclaration) cd).getName() + ".java";
- } else {
- sourceFileName = "ANONYMOUS.java";
- }
- }
- cf.addSourceFileAttribute(sourceFileName);
- }
-
- // Add "Deprecated" attribute (JVMS 4.7.10)
- if (cd instanceof Java.DocCommentable) {
- if (((Java.DocCommentable) cd).hasDeprecatedDocTag()) cf.addDeprecatedAttribute();
- }
-
- // Optional: Generate and compile class initialization method.
- {
- Java.Block b = new Java.Block(cd.getLocation());
- for (Iterator it = cd.variableDeclaratorsAndInitializers.iterator(); it.hasNext();) {
- Java.TypeBodyDeclaration tbd = (Java.TypeBodyDeclaration) it.next();
- if (tbd.isStatic()) b.addButDontEncloseStatement((Java.BlockStatement) tbd);
- }
-
- this.maybeCreateInitMethod(cd, cf, b);
- }
-
- this.compileDeclaredMethods(cd, cf);
-
-
- // Compile declared constructors.
- // As a side effect of compiling methods and constructors, synthetic "class-dollar"
- // methods (which implement class literals) are generated on-the fly.
- // We need to note how many we have here so we can compile the extras.
- int declaredMethodCount = cd.declaredMethods.size();
- {
- int syntheticFieldCount = cd.syntheticFields.size();
- Java.ConstructorDeclarator[] cds = cd.getConstructors();
- for (int i = 0; i < cds.length; ++i) {
- this.compile(cds[i], cf);
- if (syntheticFieldCount != cd.syntheticFields.size()) throw new RuntimeException("SNO: Compilation of constructor \"" + cds[i] + "\" (" + cds[i].getLocation() +") added synthetic fields!?");
- }
- }
-
- // A side effect of this call may create synthetic functions to access
- // protected parent variables
- this.compileDeclaredMemberTypes(cd, cf);
-
- // Compile the aforementioned extras.
- this.compileDeclaredMethods(cd, cf, declaredMethodCount);
-
- // Class and instance variables.
- for (Iterator it = cd.variableDeclaratorsAndInitializers.iterator(); it.hasNext();) {
- Java.TypeBodyDeclaration tbd = (Java.TypeBodyDeclaration) it.next();
- if (!(tbd instanceof Java.FieldDeclaration)) continue;
- this.addFields((Java.FieldDeclaration) tbd, cf);
- }
-
- // Synthetic fields.
- for (Iterator it = cd.syntheticFields.values().iterator(); it.hasNext();) {
- IClass.IField f = (IClass.IField) it.next();
- cf.addFieldInfo(
- Mod.PACKAGE, // modifiers,
- f.getName(), // fieldName,
- f.getType().getDescriptor(), // fieldTypeFD,
- null // optionalConstantValue
- );
- }
-
-
- // Add the generated class file to a thread-local store.
- this.generatedClassFiles.add(cf);
- }
-
- /**
- * Create {@link ClassFile.FieldInfo}s for all fields declared by the
- * given {@link Java.FieldDeclaration}.
- */
- private void addFields(Java.FieldDeclaration fd, ClassFile cf) throws CompileException {
- for (int j = 0; j < fd.variableDeclarators.length; ++j) {
- Java.VariableDeclarator vd = fd.variableDeclarators[j];
- Java.Type type = fd.type;
- for (int k = 0; k < vd.brackets; ++k) type = new Java.ArrayType(type);
-
- Object ocv = null;
- if (
- (fd.modifiers & Mod.FINAL) != 0 &&
- vd.optionalInitializer != null
- ) {
- if (vd.optionalInitializer instanceof Java.Rvalue) ocv = this.getConstantValue((Java.Rvalue) vd.optionalInitializer);
- if (ocv == Java.Rvalue.CONSTANT_VALUE_NULL) ocv = null;
- }
-
- ClassFile.FieldInfo fi;
- if (Mod.isPrivateAccess(fd.modifiers)) {
-
- // To make the private field accessible for enclosing types, enclosed types and types
- // enclosed by the same type, it is modified as follows:
- // + Access is changed from PRIVATE to PACKAGE
- fi = cf.addFieldInfo(
- Mod.changeAccess(fd.modifiers, Mod.PACKAGE), // modifiers
- vd.name, // fieldName
- this.getType(type).getDescriptor(), // fieldTypeFD
- ocv // optionalConstantValue
- );
- } else
- {
- fi = cf.addFieldInfo(
- fd.modifiers, // modifiers
- vd.name, // fieldName
- this.getType(type).getDescriptor(), // fieldTypeFD
- ocv // optionalConstantValue
- );
- }
-
- // Add "Deprecated" attribute (JVMS 4.7.10)
- if (fd.hasDeprecatedDocTag()) {
- fi.addAttribute(new ClassFile.DeprecatedAttribute(cf.addConstantUtf8Info("Deprecated")));
- }
- }
- }
-
- public void compile2(Java.AnonymousClassDeclaration acd) throws CompileException {
- this.compile2((Java.InnerClassDeclaration) acd);
- }
-
- public void compile2(Java.LocalClassDeclaration lcd) throws CompileException {
- this.compile2((Java.InnerClassDeclaration) lcd);
- }
-
- public void compile2(Java.InnerClassDeclaration icd) throws CompileException {
-
- // Define a synthetic "this$..." field if there is an enclosing instance.
- {
- List ocs = UnitCompiler.getOuterClasses(icd);
- final int nesting = ocs.size();
- if (nesting >= 2) {
- icd.defineSyntheticField(new SimpleIField(
- this.resolve(icd),
- "this$" + (nesting - 2),
- this.resolve((Java.AbstractTypeDeclaration) ocs.get(1))
- ));
- }
- }
-
- this.compile2((Java.ClassDeclaration) icd);
- }
-
- public void compile2(final Java.MemberClassDeclaration mcd) throws CompileException {
- this.compile2((Java.InnerClassDeclaration) mcd);
- }
-
- public void compile2(Java.InterfaceDeclaration id) throws CompileException {
- IClass iClass = this.resolve(id);
-
- // Determine extended interfaces.
- id.interfaces = new IClass[id.extendedTypes.length];
- String[] interfaceDescriptors = new String[id.interfaces.length];
- for (int i = 0; i < id.extendedTypes.length; ++i) {
- id.interfaces[i] = this.getType(id.extendedTypes[i]);
- interfaceDescriptors[i] = id.interfaces[i].getDescriptor();
- }
-
- // Create "ClassFile" object.
- ClassFile cf = new ClassFile(
- (short) ( // accessFlags
- id.modifiers |
- Mod.SUPER |
- Mod.INTERFACE |
- Mod.ABSTRACT
- ),
- iClass.getDescriptor(), // thisClassFD
- Descriptor.OBJECT, // superClassFD
- interfaceDescriptors // interfaceFDs
- );
-
- // Set "SourceFile" attribute.
- if (this.debuggingInformation.contains(DebuggingInformation.SOURCE)) {
- String sourceFileName;
- {
- String s = id.getLocation().getFileName();
- if (s != null) {
- sourceFileName = new File(s).getName();
- } else {
- sourceFileName = id.getName() + ".java";
- }
- }
- cf.addSourceFileAttribute(sourceFileName);
- }
-
- // Add "Deprecated" attribute (JVMS 4.7.10)
- if (id.hasDeprecatedDocTag()) cf.addDeprecatedAttribute();
-
- // Interface initialization method.
- if (!id.constantDeclarations.isEmpty()) {
- Java.Block b = new Java.Block(id.getLocation());
- b.addButDontEncloseStatements(id.constantDeclarations);
-
- maybeCreateInitMethod(id, cf, b);
- }
-
- compileDeclaredMethods(id, cf);
-
- // Class variables.
- for (int i = 0; i < id.constantDeclarations.size(); ++i) {
- Java.BlockStatement bs = (Java.BlockStatement) id.constantDeclarations.get(i);
- if (!(bs instanceof Java.FieldDeclaration)) continue;
- this.addFields((Java.FieldDeclaration) bs, cf);
- }
-
- compileDeclaredMemberTypes(id, cf);
-
- // Add the generated class file to a thread-local store.
- this.generatedClassFiles.add(cf);
- }
-
- /**
- * Create class initialization method iff there is any initialization code.
- * @param decl The type declaration
- * @param cf The class file into which to put the method
- * @param b The block for the method (possibly empty)
- * @throws CompileException
- */
- private void maybeCreateInitMethod(Java.AbstractTypeDeclaration decl,
- ClassFile cf, Java.Block b) throws CompileException {
- // Create interface initialization method iff there is any initialization code.
- if (this.generatesCode(b)) {
- Java.MethodDeclarator md = new Java.MethodDeclarator(
- decl.getLocation(), // location
- null, // optionalDocComment
- (short) (Mod.STATIC | Mod.PUBLIC), // modifiers
- new Java.BasicType( // type
- decl.getLocation(),
- Java.BasicType.VOID
- ),
- "<clinit>", // name
- new Java.FunctionDeclarator.FormalParameter[0], // formalParameters
- new Java.ReferenceType[0], // thrownExcaptions
- b // optionalBody
- );
- md.setDeclaringType(decl);
- this.compile(md, cf);
- }
- }
-
- /**
- * Compile all of the types for this declaration
- * <p>
- * NB: as a side effect this will fill in the sythetic field map
- * @throws CompileException
- */
- private void compileDeclaredMemberTypes(
- Java.AbstractTypeDeclaration decl,
- ClassFile cf
- ) throws CompileException {
- for (Iterator it = decl.getMemberTypeDeclarations().iterator(); it.hasNext();) {
- Java.AbstractTypeDeclaration atd = ((Java.AbstractTypeDeclaration) it.next());
- this.compile(atd);
-
- // Add InnerClasses attribute entry for member type declaration.
- short innerClassInfoIndex = cf.addConstantClassInfo(this.resolve(atd).getDescriptor());
- short outerClassInfoIndex = cf.addConstantClassInfo(this.resolve(decl).getDescriptor());
- short innerNameIndex = cf.addConstantUtf8Info(((Java.MemberTypeDeclaration) atd).getName());
- cf.addInnerClassesAttributeEntry(new ClassFile.InnerClassesAttribute.Entry(
- innerClassInfoIndex, // innerClassInfoIndex
- outerClassInfoIndex, // outerClassInfoIndex
- innerNameIndex, // innerNameIndex
- decl.modifiers // innerClassAccessFlags
- ));
- }
- }
-
- /**
- * Compile all of the methods for this declaration
- * <p>
- * NB: as a side effect this will fill in the sythetic field map
- * @throws CompileException
- */
- private void compileDeclaredMethods(
- Java.AbstractTypeDeclaration typeDeclaration,
- ClassFile cf
- ) throws CompileException {
- compileDeclaredMethods(typeDeclaration, cf, 0);
- }
-
- /**
- * Compile methods for this declaration starting at startPos
- * @param startPos starting param to fill in
- * @throws CompileException
- */
- private void compileDeclaredMethods(
- Java.AbstractTypeDeclaration typeDeclaration,
- ClassFile cf,
- int startPos
- ) throws CompileException {
-
- // Notice that as a side effect of compiling methods, synthetic "class-dollar"
- // methods (which implement class literals) are generated on-the fly. Hence, we
- // must not use an Iterator here.
- for (int i = startPos; i < typeDeclaration.declaredMethods.size(); ++i) {
- this.compile(((Java.MethodDeclarator) typeDeclaration.declaredMethods.get(i)), cf);
- }
- }
-
- /**
- * @return <tt>false</tt> if this statement cannot complete normally (JLS2
- * 14.20)
- */
- private boolean compile(Java.BlockStatement bs) throws CompileException {
- final boolean[] res = new boolean[1];
- class UCE extends RuntimeException { final CompileException ce; UCE(CompileException ce) { this.ce = ce; } }
- Visitor.BlockStatementVisitor bsv = new Visitor.BlockStatementVisitor() {
- public void visitInitializer (Java.Initializer i ) { try { res[0] = UnitCompiler.this.compile2(i ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitFieldDeclaration (Java.FieldDeclaration fd ) { try { res[0] = UnitCompiler.this.compile2(fd ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitLabeledStatement (Java.LabeledStatement ls ) { try { res[0] = UnitCompiler.this.compile2(ls ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitBlock (Java.Block b ) { try { res[0] = UnitCompiler.this.compile2(b ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitExpressionStatement (Java.ExpressionStatement es ) { try { res[0] = UnitCompiler.this.compile2(es ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitIfStatement (Java.IfStatement is ) { try { res[0] = UnitCompiler.this.compile2(is ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitForStatement (Java.ForStatement fs ) { try { res[0] = UnitCompiler.this.compile2(fs ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitWhileStatement (Java.WhileStatement ws ) { try { res[0] = UnitCompiler.this.compile2(ws ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitTryStatement (Java.TryStatement ts ) { try { res[0] = UnitCompiler.this.compile2(ts ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitSwitchStatement (Java.SwitchStatement ss ) { try { res[0] = UnitCompiler.this.compile2(ss ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitSynchronizedStatement (Java.SynchronizedStatement ss ) { try { res[0] = UnitCompiler.this.compile2(ss ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitDoStatement (Java.DoStatement ds ) { try { res[0] = UnitCompiler.this.compile2(ds ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitLocalVariableDeclarationStatement(Java.LocalVariableDeclarationStatement lvds) { try { res[0] = UnitCompiler.this.compile2(lvds); } catch (CompileException e) { throw new UCE(e); } }
- public void visitReturnStatement (Java.ReturnStatement rs ) { try { res[0] = UnitCompiler.this.compile2(rs ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitThrowStatement (Java.ThrowStatement ts ) { try { res[0] = UnitCompiler.this.compile2(ts ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitBreakStatement (Java.BreakStatement bs ) { try { res[0] = UnitCompiler.this.compile2(bs ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitContinueStatement (Java.ContinueStatement cs ) { try { res[0] = UnitCompiler.this.compile2(cs ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitEmptyStatement (Java.EmptyStatement es ) { res[0] = UnitCompiler.this.compile2(es ); }
- public void visitLocalClassDeclarationStatement (Java.LocalClassDeclarationStatement lcds) { try { res[0] = UnitCompiler.this.compile2(lcds); } catch (CompileException e) { throw new UCE(e); } }
- public void visitAlternateConstructorInvocation (Java.AlternateConstructorInvocation aci ) { try { res[0] = UnitCompiler.this.compile2(aci ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitSuperConstructorInvocation (Java.SuperConstructorInvocation sci ) { try { res[0] = UnitCompiler.this.compile2(sci ); } catch (CompileException e) { throw new UCE(e); } }
- };
- try {
- bs.accept(bsv);
- return res[0];
- } catch (UCE uce) {
- throw uce.ce;
- }
- }
- private boolean compile2(Java.Initializer i) throws CompileException {
- return this.compile(i.block);
- }
- private boolean compile2(Java.Block b) throws CompileException {
- this.codeContext.saveLocalVariables();
- try {
- boolean previousStatementCanCompleteNormally = true;
- for (int i = 0; i < b.statements.size(); ++i) {
- Java.BlockStatement bs = (Java.BlockStatement) b.statements.get(i);
- if (!previousStatementCanCompleteNormally && this.generatesCode(bs)) {
- this.compileError("Statement is unreachable", bs.getLocation());
- break;
- }
- previousStatementCanCompleteNormally = this.compile(bs);
- }
- return previousStatementCanCompleteNormally;
- } finally {
- this.codeContext.restoreLocalVariables();
- }
- }
- private boolean compile2(Java.DoStatement ds) throws CompileException {
- Object cvc = this.getConstantValue(ds.condition);
- if (cvc != null) {
- if (Boolean.TRUE.equals(cvc)) {
- this.warning("DSTC", "Condition of DO statement is always TRUE; the proper way of declaring an unconditional loop is \"for (;;)\"", ds.getLocation());
- return this.compileUnconditionalLoop(ds, ds.body, null);
- } else
- {
- this.warning("DSNR", "DO statement never repeats", ds.getLocation());
- }
- }
-
- ds.whereToContinue = this.codeContext.new Offset();
- ds.bodyHasContinue = false;
-
- CodeContext.Offset bodyOffset = this.codeContext.newOffset();
-
- // Compile body.
- if (!this.compile(ds.body) && !ds.bodyHasContinue) {
- this.warning("DSNTC", "\"do\" statement never tests its condition", ds.getLocation());
- if (ds.whereToBreak == null) return false;
- ds.whereToBreak.set();
- return true;
- }
-
- // Compile condition.
- ds.whereToContinue.set();
- this.compileBoolean(ds.condition, bodyOffset, Java.Rvalue.JUMP_IF_TRUE);
-
- if (ds.whereToBreak != null) ds.whereToBreak.set();
-
- return true;
- }
- private boolean compile2(Java.ForStatement fs) throws CompileException {
- this.codeContext.saveLocalVariables();
- try {
-
- // Compile init.
- if (fs.optionalInit != null) this.compile(fs.optionalInit);
-
- if (fs.optionalCondition == null) {
- return this.compileUnconditionalLoop(fs, fs.body, fs.optionalUpdate);
- } else
- {
- Object cvc = this.getConstantValue(fs.optionalCondition);
- if (cvc != null) {
- if (Boolean.TRUE.equals(cvc)) {
- this.warning("FSTC", "Condition of FOR statement is always TRUE; the proper way of declaring an unconditional loop is \"for (;;)\"", fs.getLocation());
- return this.compileUnconditionalLoop(fs, fs.body, fs.optionalUpdate);
- } else
- {
- this.warning("FSNR", "FOR statement never repeats", fs.getLocation());
- }
- }
- }
-
- CodeContext.Offset toCondition = this.codeContext.new Offset();
- this.writeBranch(fs, Opcode.GOTO, toCondition);
-
- // Compile body.
- fs.whereToContinue = this.codeContext.new Offset();
- fs.bodyHasContinue = false;
- CodeContext.Offset bodyOffset = this.codeContext.newOffset();
- boolean bodyCCN = this.compile(fs.body);
-
- // Compile update.
- fs.whereToContinue.set();
- if (fs.optionalUpdate != null) {
- if (!bodyCCN && !fs.bodyHasContinue) {
- this.warning("FUUR", "For update is unreachable", fs.getLocation());
- } else
- {
- for (int i = 0; i < fs.optionalUpdate.length; ++i) {
- this.compile(fs.optionalUpdate[i]);
- }
- }
- }
-
- // Compile condition.
- toCondition.set();
- this.compileBoolean(fs.optionalCondition, bodyOffset, Java.Rvalue.JUMP_IF_TRUE);
- } finally {
- this.codeContext.restoreLocalVariables();
- }
-
- if (fs.whereToBreak != null) fs.whereToBreak.set();
-
- return true;
- }
- private boolean compile2(Java.WhileStatement ws) throws CompileException {
- Object cvc = this.getConstantValue(ws.condition);
- if (cvc != null) {
- if (Boolean.TRUE.equals(cvc)) {
- this.warning("WSTC", "Condition of WHILE statement is always TRUE; the proper way of declaring an unconditional loop is \"for (;;)\"", ws.getLocation());
- return this.compileUnconditionalLoop(ws, ws.body, null);
- } else
- {
- this.warning("WSNR", "WHILE statement never repeats", ws.getLocation());
- }
- }
-
- ws.whereToContinue = this.codeContext.new Offset();
- ws.bodyHasContinue = false;
- this.writeBranch(ws, Opcode.GOTO, ws.whereToContinue);
-
- // Compile body.
- CodeContext.Offset bodyOffset = this.codeContext.newOffset();
- this.compile(ws.body); // Return value (CCN) is ignored.
-
- // Compile condition.
- ws.whereToContinue.set();
- this.compileBoolean(ws.condition, bodyOffset, Java.Rvalue.JUMP_IF_TRUE);
-
- if (ws.whereToBreak != null) ws.whereToBreak.set();
- return true;
- }
- private boolean compileUnconditionalLoop(
- Java.ContinuableStatement cs,
- Java.BlockStatement body,
- Java.Rvalue[] optionalUpdate
- ) throws CompileException {
- if (optionalUpdate != null) return this.compileUnconditionalLoopWithUpdate(cs, body, optionalUpdate);
-
- cs.whereToContinue = this.codeContext.newOffset();
- cs.bodyHasContinue = false;
-
- // Compile body.
- if (this.compile(body)) this.writeBranch(cs, Opcode.GOTO, cs.whereToContinue);
-
- if (cs.whereToBreak == null) return false;
- cs.whereToBreak.set();
- return true;
- }
- private boolean compileUnconditionalLoopWithUpdate(
- Java.ContinuableStatement cs,
- Java.BlockStatement body,
- Java.Rvalue[] update
- ) throws CompileException {
- cs.whereToContinue = this.codeContext.new Offset();
- cs.bodyHasContinue = false;
-
- // Compile body.
- CodeContext.Offset bodyOffset = this.codeContext.newOffset();
- boolean bodyCCN = this.compile(body);
-
- // Compile the "update".
- cs.whereToContinue.set();
- if (!bodyCCN && !cs.bodyHasContinue) {
- this.warning("LUUR", "Loop update is unreachable", update[0].getLocation());
- } else
- {
- for (int i = 0; i < update.length; ++i) this.compile(update[i]);
- this.writeBranch(cs, Opcode.GOTO, bodyOffset);
- }
-
- if (cs.whereToBreak == null) return false;
- cs.whereToBreak.set();
- return true;
- }
-
- private final boolean compile2(Java.LabeledStatement ls) throws CompileException {
- boolean canCompleteNormally = this.compile(ls.body);
- if (ls.whereToBreak != null) {
- ls.whereToBreak.set();
- canCompleteNormally = true;
- }
- return canCompleteNormally;
- }
- private boolean compile2(Java.SwitchStatement ss) throws CompileException {
-
- // Compute condition.
- IClass switchExpressionType = this.compileGetValue(ss.condition);
- this.assignmentConversion(
- (Locatable) ss, // l
- switchExpressionType, // sourceType
- IClass.INT, // targetType
- null // optionalConstantValue
- );
-
- // Prepare the map of case labels to code offsets.
- TreeMap caseLabelMap = new TreeMap(); // Integer => Offset
- CodeContext.Offset defaultLabelOffset = null;
- CodeContext.Offset[] sbsgOffsets = new CodeContext.Offset[ss.sbsgs.size()];
- for (int i = 0; i < ss.sbsgs.size(); ++i) {
- Java.SwitchStatement.SwitchBlockStatementGroup sbsg = (Java.SwitchStatement.SwitchBlockStatementGroup) ss.sbsgs.get(i);
- sbsgOffsets[i] = this.codeContext.new Offset();
- for (int j = 0; j < sbsg.caseLabels.size(); ++j) {
-
- // Verify that case label value is a constant.
- Java.Rvalue rv = (Java.Rvalue) sbsg.caseLabels.get(j);
- Object cv = this.getConstantValue(rv);
- if (cv == null) {
- this.compileError("Value of \"case\" label does not pose a constant value", rv.getLocation());
- cv = new Integer(99);
- }
-
- // Verify that case label is assignable to the type of the switch expression.
- IClass rvType = this.getType(rv);
- this.assignmentConversion(
- (Locatable) ss, // l
- rvType, // sourceType
- switchExpressionType, // targetType
- cv // optionalConstantValue
- );
-
- // Convert char, byte, short, int to "Integer".
- Integer civ;
- if (cv instanceof Integer) {
- civ = (Integer) cv;
- } else
- if (cv instanceof Number) {
- civ = new Integer(((Number) cv).intValue());
- } else
- if (cv instanceof Character) {
- civ = new Integer(((Character) cv).charValue());
- } else {
- this.compileError("Value of case label must be a char, byte, short or int constant", rv.getLocation());
- civ = new Integer(99);
- }
-
- // Store in case label map.
- if (caseLabelMap.containsKey(civ)) this.compileError("Duplicate \"case\" switch label value", rv.getLocation());
- caseLabelMap.put(civ, sbsgOffsets[i]);
- }
- if (sbsg.hasDefaultLabel) {
- if (defaultLabelOffset != null) this.compileError("Duplicate \"default\" switch label", sbsg.getLocation());
- defaultLabelOffset = sbsgOffsets[i];
- }
- }
- if (defaultLabelOffset == null) defaultLabelOffset = this.getWhereToBreak(ss);
-
- // Generate TABLESWITCH or LOOKUPSWITCH instruction.
- CodeContext.Offset switchOffset = this.codeContext.newOffset();
- if (caseLabelMap.isEmpty()) {
- // Special case: SWITCH statement without CASE labels (but maybe a DEFAULT label).
- ;
- } else
- if (
- ((Integer) caseLabelMap.firstKey()).intValue() + caseLabelMap.size() >= // Beware of INT overflow!
- ((Integer) caseLabelMap.lastKey()).intValue() - caseLabelMap.size()
- ) {
- int low = ((Integer) caseLabelMap.firstKey()).intValue();
- int high = ((Integer) caseLabelMap.lastKey()).intValue();
-
- this.writeOpcode(ss, Opcode.TABLESWITCH);
- new Java.Padder(this.codeContext).set();
- this.writeOffset(switchOffset, defaultLabelOffset);
- this.writeInt(low);
- this.writeInt(high);
- Iterator si = caseLabelMap.entrySet().iterator();
- int cur = low;
- while (si.hasNext()) {
- Map.Entry me = (Map.Entry) si.next();
- int val = ((Integer) me.getKey()).intValue();
- while (cur < val) {
- this.writeOffset(switchOffset, defaultLabelOffset);
- ++cur;
- }
- this.writeOffset(switchOffset, (CodeContext.Offset) me.getValue());
- ++cur;
- }
- } else {
- this.writeOpcode(ss, Opcode.LOOKUPSWITCH);
- new Java.Padder(this.codeContext).set();
- this.writeOffset(switchOffset, defaultLabelOffset);
- this.writeInt(caseLabelMap.size());
- Iterator si = caseLabelMap.entrySet().iterator();
- while (si.hasNext()) {
- Map.Entry me = (Map.Entry) si.next();
- this.writeInt(((Integer) me.getKey()).intValue());
- this.writeOffset(switchOffset, (CodeContext.Offset) me.getValue());
- }
- }
-
- // Compile statement groups.
- boolean canCompleteNormally = true;
- for (int i = 0; i < ss.sbsgs.size(); ++i) {
- Java.SwitchStatement.SwitchBlockStatementGroup sbsg = (Java.SwitchStatement.SwitchBlockStatementGroup) ss.sbsgs.get(i);
- sbsgOffsets[i].set();
- canCompleteNormally = true;
- for (int j = 0; j < sbsg.blockStatements.size(); ++j) {
- Java.BlockStatement bs = (Java.BlockStatement) sbsg.blockStatements.get(j);
- if (!canCompleteNormally) {
- this.compileError("Statement is unreachable", bs.getLocation());
- break;
- }
- canCompleteNormally = this.compile(bs);
- }
- }
- if (ss.whereToBreak != null) {
- ss.whereToBreak.set();
- canCompleteNormally = true;
- }
- return canCompleteNormally;
- }
- private boolean compile2(Java.BreakStatement bs) throws CompileException {
-
- // Find the broken statement.
- Java.BreakableStatement brokenStatement = null;
- if (bs.optionalLabel == null) {
- for (
- Java.Scope s = bs.getEnclosingScope();
- s instanceof Java.Statement || s instanceof Java.CatchClause;
- s = s.getEnclosingScope()
- ) {
- if (s instanceof Java.BreakableStatement) {
- brokenStatement = (Java.BreakableStatement) s;
- break;
- }
- }
- if (brokenStatement == null) {
- this.compileError("\"break\" statement is not enclosed by a breakable statement", bs.getLocation());
- return false;
- }
- } else {
- for (
- Java.Scope s = bs.getEnclosingScope();
- s instanceof Java.Statement || s instanceof Java.CatchClause;
- s = s.getEnclosingScope()
- ) {
- if (s instanceof Java.LabeledStatement) {
- Java.LabeledStatement ls = (Java.LabeledStatement) s;
- if (ls.label.equals(bs.optionalLabel)) {
- brokenStatement = ls;
- break;
- }
- }
- }
- if (brokenStatement == null) {
- this.compileError("Statement \"break " + bs.optionalLabel + "\" is not enclosed by a breakable statement with label \"" + bs.optionalLabel + "\"", bs.getLocation());
- return false;
- }
- }
-
- this.leaveStatements(
- bs.getEnclosingScope(), // from
- brokenStatement.getEnclosingScope(), // to
- null // optionalStackValueType
- );
- this.writeBranch(bs, Opcode.GOTO, this.getWhereToBreak(brokenStatement));
- return false;
- }
- private boolean compile2(Java.ContinueStatement cs) throws CompileException {
-
- // Find the continued statement.
- Java.ContinuableStatement continuedStatement = null;
- if (cs.optionalLabel == null) {
- for (
- Java.Scope s = cs.getEnclosingScope();
- s instanceof Java.Statement || s instanceof Java.CatchClause;
- s = s.getEnclosingScope()
- ) {
- if (s instanceof Java.ContinuableStatement) {
- continuedStatement = (Java.ContinuableStatement) s;
- break;
- }
- }
- if (continuedStatement == null) {
- this.compileError("\"continue\" statement is not enclosed by a continuable statement", cs.getLocation());
- return false;
- }
- } else {
- for (
- Java.Scope s = cs.getEnclosingScope();
- s instanceof Java.Statement || s instanceof Java.CatchClause;
- s = s.getEnclosingScope()
- ) {
- if (s instanceof Java.LabeledStatement) {
- Java.LabeledStatement ls = (Java.LabeledStatement) s;
- if (ls.label.equals(cs.optionalLabel)) {
- Java.Statement st = ls.body;
- while (st instanceof Java.LabeledStatement) st = ((Java.LabeledStatement) st).body;
- if (!(st instanceof Java.ContinuableStatement)) {
- this.compileError("Labeled statement is not continuable", st.getLocation());
- return false;
- }
- continuedStatement = (Java.ContinuableStatement) st;
- break;
- }
- }
- }
- if (continuedStatement == null) {
- this.compileError("Statement \"continue " + cs.optionalLabel + "\" is not enclosed by a continuable statement with label \"" + cs.optionalLabel + "\"", cs.getLocation());
- return false;
- }
- }
-
- continuedStatement.bodyHasContinue = true;
- this.leaveStatements(
- cs.getEnclosingScope(), // from
- continuedStatement.getEnclosingScope(), // to
- null // optionalStackValueType
- );
- this.writeBranch(cs, Opcode.GOTO, continuedStatement.whereToContinue);
- return false;
- }
- private boolean compile2(Java.EmptyStatement es) {
- return true;
- }
- private boolean compile2(Java.ExpressionStatement ee) throws CompileException {
- this.compile(ee.rvalue);
- return true;
- }
- private boolean compile2(Java.FieldDeclaration fd) throws CompileException {
- for (int i = 0; i < fd.variableDeclarators.length; ++i) {
- Java.VariableDeclarator vd = fd.variableDeclarators[i];
-
- Java.ArrayInitializerOrRvalue initializer = this.getNonConstantFinalInitializer(fd, vd);
- if (initializer == null) continue;
-
- if ((fd.modifiers & Mod.STATIC) == 0) {
- this.writeOpcode(fd, Opcode.ALOAD_0);
- }
- IClass fieldType = this.getType(fd.type);
- if (initializer instanceof Java.Rvalue) {
- Java.Rvalue rvalue = (Java.Rvalue) initializer;
- IClass initializerType = this.compileGetValue(rvalue);
- fieldType = fieldType.getArrayIClass(vd.brackets, this.iClassLoader.OBJECT);
- this.assignmentConversion(
- (Locatable) fd, // l
- initializerType, // sourceType
- fieldType, // destinationType
- this.getConstantValue(rvalue) // optionalConstantValue
- );
- } else
- if (initializer instanceof Java.ArrayInitializer) {
- this.compileGetValue((Java.ArrayInitializer) initializer, fieldType);
- } else
- {
- throw new RuntimeException("Unexpected array initializer or rvalue class " + initializer.getClass().getName());
- }
-
- // No need to check accessibility here.
- ;
-
- if ((fd.modifiers & Mod.STATIC) != 0) {
- this.writeOpcode(fd, Opcode.PUTSTATIC);
- } else {
- this.writeOpcode(fd, Opcode.PUTFIELD);
- }
- this.writeConstantFieldrefInfo(
- this.resolve(fd.getDeclaringType()).getDescriptor(),
- vd.name, // classFD
- fieldType.getDescriptor() // fieldFD
- );
- }
- return true;
- }
- private boolean compile2(Java.IfStatement is) throws CompileException {
- Object cv = this.getConstantValue(is.condition);
- Java.BlockStatement es = (
- is.optionalElseStatement != null
- ? is.optionalElseStatement
- : new Java.EmptyStatement(is.thenStatement.getLocation())
- );
- if (cv instanceof Boolean) {
-
- // Constant condition.
- this.fakeCompile(is.condition);
- Java.BlockStatement seeingStatement, blindStatement;
- if (((Boolean) cv).booleanValue()) {
- seeingStatement = is.thenStatement;
- blindStatement = es;
- } else {
- seeingStatement = es;
- blindStatement = is.thenStatement;
- }
-
- // Compile the seeing statement.
- CodeContext.Inserter ins = this.codeContext.newInserter();
- boolean ssccn = this.compile(seeingStatement);
- if (ssccn) return true;
-
- // Hm... the "seeing statement" cannot complete normally. Things are getting
- // complicated here! The robust solution is to compile the constant-condition-IF
- // statement as a non-constant-condition-IF statement. As an optimization, iff the
- // IF-statement is enclosed ONLY by blocks, then the remaining bytecode can be
- // written to a "fake" code context, i.e. be thrown away.
-
- // Constant-condition-IF statement only enclosed by blocks?
- Java.Scope s = is.getEnclosingScope();
- while (s instanceof Java.Block) s = s.getEnclosingScope();
- if (s instanceof Java.FunctionDeclarator) {
-
- // Yes, compile rest of method to /dev/null.
- throw UnitCompiler.STOP_COMPILING_CODE;
- } else
- {
-
- // Compile constant-condition-IF statement as non-constant-condition-IF statement.
- CodeContext.Offset off = this.codeContext.newOffset();
- this.codeContext.pushInserter(ins);
- try {
- this.pushConstant(is, new Integer(0));
- this.writeBranch((Locatable) is, Opcode.IFNE, off);
- } finally {
- this.codeContext.popInserter();
- }
- }
- return this.compile(blindStatement);
- }
-
- // Non-constant condition.
- if (this.generatesCode(is.thenStatement)) {
- if (this.generatesCode(es)) {
-
- // if (expr) stmt else stmt
- CodeContext.Offset eso = this.codeContext.new Offset();
- CodeContext.Offset end = this.codeContext.new Offset();
- this.compileBoolean(is.condition, eso, Java.Rvalue.JUMP_IF_FALSE);
- boolean tsccn = this.compile(is.thenStatement);
- if (tsccn) this.writeBranch((Locatable) is, Opcode.GOTO, end);
- eso.set();
- boolean esccn = this.compile(es);
- end.set();
- return tsccn || esccn;
- } else {
-
- // if (expr) stmt else ;
- CodeContext.Offset end = this.codeContext.new Offset();
- this.compileBoolean(is.condition, end, Java.Rvalue.JUMP_IF_FALSE);
- this.compile(is.thenStatement);
- end.set();
- return true;
- }
- } else {
- if (this.generatesCode(es)) {
-
- // if (expr) ; else stmt
- CodeContext.Offset end = this.codeContext.new Offset();
- this.compileBoolean(is.condition, end, Java.Rvalue.JUMP_IF_TRUE);
- this.compile(es);
- end.set();
- return true;
- } else {
-
- // if (expr) ; else ;
- IClass conditionType = this.compileGetValue(is.condition);
- if (conditionType != IClass.BOOLEAN) this.compileError("Not a boolean expression", is.getLocation());
- this.pop((Locatable) is, conditionType);
- return true;
- }
- }
- }
- private static final RuntimeException STOP_COMPILING_CODE = new RuntimeException("SNO: This exception should have been caught and processed");
-
- private boolean compile2(Java.LocalClassDeclarationStatement lcds) throws CompileException {
-
- // Check for redefinition.
- Java.LocalClassDeclaration otherLCD = this.findLocalClassDeclaration(lcds, lcds.lcd.name);
- if (otherLCD != lcds.lcd) this.compileError("Redeclaration of local class \"" + lcds.lcd.name + "\"; previously declared in " + otherLCD.getLocation());
-
- this.compile(lcds.lcd);
- return true;
- }
-
- /**
- * Find a local class declared in any block enclosing the given block statement.
- */
- private Java.LocalClassDeclaration findLocalClassDeclaration(Java.Scope s, String name) {
- for (;;) {
- Java.Scope es = s.getEnclosingScope();
- if (es instanceof Java.CompilationUnit) break;
- if (s instanceof Java.BlockStatement && es instanceof Java.Block) {
- Java.BlockStatement bs = (Java.BlockStatement) s;
- Java.Block b = (Java.Block) es;
- for (Iterator it = b.statements.iterator(); it.hasNext();) {
- Java.BlockStatement bs2 = (Java.BlockStatement) it.next();
- if (bs2 instanceof Java.LocalClassDeclarationStatement) {
- Java.LocalClassDeclarationStatement lcds = ((Java.LocalClassDeclarationStatement) bs2);
- if (lcds.lcd.name.equals(name)) return lcds.lcd;
- }
- if (bs2 == bs) break;
- }
- }
- s = es;
- }
- return null;
- }
-
- private boolean compile2(Java.LocalVariableDeclarationStatement lvds) throws CompileException {
- if ((lvds.modifiers & ~Mod.FINAL) != 0) this.compileError("The only allowed modifier in local variable declarations is \"final\"", lvds.getLocation());
-
- for (int j = 0; j < lvds.variableDeclarators.length; ++j) {
- Java.VariableDeclarator vd = lvds.variableDeclarators[j];
-
- Java.LocalVariable lv = this.getLocalVariable(lvds, vd);
- lv.localVariableArrayIndex = this.codeContext.allocateLocalVariable(Descriptor.size(lv.type.getDescriptor()));
-
- if (vd.optionalInitializer != null) {
- if (vd.optionalInitializer instanceof Java.Rvalue) {
- Java.Rvalue rhs = (Java.Rvalue) vd.optionalInitializer;
- this.assignmentConversion(
- (Locatable) lvds, // l
- this.compileGetValue(rhs), // sourceType
- lv.type, // targetType
- this.getConstantValue(rhs) // optionalConstantValue
- );
- } else
- if (vd.optionalInitializer instanceof Java.ArrayInitializer) {
- this.compileGetValue((Java.ArrayInitializer) vd.optionalInitializer, lv.type);
- } else
- {
- throw new RuntimeException("Unexpected rvalue or array initialized class " + vd.optionalInitializer.getClass().getName());
- }
- this.store(
- (Locatable) lvds, // l
- lv.type, // valueType
- lv // localVariable
- );
- }
- }
- return true;
- }
-
- public Java.LocalVariable getLocalVariable(
- Java.LocalVariableDeclarationStatement lvds,
- Java.VariableDeclarator vd
- ) throws CompileException {
- if (vd.localVariable == null) {
-
- // Determine variable type.
- Java.Type variableType = lvds.type;
- for (int k = 0; k < vd.brackets; ++k) variableType = new Java.ArrayType(variableType);
-
- vd.localVariable = new Java.LocalVariable((lvds.modifiers & Mod.FINAL) != 0, this.getType(variableType));
- }
- return vd.localVariable;
- }
-
- private boolean compile2(Java.ReturnStatement rs) throws CompileException {
-
- // Determine enclosing block, function and compilation Unit.
- Java.FunctionDeclarator enclosingFunction = null;
- {
- Java.Scope s = rs.getEnclosingScope();
- for (s = s.getEnclosingScope(); s instanceof Java.Statement || s instanceof Java.CatchClause; s = s.getEnclosingScope());
- enclosingFunction = (Java.FunctionDeclarator) s;
- }
-
- IClass returnType = this.getReturnType(enclosingFunction);
- if (returnType == IClass.VOID) {
- if (rs.optionalReturnValue != null) this.compileError("Method must not return a value", rs.getLocation());
- this.leaveStatements(
- rs.getEnclosingScope(), // from
- enclosingFunction, // to
- null // optionalStackValueType
- );
- this.writeOpcode(rs, Opcode.RETURN);
- return false;
- }
- if (rs.optionalReturnValue == null) {
- this.compileError("Method must return a value", rs.getLocation());
- return false;
- }
- IClass type = this.compileGetValue(rs.optionalReturnValue);
- this.assignmentConversion(
- (Locatable) rs, // l
- type, // sourceType
- returnType, // targetType
- this.getConstantValue(rs.optionalReturnValue) // optionalConstantValue
- );
-
- this.leaveStatements(
- rs.getEnclosingScope(), // from
- enclosingFunction, // to
- returnType // optionalStackValueType
- );
- this.writeOpcode(rs, Opcode.IRETURN + this.ilfda(returnType));
- return false;
- }
- private boolean compile2(Java.SynchronizedStatement ss) throws CompileException {
-
- // Evaluate monitor object expression.
- if (!this.iClassLoader.OBJECT.isAssignableFrom(this.compileGetValue(ss.expression))) this.compileError("Monitor object of \"synchronized\" statement is not a subclass of \"Object\"", ss.getLocation());
-
- this.codeContext.saveLocalVariables();
- boolean canCompleteNormally = false;
- try {
-
- // Allocate a local variable for the monitor object.
- ss.monitorLvIndex = this.codeContext.allocateLocalVariable((short) 1);
-
- // Store the monitor object.
- this.writeOpcode(ss, Opcode.DUP);
- this.store((Locatable) ss, this.iClassLoader.OBJECT, ss.monitorLvIndex);
-
- // Create lock on the monitor object.
- this.writeOpcode(ss, Opcode.MONITORENTER);
-
- // Compile the statement body.
- CodeContext.Offset monitorExitOffset = this.codeContext.new Offset();
- CodeContext.Offset beginningOfBody = this.codeContext.newOffset();
- canCompleteNormally = this.compile(ss.body);
- if (canCompleteNormally) {
- this.writeBranch(ss, Opcode.GOTO, monitorExitOffset);
- }
-
- // Generate the exception handler.
- CodeContext.Offset here = this.codeContext.newOffset();
- this.codeContext.addExceptionTableEntry(
- beginningOfBody, // startPC
- here, // endPC
- here, // handlerPC
- null // catchTypeFD
- );
- this.leave(ss, this.iClassLoader.THROWABLE);
- this.writeOpcode(ss, Opcode.ATHROW);
-
- // Unlock monitor object.
- if (canCompleteNormally) {
- monitorExitOffset.set();
- this.leave(ss, null);
- }
- } finally {
- this.codeContext.restoreLocalVariables();
- }
-
- return canCompleteNormally;
- }
- private boolean compile2(Java.ThrowStatement ts) throws CompileException {
- IClass expressionType = this.compileGetValue(ts.expression);
- this.checkThrownException(
- (Locatable) ts, // l
- expressionType, // type
- ts.getEnclosingScope() // scope
- );
- this.writeOpcode(ts, Opcode.ATHROW);
- return false;
- }
- private boolean compile2(Java.TryStatement ts) throws CompileException {
- if (ts.optionalFinally != null) ts.finallyOffset = this.codeContext.new Offset();
-
- CodeContext.Offset beginningOfBody = this.codeContext.newOffset();
- CodeContext.Offset afterStatement = this.codeContext.new Offset();
-
- this.codeContext.saveLocalVariables();
- try {
-
- // Allocate a LV for the JSR of the FINALLY clause.
- //
- // Notice:
- // For unclear reasons, this variable must not overlap with any of the body's
- // variables (although the body's variables are out of scope when it comes to the
- // FINALLY clause!?), otherwise you get
- // java.lang.VerifyError: ... Accessing value from uninitialized localvariable 4
- // See bug #56.
- short pcLVIndex = ts.optionalFinally != null ? this.codeContext.allocateLocalVariable((short) 1) : (short) 0;
-
- boolean canCompleteNormally = this.compile(ts.body);
- CodeContext.Offset afterBody = this.codeContext.newOffset();
- if (canCompleteNormally) {
- this.writeBranch(ts, Opcode.GOTO, afterStatement);
- }
-
- if (beginningOfBody.offset != afterBody.offset) { // Avoid zero-length exception table entries.
- this.codeContext.saveLocalVariables();
- try {
-
- // Allocate the "exception variable".
- short evi = this.codeContext.allocateLocalVariable((short) 1);
-
- for (int i = 0; i < ts.catchClauses.size(); ++i) {
- Java.CatchClause cc = (Java.CatchClause) ts.catchClauses.get(i);
- IClass caughtExceptionType = this.getType(cc.caughtException.type);
- this.codeContext.addExceptionTableEntry(
- beginningOfBody, // startPC
- afterBody, // endPC
- this.codeContext.newOffset(), // handlerPC
- caughtExceptionType.getDescriptor() // catchTypeFD
- );
- this.store(
- (Locatable) cc, // l
- caughtExceptionType, // lvType
- evi // lvIndex
- );
-
- // Kludge: Treat the exception variable like a local
- // variable of the catch clause body.
- UnitCompiler.this.getLocalVariable(cc.caughtException).localVariableArrayIndex = evi;
-
- if (this.compile(cc.body)) {
- canCompleteNormally = true;
- if (
- i < ts.catchClauses.size() - 1 ||
- ts.optionalFinally != null
- ) this.writeBranch(cc, Opcode.GOTO, afterStatement);
- }
- }
- } finally {
- this.codeContext.restoreLocalVariables();
- }
- }
-
- if (ts.optionalFinally != null) {
- CodeContext.Offset here = this.codeContext.newOffset();
- this.codeContext.addExceptionTableEntry(
- beginningOfBody, // startPC
- here, // endPC
- here, // handlerPC
- null // catchTypeFD
- );
-
- this.codeContext.saveLocalVariables();
- try {
-
- // Save the exception object in an anonymous local variable.
- short evi = this.codeContext.allocateLocalVariable((short) 1);
- this.store(
- (Locatable) ts.optionalFinally, // l
- this.iClassLoader.OBJECT, // valueType
- evi // localVariableIndex
- );
- this.writeBranch(ts.optionalFinally, Opcode.JSR, ts.finallyOffset);
- this.load(
- (Locatable) ts.optionalFinally, // l
- this.iClassLoader.OBJECT, // valueType
- evi // localVariableIndex
- );
- this.writeOpcode(ts.optionalFinally, Opcode.ATHROW);
-
- // Compile the "finally" body.
- ts.finallyOffset.set();
- this.store(
- (Locatable) ts.optionalFinally, // l
- this.iClassLoader.OBJECT, // valueType
- pcLVIndex // localVariableIndex
- );
- if (this.compile(ts.optionalFinally)) {
- this.writeOpcode(ts.optionalFinally, Opcode.RET);
- this.writeByte(pcLVIndex);
- }
- } finally {
-
- // The exception object local variable allocated above MUST NOT BE RELEASED
- // until after the FINALLY block is compiled, for otherwise you get
- // java.lang.VerifyError: ... Accessing value from uninitialized register 7
- this.codeContext.restoreLocalVariables();
- }
- }
-
- afterStatement.set();
- if (canCompleteNormally) this.leave(ts, null);
- return canCompleteNormally;
- } finally {
- this.codeContext.restoreLocalVariables();
- }
- }
-
- // ------------ FunctionDeclarator.compile() -------------
-
- private void compile(Java.FunctionDeclarator fd, final ClassFile classFile) throws CompileException {
- ClassFile.MethodInfo mi;
-
- if (Mod.isPrivateAccess(fd.modifiers)) {
- if (fd instanceof Java.MethodDeclarator && !fd.isStatic()){
-
- // To make the non-static private method invocable for enclosing types, enclosed types
- // and types enclosed by the same type, it is modified as follows:
- // + Access is changed from PRIVATE to PACKAGE
- // + The name is appended with "$"
- // + It is made static
- // + A parameter of type "declaring class" is prepended to the signature
- mi = classFile.addMethodInfo(
- (short) (Mod.changeAccess(fd.modifiers, Mod.PACKAGE) | Mod.STATIC), // accessFlags
- fd.name + '$', // name
- MethodDescriptor.prependParameter( // methodMD
- this.toIMethod((Java.MethodDeclarator) fd).getDescriptor(),
- this.resolve(fd.getDeclaringType()).getDescriptor()
- )
- );
- } else
- {
-
- // To make the static private method or private constructor invocable for enclosing
- // types, enclosed types and types enclosed by the same type, it is modified as
- // follows:
- // + Access is changed from PRIVATE to PACKAGE
- mi = classFile.addMethodInfo(
- Mod.changeAccess(fd.modifiers, Mod.PACKAGE), // accessFlags
- fd.name, // name
- this.toIInvocable(fd).getDescriptor() // methodMD
- );
- }
- } else
- {
- mi = classFile.addMethodInfo(
- fd.modifiers, // accessFlags
- fd.name, // name
- this.toIInvocable(fd).getDescriptor() // methodMD
- );
- }
-
- // Add "Exceptions" attribute (JVMS 4.7.4).
- {
- final short eani = classFile.addConstantUtf8Info("Exceptions");
- short[] tecciis = new short[fd.thrownExceptions.length];
- for (int i = 0; i < fd.thrownExceptions.length; ++i) {
- tecciis[i] = classFile.addConstantClassInfo(this.getType(fd.thrownExceptions[i]).getDescriptor());
- }
- mi.addAttribute(new ClassFile.ExceptionsAttribute(eani, tecciis));
- }
-
- // Add "Deprecated" attribute (JVMS 4.7.10)
- if (fd.hasDeprecatedDocTag()) {
- mi.addAttribute(new ClassFile.DeprecatedAttribute(classFile.addConstantUtf8Info("Deprecated")));
- }
-
- if ((fd.modifiers & (Mod.ABSTRACT | Mod.NATIVE)) != 0) return;
-
- // Create CodeContext.
- final CodeContext codeContext = new CodeContext(mi.getClassFile());
-
- CodeContext savedCodeContext = this.replaceCodeContext(codeContext);
- try {
-
- // Define special parameter "this".
- if ((fd.modifiers & Mod.STATIC) == 0) {
- this.codeContext.allocateLocalVariable((short) 1);
- }
-
- if (fd instanceof Java.ConstructorDeclarator) {
- Java.ConstructorDeclarator constructorDeclarator = (Java.ConstructorDeclarator) fd;
-
- // Reserve space for synthetic parameters ("this$...", "val$...").
- for (Iterator it = constructorDeclarator.getDeclaringClass().syntheticFields.values().iterator(); it.hasNext();) {
- IClass.IField sf = (IClass.IField) it.next();
- Java.LocalVariable lv = new Java.LocalVariable(true, sf.getType());
- lv.localVariableArrayIndex = this.codeContext.allocateLocalVariable(Descriptor.size(sf.getDescriptor()));
- constructorDeclarator.syntheticParameters.put(sf.getName(), lv);
- }
- }
-
- this.buildLocalVariableMap(fd);
-
- // Compile the constructor preamble.
- if (fd instanceof Java.ConstructorDeclarator) {
- Java.ConstructorDeclarator cd = (Java.ConstructorDeclarator) fd;
- if (cd.optionalConstructorInvocation != null) {
- this.compile(cd.optionalConstructorInvocation);
- if (cd.optionalConstructorInvocation instanceof Java.SuperConstructorInvocation) {
- this.assignSyntheticParametersToSyntheticFields(cd);
- this.initializeInstanceVariablesAndInvokeInstanceInitializers(cd);
- }
- } else {
-
- // Determine qualification for superconstructor invocation.
- Java.QualifiedThisReference qualification = null;
- IClass outerClassOfSuperclass = this.resolve(cd.getDeclaringClass()).getSuperclass().getOuterIClass();
- if (outerClassOfSuperclass != null) {
-// qualification = new Java.QualifiedThisReference(
-// cd.getLocation(), // location
-// cd.getDeclaringClass(), // declaringClass
-// cd, // declaringTypeBodyDeclaration
-// outerClassOfSuperclass // targetIClass
-// );
- qualification = new Java.QualifiedThisReference(
- cd.getLocation(), // location
- new Java.SimpleType( // qualification
- cd.getLocation(),
- outerClassOfSuperclass
- )
- );
- }
-
- // Invoke the superconstructor.
- Java.SuperConstructorInvocation sci = new Java.SuperConstructorInvocation(
- cd.getLocation(), // location
- qualification, // optionalQualification
- new Java.Rvalue[0] // arguments
- );
- sci.setEnclosingScope(fd);
- this.compile(sci);
- this.assignSyntheticParametersToSyntheticFields(cd);
- this.initializeInstanceVariablesAndInvokeInstanceInitializers(cd);
- }
- }
-
- // Compile the function body.
- try {
- if (fd.optionalBody == null) {
- this.compileError("Method must have a body", fd.getLocation());
- }
- boolean canCompleteNormally = this.compile(fd.optionalBody);
- if (canCompleteNormally) {
- if (this.getReturnType(fd) != IClass.VOID) this.compileError("Method must return a value", fd.getLocation());
- this.writeOpcode(fd, Opcode.RETURN);
- }
- } catch (RuntimeException ex) {
- if (ex != UnitCompiler.STOP_COMPILING_CODE) throw ex;
-
- // In very special circumstances (e.g. "if (true) return;"), code generation is
- // terminated abruptly by throwing STOP_COMPILING_CODE.
- ;
- }
- } finally {
- this.replaceCodeContext(savedCodeContext);
- }
-
- // Don't continue code attribute generation if we had compile errors.
- if (this.compileErrorCount > 0) return;
-
- // Fix up and reallocate as needed.
- codeContext.fixUpAndRelocate();
-
- // Do flow analysis.
- if (UnitCompiler.DEBUG) {
- try {
- codeContext.flowAnalysis(fd.toString());
- } catch (RuntimeException ex) {
- ex.printStackTrace();
- ;
- }
- } else {
- codeContext.flowAnalysis(fd.toString());
- }
-
- // Add the code context as a code attribute to the MethodInfo.
- final short lntani = (
- this.debuggingInformation.contains(DebuggingInformation.LINES) ?
- classFile.addConstantUtf8Info("LineNumberTable") :
- (short) 0
- );
- mi.addAttribute(new ClassFile.AttributeInfo(classFile.addConstantUtf8Info("Code")) {
- protected void storeBody(DataOutputStream dos) throws IOException {
- codeContext.storeCodeAttributeBody(dos, lntani);
- }
- });
- }
-
- private void buildLocalVariableMap(FunctionDeclarator fd) throws CompileException {
- Map localVars = new HashMap();
-
- // Add function parameters.
- for (int i = 0; i < fd.formalParameters.length; ++i) {
- Java.FunctionDeclarator.FormalParameter fp = fd.formalParameters[i];
- if (localVars.containsKey(fp.name)) this.compileError("Redefinition of formal parameter \"" + fp.name + "\"", fd.getLocation());
- Java.LocalVariable lv = this.getLocalVariable(fp);
- lv.localVariableArrayIndex = this.codeContext.allocateLocalVariable(Descriptor.size(lv.type.getDescriptor()));
-
- localVars.put(fp.name, lv);
- }
-
- fd.localVariables = localVars;
- if (fd instanceof ConstructorDeclarator) {
- ConstructorDeclarator cd = (ConstructorDeclarator) fd;
- if (cd.optionalConstructorInvocation != null) {
- buildLocalVariableMap(cd.optionalConstructorInvocation, localVars);
- }
- }
- if (fd.optionalBody != null) this.buildLocalVariableMap(fd.optionalBody, localVars);
- }
-
- private Map buildLocalVariableMap(BlockStatement bs, final Map localVars) throws CompileException {
- final Map[] resVars = new Map[] { localVars };
- class UCE extends RuntimeException { final CompileException ce; UCE(CompileException ce) { this.ce = ce; } }
- BlockStatementVisitor bsv = new BlockStatementVisitor() {
- // basic statements that use the default handlers
- public void visitAlternateConstructorInvocation(AlternateConstructorInvocation aci) { UnitCompiler.this.buildLocalVariableMap(aci, localVars); }
- public void visitBreakStatement(BreakStatement bs) { UnitCompiler.this.buildLocalVariableMap(bs, localVars); }
- public void visitContinueStatement(ContinueStatement cs) { UnitCompiler.this.buildLocalVariableMap(cs, localVars); }
- public void visitEmptyStatement(EmptyStatement es) { UnitCompiler.this.buildLocalVariableMap(es, localVars); }
- public void visitExpressionStatement(ExpressionStatement es) { UnitCompiler.this.buildLocalVariableMap(es, localVars); }
- public void visitFieldDeclaration(FieldDeclaration fd) { UnitCompiler.this.buildLocalVariableMap(fd, localVars); }
- public void visitReturnStatement(ReturnStatement rs) { UnitCompiler.this.buildLocalVariableMap(rs, localVars); }
- public void visitSuperConstructorInvocation(SuperConstructorInvocation sci) { UnitCompiler.this.buildLocalVariableMap(sci, localVars); }
- public void visitThrowStatement(ThrowStatement ts) { UnitCompiler.this.buildLocalVariableMap(ts, localVars); }
- public void visitLocalClassDeclarationStatement(LocalClassDeclarationStatement lcds){ UnitCompiler.this.buildLocalVariableMap(lcds, localVars); }
-
- // more complicated statements with specialized handlers, but don't add new variables in this scope
- public void visitBlock(Block b) { try { UnitCompiler.this.buildLocalVariableMap(b , localVars); } catch (CompileException e) { throw new UCE(e); } }
- public void visitDoStatement(DoStatement ds) { try { UnitCompiler.this.buildLocalVariableMap(ds, localVars); } catch (CompileException e) { throw new UCE(e); } }
- public void visitForStatement(ForStatement fs) { try { UnitCompiler.this.buildLocalVariableMap(fs, localVars); } catch (CompileException e) { throw new UCE(e); } }
- public void visitIfStatement(IfStatement is) { try { UnitCompiler.this.buildLocalVariableMap(is, localVars); } catch (CompileException e) { throw new UCE(e); } }
- public void visitInitializer(Initializer i) { try { UnitCompiler.this.buildLocalVariableMap(i , localVars); } catch (CompileException e) { throw new UCE(e); } }
- public void visitSwitchStatement(SwitchStatement ss) { try { UnitCompiler.this.buildLocalVariableMap(ss, localVars); } catch (CompileException e) { throw new UCE(e); } }
- public void visitSynchronizedStatement(SynchronizedStatement ss) { try { UnitCompiler.this.buildLocalVariableMap(ss, localVars); } catch (CompileException e) { throw new UCE(e); } }
- public void visitTryStatement(TryStatement ts) { try { UnitCompiler.this.buildLocalVariableMap(ts, localVars); } catch (CompileException e) { throw new UCE(e); } }
- public void visitWhileStatement(WhileStatement ws) { try { UnitCompiler.this.buildLocalVariableMap(ws, localVars); } catch (CompileException e) { throw new UCE(e); } }
-
- // more complicated statements with specialized handlers, that can add variables in this scope
- public void visitLabeledStatement(LabeledStatement ls) { try { resVars[0] = UnitCompiler.this.buildLocalVariableMap(ls , localVars); } catch (CompileException e) { throw new UCE(e); } }
- public void visitLocalVariableDeclarationStatement(LocalVariableDeclarationStatement lvds) { try { resVars[0] = UnitCompiler.this.buildLocalVariableMap(lvds, localVars); } catch (CompileException e) { throw new UCE(e); } }
- };
- try { bs.accept(bsv); } catch(UCE uce) { throw uce.ce; }
- return resVars[0];
- }
- // default handlers
- private Map buildLocalVariableMap(Statement s, final Map localVars) { return s.localVariables = localVars; }
- private Map buildLocalVariableMap(ConstructorInvocation ci, final Map localVars) { return ci.localVariables = localVars; }
-
- // specialized handlers
- private void buildLocalVariableMap(Block block, Map localVars) throws CompileException {
- block.localVariables = localVars;
- for (Iterator it = block.statements.iterator(); it.hasNext();) {
- BlockStatement bs = (BlockStatement)it.next();
- localVars = this.buildLocalVariableMap(bs, localVars);
- }
- }
- private void buildLocalVariableMap(DoStatement ds, final Map localVars) throws CompileException {
- ds.localVariables = localVars;
- this.buildLocalVariableMap(ds.body, localVars);
- }
- private void buildLocalVariableMap(ForStatement fs, final Map localVars) throws CompileException {
- Map inner = localVars;
- if(fs.optionalInit != null) {
- inner = UnitCompiler.this.buildLocalVariableMap(fs.optionalInit, localVars);
- }
- fs.localVariables = inner;
- UnitCompiler.this.buildLocalVariableMap(fs.body, inner);
- }
- private void buildLocalVariableMap(IfStatement is, final Map localVars) throws CompileException {
- is.localVariables = localVars;
- UnitCompiler.this.buildLocalVariableMap(is.thenStatement, localVars);
- if(is.optionalElseStatement != null) {
- UnitCompiler.this.buildLocalVariableMap(is.optionalElseStatement, localVars);
- }
- }
- private void buildLocalVariableMap(Initializer i, final Map localVars) throws CompileException {
- UnitCompiler.this.buildLocalVariableMap(i.block, localVars);
- }
- private void buildLocalVariableMap(SwitchStatement ss, final Map localVars) throws CompileException {
- ss.localVariables = localVars;
- Map vars = localVars;
- for (Iterator cases = ss.sbsgs.iterator(); cases.hasNext();) {
- SwitchStatement.SwitchBlockStatementGroup sbsg = (SwitchStatement.SwitchBlockStatementGroup) cases.next();
- for (Iterator stmts = sbsg.blockStatements.iterator(); stmts.hasNext();) {
- BlockStatement bs = (BlockStatement) stmts.next();
- vars = UnitCompiler.this.buildLocalVariableMap(bs, vars);
- }
- }
- }
- private void buildLocalVariableMap(SynchronizedStatement ss, final Map localVars) throws CompileException {
- ss.localVariables = localVars;
- UnitCompiler.this.buildLocalVariableMap(ss.body, localVars);
- }
- private void buildLocalVariableMap(TryStatement ts, final Map localVars) throws CompileException {
- ts.localVariables = localVars;
- UnitCompiler.this.buildLocalVariableMap(ts.body, localVars);
- for (Iterator it = ts.catchClauses.iterator(); it.hasNext();) {
- Java.CatchClause cc = (Java.CatchClause) it.next();
- UnitCompiler.this.buildLocalVariableMap(cc, localVars);
- }
- if(ts.optionalFinally != null) {
- UnitCompiler.this.buildLocalVariableMap(ts.optionalFinally, localVars);
- }
- }
- private void buildLocalVariableMap(WhileStatement ws, final Map localVars) throws CompileException {
- ws.localVariables = localVars;
- UnitCompiler.this.buildLocalVariableMap(ws.body, localVars);
- }
-
- private Map buildLocalVariableMap(LabeledStatement ls, final Map localVars) throws CompileException {
- ls.localVariables = localVars;
- return UnitCompiler.this.buildLocalVariableMap((BlockStatement)ls.body, localVars);
- }
- private Map buildLocalVariableMap(LocalVariableDeclarationStatement lvds, final Map localVars) throws CompileException {
- Map newVars = new HashMap();
- newVars.putAll(localVars);
- for(int i = 0; i < lvds.variableDeclarators.length; ++i) {
- Java.VariableDeclarator vd = lvds.variableDeclarators[i];
- Java.LocalVariable lv = UnitCompiler.this.getLocalVariable(lvds, vd);
- if(newVars.containsKey(vd.name)) this.compileError("Redefinition of local variable \"" + vd.name + "\" ", vd.getLocation());
- newVars.put(vd.name, lv);
- }
- lvds.localVariables = newVars;
- return newVars;
- }
- protected void buildLocalVariableMap(CatchClause cc, Map localVars) throws CompileException {
- Map vars = new HashMap();
- vars.putAll(localVars);
- LocalVariable lv = this.getLocalVariable(cc.caughtException);
- vars.put(cc.caughtException.name, lv);
- this.buildLocalVariableMap(cc.body, vars);
- }
-
-
-
- public Java.LocalVariable getLocalVariable(Java.FunctionDeclarator.FormalParameter fp) throws CompileException {
- if (fp.localVariable == null) {
- fp.localVariable = new Java.LocalVariable(fp.finaL, this.getType(fp.type));
- }
- return fp.localVariable;
- }
-
- // ------------------ Rvalue.compile() ----------------
-
- /**
- * Call to check whether the given {@link Java.Rvalue} compiles or not.
- */
- private void fakeCompile(Java.Rvalue rv) throws CompileException {
- CodeContext savedCodeContext = this.replaceCodeContext(this.createDummyCodeContext());
- try {
- this.compileContext(rv);
- this.compileGet(rv);
- } finally {
- this.replaceCodeContext(savedCodeContext);
- }
- }
-
- /**
- * Some {@link Java.Rvalue}s compile more efficiently when their value
- * is not needed, e.g. "i++".
- */
- private void compile(Java.Rvalue rv) throws CompileException {
- class UCE extends RuntimeException { final CompileException ce; UCE(CompileException ce) { this.ce = ce; } }
- Visitor.RvalueVisitor rvv = new Visitor.RvalueVisitor() {
- public void visitArrayLength (Java.ArrayLength al ) { try { UnitCompiler.this.compile2(al ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitAssignment (Java.Assignment a ) { try { UnitCompiler.this.compile2(a ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitUnaryOperation (Java.UnaryOperation uo ) { try { UnitCompiler.this.compile2(uo ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitBinaryOperation (Java.BinaryOperation bo ) { try { UnitCompiler.this.compile2(bo ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitCast (Java.Cast c ) { try { UnitCompiler.this.compile2(c ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitClassLiteral (Java.ClassLiteral cl ) { try { UnitCompiler.this.compile2(cl ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitConditionalExpression (Java.ConditionalExpression ce ) { try { UnitCompiler.this.compile2(ce ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitCrement (Java.Crement c ) { try { UnitCompiler.this.compile2(c ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitInstanceof (Java.Instanceof io ) { try { UnitCompiler.this.compile2(io ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitMethodInvocation (Java.MethodInvocation mi ) { try { UnitCompiler.this.compile2(mi ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitSuperclassMethodInvocation (Java.SuperclassMethodInvocation smi ) { try { UnitCompiler.this.compile2(smi ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitLiteral (Java.Literal l ) { try { UnitCompiler.this.compile2(l ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitNewAnonymousClassInstance (Java.NewAnonymousClassInstance naci) { try { UnitCompiler.this.compile2(naci); } catch (CompileException e) { throw new UCE(e); } }
- public void visitNewArray (Java.NewArray na ) { try { UnitCompiler.this.compile2(na ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitNewInitializedArray (Java.NewInitializedArray nia ) { try { UnitCompiler.this.compile2(nia ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitNewClassInstance (Java.NewClassInstance nci ) { try { UnitCompiler.this.compile2(nci ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitParameterAccess (Java.ParameterAccess pa ) { try { UnitCompiler.this.compile2(pa ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitQualifiedThisReference (Java.QualifiedThisReference qtr ) { try { UnitCompiler.this.compile2(qtr ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitThisReference (Java.ThisReference tr ) { try { UnitCompiler.this.compile2(tr ); } catch (CompileException e) { throw new UCE(e); } }
-
- public void visitAmbiguousName (Java.AmbiguousName an ) { try { UnitCompiler.this.compile2(an ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitArrayAccessExpression (Java.ArrayAccessExpression aae ) { try { UnitCompiler.this.compile2(aae ); } catch (CompileException e) { throw new UCE(e); } };
- public void visitFieldAccess (Java.FieldAccess fa ) { try { UnitCompiler.this.compile2(fa ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitFieldAccessExpression (Java.FieldAccessExpression fae ) { try { UnitCompiler.this.compile2(fae ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitSuperclassFieldAccessExpression(SuperclassFieldAccessExpression scfae) { try { UnitCompiler.this.compile2(scfae); } catch (CompileException e) { throw new UCE(e); } }
- public void visitLocalVariableAccess (Java.LocalVariableAccess lva ) { try { UnitCompiler.this.compile2(lva ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitParenthesizedExpression (Java.ParenthesizedExpression pe ) { try { UnitCompiler.this.compile2(pe ); } catch (CompileException e) { throw new UCE(e); } }
- };
- try {
- rv.accept(rvv);
- } catch (UCE uce) {
- throw uce.ce;
- }
- }
- private void compile2(Java.Rvalue rv) throws CompileException {
- this.pop((Locatable) rv, this.compileGetValue(rv));
- }
- private void compile2(Java.Assignment a) throws CompileException {
- if (a.operator == "=") {
- this.compileContext(a.lhs);
- this.assignmentConversion(
- (Locatable) a, // l
- this.compileGetValue(a.rhs), // sourceType
- this.getType(a.lhs), // targetType
- this.getConstantValue(a.rhs) // optionalConstantValue
- );
- this.compileSet(a.lhs);
- return;
- }
-
- // Implement "|= ^= &= *= /= %= += -= <<= >>= >>>=".
- int lhsCS = this.compileContext(a.lhs);
- this.dup((Locatable) a, lhsCS);
- IClass lhsType = this.compileGet(a.lhs);
- IClass resultType = this.compileArithmeticBinaryOperation(
- (Locatable) a, // l
- lhsType, // lhsType
- a.operator.substring( // operator
- 0,
- a.operator.length() - 1
- ).intern(), // <= IMPORTANT!
- a.rhs // rhs
- );
- // Convert the result to LHS type (JLS2 15.26.2).
- if (
- !this.tryIdentityConversion(resultType, lhsType) &&
- !this.tryNarrowingPrimitiveConversion(
- (Locatable) a, // l
- resultType, // sourceType
- lhsType // destinationType
- )
- ) throw new RuntimeException("SNO: \"" + a.operator + "\" reconversion failed");
- this.compileSet(a.lhs);
- }
- private void compile2(Java.Crement c) throws CompileException {
-
- // Optimized crement of integer local variable.
- Java.LocalVariable lv = this.isIntLV(c);
- if (lv != null) {
- this.writeOpcode(c, Opcode.IINC);
- this.writeByte(lv.localVariableArrayIndex);
- this.writeByte(c.operator == "++" ? 1 : -1);
- return;
- }
-
- int cs = this.compileContext(c.operand);
- this.dup((Locatable) c, cs);
- IClass type = this.compileGet(c.operand);
- IClass promotedType = this.unaryNumericPromotion((Locatable) c, type);
- this.writeOpcode(c, UnitCompiler.ilfd(
- promotedType,
- Opcode.ICONST_1,
- Opcode.LCONST_1,
- Opcode.FCONST_1,
- Opcode.DCONST_1
- ));
- if (c.operator == "++") {
- this.writeOpcode(c, Opcode.IADD + UnitCompiler.ilfd(promotedType));
- } else
- if (c.operator == "--") {
- this.writeOpcode(c, Opcode.ISUB + UnitCompiler.ilfd(promotedType));
- } else {
- this.compileError("Unexpected operator \"" + c.operator + "\"", c.getLocation());
- }
-
- this.reverseUnaryNumericPromotion((Locatable) c, promotedType, type);
- this.compileSet(c.operand);
- }
- private void compile2(Java.ParenthesizedExpression pe) throws CompileException {
- this.compile(pe.value);
- }
-
- private boolean compile2(Java.AlternateConstructorInvocation aci) throws CompileException {
- Java.ConstructorDeclarator declaringConstructor = (Java.ConstructorDeclarator) aci.getEnclosingScope();
- IClass declaringIClass = this.resolve(declaringConstructor.getDeclaringClass());
-
- this.writeOpcode(aci, Opcode.ALOAD_0);
- if (declaringIClass.getOuterIClass() != null) this.writeOpcode(aci, Opcode.ALOAD_1);
- this.invokeConstructor(
- (Locatable) aci, // l
- (Java.Scope) declaringConstructor, // scope
- (Java.Rvalue) null, // optionalEnclosingInstance
- declaringIClass, // targetClass
- aci.arguments // arguments
- );
- return true;
- }
- private boolean compile2(Java.SuperConstructorInvocation sci) throws CompileException {
- Java.ConstructorDeclarator declaringConstructor = (Java.ConstructorDeclarator) sci.getEnclosingScope();
- this.writeOpcode(sci, Opcode.ALOAD_0);
- Java.ClassDeclaration declaringClass = declaringConstructor.getDeclaringClass();
- IClass superclass = this.resolve(declaringClass).getSuperclass();
-
- Java.Rvalue optionalEnclosingInstance;
- if (sci.optionalQualification != null) {
- optionalEnclosingInstance = sci.optionalQualification;
- } else {
- IClass outerIClassOfSuperclass = superclass.getOuterIClass();
- if (outerIClassOfSuperclass == null) {
- optionalEnclosingInstance = null;
- } else {
-// optionalEnclosingInstance = new Java.QualifiedThisReference(
-// sci.getLocation(), // location
-// declaringClass, // declaringClass
-// declaringConstructor, // declaringTypeBodyDeclaration
-// outerIClassOfSuperclass // targetClass
-// );
- optionalEnclosingInstance = new Java.QualifiedThisReference(
- sci.getLocation(), // location
- new Java.SimpleType( // qualification
- sci.getLocation(),
- outerIClassOfSuperclass
- )
- );
- optionalEnclosingInstance.setEnclosingBlockStatement(sci);
- }
- }
- this.invokeConstructor(
- (Locatable) sci, // l
- (Java.Scope) declaringConstructor, // scope
- optionalEnclosingInstance, // optionalEnclosingInstance
- superclass, // targetClass
- sci.arguments // arguments
- );
- return true;
- }
-
- /**
- * Some {@link Java.Rvalue}s compile more efficiently when their value is the
- * condition for a branch.<br>
- *
- * Notice that if "this" is a constant, then either "dst" is never
- * branched to, or it is unconditionally branched to. "Unexamined code"
- * errors may result during bytecode validation.
- */
- private void compileBoolean(
- Java.Rvalue rv,
- final CodeContext.Offset dst, // Where to jump.
- final boolean orientation // JUMP_IF_TRUE or JUMP_IF_FALSE.
- ) throws CompileException {
- class UCE extends RuntimeException { final CompileException ce; UCE(CompileException ce) { this.ce = ce; } }
- Visitor.RvalueVisitor rvv = new Visitor.RvalueVisitor() {
- public void visitArrayLength (Java.ArrayLength al ) { try { UnitCompiler.this.compileBoolean2(al , dst, orientation); } catch (CompileException e) { throw new UCE(e); } }
- public void visitAssignment (Java.Assignment a ) { try { UnitCompiler.this.compileBoolean2(a , dst, orientation); } catch (CompileException e) { throw new UCE(e); } }
- public void visitUnaryOperation (Java.UnaryOperation uo ) { try { UnitCompiler.this.compileBoolean2(uo , dst, orientation); } catch (CompileException e) { throw new UCE(e); } }
- public void visitBinaryOperation (Java.BinaryOperation bo ) { try { UnitCompiler.this.compileBoolean2(bo , dst, orientation); } catch (CompileException e) { throw new UCE(e); } }
- public void visitCast (Java.Cast c ) { try { UnitCompiler.this.compileBoolean2(c , dst, orientation); } catch (CompileException e) { throw new UCE(e); } }
- public void visitClassLiteral (Java.ClassLiteral cl ) { try { UnitCompiler.this.compileBoolean2(cl , dst, orientation); } catch (CompileException e) { throw new UCE(e); } }
- public void visitConditionalExpression (Java.ConditionalExpression ce ) { try { UnitCompiler.this.compileBoolean2(ce , dst, orientation); } catch (CompileException e) { throw new UCE(e); } }
- public void visitCrement (Java.Crement c ) { try { UnitCompiler.this.compileBoolean2(c , dst, orientation); } catch (CompileException e) { throw new UCE(e); } }
- public void visitInstanceof (Java.Instanceof io ) { try { UnitCompiler.this.compileBoolean2(io , dst, orientation); } catch (CompileException e) { throw new UCE(e); } }
- public void visitMethodInvocation (Java.MethodInvocation mi ) { try { UnitCompiler.this.compileBoolean2(mi , dst, orientation); } catch (CompileException e) { throw new UCE(e); } }
- public void visitSuperclassMethodInvocation (Java.SuperclassMethodInvocation smi ) { try { UnitCompiler.this.compileBoolean2(smi , dst, orientation); } catch (CompileException e) { throw new UCE(e); } }
- public void visitLiteral (Java.Literal l ) { try { UnitCompiler.this.compileBoolean2(l , dst, orientation); } catch (CompileException e) { throw new UCE(e); } }
- public void visitNewAnonymousClassInstance (Java.NewAnonymousClassInstance naci) { try { UnitCompiler.this.compileBoolean2(naci, dst, orientation); } catch (CompileException e) { throw new UCE(e); } }
- public void visitNewArray (Java.NewArray na ) { try { UnitCompiler.this.compileBoolean2(na , dst, orientation); } catch (CompileException e) { throw new UCE(e); } }
- public void visitNewInitializedArray (Java.NewInitializedArray nia ) { try { UnitCompiler.this.compileBoolean2(nia , dst, orientation); } catch (CompileException e) { throw new UCE(e); } }
- public void visitNewClassInstance (Java.NewClassInstance nci ) { try { UnitCompiler.this.compileBoolean2(nci , dst, orientation); } catch (CompileException e) { throw new UCE(e); } }
- public void visitParameterAccess (Java.ParameterAccess pa ) { try { UnitCompiler.this.compileBoolean2(pa , dst, orientation); } catch (CompileException e) { throw new UCE(e); } }
- public void visitQualifiedThisReference (Java.QualifiedThisReference qtr ) { try { UnitCompiler.this.compileBoolean2(qtr , dst, orientation); } catch (CompileException e) { throw new UCE(e); } }
- public void visitThisReference (Java.ThisReference tr ) { try { UnitCompiler.this.compileBoolean2(tr , dst, orientation); } catch (CompileException e) { throw new UCE(e); } }
-
- public void visitAmbiguousName (Java.AmbiguousName an ) { try { UnitCompiler.this.compileBoolean2(an , dst, orientation); } catch (CompileException e) { throw new UCE(e); } }
- public void visitArrayAccessExpression (Java.ArrayAccessExpression aae ) { try { UnitCompiler.this.compileBoolean2(aae , dst, orientation); } catch (CompileException e) { throw new UCE(e); } };
- public void visitFieldAccess (Java.FieldAccess fa ) { try { UnitCompiler.this.compileBoolean2(fa , dst, orientation); } catch (CompileException e) { throw new UCE(e); } }
- public void visitFieldAccessExpression (Java.FieldAccessExpression fae ) { try { UnitCompiler.this.compileBoolean2(fae , dst, orientation); } catch (CompileException e) { throw new UCE(e); } }
- public void visitSuperclassFieldAccessExpression(Java.SuperclassFieldAccessExpression scfae) { try { UnitCompiler.this.compileBoolean2(scfae, dst, orientation); } catch (CompileException e) { throw new UCE(e); } }
- public void visitLocalVariableAccess (Java.LocalVariableAccess lva ) { try { UnitCompiler.this.compileBoolean2(lva , dst, orientation); } catch (CompileException e) { throw new UCE(e); } }
- public void visitParenthesizedExpression (Java.ParenthesizedExpression pe ) { try { UnitCompiler.this.compileBoolean2(pe , dst, orientation); } catch (CompileException e) { throw new UCE(e); } }
- };
- try {
- rv.accept(rvv);
- } catch (UCE uce) {
- throw uce.ce;
- }
- }
- private void compileBoolean2(
- Java.Rvalue rv,
- CodeContext.Offset dst, // Where to jump.
- boolean orientation // JUMP_IF_TRUE or JUMP_IF_FALSE.
- ) throws CompileException {
- IClass type = this.compileGetValue(rv);
- IClassLoader icl = this.iClassLoader;
- if (type == icl.BOOLEAN) {
- this.unboxingConversion((Locatable) rv, icl.BOOLEAN, IClass.BOOLEAN);
- } else
- if (type != IClass.BOOLEAN) {
- this.compileError("Not a boolean expression", rv.getLocation());
- }
- this.writeBranch(rv, orientation == Java.Rvalue.JUMP_IF_TRUE ? Opcode.IFNE : Opcode.IFEQ, dst);
- }
- private void compileBoolean2(
- Java.UnaryOperation ue,
- CodeContext.Offset dst, // Where to jump.
- boolean orientation // JUMP_IF_TRUE or JUMP_IF_FALSE.
- ) throws CompileException {
- if (ue.operator == "!") {
- this.compileBoolean(ue.operand, dst, !orientation);
- return;
- }
-
- this.compileError("Boolean expression expected", ue.getLocation());
- }
- private void compileBoolean2(
- Java.BinaryOperation bo,
- CodeContext.Offset dst, // Where to jump.
- boolean orientation // JUMP_IF_TRUE or JUMP_IF_FALSE.
- ) throws CompileException {
-
- if (bo.op == "|" || bo.op == "^" || bo.op == "&") {
- this.compileBoolean2((Java.Rvalue) bo, dst, orientation);
- return;
- }
-
- if (bo.op == "||" || bo.op == "&&") {
- Object lhsCV = this.getConstantValue(bo.lhs);
- if (lhsCV instanceof Boolean) {
- if (((Boolean) lhsCV).booleanValue() ^ bo.op == "||") {
- // "true && a", "false || a"
- this.compileBoolean(bo.rhs, dst, Java.Rvalue.JUMP_IF_TRUE ^ orientation == Java.Rvalue.JUMP_IF_FALSE);
- } else {
- // "false && a", "true || a"
- this.compileBoolean(bo.lhs, dst, Java.Rvalue.JUMP_IF_TRUE ^ orientation == Java.Rvalue.JUMP_IF_FALSE);
- this.fakeCompile(bo.rhs);
- }
- return;
- }
- Object rhsCV = this.getConstantValue(bo.rhs);
- if (rhsCV instanceof Boolean) {
- if (((Boolean) rhsCV).booleanValue() ^ bo.op == "||") {
- // "a && true", "a || false"
- this.compileBoolean(bo.lhs, dst, Java.Rvalue.JUMP_IF_TRUE ^ orientation == Java.Rvalue.JUMP_IF_FALSE);
- } else {
- // "a && false", "a || true"
- this.pop((Locatable) bo.lhs, this.compileGetValue(bo.lhs));
- this.compileBoolean(bo.rhs, dst, Java.Rvalue.JUMP_IF_TRUE ^ orientation == Java.Rvalue.JUMP_IF_FALSE);
- }
- return;
- }
- if (bo.op == "||" ^ orientation == Java.Rvalue.JUMP_IF_FALSE) {
- this.compileBoolean(bo.lhs, dst, Java.Rvalue.JUMP_IF_TRUE ^ orientation == Java.Rvalue.JUMP_IF_FALSE);
- this.compileBoolean(bo.rhs, dst, Java.Rvalue.JUMP_IF_TRUE ^ orientation == Java.Rvalue.JUMP_IF_FALSE);
- } else {
- CodeContext.Offset end = this.codeContext.new Offset();
- this.compileBoolean(bo.lhs, end, Java.Rvalue.JUMP_IF_FALSE ^ orientation == Java.Rvalue.JUMP_IF_FALSE);
- this.compileBoolean(bo.rhs, dst, Java.Rvalue.JUMP_IF_TRUE ^ orientation == Java.Rvalue.JUMP_IF_FALSE);
- end.set();
- }
- return;
- }
-
- if (
- bo.op == "==" ||
- bo.op == "!=" ||
- bo.op == "<=" ||
- bo.op == ">=" ||
- bo.op == "<" ||
- bo.op == ">"
- ) {
- int opIdx = (
- bo.op == "==" ? 0 :
- bo.op == "!=" ? 1 :
- bo.op == "<" ? 2 :
- bo.op == ">=" ? 3 :
- bo.op == ">" ? 4 :
- bo.op == "<=" ? 5 : Integer.MIN_VALUE
- );
- if (orientation == Java.Rvalue.JUMP_IF_FALSE) opIdx ^= 1;
-
- // Comparison with "null".
- {
- boolean lhsIsNull = this.getConstantValue(bo.lhs) == Java.Rvalue.CONSTANT_VALUE_NULL;
- boolean rhsIsNull = this.getConstantValue(bo.rhs) == Java.Rvalue.CONSTANT_VALUE_NULL;
-
- if (lhsIsNull || rhsIsNull) {
- if (bo.op != "==" && bo.op != "!=") this.compileError("Operator \"" + bo.op + "\" not allowed on operand \"null\"", bo.getLocation());
-
- // null == x
- // x == null
- IClass ohsType = this.compileGetValue(lhsIsNull ? bo.rhs : bo.lhs);
- if (ohsType.isPrimitive()) this.compileError("Cannot compare \"null\" with primitive type \"" + ohsType.toString() + "\"", bo.getLocation());
- this.writeBranch(bo, Opcode.IFNULL + opIdx, dst);
- return;
- }
- }
-
- IClass lhsType = this.compileGetValue(bo.lhs);
- CodeContext.Inserter convertLhsInserter = this.codeContext.newInserter();
- IClass rhsType = this.compileGetValue(bo.rhs);
-
- // 15.20.1 Numerical comparison.
- if (
- this.getUnboxedType(lhsType).isPrimitiveNumeric() &&
- this.getUnboxedType(rhsType).isPrimitiveNumeric() &&
- !((bo.op == "==" || bo.op == "!=") && !lhsType.isPrimitive() && !rhsType.isPrimitive())
- ) {
- IClass promotedType = this.binaryNumericPromotion((Locatable) bo, lhsType, convertLhsInserter, rhsType);
- if (promotedType == IClass.INT) {
- this.writeBranch(bo, Opcode.IF_ICMPEQ + opIdx, dst);
- } else
- if (promotedType == IClass.LONG) {
- this.writeOpcode(bo, Opcode.LCMP);
- this.writeBranch(bo, Opcode.IFEQ + opIdx, dst);
- } else
- if (promotedType == IClass.FLOAT) {
- this.writeOpcode(bo, Opcode.FCMPG);
- this.writeBranch(bo, Opcode.IFEQ + opIdx, dst);
- } else
- if (promotedType == IClass.DOUBLE) {
- this.writeOpcode(bo, Opcode.DCMPG);
- this.writeBranch(bo, Opcode.IFEQ + opIdx, dst);
- } else
- {
- throw new RuntimeException("Unexpected promoted type \"" + promotedType + "\"");
- }
- return;
- }
-
- // JLS3 15.21.2 Boolean Equality Operators == and !=
- if (
- (lhsType == IClass.BOOLEAN && this.getUnboxedType(rhsType) == IClass.BOOLEAN) ||
- (rhsType == IClass.BOOLEAN && this.getUnboxedType(lhsType) == IClass.BOOLEAN)
- ) {
- if (bo.op != "==" && bo.op != "!=") this.compileError("Operator \"" + bo.op + "\" not allowed on boolean operands", bo.getLocation());
- IClassLoader icl = this.iClassLoader;
-
- // Unbox LHS if necessary.
- if (lhsType == icl.BOOLEAN) {
- this.codeContext.pushInserter(convertLhsInserter);
- try {
- this.unboxingConversion((Locatable) bo, icl.BOOLEAN, IClass.BOOLEAN);
- } finally {
- this.codeContext.popInserter();
- }
- }
-
- // Unbox RHS if necessary.
- if (rhsType == icl.BOOLEAN) {
- this.unboxingConversion((Locatable) bo, icl.BOOLEAN, IClass.BOOLEAN);
- }
-
- this.writeBranch(bo, Opcode.IF_ICMPEQ + opIdx, dst);
- return;
- }
-
- // Reference comparison.
- // Note: Comparison with "null" is already handled above.
- if (
- !lhsType.isPrimitive() &&
- !rhsType.isPrimitive()
- ) {
- if (bo.op != "==" && bo.op != "!=") this.compileError("Operator \"" + bo.op + "\" not allowed on reference operands", bo.getLocation());
- this.writeBranch(bo, Opcode.IF_ACMPEQ + opIdx, dst);
- return;
- }
-
- this.compileError("Cannot compare types \"" + lhsType + "\" and \"" + rhsType + "\"", bo.getLocation());
- }
-
- this.compileError("Boolean expression expected", bo.getLocation());
- }
- private void compileBoolean2(
- Java.ParenthesizedExpression pe,
- CodeContext.Offset dst,
- boolean orientation
- ) throws CompileException {
- this.compileBoolean(pe.value, dst, orientation);
- }
-
- /**
- * Generates code that determines the context of the {@link
- * Java.Rvalue} and puts it on the operand stack. Most expressions
- * do not have a "context", but some do. E.g. for "x[y]", the context
- * is "x, y". The bottom line is that for statements like "x[y] += 3"
- * the context is only evaluated once.
- *
- * @return The size of the context on the operand stack
- */
- private int compileContext(Java.Rvalue rv) throws CompileException {
- final int[] res = new int[1];
- class UCE extends RuntimeException { final CompileException ce; UCE(CompileException ce) { this.ce = ce; } }
- Visitor.RvalueVisitor rvv = new Visitor.RvalueVisitor() {
- public void visitArrayLength (Java.ArrayLength al ) { try { res[0] = UnitCompiler.this.compileContext2(al ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitAssignment (Java.Assignment a ) { res[0] = UnitCompiler.this.compileContext2(a ); }
- public void visitUnaryOperation (Java.UnaryOperation uo ) { res[0] = UnitCompiler.this.compileContext2(uo ); }
- public void visitBinaryOperation (Java.BinaryOperation bo ) { res[0] = UnitCompiler.this.compileContext2(bo ); }
- public void visitCast (Java.Cast c ) { res[0] = UnitCompiler.this.compileContext2(c ); }
- public void visitClassLiteral (Java.ClassLiteral cl ) { res[0] = UnitCompiler.this.compileContext2(cl ); }
- public void visitConditionalExpression (Java.ConditionalExpression ce ) { res[0] = UnitCompiler.this.compileContext2(ce ); }
- public void visitCrement (Java.Crement c ) { res[0] = UnitCompiler.this.compileContext2(c ); }
- public void visitInstanceof (Java.Instanceof io ) { res[0] = UnitCompiler.this.compileContext2(io ); }
- public void visitMethodInvocation (Java.MethodInvocation mi ) { res[0] = UnitCompiler.this.compileContext2(mi ); }
- public void visitSuperclassMethodInvocation (Java.SuperclassMethodInvocation smi ) { res[0] = UnitCompiler.this.compileContext2(smi ); }
- public void visitLiteral (Java.Literal l ) { res[0] = UnitCompiler.this.compileContext2(l ); }
- public void visitNewAnonymousClassInstance (Java.NewAnonymousClassInstance naci) { res[0] = UnitCompiler.this.compileContext2(naci); }
- public void visitNewArray (Java.NewArray na ) { res[0] = UnitCompiler.this.compileContext2(na ); }
- public void visitNewInitializedArray (Java.NewInitializedArray nia ) { res[0] = UnitCompiler.this.compileContext2(nia ); }
- public void visitNewClassInstance (Java.NewClassInstance nci ) { res[0] = UnitCompiler.this.compileContext2(nci ); }
- public void visitParameterAccess (Java.ParameterAccess pa ) { res[0] = UnitCompiler.this.compileContext2(pa ); }
- public void visitQualifiedThisReference (Java.QualifiedThisReference qtr ) { res[0] = UnitCompiler.this.compileContext2(qtr ); }
- public void visitThisReference (Java.ThisReference tr ) { res[0] = UnitCompiler.this.compileContext2(tr ); }
-
- public void visitAmbiguousName (Java.AmbiguousName an ) { try { res[0] = UnitCompiler.this.compileContext2(an ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitArrayAccessExpression (Java.ArrayAccessExpression aae ) { try { res[0] = UnitCompiler.this.compileContext2(aae ); } catch (CompileException e) { throw new UCE(e); } };
- public void visitFieldAccess (Java.FieldAccess fa ) { try { res[0] = UnitCompiler.this.compileContext2(fa ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitFieldAccessExpression (Java.FieldAccessExpression fae ) { try { res[0] = UnitCompiler.this.compileContext2(fae ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitSuperclassFieldAccessExpression(Java.SuperclassFieldAccessExpression scfae) { try { res[0] = UnitCompiler.this.compileContext2(scfae); } catch (CompileException e) { throw new UCE(e); } }
- public void visitLocalVariableAccess (Java.LocalVariableAccess lva ) { res[0] = UnitCompiler.this.compileContext2(lva ); }
- public void visitParenthesizedExpression (Java.ParenthesizedExpression pe ) { try { res[0] = UnitCompiler.this.compileContext2(pe ); } catch (CompileException e) { throw new UCE(e); } }
- };
- try {
- rv.accept(rvv);
- return res[0];
- } catch (UCE uce) {
- throw uce.ce;
- }
- }
- private int compileContext2(Java.Rvalue rv) {
- return 0;
- }
- private int compileContext2(Java.AmbiguousName an) throws CompileException {
- return this.compileContext(this.toRvalueOrCE(this.reclassify(an)));
- }
- private int compileContext2(Java.FieldAccess fa) throws CompileException {
- if (fa.field.isStatic()) {
- this.getType(this.toTypeOrCE(fa.lhs));
- return 0;
- } else {
- this.compileGetValue(this.toRvalueOrCE(fa.lhs));
- return 1;
- }
- }
- private int compileContext2(Java.ArrayLength al) throws CompileException {
- if (!this.compileGetValue(al.lhs).isArray()) this.compileError("Cannot determine length of non-array type", al.getLocation());
- return 1;
- }
- private int compileContext2(Java.ArrayAccessExpression aae) throws CompileException {
- IClass lhsType = this.compileGetValue(aae.lhs);
- if (!lhsType.isArray()) this.compileError("Subscript not allowed on non-array type \"" + lhsType.toString() + "\"", aae.getLocation());
-
- IClass indexType = this.compileGetValue(aae.index);
- if (
- !this.tryIdentityConversion(indexType, IClass.INT) &&
- !this.tryWideningPrimitiveConversion(
- (Locatable) aae, // l
- indexType, // sourceType
- IClass.INT // targetType
- )
- ) this.compileError("Index expression of type \"" + indexType + "\" cannot be widened to \"int\"", aae.getLocation());
-
- return 2;
- }
- private int compileContext2(Java.FieldAccessExpression fae) throws CompileException {
- this.determineValue(fae);
- return this.compileContext(fae.value);
- }
- private int compileContext2(Java.SuperclassFieldAccessExpression scfae) throws CompileException {
- this.determineValue(scfae);
- return this.compileContext(scfae.value);
- }
- private int compileContext2(Java.ParenthesizedExpression pe) throws CompileException {
- return this.compileContext(pe.value);
- }
-
- /**
- * Generates code that determines the value of the {@link Java.Rvalue}
- * and puts it on the operand stack. This method relies on that the
- * "context" of the {@link Java.Rvalue} is on top of the operand stack
- * (see {@link #compileContext(Java.Rvalue)}).
- *
- * @return The type of the {@link Java.Rvalue}
- */
- private IClass compileGet(Java.Rvalue rv) throws CompileException {
- final IClass[] res = new IClass[1];
- class UCE extends RuntimeException { final CompileException ce; UCE(CompileException ce) { this.ce = ce; } }
- Visitor.RvalueVisitor rvv = new Visitor.RvalueVisitor() {
- public void visitArrayLength (Java.ArrayLength al ) { res[0] = UnitCompiler.this.compileGet2(al ); }
- public void visitAssignment (Java.Assignment a ) { try { res[0] = UnitCompiler.this.compileGet2(a ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitUnaryOperation (Java.UnaryOperation uo ) { try { res[0] = UnitCompiler.this.compileGet2(uo ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitBinaryOperation (Java.BinaryOperation bo ) { try { res[0] = UnitCompiler.this.compileGet2(bo ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitCast (Java.Cast c ) { try { res[0] = UnitCompiler.this.compileGet2(c ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitClassLiteral (Java.ClassLiteral cl ) { try { res[0] = UnitCompiler.this.compileGet2(cl ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitConditionalExpression (Java.ConditionalExpression ce ) { try { res[0] = UnitCompiler.this.compileGet2(ce ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitCrement (Java.Crement c ) { try { res[0] = UnitCompiler.this.compileGet2(c ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitInstanceof (Java.Instanceof io ) { try { res[0] = UnitCompiler.this.compileGet2(io ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitMethodInvocation (Java.MethodInvocation mi ) { try { res[0] = UnitCompiler.this.compileGet2(mi ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitSuperclassMethodInvocation (Java.SuperclassMethodInvocation smi ) { try { res[0] = UnitCompiler.this.compileGet2(smi ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitLiteral (Java.Literal l ) { try { res[0] = UnitCompiler.this.compileGet2(l ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitNewAnonymousClassInstance (Java.NewAnonymousClassInstance naci) { try { res[0] = UnitCompiler.this.compileGet2(naci); } catch (CompileException e) { throw new UCE(e); } }
- public void visitNewArray (Java.NewArray na ) { try { res[0] = UnitCompiler.this.compileGet2(na ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitNewInitializedArray (Java.NewInitializedArray nia ) { try { res[0] = UnitCompiler.this.compileGet2(nia ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitNewClassInstance (Java.NewClassInstance nci ) { try { res[0] = UnitCompiler.this.compileGet2(nci ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitParameterAccess (Java.ParameterAccess pa ) { try { res[0] = UnitCompiler.this.compileGet2(pa ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitQualifiedThisReference (Java.QualifiedThisReference qtr ) { try { res[0] = UnitCompiler.this.compileGet2(qtr ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitThisReference (Java.ThisReference tr ) { try { res[0] = UnitCompiler.this.compileGet2(tr ); } catch (CompileException e) { throw new UCE(e); } }
-
- public void visitAmbiguousName (Java.AmbiguousName an ) { try { res[0] = UnitCompiler.this.compileGet2(an ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitArrayAccessExpression (Java.ArrayAccessExpression aae ) { try { res[0] = UnitCompiler.this.compileGet2(aae ); } catch (CompileException e) { throw new UCE(e); } };
- public void visitFieldAccess (Java.FieldAccess fa ) { try { res[0] = UnitCompiler.this.compileGet2(fa ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitFieldAccessExpression (Java.FieldAccessExpression fae ) { try { res[0] = UnitCompiler.this.compileGet2(fae ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitSuperclassFieldAccessExpression(Java.SuperclassFieldAccessExpression scfae) { try { res[0] = UnitCompiler.this.compileGet2(scfae); } catch (CompileException e) { throw new UCE(e); } }
- public void visitLocalVariableAccess (Java.LocalVariableAccess lva ) { res[0] = UnitCompiler.this.compileGet2(lva ); }
- public void visitParenthesizedExpression (Java.ParenthesizedExpression pe ) { try { res[0] = UnitCompiler.this.compileGet2(pe ); } catch (CompileException e) { throw new UCE(e); } }
- };
- try {
- rv.accept(rvv);
- return res[0];
- } catch (UCE uce) {
- throw uce.ce;
- }
- }
- private IClass compileGet2(Java.BooleanRvalue brv) throws CompileException {
- CodeContext.Offset isTrue = this.codeContext.new Offset();
- this.compileBoolean(brv, isTrue, Java.Rvalue.JUMP_IF_TRUE);
- this.writeOpcode(brv, Opcode.ICONST_0);
- CodeContext.Offset end = this.codeContext.new Offset();
- this.writeBranch(brv, Opcode.GOTO, end);
- isTrue.set();
- this.writeOpcode(brv, Opcode.ICONST_1);
- end.set();
-
- return IClass.BOOLEAN;
- }
- private IClass compileGet2(Java.AmbiguousName an) throws CompileException {
- return this.compileGet(this.toRvalueOrCE(this.reclassify(an)));
- }
- private IClass compileGet2(Java.LocalVariableAccess lva) {
- return this.load((Locatable) lva, lva.localVariable);
- }
- private IClass compileGet2(Java.FieldAccess fa) throws CompileException {
- this.checkAccessible(fa.field, fa.getEnclosingBlockStatement());
- if (fa.field.isStatic()) {
- this.writeOpcode(fa, Opcode.GETSTATIC);
- } else {
- this.writeOpcode(fa, Opcode.GETFIELD);
- }
- this.writeConstantFieldrefInfo(
- fa.field.getDeclaringIClass().getDescriptor(),
- fa.field.getName(), // classFD
- fa.field.getType().getDescriptor() // fieldFD
- );
- return fa.field.getType();
- }
- private IClass compileGet2(Java.ArrayLength al) {
- this.writeOpcode(al, Opcode.ARRAYLENGTH);
- return IClass.INT;
- }
- private IClass compileGet2(Java.ThisReference tr) throws CompileException {
- this.referenceThis((Locatable) tr);
- return this.getIClass(tr);
- }
- private IClass compileGet2(Java.QualifiedThisReference qtr) throws CompileException {
- this.referenceThis(
- (Locatable) qtr, // l
- this.getDeclaringClass(qtr), // declaringClass
- this.getDeclaringTypeBodyDeclaration(qtr), // declaringTypeBodyDeclaration
- this.getTargetIClass(qtr) // targetIClass
- );
- return this.getTargetIClass(qtr);
- }
- private IClass compileGet2(Java.ClassLiteral cl) throws CompileException {
- Location loc = cl.getLocation();
- final IClassLoader icl = this.iClassLoader;
- IClass iClass = this.getType(cl.type);
-
- if (iClass.isPrimitive()) {
-
- // Primitive class literal.
- this.writeOpcode(cl, Opcode.GETSTATIC);
- String wrapperClassDescriptor = (
- iClass == IClass.VOID ? "Ljava/lang/Void;" :
- iClass == IClass.BYTE ? "Ljava/lang/Byte;" :
- iClass == IClass.CHAR ? "Ljava/lang/Character;" :
- iClass == IClass.DOUBLE ? "Ljava/lang/Double;" :
- iClass == IClass.FLOAT ? "Ljava/lang/Float;" :
- iClass == IClass.INT ? "Ljava/lang/Integer;" :
- iClass == IClass.LONG ? "Ljava/lang/Long;" :
- iClass == IClass.SHORT ? "Ljava/lang/Short;" :
- iClass == IClass.BOOLEAN ? "Ljava/lang/Boolean;" :
- null
- );
- if (wrapperClassDescriptor == null) throw new RuntimeException("SNO: Unidentifiable primitive type \"" + iClass + "\"");
-
- this.writeConstantFieldrefInfo(
- wrapperClassDescriptor,
- "TYPE", // classFD
- "Ljava/lang/Class;" // fieldFD
- );
- return icl.CLASS;
- }
-
- // Non-primitive class literal.
-
- Java.AbstractTypeDeclaration declaringType;
- for (Java.Scope s = cl.getEnclosingBlockStatement();; s = s.getEnclosingScope()) {
- if (s instanceof Java.TypeDeclaration) {
- declaringType = (Java.AbstractTypeDeclaration) s;
- break;
- }
- }
-
- // Check if synthetic method "static Class class$(String className)" is already
- // declared.
- if (declaringType.getMethodDeclaration("class$") == null) this.declareClassDollarMethod(cl);
-
- // Determine the statics of the declaring class (this is where static fields
- // declarations are found).
- List statics; // TypeBodyDeclaration
- if (declaringType instanceof Java.ClassDeclaration) {
- statics = ((Java.ClassDeclaration) declaringType).variableDeclaratorsAndInitializers;
- } else
- if (declaringType instanceof Java.InterfaceDeclaration) {
- statics = ((Java.InterfaceDeclaration) declaringType).constantDeclarations;
- } else {
- throw new RuntimeException("SNO: AbstractTypeDeclaration is neither ClassDeclaration nor InterfaceDeclaration");
- }
-
- String className = Descriptor.toClassName(iClass.getDescriptor());
-
- // Compose the "class-dollar" field name. This i done as follows:
- // Type Class-name Field-name
- // String java.lang.String class$java$lang$String
- // String[] [Ljava.lang.String; array$Ljava$lang$String
- // String[][] [[Ljava.lang.String; array$$Ljava$lang$String
- // String[][][] [[[java.lang.String; array$$$Ljava$lang$String
- // int[] [I array$I
- // int[][] [[I array$$I
- String classDollarFieldName;
- {
- if (className.startsWith("[")) {
- classDollarFieldName = "array" + className.replace('.', '$').replace('[', '$');
- if (classDollarFieldName.endsWith(";")) classDollarFieldName = classDollarFieldName.substring(0, classDollarFieldName.length() - 1);
- } else
- {
- classDollarFieldName = "class$" + className.replace('.', '$');
- }
- }
-
- // Declare the static "class dollar field" if not already done.
- {
- boolean hasClassDollarField = false;
- BLOCK_STATEMENTS: for (Iterator it = statics.iterator(); it.hasNext();) {
- Java.TypeBodyDeclaration tbd = (Java.TypeBodyDeclaration) it.next();
- if (!tbd.isStatic()) continue;
- if (tbd instanceof Java.FieldDeclaration) {
- Java.FieldDeclaration fd = (Java.FieldDeclaration) tbd;
- IClass.IField[] fds = this.getIFields(fd);
- for (int j = 0; j < fds.length; ++j) {
- if (fds[j].getName().equals(classDollarFieldName)) {
- hasClassDollarField = true;
- break BLOCK_STATEMENTS;
- }
- }
- }
- }
- if (!hasClassDollarField) {
- Java.Type classType = new Java.SimpleType(loc, icl.CLASS);
- Java.FieldDeclaration fd = new Java.FieldDeclaration(
- loc, // location
- null, // optionalDocComment
- Mod.STATIC, // modifiers
- classType, // type
- new Java.VariableDeclarator[] { // variableDeclarators
- new Java.VariableDeclarator(
- loc, // location
- classDollarFieldName, // name
- 0, // brackets
- (Java.Rvalue) null // optionalInitializer
- )
- }
- );
- if (declaringType instanceof Java.ClassDeclaration) {
- ((Java.ClassDeclaration) declaringType).addVariableDeclaratorOrInitializer(fd);
- } else
- if (declaringType instanceof Java.InterfaceDeclaration) {
- ((Java.InterfaceDeclaration) declaringType).addConstantDeclaration(fd);
- } else {
- throw new RuntimeException("SNO: AbstractTypeDeclaration is neither ClassDeclaration nor InterfaceDeclaration");
- }
- }
- }
-
- // return (class$X != null) ? class$X : (class$X = class$("X"));
- Java.Type declaringClassOrInterfaceType = new Java.SimpleType(loc, this.resolve(declaringType));
- Java.Lvalue classDollarFieldAccess = new Java.FieldAccessExpression(
- loc, // location
- declaringClassOrInterfaceType, // lhs
- classDollarFieldName // fieldName
- );
- Java.ConditionalExpression ce = new Java.ConditionalExpression(
- loc, // location
- new Java.BinaryOperation( // lhs
- loc, // location
- classDollarFieldAccess, // lhs
- "!=", // op
- new Java.Literal(loc, null) // rhs
- ),
- classDollarFieldAccess, // mhs
- new Java.Assignment( // rhs
- loc, // location
- classDollarFieldAccess, // lhs
- "=", // operator
- new Java.MethodInvocation( // rhs
- loc, // location
- declaringClassOrInterfaceType, // optionalTarget
- "class$", // methodName
- new Java.Rvalue[] { // arguments
- new Java.Literal(
- loc, // location
- className // constantValue
- )
- }
- )
- )
- );
- ce.setEnclosingBlockStatement(cl.getEnclosingBlockStatement());
- return this.compileGet(ce);
- }
- private IClass compileGet2(Java.Assignment a) throws CompileException {
- if (a.operator == "=") {
- int lhsCS = this.compileContext(a.lhs);
- IClass rhsType = this.compileGetValue(a.rhs);
- IClass lhsType = this.getType(a.lhs);
- Object rhsCV = this.getConstantValue(a.rhs);
- this.assignmentConversion(
- (Locatable) a, // l
- rhsType, // sourceType
- lhsType, // targetType
- rhsCV // optionalConstantValue
- );
- this.dupx(
- (Locatable) a, // l
- lhsType, // type
- lhsCS // x
- );
- this.compileSet(a.lhs);
- return lhsType;
- }
-
- // Implement "|= ^= &= *= /= %= += -= <<= >>= >>>=".
- int lhsCS = this.compileContext(a.lhs);
- this.dup((Locatable) a, lhsCS);
- IClass lhsType = this.compileGet(a.lhs);
- IClass resultType = this.compileArithmeticBinaryOperation(
- (Locatable) a, // l
- lhsType, // lhsType
- a.operator.substring( // operator
- 0,
- a.operator.length() - 1
- ).intern(), // <= IMPORTANT!
- a.rhs // rhs
- );
- // Convert the result to LHS type (JLS2 15.26.2).
- if (
- !this.tryIdentityConversion(resultType, lhsType) &&
- !this.tryNarrowingPrimitiveConversion(
- (Locatable) a, // l
- resultType, // sourceType
- lhsType // destinationType
- )
- ) throw new RuntimeException("SNO: \"" + a.operator + "\" reconversion failed");
- this.dupx(
- (Locatable) a, // l
- lhsType, // type
- lhsCS // x
- );
- this.compileSet(a.lhs);
- return lhsType;
- }
- private IClass compileGet2(Java.ConditionalExpression ce) throws CompileException {
- IClass mhsType, rhsType;
- CodeContext.Inserter mhsConvertInserter, rhsConvertInserter;
- CodeContext.Offset toEnd = this.codeContext.new Offset();
- Object cv = this.getConstantValue(ce.lhs);
- if (cv instanceof Boolean) {
- if (((Boolean) cv).booleanValue()) {
- mhsType = this.compileGetValue(ce.mhs);
- mhsConvertInserter = this.codeContext.newInserter();
- rhsType = this.getType(ce.rhs);
- rhsConvertInserter = null;
- } else {
- mhsType = this.getType(ce.mhs);
- mhsConvertInserter = null;
- rhsType = this.compileGetValue(ce.rhs);
- rhsConvertInserter = this.codeContext.currentInserter();
- }
- } else {
- CodeContext.Offset toRhs = this.codeContext.new Offset();
-
- this.compileBoolean(ce.lhs, toRhs, Java.Rvalue.JUMP_IF_FALSE);
- mhsType = this.compileGetValue(ce.mhs);
- mhsConvertInserter = this.codeContext.newInserter();
- this.writeBranch(ce, Opcode.GOTO, toEnd);
- toRhs.set();
- rhsType = this.compileGetValue(ce.rhs);
- rhsConvertInserter = this.codeContext.currentInserter();
- }
-
- IClass expressionType;
- if (mhsType == rhsType) {
-
- // JLS 15.25.1.1
- expressionType = mhsType;
- } else
- if (mhsType.isPrimitiveNumeric() && rhsType.isPrimitiveNumeric()) {
-
- // JLS 15.25.1.2
-
- // TODO JLS 15.25.1.2.1
-
- // TODO JLS 15.25.1.2.2
-
- // JLS 15.25.1.2.3
- expressionType = this.binaryNumericPromotion(
- (Locatable) ce, // l
- mhsType, // type1
- mhsConvertInserter, // convertInserter1
- rhsType, // type2
- rhsConvertInserter // convertInserter2
- );
- } else
- if (this.getConstantValue(ce.mhs) == Java.Rvalue.CONSTANT_VALUE_NULL && !rhsType.isPrimitive()) {
-
- // JLS 15.25.1.3 (null : ref)
- expressionType = rhsType;
- } else
- if (!mhsType.isPrimitive() && this.getConstantValue(ce.rhs) == Java.Rvalue.CONSTANT_VALUE_NULL) {
-
- // JLS 15.25.1.3 (ref : null)
- expressionType = mhsType;
- } else
- if (!mhsType.isPrimitive() && !rhsType.isPrimitive()) {
- if (mhsType.isAssignableFrom(rhsType)) {
- expressionType = mhsType;
- } else
- if (rhsType.isAssignableFrom(mhsType)) {
- expressionType = rhsType;
- } else {
- this.compileError("Reference types \"" + mhsType + "\" and \"" + rhsType + "\" don't match", ce.getLocation());
- return this.iClassLoader.OBJECT;
- }
- } else
- {
- this.compileError("Incompatible expression types \"" + mhsType + "\" and \"" + rhsType + "\"", ce.getLocation());
- return this.iClassLoader.OBJECT;
- }
- toEnd.set();
-
- return expressionType;
- }
- private IClass compileGet2(Java.Crement c) throws CompileException {
-
- // Optimized crement of integer local variable.
- Java.LocalVariable lv = this.isIntLV(c);
- if (lv != null) {
- if (!c.pre) this.load((Locatable) c, lv);
- this.writeOpcode(c, Opcode.IINC);
- this.writeByte(lv.localVariableArrayIndex);
- this.writeByte(c.operator == "++" ? 1 : -1);
- if (c.pre) this.load((Locatable) c, lv);
- return lv.type;
- }
-
- // Compile operand context.
- int cs = this.compileContext(c.operand);
- // DUP operand context.
- this.dup((Locatable) c, cs);
- // Get operand value.
- IClass type = this.compileGet(c.operand);
- // DUPX operand value.
- if (!c.pre) this.dupx((Locatable) c, type, cs);
- // Apply "unary numeric promotion".
- IClass promotedType = this.unaryNumericPromotion((Locatable) c, type);
- // Crement.
- this.writeOpcode(c, UnitCompiler.ilfd(
- promotedType,
- Opcode.ICONST_1,
- Opcode.LCONST_1,
- Opcode.FCONST_1,
- Opcode.DCONST_1
- ));
- if (c.operator == "++") {
- this.writeOpcode(c, Opcode.IADD + UnitCompiler.ilfd(promotedType));
- } else
- if (c.operator == "--") {
- this.writeOpcode(c, Opcode.ISUB + UnitCompiler.ilfd(promotedType));
- } else {
- this.compileError("Unexpected operator \"" + c.operator + "\"", c.getLocation());
- }
- this.reverseUnaryNumericPromotion((Locatable) c, promotedType, type);
- // DUPX cremented operand value.
- if (c.pre) this.dupx((Locatable) c, type, cs);
- // Set operand.
- this.compileSet(c.operand);
-
- return type;
- }
- private IClass compileGet2(Java.ArrayAccessExpression aae) throws CompileException {
- IClass lhsComponentType = this.getType(aae);
- this.writeOpcode(aae, Opcode.IALOAD + UnitCompiler.ilfdabcs(lhsComponentType));
- return lhsComponentType;
- }
- private IClass compileGet2(Java.FieldAccessExpression fae) throws CompileException {
- this.determineValue(fae);
- return this.compileGet(fae.value);
- }
- private IClass compileGet2(Java.SuperclassFieldAccessExpression scfae) throws CompileException {
- this.determineValue(scfae);
- return this.compileGet(scfae.value);
- }
- private IClass compileGet2(Java.UnaryOperation uo) throws CompileException {
- if (uo.operator == "!") {
- return this.compileGet2((Java.BooleanRvalue) uo);
- }
-
- if (uo.operator == "+") {
- return this.unaryNumericPromotion(
- (Locatable) uo,
- this.convertToPrimitiveNumericType((Locatable) uo, this.compileGetValue(uo.operand))
- );
- }
-
- if (uo.operator == "-") {
-
- // Special handling for negated literals.
- if (uo.operand instanceof Java.Literal) {
- Java.Literal l = (Java.Literal) uo.operand;
- this.pushConstant((Locatable) uo, this.getNegatedConstantValue2(l));
- return this.unaryNumericPromotion((Locatable) uo, this.getType2(l));
- }
-
- IClass promotedType = this.unaryNumericPromotion(
- (Locatable) uo,
- this.convertToPrimitiveNumericType((Locatable) uo, this.compileGetValue(uo.operand))
- );
- this.writeOpcode(uo, Opcode.INEG + UnitCompiler.ilfd(promotedType));
- return promotedType;
- }
-
- if (uo.operator == "~") {
- IClass operandType = this.compileGetValue(uo.operand);
-
- IClass promotedType = this.unaryNumericPromotion((Locatable) uo, operandType);
- if (promotedType == IClass.INT) {
- this.writeOpcode(uo, Opcode.ICONST_M1);
- this.writeOpcode(uo, Opcode.IXOR);
- return IClass.INT;
- }
- if (promotedType == IClass.LONG) {
- this.writeOpcode(uo, Opcode.LDC2_W);
- this.writeConstantLongInfo(-1L);
- this.writeOpcode(uo, Opcode.LXOR);
- return IClass.LONG;
- }
- this.compileError("Operator \"~\" not applicable to type \"" + promotedType + "\"", uo.getLocation());
- }
-
- this.compileError("Unexpected operator \"" + uo.operator + "\"", uo.getLocation());
- return this.iClassLoader.OBJECT;
- }
- private IClass compileGet2(Java.Instanceof io) throws CompileException {
- IClass lhsType = this.compileGetValue(io.lhs);
- IClass rhsType = this.getType(io.rhs);
-
- if (rhsType.isAssignableFrom(lhsType)) {
- this.pop((Locatable) io, lhsType);
- this.writeOpcode(io, Opcode.ICONST_1);
- } else
- if (
- lhsType.isInterface() ||
- rhsType.isInterface() ||
- lhsType.isAssignableFrom(rhsType)
- ) {
- this.writeOpcode(io, Opcode.INSTANCEOF);
- this.writeConstantClassInfo(rhsType.getDescriptor());
- } else {
- this.compileError("\"" + lhsType + "\" can never be an instance of \"" + rhsType + "\"", io.getLocation());
- }
- return IClass.BOOLEAN;
- }
- private IClass compileGet2(Java.BinaryOperation bo) throws CompileException {
- if (
- bo.op == "||" ||
- bo.op == "&&" ||
- bo.op == "==" ||
- bo.op == "!=" ||
- bo.op == "<" ||
- bo.op == ">" ||
- bo.op == "<=" ||
- bo.op == ">="
- ) {
- // Eventually calls "compileBoolean()".
- return this.compileGet2((Java.BooleanRvalue) bo);
- }
-
- // Implements "| ^ & * / % + - << >> >>>".
- return this.compileArithmeticOperation(
- (Locatable) bo, // l
- null, // type
- bo.unrollLeftAssociation(), // operands
- bo.op // operator
- );
- }
- private IClass compileGet2(Java.Cast c) throws CompileException {
-
- // JLS3 5.5 Casting Conversion
- IClass tt = this.getType(c.targetType);
- IClass vt = this.compileGetValue(c.value);
- if (
- !this.tryIdentityConversion(vt, tt) &&
- !this.tryWideningPrimitiveConversion((Locatable) c, vt, tt) &&
- !this.tryNarrowingPrimitiveConversion((Locatable) c, vt, tt) &&
- !this.tryWideningReferenceConversion(vt, tt) &&
- !this.tryNarrowingReferenceConversion((Locatable) c, vt, tt) &&
- !this.tryBoxingConversion((Locatable) c, vt, tt) &&
- !this.tryUnboxingConversion((Locatable) c, vt, tt)
- ) this.compileError("Cannot cast \"" + vt + "\" to \"" + tt + "\"", c.getLocation());
- return tt;
- }
- private IClass compileGet2(Java.ParenthesizedExpression pe) throws CompileException {
- return this.compileGet(pe.value);
- }
- private IClass compileGet2(Java.MethodInvocation mi) throws CompileException {
- IClass.IMethod iMethod = this.findIMethod(mi);
-
- if (mi.optionalTarget == null) {
-
- // JLS2 6.5.7.1, 15.12.4.1.1.1
- Java.TypeBodyDeclaration scopeTBD;
- Java.ClassDeclaration scopeClassDeclaration;
- {
- Java.Scope s;
- for (s = mi.getEnclosingBlockStatement(); !(s instanceof Java.TypeBodyDeclaration); s = s.getEnclosingScope());
- scopeTBD = (Java.TypeBodyDeclaration) s;
- if (!(s instanceof Java.ClassDeclaration)) s = s.getEnclosingScope();
- scopeClassDeclaration = (Java.ClassDeclaration) s;
- }
- if (iMethod.isStatic()) {
- this.warning("IASM", "Implicit access to static method \"" + iMethod.toString() + "\"", mi.getLocation());
- // JLS2 15.12.4.1.1.1.1
- ;
- } else {
- this.warning("IANSM", "Implicit access to non-static method \"" + iMethod.toString() + "\"", mi.getLocation());
- // JLS2 15.12.4.1.1.1.2
- if (scopeTBD.isStatic()) this.compileError("Instance method \"" + iMethod.toString() + "\" cannot be invoked in static context", mi.getLocation());
- this.referenceThis(
- (Locatable) mi, // l
- scopeClassDeclaration, // declaringClass
- scopeTBD, // declaringTypeBodyDeclaration
- iMethod.getDeclaringIClass() // targetIClass
- );
- }
- } else {
-
- // 6.5.7.2
- boolean staticContext = this.isType(mi.optionalTarget);
- if (staticContext) {
- this.getType(this.toTypeOrCE(mi.optionalTarget));
- } else
- {
- this.compileGetValue(this.toRvalueOrCE(mi.optionalTarget));
- }
- if (iMethod.isStatic()) {
- if (!staticContext) {
- // JLS2 15.12.4.1.2.1
- this.pop((Locatable) mi.optionalTarget, this.getType(mi.optionalTarget));
- }
- } else {
- if (staticContext) this.compileError("Instance method \"" + mi.methodName + "\" cannot be invoked in static context", mi.getLocation());
- }
- }
-
- // Evaluate method parameters.
- IClass[] parameterTypes = iMethod.getParameterTypes();
- for (int i = 0; i < mi.arguments.length; ++i) {
- this.assignmentConversion(
- (Locatable) mi, // l
- this.compileGetValue(mi.arguments[i]), // sourceType
- parameterTypes[i], // targetType
- this.getConstantValue(mi.arguments[i]) // optionalConstantValue
- );
- }
-
- // Invoke!
- this.checkAccessible(iMethod, mi.getEnclosingBlockStatement());
- if (iMethod.getDeclaringIClass().isInterface()) {
- this.writeOpcode(mi, Opcode.INVOKEINTERFACE);
- this.writeConstantInterfaceMethodrefInfo(
- iMethod.getDeclaringIClass().getDescriptor(), // locatable
- iMethod.getName(), // classFD
- iMethod.getDescriptor() // methodMD
- );
- IClass[] pts = iMethod.getParameterTypes();
- int count = 1;
- for (int i = 0; i < pts.length; ++i) count += Descriptor.size(pts[i].getDescriptor());
- this.writeByte(count);
- this.writeByte(0);
- } else {
- if (!iMethod.isStatic() && iMethod.getAccess() == Access.PRIVATE) {
-
- // In order to make a non-static private method invocable for enclosing types,
- // enclosed types and types enclosed by the same type, "compile(FunctionDeclarator)"
- // modifies it on-the-fly as follows:
- // + Access is changed from PRIVATE to PACKAGE
- // + The name is appended with "$"
- // + It is made static
- // + A parameter of type "declaring class" is prepended to the signature
- // Hence, the invocation of such a method must be modified accordingly.
- this.writeOpcode(mi, Opcode.INVOKESTATIC);
- this.writeConstantMethodrefInfo(
- iMethod.getDeclaringIClass().getDescriptor(), // locatable
- iMethod.getName() + '$', // classFD
- MethodDescriptor.prependParameter( // methodMD
- iMethod.getDescriptor(),
- iMethod.getDeclaringIClass().getDescriptor()
- )
- );
- } else
- {
- byte opcode = iMethod.isStatic() ? Opcode.INVOKESTATIC : Opcode.INVOKEVIRTUAL;
- this.writeOpcode(mi, opcode);
- this.writeConstantMethodrefInfo(
- iMethod.getDeclaringIClass().getDescriptor(), // classFD
- iMethod.getName(), // methodName
- iMethod.getDescriptor() // methodMD
- );
- }
- }
- return iMethod.getReturnType();
- }
- private IClass compileGet2(Java.SuperclassMethodInvocation scmi) throws CompileException {
- IClass.IMethod iMethod = this.findIMethod(scmi);
-
- Java.Scope s;
- for (s = scmi.getEnclosingBlockStatement(); s instanceof Java.Statement || s instanceof Java.CatchClause; s = s.getEnclosingScope());
- Java.FunctionDeclarator fd = s instanceof Java.FunctionDeclarator ? (Java.FunctionDeclarator) s : null;
- if (fd == null) {
- this.compileError("Cannot invoke superclass method in non-method scope", scmi.getLocation());
- return IClass.INT;
- }
- if ((fd.modifiers & Mod.STATIC) != 0) this.compileError("Cannot invoke superclass method in static context", scmi.getLocation());
- this.load((Locatable) scmi, this.resolve(fd.getDeclaringType()), 0);
-
- // Evaluate method parameters.
- IClass[] parameterTypes = iMethod.getParameterTypes();
- for (int i = 0; i < scmi.arguments.length; ++i) {
- this.assignmentConversion(
- (Locatable) scmi, // l
- this.compileGetValue(scmi.arguments[i]), // sourceType
- parameterTypes[i], // targetType
- this.getConstantValue(scmi.arguments[i]) // optionalConstantValue
- );
- }
-
- // Invoke!
- this.writeOpcode(scmi, Opcode.INVOKESPECIAL);
- this.writeConstantMethodrefInfo(
- iMethod.getDeclaringIClass().getDescriptor(), // classFD
- scmi.methodName, // methodName
- iMethod.getDescriptor() // methodMD
- );
- return iMethod.getReturnType();
- }
- private IClass compileGet2(Java.NewClassInstance nci) throws CompileException {
- if (nci.iClass == null) nci.iClass = this.getType(nci.type);
-
- this.writeOpcode(nci, Opcode.NEW);
- this.writeConstantClassInfo(nci.iClass.getDescriptor());
- this.writeOpcode(nci, Opcode.DUP);
-
- if (nci.iClass.isInterface()) this.compileError("Cannot instantiate \"" + nci.iClass + "\"", nci.getLocation());
- this.checkAccessible(nci.iClass, nci.getEnclosingBlockStatement());
- if (nci.iClass.isAbstract()) this.compileError("Cannot instantiate abstract \"" + nci.iClass + "\"", nci.getLocation());
-
- // Determine the enclosing instance for the new object.
- Java.Rvalue optionalEnclosingInstance;
- if (nci.optionalQualification != null) {
- if (nci.iClass.getOuterIClass() == null) this.compileError("Static member class cannot be instantiated with qualified NEW");
-
- // Enclosing instance defined by qualification (JLS 15.9.2.BL1.B3.B2).
- optionalEnclosingInstance = nci.optionalQualification;
- } else {
- Java.Scope s = nci.getEnclosingBlockStatement();
- for (; !(s instanceof Java.TypeBodyDeclaration); s = s.getEnclosingScope());
- Java.TypeBodyDeclaration enclosingTypeBodyDeclaration = (Java.TypeBodyDeclaration) s;
- Java.TypeDeclaration enclosingTypeDeclaration = (Java.TypeDeclaration) s.getEnclosingScope();
-
- if (
- !(enclosingTypeDeclaration instanceof Java.ClassDeclaration)
- || enclosingTypeBodyDeclaration.isStatic()
- ) {
-
- // No enclosing instance in
- // + interface method declaration or
- // + static type body declaration (here: method or initializer or field declarator)
- // context (JLS 15.9.2.BL1.B3.B1.B1).
- if (nci.iClass.getOuterIClass() != null) this.compileError("Instantiation of \"" + nci.type + "\" requires an enclosing instance", nci.getLocation());
- optionalEnclosingInstance = null;
- } else {
-
- // Determine the type of the enclosing instance for the new object.
- IClass optionalOuterIClass = nci.iClass.getDeclaringIClass();
- if (optionalOuterIClass == null) {
-
- // No enclosing instance needed for a top-level class object.
- optionalEnclosingInstance = null;
- } else {
-
- // Find an appropriate enclosing instance for the new inner class object among
- // the enclosing instances of the current object (JLS
- // 15.9.2.BL1.B3.B1.B2).
-// Java.ClassDeclaration outerClassDeclaration = (Java.ClassDeclaration) enclosingTypeDeclaration;
-// optionalEnclosingInstance = new Java.QualifiedThisReference(
-// nci.getLocation(), // location
-// outerClassDeclaration, // declaringClass
-// enclosingTypeBodyDeclaration, // declaringTypeBodyDeclaration
-// optionalOuterIClass // targetIClass
-// );
- optionalEnclosingInstance = new Java.QualifiedThisReference(
- nci.getLocation(), // location
- new Java.SimpleType( // qualification
- nci.getLocation(),
- optionalOuterIClass
- )
- );
- optionalEnclosingInstance.setEnclosingBlockStatement(nci.getEnclosingBlockStatement());
- }
- }
- }
-
- this.invokeConstructor(
- (Locatable) nci, // l
- nci.getEnclosingBlockStatement(), // scope
- optionalEnclosingInstance, // optionalEnclosingInstance
- nci.iClass, // targetClass
- nci.arguments // arguments
- );
- return nci.iClass;
- }
- private IClass compileGet2(Java.NewAnonymousClassInstance naci) throws CompileException {
-
- // Find constructors.
- Java.AnonymousClassDeclaration acd = naci.anonymousClassDeclaration;
- IClass sc = this.resolve(acd).getSuperclass();
- IClass.IConstructor[] iConstructors = sc.getDeclaredIConstructors();
- if (iConstructors.length == 0) throw new RuntimeException("SNO: Base class has no constructors");
-
- // Determine most specific constructor.
- IClass.IConstructor iConstructor = (IClass.IConstructor) this.findMostSpecificIInvocable(
- (Locatable) naci, // l
- iConstructors, // iInvocables
- naci.arguments // arguments
- );
-
- IClass[] pts = iConstructor.getParameterTypes();
-
- // Determine formal parameters of anonymous constructor.
- Java.FunctionDeclarator.FormalParameter[] fps;
- Location loc = naci.getLocation();
- {
- List l = new ArrayList(); // FormalParameter
-
- // Pass the enclosing instance of the base class as parameter #1.
- if (naci.optionalQualification != null) l.add(new Java.FunctionDeclarator.FormalParameter(
- loc, // location
- true, // finaL
- new Java.SimpleType(loc, this.getType(naci.optionalQualification)), // type
- "this$base" // name
- ));
- for (int i = 0; i < pts.length; ++i) l.add(new Java.FunctionDeclarator.FormalParameter(
- loc, // location
- true, // finaL
- new Java.SimpleType(loc, pts[i]), // type
- "p" + i // name
- ));
- fps = (Java.FunctionDeclarator.FormalParameter[]) l.toArray(new Java.FunctionDeclarator.FormalParameter[l.size()]);
- }
-
- // Determine thrown exceptions of anonymous constructor.
- IClass[] tes = iConstructor.getThrownExceptions();
- Java.Type[] tets = new Java.Type[tes.length];
- for (int i = 0; i < tes.length; ++i) tets[i] = new Java.SimpleType(loc, tes[i]);
-
- // The anonymous constructor merely invokes the constructor of its superclass.
- int j = 0;
- Java.Rvalue optionalQualificationAccess;
- if (naci.optionalQualification == null) {
- optionalQualificationAccess = null;
- } else
- {
- optionalQualificationAccess = new Java.ParameterAccess(loc, fps[j++]);
- }
- Java.Rvalue[] parameterAccesses = new Java.Rvalue[pts.length];
- for (int i = 0; i < pts.length; ++i) {
- parameterAccesses[i] = new Java.ParameterAccess(loc, fps[j++]);
- }
-
- // Generate the anonymous constructor for the anonymous class (JLS 15.9.5.1).
- acd.addConstructor(new Java.ConstructorDeclarator(
- loc, // location
- null, // optionalDocComment
- Mod.PACKAGE, // modifiers
- fps, // formalParameters
- tets, // thrownExceptions
- new Java.SuperConstructorInvocation( // optionalExplicitConstructorInvocation
- loc, // location
- optionalQualificationAccess, // optionalQualification
- parameterAccesses // arguments
- ),
- new Java.Block(loc) // optionalBody
- ));
-
- // Compile the anonymous class.
- this.compile(acd);
-
- // Instantiate the anonymous class.
- this.writeOpcode(naci, Opcode.NEW);
- this.writeConstantClassInfo(this.resolve(naci.anonymousClassDeclaration).getDescriptor());
-
- // Invoke the anonymous constructor.
- this.writeOpcode(naci, Opcode.DUP);
- Java.Rvalue[] arguments2;
- if (naci.optionalQualification == null) {
- arguments2 = naci.arguments;
- } else {
- arguments2 = new Java.Rvalue[naci.arguments.length + 1];
- arguments2[0] = naci.optionalQualification;
- System.arraycopy(naci.arguments, 0, arguments2, 1, naci.arguments.length);
- }
-
- // Notice: The enclosing instance of the anonymous class is "this", not the
- // qualification of the NewAnonymousClassInstance.
- Java.Scope s;
- for (s = naci.getEnclosingBlockStatement(); !(s instanceof Java.TypeBodyDeclaration); s = s.getEnclosingScope());
- Java.ThisReference oei;
- if (((Java.TypeBodyDeclaration) s).isStatic()) {
- oei = null;
- } else
- {
- oei = new Java.ThisReference(loc);
- oei.setEnclosingBlockStatement(naci.getEnclosingBlockStatement());
- }
- this.invokeConstructor(
- (Locatable) naci, // l
- (Java.Scope) naci.getEnclosingBlockStatement(), // scope
- oei, // optionalEnclosingInstance
- this.resolve(naci.anonymousClassDeclaration), // targetClass
- arguments2 // arguments
- );
- return this.resolve(naci.anonymousClassDeclaration);
- }
- private IClass compileGet2(Java.ParameterAccess pa) throws CompileException {
- Java.LocalVariable lv = this.getLocalVariable(pa.formalParameter);
- this.load((Locatable) pa, lv);
- return lv.type;
- }
- private IClass compileGet2(Java.NewArray na) throws CompileException {
- for (int i = 0; i < na.dimExprs.length; ++i) {
- IClass dimType = this.compileGetValue(na.dimExprs[i]);
- if (dimType != IClass.INT && this.unaryNumericPromotion(
- (Locatable) na, // l
- dimType // type
- ) != IClass.INT) this.compileError("Invalid array size expression type", na.getLocation());
- }
-
- return this.newArray(
- (Locatable) na, // l
- na.dimExprs.length, // dimExprCount
- na.dims, // dims
- this.getType(na.type) // componentType
- );
- }
- private IClass compileGet2(Java.NewInitializedArray nia) throws CompileException {
- IClass at = this.getType(nia.arrayType);
- this.compileGetValue(nia.arrayInitializer, at);
- return at;
- }
- private void compileGetValue(Java.ArrayInitializer ai, IClass arrayType) throws CompileException {
- if (!arrayType.isArray()) this.compileError("Array initializer not allowed for non-array type \"" + arrayType.toString() + "\"");
- IClass ct = arrayType.getComponentType();
-
- this.pushConstant((Locatable) ai, new Integer(ai.values.length));
- this.newArray(
- (Locatable) ai, // l
- 1, // dimExprCount,
- 0, // dims,
- ct // componentType
- );
-
- for (int i = 0; i < ai.values.length; ++i) {
- this.writeOpcode(ai, Opcode.DUP);
- this.pushConstant((Locatable) ai, new Integer(i));
- Java.ArrayInitializerOrRvalue aiorv = ai.values[i];
- if (aiorv instanceof Java.Rvalue) {
- Java.Rvalue rv = (Java.Rvalue) aiorv;
- this.assignmentConversion(
- (Locatable) ai, // l
- this.compileGetValue(rv), // sourceType
- ct, // targetType
- this.getConstantValue(rv) // optionalConstantValue
- );
- } else
- if (aiorv instanceof Java.ArrayInitializer) {
- this.compileGetValue((Java.ArrayInitializer) aiorv, ct);
- } else
- {
- throw new RuntimeException("Unexpected array initializer or rvalue class " + aiorv.getClass().getName());
- }
- this.writeOpcode(ai, Opcode.IASTORE + UnitCompiler.ilfdabcs(ct));
- }
- }
- private IClass compileGet2(Java.Literal l) throws CompileException {
- if (
- l.value == Scanner.MAGIC_INTEGER ||
- l.value == Scanner.MAGIC_LONG
- ) this.compileError("This literal value may only appear in a negated context", l.getLocation());
- return this.pushConstant((Locatable) l, l.value == null ? Java.Rvalue.CONSTANT_VALUE_NULL : l.value);
- }
-
- /**
- * Convenience function that calls {@link #compileContext(Java.Rvalue)}
- * and {@link #compileGet(Java.Rvalue)}.
- * @return The type of the Rvalue
- */
- private IClass compileGetValue(Java.Rvalue rv) throws CompileException {
- Object cv = this.getConstantValue(rv);
- if (cv != null) {
- this.fakeCompile(rv); // To check that, e.g., "a" compiles in "true || a".
- this.pushConstant((Locatable) rv, cv);
- return this.getType(rv);
- }
-
- this.compileContext(rv);
- return this.compileGet(rv);
- }
-
- // -------------------- Rvalue.getConstantValue() -----------------
-
- /**
- * Attempts to evaluate as a constant expression.
- * <p>
- * <table>
- * <tr><th>Expression type</th><th>Return value type</th></tr>
- * <tr><td>String</td><td>String</td></tr>
- * <tr><td>byte</td><td>Byte</td></tr>
- * <tr><td>short</td><td>Chort</td></tr>
- * <tr><td>int</td><td>Integer</td></tr>
- * <tr><td>boolean</td><td>Boolean</td></tr>
- * <tr><td>char</td><td>Character</td></tr>
- * <tr><td>float</td><td>Float</td></tr>
- * <tr><td>long</td><td>Long</td></tr>
- * <tr><td>double</td><td>Double</td></tr>
- * <tr><td>null</td><td>{@link Java.Rvalue#CONSTANT_VALUE_NULL}</td></tr>
- * </table>
- *
- * @return <code>null</code> iff the rvalue is not a constant value
- */
- public final Object getConstantValue(Java.Rvalue rv) throws CompileException {
- if (rv.constantValue != Java.Rvalue.CONSTANT_VALUE_UNKNOWN) return rv.constantValue;
-
- final Object[] res = new Object[1];
- class UCE extends RuntimeException { final CompileException ce; UCE(CompileException ce) { this.ce = ce; } }
- Visitor.RvalueVisitor rvv = new Visitor.RvalueVisitor() {
- public void visitArrayLength (Java.ArrayLength al ) { res[0] = UnitCompiler.this.getConstantValue2(al ); }
- public void visitAssignment (Java.Assignment a ) { res[0] = UnitCompiler.this.getConstantValue2(a ); }
- public void visitUnaryOperation (Java.UnaryOperation uo ) { try { res[0] = UnitCompiler.this.getConstantValue2(uo ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitBinaryOperation (Java.BinaryOperation bo ) { try { res[0] = UnitCompiler.this.getConstantValue2(bo ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitCast (Java.Cast c ) { try { res[0] = UnitCompiler.this.getConstantValue2(c ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitClassLiteral (Java.ClassLiteral cl ) { res[0] = UnitCompiler.this.getConstantValue2(cl ); }
- public void visitConditionalExpression (Java.ConditionalExpression ce ) { res[0] = UnitCompiler.this.getConstantValue2(ce ); }
- public void visitCrement (Java.Crement c ) { res[0] = UnitCompiler.this.getConstantValue2(c ); }
- public void visitInstanceof (Java.Instanceof io ) { res[0] = UnitCompiler.this.getConstantValue2(io ); }
- public void visitMethodInvocation (Java.MethodInvocation mi ) { res[0] = UnitCompiler.this.getConstantValue2(mi ); }
- public void visitSuperclassMethodInvocation(Java.SuperclassMethodInvocation smi ) { res[0] = UnitCompiler.this.getConstantValue2(smi ); }
- public void visitLiteral (Java.Literal l ) { try { res[0] = UnitCompiler.this.getConstantValue2(l ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitNewAnonymousClassInstance (Java.NewAnonymousClassInstance naci) { res[0] = UnitCompiler.this.getConstantValue2(naci); }
- public void visitNewArray (Java.NewArray na ) { res[0] = UnitCompiler.this.getConstantValue2(na ); }
- public void visitNewInitializedArray (Java.NewInitializedArray nia ) { res[0] = UnitCompiler.this.getConstantValue2(nia ); }
- public void visitNewClassInstance (Java.NewClassInstance nci ) { res[0] = UnitCompiler.this.getConstantValue2(nci ); }
- public void visitParameterAccess (Java.ParameterAccess pa ) { res[0] = UnitCompiler.this.getConstantValue2(pa ); }
- public void visitQualifiedThisReference (Java.QualifiedThisReference qtr ) { res[0] = UnitCompiler.this.getConstantValue2(qtr ); }
- public void visitThisReference (Java.ThisReference tr ) { res[0] = UnitCompiler.this.getConstantValue2(tr ); }
-
- public void visitAmbiguousName (Java.AmbiguousName an ) { try { res[0] = UnitCompiler.this.getConstantValue2(an ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitArrayAccessExpression (Java.ArrayAccessExpression aae ) { res[0] = UnitCompiler.this.getConstantValue2(aae ); }
- public void visitFieldAccess (Java.FieldAccess fa ) { try { res[0] = UnitCompiler.this.getConstantValue2(fa ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitFieldAccessExpression (Java.FieldAccessExpression fae ) { res[0] = UnitCompiler.this.getConstantValue2(fae ); }
- public void visitSuperclassFieldAccessExpression(Java.SuperclassFieldAccessExpression scfae) { res[0] = UnitCompiler.this.getConstantValue2(scfae); }
- public void visitLocalVariableAccess (Java.LocalVariableAccess lva ) { res[0] = UnitCompiler.this.getConstantValue2(lva ); }
- public void visitParenthesizedExpression (Java.ParenthesizedExpression pe ) { try { res[0] = UnitCompiler.this.getConstantValue2(pe ); } catch (CompileException e) { throw new UCE(e); } }
- };
- try {
- rv.accept(rvv);
- rv.constantValue = res[0];
- return rv.constantValue;
- } catch (UCE uce) {
- throw uce.ce;
- }
- }
- private Object getConstantValue2(Java.Rvalue rv) {
- return null;
- }
- private Object getConstantValue2(Java.AmbiguousName an) throws CompileException {
- return this.getConstantValue(this.toRvalueOrCE(this.reclassify(an)));
- }
- private Object getConstantValue2(Java.FieldAccess fa) throws CompileException {
- return fa.field.getConstantValue();
- }
- private Object getConstantValue2(Java.UnaryOperation uo) throws CompileException {
- if (uo.operator.equals("+")) return this.getConstantValue(uo.operand);
- if (uo.operator.equals("-")) return this.getNegatedConstantValue(uo.operand);
- if (uo.operator.equals("!")) {
- Object cv = this.getConstantValue(uo.operand);
- return cv instanceof Boolean ? (
- ((Boolean) cv).booleanValue() ? Boolean.FALSE : Boolean.TRUE
- ) : null;
- }
- return null;
- }
- private Object getConstantValue2(Java.BinaryOperation bo) throws CompileException {
-
- // null == null
- // null != null
- if (
- (bo.op == "==" || bo.op == "!=") &&
- this.getConstantValue(bo.lhs) == Java.Rvalue.CONSTANT_VALUE_NULL &&
- this.getConstantValue(bo.rhs) == Java.Rvalue.CONSTANT_VALUE_NULL
- ) return bo.op == "==" ? Boolean.TRUE : Boolean.FALSE;
-
- // "|", "^", "&", "*", "/", "%", "+", "-".
- if (
- bo.op == "|" ||
- bo.op == "^" ||
- bo.op == "&" ||
- bo.op == "*" ||
- bo.op == "/" ||
- bo.op == "%" ||
- bo.op == "+" ||
- bo.op == "-"
- ) {
-
- // Unroll the constant operands.
- List cvs = new ArrayList();
- for (Iterator it = bo.unrollLeftAssociation(); it.hasNext();) {
- Object cv = this.getConstantValue(((Java.Rvalue) it.next()));
- if (cv == null) return null;
- cvs.add(cv);
- }
-
- // Compute the constant value of the unrolled binary operation.
- Iterator it = cvs.iterator();
- Object lhs = it.next();
- while (it.hasNext()) {
- Object rhs = it.next();
-
- // String concatenation?
- if (bo.op == "+" && (lhs instanceof String || rhs instanceof String)) {
- StringBuffer sb = new StringBuffer();
- sb.append(lhs.toString()).append(rhs.toString());
- while (it.hasNext()) sb.append(it.next().toString());
- return sb.toString();
- }
-
- if (!(lhs instanceof Number) || !(rhs instanceof Number)) return null;
-
- try {
- // Numeric binary operation.
- if (lhs instanceof Double || rhs instanceof Double) {
- double lhsD = ((Number) lhs).doubleValue();
- double rhsD = ((Number) rhs).doubleValue();
- double cvD;
- if (bo.op == "*") cvD = lhsD * rhsD; else
- if (bo.op == "/") cvD = lhsD / rhsD; else
- if (bo.op == "%") cvD = lhsD % rhsD; else
- if (bo.op == "+") cvD = lhsD + rhsD; else
- if (bo.op == "-") cvD = lhsD - rhsD; else return null;
- lhs = new Double(cvD);
- } else
- if (lhs instanceof Float || rhs instanceof Float) {
- float lhsF = ((Number) lhs).floatValue();
- float rhsF = ((Number) rhs).floatValue();
- float cvF;
- if (bo.op == "*") cvF = lhsF * rhsF; else
- if (bo.op == "/") cvF = lhsF / rhsF; else
- if (bo.op == "%") cvF = lhsF % rhsF; else
- if (bo.op == "+") cvF = lhsF + rhsF; else
- if (bo.op == "-") cvF = lhsF - rhsF; else return null;
- lhs = new Float(cvF);
- } else
- if (lhs instanceof Long || rhs instanceof Long) {
- long lhsL = ((Number) lhs).longValue();
- long rhsL = ((Number) rhs).longValue();
- long cvL;
- if (bo.op == "|") cvL = lhsL | rhsL; else
- if (bo.op == "^") cvL = lhsL ^ rhsL; else
- if (bo.op == "&") cvL = lhsL & rhsL; else
- if (bo.op == "*") cvL = lhsL * rhsL; else
- if (bo.op == "/") cvL = lhsL / rhsL; else
- if (bo.op == "%") cvL = lhsL % rhsL; else
- if (bo.op == "+") cvL = lhsL + rhsL; else
- if (bo.op == "-") cvL = lhsL - rhsL; else return null;
- lhs = new Long(cvL);
- } else
- {
- int lhsI = ((Number) lhs).intValue();
- int rhsI = ((Number) rhs).intValue();
- int cvI;
- if (bo.op == "|") cvI = lhsI | rhsI; else
- if (bo.op == "^") cvI = lhsI ^ rhsI; else
- if (bo.op == "&") cvI = lhsI & rhsI; else
- if (bo.op == "*") cvI = lhsI * rhsI; else
- if (bo.op == "/") cvI = lhsI / rhsI; else
- if (bo.op == "%") cvI = lhsI % rhsI; else
- if (bo.op == "+") cvI = lhsI + rhsI; else
- if (bo.op == "-") cvI = lhsI - rhsI; else return null;
- lhs = new Integer(cvI);
- }
- } catch (ArithmeticException ae) {
- // Most likely a div by zero or mod by zero.
- // Guess we can't make this expression into a constant.
- return null;
- }
- }
- return lhs;
- }
-
- // "&&" and "||" with constant LHS operand.
- if (
- bo.op == "&&" ||
- bo.op == "||"
- ) {
- Object lhsValue = this.getConstantValue(bo.lhs);
- if (lhsValue instanceof Boolean) {
- boolean lhsBV = ((Boolean) lhsValue).booleanValue();
- return (
- bo.op == "&&" ?
- (lhsBV ? this.getConstantValue(bo.rhs) : Boolean.FALSE) :
- (lhsBV ? Boolean.TRUE : this.getConstantValue(bo.rhs))
- );
- }
- }
-
- return null;
- }
- private Object getConstantValue2(Java.Cast c) throws CompileException {
- Object cv = this.getConstantValue(c.value);
- if (cv == null) return null;
-
- if (cv instanceof Number) {
- IClass tt = this.getType(c.targetType);
- if (tt == IClass.BYTE ) return new Byte(((Number) cv).byteValue());
- if (tt == IClass.SHORT ) return new Short(((Number) cv).shortValue());
- if (tt == IClass.INT ) return new Integer(((Number) cv).intValue());
- if (tt == IClass.LONG ) return new Long(((Number) cv).longValue());
- if (tt == IClass.FLOAT ) return new Float(((Number) cv).floatValue());
- if (tt == IClass.DOUBLE) return new Double(((Number) cv).doubleValue());
- }
-
- return null;
- }
- private Object getConstantValue2(Java.ParenthesizedExpression pe) throws CompileException {
- return this.getConstantValue(pe.value);
- }
- private Object getConstantValue2(Java.Literal l) throws CompileException {
- if (
- l.value == Scanner.MAGIC_INTEGER ||
- l.value == Scanner.MAGIC_LONG
- ) this.compileError("This literal value may only appear in a negated context", l.getLocation());
- return l.value == null ? Java.Rvalue.CONSTANT_VALUE_NULL : l.value;
- }
-
- /**
- * Attempts to evaluate the negated value of a constant {@link Java.Rvalue}.
- * This is particularly relevant for the smallest value of an integer or
- * long literal.
- *
- * @return null if value is not constant; otherwise a String, Byte,
- * Short, Integer, Boolean, Character, Float, Long or Double
- */
- private final Object getNegatedConstantValue(Java.Rvalue rv) throws CompileException {
- final Object[] res = new Object[1];
- class UCE extends RuntimeException { final CompileException ce; UCE(CompileException ce) { this.ce = ce; } }
- Visitor.RvalueVisitor rvv = new Visitor.RvalueVisitor() {
- public void visitArrayLength (Java.ArrayLength al ) { res[0] = UnitCompiler.this.getNegatedConstantValue2(al ); }
- public void visitAssignment (Java.Assignment a ) { res[0] = UnitCompiler.this.getNegatedConstantValue2(a ); }
- public void visitUnaryOperation (Java.UnaryOperation uo ) { try { res[0] = UnitCompiler.this.getNegatedConstantValue2(uo ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitBinaryOperation (Java.BinaryOperation bo ) { res[0] = UnitCompiler.this.getNegatedConstantValue2(bo ); }
- public void visitCast (Java.Cast c ) { res[0] = UnitCompiler.this.getNegatedConstantValue2(c ); }
- public void visitClassLiteral (Java.ClassLiteral cl ) { res[0] = UnitCompiler.this.getNegatedConstantValue2(cl ); }
- public void visitConditionalExpression (Java.ConditionalExpression ce ) { res[0] = UnitCompiler.this.getNegatedConstantValue2(ce ); }
- public void visitCrement (Java.Crement c ) { res[0] = UnitCompiler.this.getNegatedConstantValue2(c ); }
- public void visitInstanceof (Java.Instanceof io ) { res[0] = UnitCompiler.this.getNegatedConstantValue2(io ); }
- public void visitMethodInvocation (Java.MethodInvocation mi ) { res[0] = UnitCompiler.this.getNegatedConstantValue2(mi ); }
- public void visitSuperclassMethodInvocation(Java.SuperclassMethodInvocation smi ) { res[0] = UnitCompiler.this.getNegatedConstantValue2(smi ); }
- public void visitLiteral (Java.Literal l ) { try { res[0] = UnitCompiler.this.getNegatedConstantValue2(l ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitNewAnonymousClassInstance (Java.NewAnonymousClassInstance naci) { res[0] = UnitCompiler.this.getNegatedConstantValue2(naci); }
- public void visitNewArray (Java.NewArray na ) { res[0] = UnitCompiler.this.getNegatedConstantValue2(na ); }
- public void visitNewInitializedArray (Java.NewInitializedArray nia ) { res[0] = UnitCompiler.this.getNegatedConstantValue2(nia ); }
- public void visitNewClassInstance (Java.NewClassInstance nci ) { res[0] = UnitCompiler.this.getNegatedConstantValue2(nci ); }
- public void visitParameterAccess (Java.ParameterAccess pa ) { res[0] = UnitCompiler.this.getNegatedConstantValue2(pa ); }
- public void visitQualifiedThisReference (Java.QualifiedThisReference qtr ) { res[0] = UnitCompiler.this.getNegatedConstantValue2(qtr ); }
- public void visitThisReference (Java.ThisReference tr ) { res[0] = UnitCompiler.this.getNegatedConstantValue2(tr ); }
-
- public void visitAmbiguousName (Java.AmbiguousName an ) { res[0] = UnitCompiler.this.getNegatedConstantValue2(an ); }
- public void visitArrayAccessExpression (Java.ArrayAccessExpression aae ) { res[0] = UnitCompiler.this.getNegatedConstantValue2(aae ); }
- public void visitFieldAccess (Java.FieldAccess fa ) { res[0] = UnitCompiler.this.getNegatedConstantValue2(fa ); }
- public void visitFieldAccessExpression (Java.FieldAccessExpression fae ) { res[0] = UnitCompiler.this.getNegatedConstantValue2(fae ); }
- public void visitSuperclassFieldAccessExpression(Java.SuperclassFieldAccessExpression scfae) { res[0] = UnitCompiler.this.getNegatedConstantValue2(scfae); }
- public void visitLocalVariableAccess (Java.LocalVariableAccess lva ) { res[0] = UnitCompiler.this.getNegatedConstantValue2(lva ); }
- public void visitParenthesizedExpression (Java.ParenthesizedExpression pe ) { try { res[0] = UnitCompiler.this.getNegatedConstantValue2(pe ); } catch (CompileException e) { throw new UCE(e); } }
- };
- try {
- rv.accept(rvv);
- return res[0];
- } catch (UCE uce) {
- throw uce.ce;
- }
- }
- private Object getNegatedConstantValue2(Java.Rvalue rv) {
- return null;
- }
- private Object getNegatedConstantValue2(Java.UnaryOperation uo) throws CompileException {
- return (
- uo.operator.equals("+") ? this.getNegatedConstantValue(uo.operand) :
- uo.operator.equals("-") ? this.getConstantValue(uo.operand) :
- null
- );
- }
- private Object getNegatedConstantValue2(Java.ParenthesizedExpression pe) throws CompileException {
- return this.getNegatedConstantValue(pe.value);
- }
- private Object getNegatedConstantValue2(Java.Literal l) throws CompileException {
- if (l.value instanceof Integer) return new Integer(-((Integer) l.value).intValue() );
- if (l.value instanceof Long ) return new Long (-((Long ) l.value).longValue() );
- if (l.value instanceof Float ) return new Float (-((Float ) l.value).floatValue() );
- if (l.value instanceof Double ) return new Double (-((Double ) l.value).doubleValue());
-
- this.compileError("Cannot negate this literal", l.getLocation());
- return null;
- }
-
- // ------------ BlockStatement.generatesCode() -------------
-
- /**
- * Check whether invocation of {@link #compile(Java.BlockStatement)} would
- * generate more than zero code bytes.
- */
- private boolean generatesCode(Java.BlockStatement bs) throws CompileException {
- final boolean[] res = new boolean[1];
- class UCE extends RuntimeException { final CompileException ce; UCE(CompileException ce) { this.ce = ce; } }
- Visitor.BlockStatementVisitor bsv = new Visitor.BlockStatementVisitor() {
- public void visitInitializer (Java.Initializer i ) { try { res[0] = UnitCompiler.this.generatesCode2(i ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitFieldDeclaration (Java.FieldDeclaration fd ) { try { res[0] = UnitCompiler.this.generatesCode2(fd ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitLabeledStatement (Java.LabeledStatement ls ) { res[0] = UnitCompiler.this.generatesCode2(ls ); }
- public void visitBlock (Java.Block b ) { try { res[0] = UnitCompiler.this.generatesCode2(b ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitExpressionStatement (Java.ExpressionStatement es ) { res[0] = UnitCompiler.this.generatesCode2(es ); }
- public void visitIfStatement (Java.IfStatement is ) { res[0] = UnitCompiler.this.generatesCode2(is ); }
- public void visitForStatement (Java.ForStatement fs ) { res[0] = UnitCompiler.this.generatesCode2(fs ); }
- public void visitWhileStatement (Java.WhileStatement ws ) { res[0] = UnitCompiler.this.generatesCode2(ws ); }
- public void visitTryStatement (Java.TryStatement ts ) { res[0] = UnitCompiler.this.generatesCode2(ts ); }
- public void visitSwitchStatement (Java.SwitchStatement ss ) { res[0] = UnitCompiler.this.generatesCode2(ss ); }
- public void visitSynchronizedStatement (Java.SynchronizedStatement ss ) { res[0] = UnitCompiler.this.generatesCode2(ss ); }
- public void visitDoStatement (Java.DoStatement ds ) { res[0] = UnitCompiler.this.generatesCode2(ds ); }
- public void visitLocalVariableDeclarationStatement(Java.LocalVariableDeclarationStatement lvds) { res[0] = UnitCompiler.this.generatesCode2(lvds); }
- public void visitReturnStatement (Java.ReturnStatement rs ) { res[0] = UnitCompiler.this.generatesCode2(rs ); }
- public void visitThrowStatement (Java.ThrowStatement ts ) { res[0] = UnitCompiler.this.generatesCode2(ts ); }
- public void visitBreakStatement (Java.BreakStatement bs ) { res[0] = UnitCompiler.this.generatesCode2(bs ); }
- public void visitContinueStatement (Java.ContinueStatement cs ) { res[0] = UnitCompiler.this.generatesCode2(cs ); }
- public void visitEmptyStatement (Java.EmptyStatement es ) { res[0] = UnitCompiler.this.generatesCode2(es ); }
- public void visitLocalClassDeclarationStatement (Java.LocalClassDeclarationStatement lcds) { res[0] = UnitCompiler.this.generatesCode2(lcds); }
- public void visitAlternateConstructorInvocation (Java.AlternateConstructorInvocation aci ) { res[0] = UnitCompiler.this.generatesCode2(aci ); }
- public void visitSuperConstructorInvocation (Java.SuperConstructorInvocation sci ) { res[0] = UnitCompiler.this.generatesCode2(sci ); }
- };
- try {
- bs.accept(bsv);
- return res[0];
- } catch (UCE uce) {
- throw uce.ce;
- }
- }
- public boolean generatesCode2(Java.BlockStatement bs) { return true; }
- public boolean generatesCode2(Java.EmptyStatement es) { return false; }
- public boolean generatesCode2(Java.LocalClassDeclarationStatement lcds) { return false; }
- public boolean generatesCode2(Java.Initializer i) throws CompileException { return this.generatesCode(i.block); }
- // Takes a List<Java.BlockStatement>.
- public boolean generatesCode2ListStatements(List l) throws CompileException {
- for (int i = 0; i < l.size(); ++i) {
- if (this.generatesCode(((Java.BlockStatement) l.get(i)))) return true;
- }
- return false;
- }
- public boolean generatesCode2(Java.Block b) throws CompileException {
- return generatesCode2ListStatements(b.statements);
- }
- public boolean generatesCode2(Java.FieldDeclaration fd) throws CompileException {
- // Code is only generated if at least one of the declared variables has a
- // non-constant-final initializer.
- for (int i = 0; i < fd.variableDeclarators.length; ++i) {
- Java.VariableDeclarator vd = fd.variableDeclarators[i];
- if (this.getNonConstantFinalInitializer(fd, vd) != null) return true;
- }
- return false;
- }
-
- // ------------ BlockStatement.leave() -------------
-
- /**
- * Clean up the statement context. This is currently relevant for
- * "try ... catch ... finally" statements (execute "finally" clause)
- * and "synchronized" statements (monitorexit).
- * <p>
- * Statements like "return", "break", "continue" must call this method
- * for all the statements they terminate.
- * <p>
- * Notice: If <code>optionalStackValueType</code> is <code>null</code>,
- * then the operand stack is empty; otherwise exactly one operand with that
- * type is on the stack. This information is vital to implementations of
- * {@link #leave(Java.BlockStatement, IClass)} that require a specific
- * operand stack state (e.g. an empty operand stack for JSR).
- */
- private void leave(Java.BlockStatement bs, final IClass optionalStackValueType) {
- Visitor.BlockStatementVisitor bsv = new Visitor.BlockStatementVisitor() {
- public void visitInitializer (Java.Initializer i ) { UnitCompiler.this.leave2(i, optionalStackValueType); }
- public void visitFieldDeclaration (Java.FieldDeclaration fd ) { UnitCompiler.this.leave2(fd, optionalStackValueType); }
- public void visitLabeledStatement (Java.LabeledStatement ls ) { UnitCompiler.this.leave2(ls, optionalStackValueType); }
- public void visitBlock (Java.Block b ) { UnitCompiler.this.leave2(b, optionalStackValueType); }
- public void visitExpressionStatement (Java.ExpressionStatement es ) { UnitCompiler.this.leave2(es, optionalStackValueType); }
- public void visitIfStatement (Java.IfStatement is ) { UnitCompiler.this.leave2(is, optionalStackValueType); }
- public void visitForStatement (Java.ForStatement fs ) { UnitCompiler.this.leave2(fs, optionalStackValueType); }
- public void visitWhileStatement (Java.WhileStatement ws ) { UnitCompiler.this.leave2(ws, optionalStackValueType); }
- public void visitTryStatement (Java.TryStatement ts ) { UnitCompiler.this.leave2(ts, optionalStackValueType); }
- public void visitSwitchStatement (Java.SwitchStatement ss ) { UnitCompiler.this.leave2(ss, optionalStackValueType); }
- public void visitSynchronizedStatement (Java.SynchronizedStatement ss ) { UnitCompiler.this.leave2(ss, optionalStackValueType); }
- public void visitDoStatement (Java.DoStatement ds ) { UnitCompiler.this.leave2(ds, optionalStackValueType); }
- public void visitLocalVariableDeclarationStatement(Java.LocalVariableDeclarationStatement lvds) { UnitCompiler.this.leave2(lvds, optionalStackValueType); }
- public void visitReturnStatement (Java.ReturnStatement rs ) { UnitCompiler.this.leave2(rs, optionalStackValueType); }
- public void visitThrowStatement (Java.ThrowStatement ts ) { UnitCompiler.this.leave2(ts, optionalStackValueType); }
- public void visitBreakStatement (Java.BreakStatement bs ) { UnitCompiler.this.leave2(bs, optionalStackValueType); }
- public void visitContinueStatement (Java.ContinueStatement cs ) { UnitCompiler.this.leave2(cs, optionalStackValueType); }
- public void visitEmptyStatement (Java.EmptyStatement es ) { UnitCompiler.this.leave2(es, optionalStackValueType); }
- public void visitLocalClassDeclarationStatement (Java.LocalClassDeclarationStatement lcds) { UnitCompiler.this.leave2(lcds, optionalStackValueType); }
- public void visitAlternateConstructorInvocation (Java.AlternateConstructorInvocation aci ) { UnitCompiler.this.leave2(aci, optionalStackValueType); }
- public void visitSuperConstructorInvocation (Java.SuperConstructorInvocation sci ) { UnitCompiler.this.leave2(sci, optionalStackValueType); }
- };
- bs.accept(bsv);
- }
- public void leave2(Java.BlockStatement bs, IClass optionalStackValueType) { ; }
- public void leave2(Java.SynchronizedStatement ss, IClass optionalStackValueType) {
- this.load((Locatable) ss, this.iClassLoader.OBJECT, ss.monitorLvIndex);
- this.writeOpcode(ss, Opcode.MONITOREXIT);
- }
- public void leave2(Java.TryStatement ts, IClass optionalStackValueType) {
- if (ts.finallyOffset != null) {
-
- this.codeContext.saveLocalVariables();
- try {
- short sv = 0;
-
- // Obviously, JSR must always be executed with the operand stack being
- // empty; otherwise we get "java.lang.VerifyError: Inconsistent stack height
- // 1 != 2"
- if (optionalStackValueType != null) {
- sv = this.codeContext.allocateLocalVariable(Descriptor.size(optionalStackValueType.getDescriptor()));
- this.store((Locatable) ts, optionalStackValueType, sv);
- }
-
- this.writeBranch(ts, Opcode.JSR, ts.finallyOffset);
-
- if (optionalStackValueType != null) {
- this.load((Locatable) ts, optionalStackValueType, sv);
- }
- } finally {
- this.codeContext.restoreLocalVariables();
- }
- }
- }
-
- // ---------------- Lvalue.compileSet() -----------------
-
- /**
- * Generates code that stores a value in the {@link Java.Lvalue}.
- * Expects the {@link Java.Lvalue}'s context (see {@link
- * #compileContext}) and a value of the {@link Java.Lvalue}'s type
- * on the operand stack.
- */
- private void compileSet(Java.Lvalue lv) throws CompileException {
- class UCE extends RuntimeException { final CompileException ce; UCE(CompileException ce) { this.ce = ce; } }
- Visitor.LvalueVisitor lvv = new Visitor.LvalueVisitor() {
- public void visitAmbiguousName (Java.AmbiguousName an ) { try { UnitCompiler.this.compileSet2(an ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitArrayAccessExpression (Java.ArrayAccessExpression aae ) { try { UnitCompiler.this.compileSet2(aae ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitFieldAccess (Java.FieldAccess fa ) { try { UnitCompiler.this.compileSet2(fa ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitFieldAccessExpression (Java.FieldAccessExpression fae ) { try { UnitCompiler.this.compileSet2(fae ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitSuperclassFieldAccessExpression(Java.SuperclassFieldAccessExpression scfae) { try { UnitCompiler.this.compileSet2(scfae); } catch (CompileException e) { throw new UCE(e); } }
- public void visitLocalVariableAccess (Java.LocalVariableAccess lva ) { UnitCompiler.this.compileSet2(lva ); }
- public void visitParenthesizedExpression (Java.ParenthesizedExpression pe ) { try { UnitCompiler.this.compileSet2(pe ); } catch (CompileException e) { throw new UCE(e); } }
- };
- try {
- lv.accept(lvv);
- } catch (UCE uce) {
- throw uce.ce;
- }
- }
- private void compileSet2(Java.AmbiguousName an) throws CompileException {
- this.compileSet(this.toLvalueOrCE(this.reclassify(an)));
- }
- private void compileSet2(Java.LocalVariableAccess lva) {
- this.store(
- (Locatable) lva,
- lva.localVariable.type,
- lva.localVariable
- );
- }
- private void compileSet2(Java.FieldAccess fa) throws CompileException {
- this.checkAccessible(fa.field, fa.getEnclosingBlockStatement());
- this.writeOpcode(fa, (
- fa.field.isStatic() ?
- Opcode.PUTSTATIC :
- Opcode.PUTFIELD
- ));
- this.writeConstantFieldrefInfo(
- fa.field.getDeclaringIClass().getDescriptor(),
- fa.field.getName(), // classFD
- fa.field.getDescriptor() // fieldFD
- );
- }
- private void compileSet2(Java.ArrayAccessExpression aae) throws CompileException {
- this.writeOpcode(aae, Opcode.IASTORE + UnitCompiler.ilfdabcs(this.getType(aae)));
- }
- private void compileSet2(Java.FieldAccessExpression fae) throws CompileException {
- this.determineValue(fae);
- this.compileSet(this.toLvalueOrCE(fae.value));
- }
- private void compileSet2(Java.SuperclassFieldAccessExpression scfae) throws CompileException {
- this.determineValue(scfae);
- this.compileSet(this.toLvalueOrCE(scfae.value));
- }
- private void compileSet2(Java.ParenthesizedExpression pe) throws CompileException {
- this.compileSet(this.toLvalueOrCE(pe.value));
- }
-
- // ---------------- Atom.getType() ----------------
-
- private IClass getType(Java.Atom a) throws CompileException {
- final IClass[] res = new IClass[1];
- class UCE extends RuntimeException { final CompileException ce; UCE(CompileException ce) { this.ce = ce; } }
- Visitor.AtomVisitor av = new Visitor.AtomVisitor() {
- // AtomVisitor
- public void visitPackage (Java.Package p ) { try { res[0] = UnitCompiler.this.getType2(p ); } catch (CompileException e) { throw new UCE(e); } }
- // TypeVisitor
- public void visitArrayType (Java.ArrayType at ) { try { res[0] = UnitCompiler.this.getType2(at ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitBasicType (Java.BasicType bt ) { res[0] = UnitCompiler.this.getType2(bt ); }
- public void visitReferenceType (Java.ReferenceType rt ) { try { res[0] = UnitCompiler.this.getType2(rt ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitRvalueMemberType (Java.RvalueMemberType rmt ) { try { res[0] = UnitCompiler.this.getType2(rmt ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitSimpleType (Java.SimpleType st ) { res[0] = UnitCompiler.this.getType2(st ); }
- // RvalueVisitor
- public void visitArrayLength (Java.ArrayLength al ) { res[0] = UnitCompiler.this.getType2(al ); }
- public void visitAssignment (Java.Assignment a ) { try { res[0] = UnitCompiler.this.getType2(a ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitUnaryOperation (Java.UnaryOperation uo ) { try { res[0] = UnitCompiler.this.getType2(uo ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitBinaryOperation (Java.BinaryOperation bo ) { try { res[0] = UnitCompiler.this.getType2(bo ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitCast (Java.Cast c ) { try { res[0] = UnitCompiler.this.getType2(c ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitClassLiteral (Java.ClassLiteral cl ) { res[0] = UnitCompiler.this.getType2(cl ); }
- public void visitConditionalExpression (Java.ConditionalExpression ce ) { try { res[0] = UnitCompiler.this.getType2(ce ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitCrement (Java.Crement c ) { try { res[0] = UnitCompiler.this.getType2(c ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitInstanceof (Java.Instanceof io ) { res[0] = UnitCompiler.this.getType2(io ); }
- public void visitMethodInvocation (Java.MethodInvocation mi ) { try { res[0] = UnitCompiler.this.getType2(mi ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitSuperclassMethodInvocation (Java.SuperclassMethodInvocation smi ) { try { res[0] = UnitCompiler.this.getType2(smi ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitLiteral (Java.Literal l ) { res[0] = UnitCompiler.this.getType2(l ); }
- public void visitNewAnonymousClassInstance (Java.NewAnonymousClassInstance naci) { res[0] = UnitCompiler.this.getType2(naci); }
- public void visitNewArray (Java.NewArray na ) { try { res[0] = UnitCompiler.this.getType2(na ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitNewInitializedArray (Java.NewInitializedArray nia ) { try { res[0] = UnitCompiler.this.getType2(nia ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitNewClassInstance (Java.NewClassInstance nci ) { try { res[0] = UnitCompiler.this.getType2(nci ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitParameterAccess (Java.ParameterAccess pa ) { try { res[0] = UnitCompiler.this.getType2(pa ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitQualifiedThisReference (Java.QualifiedThisReference qtr ) { try { res[0] = UnitCompiler.this.getType2(qtr ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitThisReference (Java.ThisReference tr ) { try { res[0] = UnitCompiler.this.getType2(tr ); } catch (CompileException e) { throw new UCE(e); } }
- // LvalueVisitor
- public void visitAmbiguousName (Java.AmbiguousName an ) { try { res[0] = UnitCompiler.this.getType2(an ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitArrayAccessExpression (Java.ArrayAccessExpression aae ) { try { res[0] = UnitCompiler.this.getType2(aae ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitFieldAccess (Java.FieldAccess fa ) { try { res[0] = UnitCompiler.this.getType2(fa ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitFieldAccessExpression (Java.FieldAccessExpression fae ) { try { res[0] = UnitCompiler.this.getType2(fae ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitSuperclassFieldAccessExpression(Java.SuperclassFieldAccessExpression scfae) { try { res[0] = UnitCompiler.this.getType2(scfae); } catch (CompileException e) { throw new UCE(e); } }
- public void visitLocalVariableAccess (Java.LocalVariableAccess lva ) { res[0] = UnitCompiler.this.getType2(lva ); }
- public void visitParenthesizedExpression (Java.ParenthesizedExpression pe ) { try { res[0] = UnitCompiler.this.getType2(pe ); } catch (CompileException e) { throw new UCE(e); } }
- };
- try {
- a.accept(av);
- return res[0] != null ? res[0] : this.iClassLoader.OBJECT;
- } catch (UCE uce) {
- throw uce.ce;
- }
- }
- private IClass getType2(Java.SimpleType st) { return st.iClass; }
- private IClass getType2(Java.BasicType bt) {
- switch (bt.index) {
- case Java.BasicType.VOID: return IClass.VOID;
- case Java.BasicType.BYTE: return IClass.BYTE;
- case Java.BasicType.SHORT: return IClass.SHORT;
- case Java.BasicType.CHAR: return IClass.CHAR;
- case Java.BasicType.INT: return IClass.INT;
- case Java.BasicType.LONG: return IClass.LONG;
- case Java.BasicType.FLOAT: return IClass.FLOAT;
- case Java.BasicType.DOUBLE: return IClass.DOUBLE;
- case Java.BasicType.BOOLEAN: return IClass.BOOLEAN;
- default: throw new RuntimeException("Invalid index " + bt.index);
- }
- }
- private IClass getType2(Java.ReferenceType rt) throws CompileException {
- Java.BlockStatement scopeBlockStatement = null;
- Java.TypeDeclaration scopeTypeDeclaration = null;
- Java.CompilationUnit scopeCompilationUnit;
- for (Java.Scope s = rt.getEnclosingScope();; s = s.getEnclosingScope()) {
- if (s instanceof Java.BlockStatement && scopeBlockStatement == null) {
- scopeBlockStatement = (Java.BlockStatement) s;
- }
- if (s instanceof Java.TypeDeclaration && scopeTypeDeclaration == null) {
- scopeTypeDeclaration = (Java.TypeDeclaration) s;
- }
- if (s instanceof Java.CompilationUnit) {
- scopeCompilationUnit = (Java.CompilationUnit) s;
- break;
- }
- }
-
- if (rt.identifiers.length == 1) {
-
- // 6.5.5.1 Simple type name (single identifier).
- String simpleTypeName = rt.identifiers[0];
-
- // 6.5.5.1.1 Local class.
- {
- Java.LocalClassDeclaration lcd = this.findLocalClassDeclaration(rt.getEnclosingScope(), simpleTypeName);
- if (lcd != null) return this.resolve(lcd);
- }
-
- // 6.5.5.1.2 Member type.
- if (scopeTypeDeclaration != null) { // If enclosed by another type declaration...
- for (Java.Scope s = scopeTypeDeclaration; !(s instanceof Java.CompilationUnit); s = s.getEnclosingScope()) {
- if (s instanceof Java.TypeDeclaration) {
- IClass mt = this.findMemberType(this.resolve((Java.AbstractTypeDeclaration) s), simpleTypeName, rt.getLocation());
- if (mt != null) return mt;
- }
- }
- }
-
- {
-
- // 6.5.5.1.4a Single-type import.
- {
- IClass importedClass = this.importSingleType(simpleTypeName, rt.getLocation());
- if (importedClass != null) return importedClass;
- }
-
- // 6.5.5.1.4b Type declared in same compilation unit.
- {
- Java.PackageMemberTypeDeclaration pmtd = scopeCompilationUnit.getPackageMemberTypeDeclaration(simpleTypeName);
- if (pmtd != null) return this.resolve((Java.AbstractTypeDeclaration) pmtd);
- }
- }
-
- // 6.5.5.1.5 Type declared in other compilation unit of same
- // package.
- {
- String pkg = (
- scopeCompilationUnit.optionalPackageDeclaration == null ? null :
- scopeCompilationUnit.optionalPackageDeclaration.packageName
- );
- String className = pkg == null ? simpleTypeName : pkg + "." + simpleTypeName;
- IClass result = findClassByName(rt.getLocation(), className);
- if (result != null) return result;
- }
-
- // 6.5.5.1.6 Type-import-on-demand declaration.
- {
- IClass importedClass = this.importTypeOnDemand(simpleTypeName, rt.getLocation());
- if (importedClass != null) return importedClass;
- }
-
- // JLS3 ???: Type imported through single static import.
- {
- Object o = this.singleStaticImports.get(simpleTypeName);
- if (o instanceof IClass) return (IClass) o;
- }
-
- // JLS3 ???: Type imported through static-import-on-demand.
- {
- IClass importedMemberType = null;
- for (Iterator it = this.staticImportsOnDemand.iterator(); it.hasNext();) {
- IClass ic = (IClass) it.next();
- IClass[] memberTypes = ic.getDeclaredIClasses();
- for (int i = 0; i < memberTypes.length; ++i) {
- IClass mt = memberTypes[i];
- if (!UnitCompiler.this.isAccessible(mt, scopeBlockStatement)) continue;
- if (mt.getDescriptor().endsWith('$' + simpleTypeName + ';')) {
- if (importedMemberType != null) UnitCompiler.this.compileError("Ambiguous static imports: \"" + importedMemberType.toString() + "\" vs. \"" + mt.toString() + "\"");
- importedMemberType = mt;
- }
- }
- }
- if (importedMemberType != null) return importedMemberType;
- }
-
- // 6.5.5.1.8 Give up.
- this.compileError("Cannot determine simple type name \"" + simpleTypeName + "\"", rt.getLocation());
- return this.iClassLoader.OBJECT;
- } else {
-
- // 6.5.5.2 Qualified type name (two or more identifiers).
- Java.Atom q = this.reclassifyName(rt.getLocation(), rt.getEnclosingScope(), rt.identifiers, rt.identifiers.length - 1);
-
- // 6.5.5.2.1 PACKAGE.CLASS
- if (q instanceof Java.Package) {
- String className = Java.join(rt.identifiers, ".");
- IClass result = findClassByName(rt.getLocation(), className);
- if (result != null) return result;
-
- this.compileError("Class \"" + className + "\" not found", rt.getLocation());
- return this.iClassLoader.OBJECT;
- }
-
- // 6.5.5.2.2 CLASS.CLASS (member type)
- String memberTypeName = rt.identifiers[rt.identifiers.length - 1];
- IClass[] types = this.getType(this.toTypeOrCE(q)).findMemberType(memberTypeName);
- if (types.length == 1) return types[0];
- if (types.length == 0) {
- this.compileError("\"" + q + "\" declares no member type \"" + memberTypeName + "\"", rt.getLocation());
- } else
- {
- this.compileError("\"" + q + "\" and its supertypes declare more than one member type \"" + memberTypeName + "\"", rt.getLocation());
- }
- return this.iClassLoader.OBJECT;
- }
- }
-
- private IClass getType2(Java.RvalueMemberType rvmt) throws CompileException {
- IClass rvt = this.getType(rvmt.rvalue);
- IClass memberType = this.findMemberType(rvt, rvmt.identifier, rvmt.getLocation());
- if (memberType == null) this.compileError("\"" + rvt + "\" has no member type \"" + rvmt.identifier + "\"", rvmt.getLocation());
- return memberType;
- }
- private IClass getType2(Java.ArrayType at) throws CompileException {
- return this.getType(at.componentType).getArrayIClass(this.iClassLoader.OBJECT);
- }
- private IClass getType2(Java.AmbiguousName an) throws CompileException {
- return this.getType(this.reclassify(an));
- }
- private IClass getType2(Java.Package p) throws CompileException {
- this.compileError("Unknown variable or type \"" + p.name + "\"", p.getLocation());
- return this.iClassLoader.OBJECT;
- }
- private IClass getType2(Java.LocalVariableAccess lva) {
- return lva.localVariable.type;
- }
- private IClass getType2(Java.FieldAccess fa) throws CompileException {
- return fa.field.getType();
- }
- private IClass getType2(Java.ArrayLength al) {
- return IClass.INT;
- }
- private IClass getType2(Java.ThisReference tr) throws CompileException {
- return this.getIClass(tr);
- }
- private IClass getType2(Java.QualifiedThisReference qtr) throws CompileException {
- return this.getTargetIClass(qtr);
- }
- private IClass getType2(Java.ClassLiteral cl) {
- return this.iClassLoader.CLASS;
- }
- private IClass getType2(Java.Assignment a) throws CompileException {
- return this.getType(a.lhs);
- }
- private IClass getType2(Java.ConditionalExpression ce) throws CompileException {
- IClass mhsType = this.getType(ce.mhs);
- IClass rhsType = this.getType(ce.rhs);
-
- if (mhsType == rhsType) {
-
- // JLS 15.25.1.1
- return mhsType;
- } else
- if (mhsType.isPrimitiveNumeric() && rhsType.isPrimitiveNumeric()) {
-
- // JLS 15.25.1.2
-
- // TODO JLS 15.25.1.2.1
-
- // TODO JLS 15.25.1.2.2
-
- // JLS 15.25.1.2.3
- return this.binaryNumericPromotionType((Java.Locatable) ce, mhsType, rhsType);
- } else
- if (this.getConstantValue(ce.mhs) == Java.Rvalue.CONSTANT_VALUE_NULL && !rhsType.isPrimitive()) {
-
- // JLS 15.25.1.3 (null : ref)
- return rhsType;
- } else
- if (!mhsType.isPrimitive() && this.getConstantValue(ce.rhs) == Java.Rvalue.CONSTANT_VALUE_NULL) {
-
- // JLS 15.25.1.3 (ref : null)
- return mhsType;
- } else
- if (!mhsType.isPrimitive() && !rhsType.isPrimitive()) {
- if (mhsType.isAssignableFrom(rhsType)) {
- return mhsType;
- } else
- if (rhsType.isAssignableFrom(mhsType)) {
- return rhsType;
- } else {
- this.compileError("Reference types \"" + mhsType + "\" and \"" + rhsType + "\" don't match", ce.getLocation());
- return this.iClassLoader.OBJECT;
- }
- } else
- {
- this.compileError("Incompatible expression types \"" + mhsType + "\" and \"" + rhsType + "\"", ce.getLocation());
- return this.iClassLoader.OBJECT;
- }
- }
- private IClass getType2(Java.Crement c) throws CompileException {
- return this.getType(c.operand);
- }
- private IClass getType2(Java.ArrayAccessExpression aae) throws CompileException {
- return this.getType(aae.lhs).getComponentType();
- }
- private IClass getType2(Java.FieldAccessExpression fae) throws CompileException {
- this.determineValue(fae);
- return this.getType(fae.value);
- }
- private IClass getType2(Java.SuperclassFieldAccessExpression scfae) throws CompileException {
- this.determineValue(scfae);
- return this.getType(scfae.value);
- }
- private IClass getType2(Java.UnaryOperation uo) throws CompileException {
- if (uo.operator == "!") return IClass.BOOLEAN;
-
- if (
- uo.operator == "+" ||
- uo.operator == "-" ||
- uo.operator == "~"
- ) return this.unaryNumericPromotionType((Locatable) uo, this.getUnboxedType(this.getType(uo.operand)));
-
- this.compileError("Unexpected operator \"" + uo.operator + "\"", uo.getLocation());
- return IClass.BOOLEAN;
- }
- private IClass getType2(Java.Instanceof io) {
- return IClass.BOOLEAN;
- }
- private IClass getType2(Java.BinaryOperation bo) throws CompileException {
- if (
- bo.op == "||" ||
- bo.op == "&&" ||
- bo.op == "==" ||
- bo.op == "!=" ||
- bo.op == "<" ||
- bo.op == ">" ||
- bo.op == "<=" ||
- bo.op == ">="
- ) return IClass.BOOLEAN;
-
- if (
- bo.op == "|" ||
- bo.op == "^" ||
- bo.op == "&"
- ) {
- IClass lhsType = this.getType(bo.lhs);
- return (
- lhsType == IClass.BOOLEAN || lhsType == this.iClassLoader.BOOLEAN ?
- IClass.BOOLEAN :
- this.binaryNumericPromotionType(
- (Java.Locatable) bo,
- lhsType,
- this.getType(bo.rhs)
- )
- );
- }
-
- if (
- bo.op == "*" ||
- bo.op == "/" ||
- bo.op == "%" ||
- bo.op == "+" ||
- bo.op == "-"
- ) {
- IClassLoader icl = this.iClassLoader;
-
- // Unroll the operands of this binary operation.
- Iterator ops = bo.unrollLeftAssociation();
-
- // Check the far left operand type.
- IClass lhsType = this.getUnboxedType(this.getType(((Java.Rvalue) ops.next())));
- if (bo.op == "+" && lhsType == icl.STRING) return icl.STRING;
-
- // Determine the expression type.
- do {
- IClass rhsType = this.getUnboxedType(this.getType(((Java.Rvalue) ops.next())));
- if (bo.op == "+" && rhsType == icl.STRING) return icl.STRING;
- lhsType = this.binaryNumericPromotionType((Java.Locatable) bo, lhsType, rhsType);
- } while (ops.hasNext());
- return lhsType;
- }
-
- if (
- bo.op == "<<" ||
- bo.op == ">>" ||
- bo.op == ">>>"
- ) {
- IClass lhsType = this.getType(bo.lhs);
- return this.unaryNumericPromotionType((Locatable) bo, lhsType);
- }
-
- this.compileError("Unexpected operator \"" + bo.op + "\"", bo.getLocation());
- return this.iClassLoader.OBJECT;
- }
- private IClass getUnboxedType(IClass type) {
- IClass c = this.isUnboxingConvertible(type);
- return c != null ? c : type;
- }
- private IClass getType2(Java.Cast c) throws CompileException {
- return this.getType(c.targetType);
- }
- private IClass getType2(Java.ParenthesizedExpression pe) throws CompileException {
- return this.getType(pe.value);
- }
-// private IClass getType2(Java.ConstructorInvocation ci) {
-// throw new RuntimeException();
-// }
- private IClass getType2(Java.MethodInvocation mi) throws CompileException {
- if (mi.iMethod == null) {
- mi.iMethod = this.findIMethod(mi);
- }
- return mi.iMethod.getReturnType();
- }
- private IClass getType2(Java.SuperclassMethodInvocation scmi) throws CompileException {
- return this.findIMethod(scmi).getReturnType();
- }
- private IClass getType2(Java.NewClassInstance nci) throws CompileException {
- if (nci.iClass == null) nci.iClass = this.getType(nci.type);
- return nci.iClass;
- }
- private IClass getType2(Java.NewAnonymousClassInstance naci) {
- return this.resolve(naci.anonymousClassDeclaration);
- }
- private IClass getType2(Java.ParameterAccess pa) throws CompileException {
- return this.getLocalVariable(pa.formalParameter).type;
- }
- private IClass getType2(Java.NewArray na) throws CompileException {
- IClass res = this.getType(na.type);
- return res.getArrayIClass(na.dimExprs.length + na.dims, this.iClassLoader.OBJECT);
- }
- private IClass getType2(Java.NewInitializedArray nia) throws CompileException {
- return this.getType(nia.arrayType);
- }
- private IClass getType2(Java.Literal l) {
- if (l.value instanceof Integer ) return IClass.INT;
- if (l.value instanceof Long ) return IClass.LONG;
- if (l.value instanceof Float ) return IClass.FLOAT;
- if (l.value instanceof Double ) return IClass.DOUBLE;
- if (l.value instanceof String ) return this.iClassLoader.STRING;
- if (l.value instanceof Character) return IClass.CHAR;
- if (l.value instanceof Boolean ) return IClass.BOOLEAN;
- if (l.value == null ) return IClass.VOID;
- throw new RuntimeException("SNO: Unidentifiable literal type \"" + l.value.getClass().getName() + "\"");
- }
-
- // ---------------- Atom.isType() ---------------
-
- private boolean isType(Java.Atom a) throws CompileException {
- final boolean[] res = new boolean[1];
- class UCE extends RuntimeException { final CompileException ce; UCE(CompileException ce) { this.ce = ce; } }
- Visitor.AtomVisitor av = new Visitor.AtomVisitor() {
- // AtomVisitor
- public void visitPackage(Java.Package p) { res[0] = UnitCompiler.this.isType2(p); }
- // TypeVisitor
- public void visitArrayType (Java.ArrayType at ) { res[0] = UnitCompiler.this.isType2(at ); }
- public void visitBasicType (Java.BasicType bt ) { res[0] = UnitCompiler.this.isType2(bt ); }
- public void visitReferenceType (Java.ReferenceType rt ) { res[0] = UnitCompiler.this.isType2(rt ); }
- public void visitRvalueMemberType(Java.RvalueMemberType rmt ) { res[0] = UnitCompiler.this.isType2(rmt); }
- public void visitSimpleType (Java.SimpleType st ) { res[0] = UnitCompiler.this.isType2(st ); }
- // RvalueVisitor
- public void visitArrayLength (Java.ArrayLength al ) { res[0] = UnitCompiler.this.isType2(al ); }
- public void visitAssignment (Java.Assignment a ) { res[0] = UnitCompiler.this.isType2(a ); }
- public void visitUnaryOperation (Java.UnaryOperation uo ) { res[0] = UnitCompiler.this.isType2(uo ); }
- public void visitBinaryOperation (Java.BinaryOperation bo ) { res[0] = UnitCompiler.this.isType2(bo ); }
- public void visitCast (Java.Cast c ) { res[0] = UnitCompiler.this.isType2(c ); }
- public void visitClassLiteral (Java.ClassLiteral cl ) { res[0] = UnitCompiler.this.isType2(cl ); }
- public void visitConditionalExpression (Java.ConditionalExpression ce ) { res[0] = UnitCompiler.this.isType2(ce ); }
- public void visitCrement (Java.Crement c ) { res[0] = UnitCompiler.this.isType2(c ); }
- public void visitInstanceof (Java.Instanceof io ) { res[0] = UnitCompiler.this.isType2(io ); }
- public void visitMethodInvocation (Java.MethodInvocation mi ) { res[0] = UnitCompiler.this.isType2(mi ); }
- public void visitSuperclassMethodInvocation(Java.SuperclassMethodInvocation smi ) { res[0] = UnitCompiler.this.isType2(smi ); }
- public void visitLiteral (Java.Literal l ) { res[0] = UnitCompiler.this.isType2(l ); }
- public void visitNewAnonymousClassInstance (Java.NewAnonymousClassInstance naci) { res[0] = UnitCompiler.this.isType2(naci); }
- public void visitNewArray (Java.NewArray na ) { res[0] = UnitCompiler.this.isType2(na ); }
- public void visitNewInitializedArray (Java.NewInitializedArray nia ) { res[0] = UnitCompiler.this.isType2(nia ); }
- public void visitNewClassInstance (Java.NewClassInstance nci ) { res[0] = UnitCompiler.this.isType2(nci ); }
- public void visitParameterAccess (Java.ParameterAccess pa ) { res[0] = UnitCompiler.this.isType2(pa ); }
- public void visitQualifiedThisReference (Java.QualifiedThisReference qtr ) { res[0] = UnitCompiler.this.isType2(qtr ); }
- public void visitThisReference (Java.ThisReference tr ) { res[0] = UnitCompiler.this.isType2(tr ); }
- // LvalueVisitor
- public void visitAmbiguousName (Java.AmbiguousName an ) { try { res[0] = UnitCompiler.this.isType2(an ); } catch (CompileException e) { throw new UCE(e); } }
- public void visitArrayAccessExpression (Java.ArrayAccessExpression aae ) { res[0] = UnitCompiler.this.isType2(aae ); }
- public void visitFieldAccess (Java.FieldAccess fa ) { res[0] = UnitCompiler.this.isType2(fa ); }
- public void visitFieldAccessExpression (Java.FieldAccessExpression fae ) { res[0] = UnitCompiler.this.isType2(fae ); }
- public void visitSuperclassFieldAccessExpression(Java.SuperclassFieldAccessExpression scfae) { res[0] = UnitCompiler.this.isType2(scfae); }
- public void visitLocalVariableAccess (Java.LocalVariableAccess lva ) { res[0] = UnitCompiler.this.isType2(lva ); }
- public void visitParenthesizedExpression (Java.ParenthesizedExpression pe ) { res[0] = UnitCompiler.this.isType2(pe ); }
- };
- try {
- a.accept(av);
- return res[0];
- } catch (UCE uce) {
- throw uce.ce;
- }
- }
- private boolean isType2(Java.Atom a) {
- return a instanceof Java.Type;
- }
- private boolean isType2(Java.AmbiguousName an) throws CompileException {
- return this.isType(this.reclassify(an));
- }
-
- /**
- * Determine whether the given {@link IClass.IMember} is accessible in the given context,
- * according to JLS 6.6.1.4. Issues a {@link #compileError(String)} if not.
- */
- private boolean isAccessible(
- IClass.IMember member,
- Java.BlockStatement contextBlockStatement
- ) throws CompileException {
- return this.isAccessible(member.getDeclaringIClass(), member.getAccess(), contextBlockStatement);
- }
-
- /**
- * Check whether the given {@link IClass.IMember} is accessible in the given context,
- * according to JLS 6.6.1.4. Issue a {@link #compileError(String)} if not.
- */
- private void checkAccessible(
- IClass.IMember member,
- Java.BlockStatement contextBlockStatement
- ) throws CompileException {
- this.checkAccessible(member.getDeclaringIClass(), member.getAccess(), contextBlockStatement);
- }
-
- /**
- * Determine whether a member (class, interface, field or method) declared in a
- * given class is accessible from a given block statement context, according
- * to JLS2 6.6.1.4.
- */
- private boolean isAccessible(
- IClass iClassDeclaringMember,
- Access memberAccess,
- Java.BlockStatement contextBlockStatement
- ) throws CompileException {
- return null == this.internalCheckAccessible(iClassDeclaringMember, memberAccess, contextBlockStatement);
- }
-
- /**
- * Verify that a member (class, interface, field or method) declared in a
- * given class is accessible from a given block statement context, according
- * to JLS2 6.6.1.4. Issue a {@link #compileError(String)} if not.
- */
- private void checkAccessible(
- IClass iClassDeclaringMember,
- Access memberAccess,
- Java.BlockStatement contextBlockStatement
- ) throws CompileException {
- String message = this.internalCheckAccessible(iClassDeclaringMember, memberAccess, contextBlockStatement);
- if (message != null) this.compileError(message, contextBlockStatement.getLocation());
- }
-
- /**
- * @return a descriptive text iff a member declared in that {@link IClass} with that {@link Access} is inaccessible
- */
- private String internalCheckAccessible(
- IClass iClassDeclaringMember,
- Access memberAccess,
- Java.BlockStatement contextBlockStatement
- ) throws CompileException {
-
- // At this point, memberAccess is PUBLIC, DEFAULT, PROECTEDED or PRIVATE.
-
- // PUBLIC members are always accessible.
- if (memberAccess == Access.PUBLIC) return null;
-
- // At this point, the member is DEFAULT, PROECTEDED or PRIVATE accessible.
-
- // Determine the class declaring the context block statement.
- IClass iClassDeclaringContextBlockStatement;
- for (Java.Scope s = contextBlockStatement.getEnclosingScope();; s = s.getEnclosingScope()) {
- if (s instanceof Java.TypeDeclaration) {
- iClassDeclaringContextBlockStatement = this.resolve((Java.TypeDeclaration) s);
- break;
- }
- }
-
- // Access is always allowed for block statements declared in the same class as the member.
- if (iClassDeclaringContextBlockStatement == iClassDeclaringMember) return null;
-
- // Check whether the member and the context block statement are enclosed by the same
- // top-level type.
- {
- IClass topLevelIClassEnclosingMember = iClassDeclaringMember;
- for (IClass c = iClassDeclaringMember.getDeclaringIClass(); c != null; c = c.getDeclaringIClass()) {
- topLevelIClassEnclosingMember = c;
- }
- IClass topLevelIClassEnclosingContextBlockStatement = iClassDeclaringContextBlockStatement;
- for (IClass c = iClassDeclaringContextBlockStatement.getDeclaringIClass(); c != null; c = c.getDeclaringIClass()) {
- topLevelIClassEnclosingContextBlockStatement = c;
- }
-
- if (topLevelIClassEnclosingMember == topLevelIClassEnclosingContextBlockStatement) return null;
- }
-
- if (memberAccess == Access.PRIVATE) {
- return "Private member cannot be accessed from type \"" + iClassDeclaringContextBlockStatement + "\".";
- }
-
- // At this point, the member is DEFAULT or PROTECTED accessible.
-
- // Check whether the member and the context block statement are declared in the same
- // package.
- if (Descriptor.areInSamePackage(
- iClassDeclaringMember.getDescriptor(),
- iClassDeclaringContextBlockStatement.getDescriptor()
- )) return null;
-
- if (memberAccess == Access.DEFAULT) {
- return "Member with \"" + memberAccess + "\" access cannot be accessed from type \"" + iClassDeclaringContextBlockStatement + "\".";
- }
-
- // At this point, the member is PROTECTED accessible.
-
- // Check whether the class declaring the context block statement is a subclass of the
- // class declaring the member or a nested class whose parent is a subclass
- IClass parentClass = iClassDeclaringContextBlockStatement;
- do {
- if (iClassDeclaringMember.isAssignableFrom(parentClass)) {
- return null;
- }
- parentClass = parentClass.getOuterIClass();
- } while(parentClass != null);
-
- return "Protected member cannot be accessed from type \"" + iClassDeclaringContextBlockStatement + "\", which is neither declared in the same package as nor is a subclass of \"" + iClassDeclaringMember + "\".";
- }
-
- /**
- * Determine whether the given {@link IClass} is accessible in the given context,
- * according to JLS2 6.6.1.2 and 6.6.1.4.
- */
- private boolean isAccessible(
- IClass type,
- Java.BlockStatement contextBlockStatement
- ) throws CompileException {
- return null == this.internalCheckAccessible(type, contextBlockStatement);
- }
-
- /**
- * Check whether the given {@link IClass} is accessible in the given context,
- * according to JLS2 6.6.1.2 and 6.6.1.4. Issues a {@link #compileError(String)} if not.
- */
- private void checkAccessible(
- IClass type,
- Java.BlockStatement contextBlockStatement
- ) throws CompileException {
- String message = this.internalCheckAccessible(type, contextBlockStatement);
- if (message != null) this.compileError(message, contextBlockStatement.getLocation());
- }
-
- private String internalCheckAccessible(
- IClass type,
- Java.BlockStatement contextBlockStatement
- ) throws CompileException {
-
- // Determine the type declaring the type.
- IClass iClassDeclaringType = type.getDeclaringIClass();
-
- // Check accessibility of package member type.
- if (iClassDeclaringType == null) {
- if (type.getAccess() == Access.PUBLIC) {
- return null;
- } else
- if (type.getAccess() == Access.DEFAULT) {
-
- // Determine the type declaring the context block statement.
- IClass iClassDeclaringContextBlockStatement;
- for (Java.Scope s = contextBlockStatement.getEnclosingScope();; s = s.getEnclosingScope()) {
- if (s instanceof Java.TypeDeclaration) {
- iClassDeclaringContextBlockStatement = this.resolve((Java.TypeDeclaration) s);
- break;
- }
- }
-
- // Check whether the type is accessed from within the same package.
- String packageDeclaringType = Descriptor.getPackageName(type.getDescriptor());
- String contextPackage = Descriptor.getPackageName(iClassDeclaringContextBlockStatement.getDescriptor());
- if (!(packageDeclaringType == null ? contextPackage == null : packageDeclaringType.equals(contextPackage))) return "\"" + type + "\" is inaccessible from this package";
- return null;
- } else
- {
- throw new RuntimeException("\"" + type + "\" has unexpected access \"" + type.getAccess() + "\"");
- }
- }
-
- // "type" is a member type at this point.
-
- return this.internalCheckAccessible(iClassDeclaringType, type.getAccess(), contextBlockStatement);
- }
-
- private final Java.Type toTypeOrCE(Java.Atom a) throws CompileException {
- Java.Type result = a.toType();
- if (result == null) {
- this.compileError("Expression \"" + a.toString() + "\" is not a type", a.getLocation());
- return new Java.SimpleType(a.getLocation(), this.iClassLoader.OBJECT);
- }
- return result;
- }
- private final Java.Rvalue toRvalueOrCE(final Java.Atom a) throws CompileException {
- Java.Rvalue result = a.toRvalue();
- if (result == null) {
- this.compileError("Expression \"" + a.toString() + "\" is not an rvalue", a.getLocation());
- return new Java.Literal(a.getLocation(), "X");
- }
- return result;
- }
- public final Java.Lvalue toLvalueOrCE(final Java.Atom a) throws CompileException {
- Java.Lvalue result = a.toLvalue();
- if (result == null) {
- this.compileError("Expression \"" + a.toString() + "\" is not an lvalue", a.getLocation());
- return new Java.Lvalue(a.getLocation()) {
- public String toString() { return a.toString(); }
- public void accept(Visitor.AtomVisitor visitor) {}
- public void accept(Visitor.RvalueVisitor visitor) {}
- public void accept(Visitor.LvalueVisitor visitor) {}
- };
- }
- return result;
- }
-
- /**
- * Copies the values of the synthetic parameters of this constructor ("this$..." and
- * "val$...") to the synthetic fields of the object ("this$..." and "val$...").
- */
- void assignSyntheticParametersToSyntheticFields(Java.ConstructorDeclarator cd) throws CompileException {
- for (Iterator it = cd.getDeclaringClass().syntheticFields.values().iterator(); it.hasNext();) {
- IClass.IField sf = (IClass.IField) it.next();
- Java.LocalVariable syntheticParameter = (Java.LocalVariable) cd.syntheticParameters.get(sf.getName());
- if (syntheticParameter == null) throw new RuntimeException("SNO: Synthetic parameter for synthetic field \"" + sf.getName() + "\" not found");
- try {
- Java.ExpressionStatement es = new Java.ExpressionStatement(new Java.Assignment(
- cd.getLocation(), // location
- new Java.FieldAccess( // lhs
- cd.getLocation(), // location
- new Java.ThisReference(cd.getLocation()), // lhs
- sf // field
- ),
- "=", // operator
- new Java.LocalVariableAccess( // rhs
- cd.getLocation(), // location
- syntheticParameter // localVariable
- )
- ));
- es.setEnclosingScope(cd);
- this.compile(es);
- } catch (Parser.ParseException e) {
- throw new RuntimeException("S.N.O.");
- }
- }
- }
-
- /**
- * Compiles the instance variable initializers and the instance initializers in their
- * lexical order.
- */
- void initializeInstanceVariablesAndInvokeInstanceInitializers(Java.ConstructorDeclarator cd) throws CompileException {
- for (int i = 0; i < cd.getDeclaringClass().variableDeclaratorsAndInitializers.size(); ++i) {
- Java.TypeBodyDeclaration tbd = (Java.TypeBodyDeclaration) cd.getDeclaringClass().variableDeclaratorsAndInitializers.get(i);
- if (!tbd.isStatic()) {
- Java.BlockStatement bs = (Java.BlockStatement) tbd;
- if (!this.compile(bs)) this.compileError("Instance variable declarator or instance initializer does not complete normally", bs.getLocation());
- }
- }
- }
-
- /**
- * Statements that jump out of blocks ("return", "break", "continue")
- * must call this method to make sure that the "finally" clauses of all
- * "try...catch" statements are executed.
- */
- private void leaveStatements(
- Java.Scope from,
- Java.Scope to,
- IClass optionalStackValueType
- ) {
- for (Java.Scope s = from; s != to; s = s.getEnclosingScope()) {
- if (s instanceof Java.BlockStatement) {
- this.leave((Java.BlockStatement) s, optionalStackValueType);
- }
- }
- }
-
- /**
- * The LHS operand of type <code>lhsType</code> is expected on the stack.
- * <p>
- * The following operators are supported:
- * <code> | ^ & * / % + - << >> >>></code>
- */
- private IClass compileArithmeticBinaryOperation(
- Locatable l,
- IClass lhsType,
- String operator,
- Java.Rvalue rhs
- ) throws CompileException {
- return this.compileArithmeticOperation(
- l,
- lhsType,
- Arrays.asList(new Java.Rvalue[] { rhs }).iterator(),
- operator
- );
- }
-
- /**
- * Execute an arithmetic operation on a sequence of <code>operands</code>. If
- * <code>type</code> is non-null, the first operand with that type is already on the stack.
- * <p>
- * The following operators are supported:
- * <code> | ^ & * / % + - << >> >>></code>
- */
- private IClass compileArithmeticOperation(
- final Locatable l,
- IClass type,
- Iterator operands,
- String operator
- ) throws CompileException {
- if (
- operator == "|" ||
- operator == "^" ||
- operator == "&"
- ) {
- final int iopcode = (
- operator == "&" ? Opcode.IAND :
- operator == "|" ? Opcode.IOR :
- operator == "^" ? Opcode.IXOR : Integer.MAX_VALUE
- );
-
- do {
- Java.Rvalue operand = (Java.Rvalue) operands.next();
-
- if (type == null) {
- type = this.compileGetValue(operand);
- } else {
- CodeContext.Inserter convertLhsInserter = this.codeContext.newInserter();
- IClass rhsType = this.compileGetValue(operand);
-
- if (
- type.isPrimitiveNumeric() &&
- rhsType.isPrimitiveNumeric()
- ) {
- IClass promotedType = this.binaryNumericPromotion(l, type, convertLhsInserter, rhsType);
- if (promotedType == IClass.INT) {
- this.writeOpcode(l, iopcode);
- } else
- if (promotedType == IClass.LONG) {
- this.writeOpcode(l, iopcode + 1);
- } else
- {
- this.compileError("Operator \"" + operator + "\" not defined on types \"" + type + "\" and \"" + rhsType + "\"", l.getLocation());
- }
- type = promotedType;
- } else
- if (
- (type == IClass.BOOLEAN && this.getUnboxedType(rhsType) == IClass.BOOLEAN) ||
- (this.getUnboxedType(type) == IClass.BOOLEAN && rhsType == IClass.BOOLEAN)
- ) {
- IClassLoader icl = this.iClassLoader;
- if (type == icl.BOOLEAN) {
- this.codeContext.pushInserter(convertLhsInserter);
- try {
- this.unboxingConversion(l, icl.BOOLEAN, IClass.BOOLEAN);
- } finally {
- this.codeContext.popInserter();
- }
- }
- if (rhsType == icl.BOOLEAN) {
- this.unboxingConversion(l, icl.BOOLEAN, IClass.BOOLEAN);
- }
- this.writeOpcode(l, iopcode);
- type = IClass.BOOLEAN;
- } else
- {
- this.compileError("Operator \"" + operator + "\" not defined on types \"" + type + "\" and \"" + rhsType + "\"", l.getLocation());
- type = IClass.INT;
- }
- }
- } while (operands.hasNext());
- return type;
- }
-
- if (
- operator == "*" ||
- operator == "/" ||
- operator == "%" ||
- operator == "+" ||
- operator == "-"
- ) {
- final int iopcode = (
- operator == "*" ? Opcode.IMUL :
- operator == "/" ? Opcode.IDIV :
- operator == "%" ? Opcode.IREM :
- operator == "+" ? Opcode.IADD :
- operator == "-" ? Opcode.ISUB : Integer.MAX_VALUE
- );
-
- do {
- Java.Rvalue operand = (Java.Rvalue) operands.next();
-
- IClass operandType = this.getType(operand);
- IClassLoader icl = this.iClassLoader;
-
- // String concatenation?
- if (operator == "+" && (type == icl.STRING || operandType == icl.STRING)) {
- return this.compileStringConcatenation(l, type, operand, operands);
- }
-
- if (type == null) {
- type = this.compileGetValue(operand);
- } else {
- CodeContext.Inserter convertLhsInserter = this.codeContext.newInserter();
- IClass rhsType = this.compileGetValue(operand);
-
- type = this.binaryNumericPromotion(l, type, convertLhsInserter, rhsType);
-
- int opcode;
- if (type == IClass.INT) {
- opcode = iopcode;
- } else
- if (type == IClass.LONG) {
- opcode = iopcode + 1;
- } else
- if (type == IClass.FLOAT) {
- opcode = iopcode + 2;
- } else
- if (type == IClass.DOUBLE) {
- opcode = iopcode + 3;
- } else
- {
- this.compileError("Unexpected promoted type \"" + type + "\"", l.getLocation());
- opcode = iopcode;
- }
- this.writeOpcode(l, opcode);
- }
- } while (operands.hasNext());
- return type;
- }
-
- if (
- operator == "<<" ||
- operator == ">>" ||
- operator == ">>>"
- ) {
- final int iopcode = (
- operator == "<<" ? Opcode.ISHL :
- operator == ">>" ? Opcode.ISHR :
- operator == ">>>" ? Opcode.IUSHR : Integer.MAX_VALUE
- );
-
- do {
- Java.Rvalue operand = (Java.Rvalue) operands.next();
-
- if (type == null) {
- type = this.compileGetValue(operand);
- } else {
- CodeContext.Inserter convertLhsInserter = this.codeContext.newInserter();
- IClass rhsType = this.compileGetValue(operand);
-
- IClass promotedLhsType;
- this.codeContext.pushInserter(convertLhsInserter);
- try {
- promotedLhsType = this.unaryNumericPromotion(l, type);
- } finally {
- this.codeContext.popInserter();
- }
- if (promotedLhsType != IClass.INT && promotedLhsType != IClass.LONG) this.compileError("Shift operation not allowed on operand type \"" + type + "\"", l.getLocation());
-
- IClass promotedRhsType = this.unaryNumericPromotion(l, rhsType);
- if (promotedRhsType != IClass.INT && promotedRhsType != IClass.LONG) this.compileError("Shift distance of type \"" + rhsType + "\" is not allowed", l.getLocation());
-
- if (promotedRhsType == IClass.LONG) this.writeOpcode(l, Opcode.L2I);
-
- this.writeOpcode(l, promotedLhsType == IClass.LONG ? iopcode + 1 : iopcode);
- type = promotedLhsType;
- }
- } while (operands.hasNext());
- return type;
- }
-
- throw new RuntimeException("Unexpected operator \"" + operator + "\"");
- }
-
- /**
- * @param type If non-null, the first operand with that type is already on the stack
- * @param operand The next operand
- * @param operands All following operands ({@link Iterator} over {@link Java.Rvalue}s)
- */
- private IClass compileStringConcatenation(
- final Locatable l,
- IClass type,
- Java.Rvalue operand,
- Iterator operands
- ) throws CompileException {
- boolean operandOnStack;
- if (type != null) {
- this.stringConversion(l, type);
- operandOnStack = true;
- } else
- {
- operandOnStack = false;
- }
-
- // Compute list of operands and merge consecutive constant operands.
- List tmp = new ArrayList(); // Compilable
- do {
- Object cv = this.getConstantValue(operand);
- if (cv == null) {
- // Non-constant operand.
- final Java.Rvalue final_operand = operand;
- tmp.add(new Compilable() {
- public void compile() throws CompileException {
- UnitCompiler.this.stringConversion(l, UnitCompiler.this.compileGetValue(final_operand));
- }
- });
-
- operand = operands.hasNext() ? (Java.Rvalue) operands.next() : null;
- } else
- {
- // Constant operand. Check to see whether the next operand is also constant.
- if (operands.hasNext()) {
- operand = (Java.Rvalue) operands.next();
- Object cv2 = this.getConstantValue(operand);
- if (cv2 != null) {
- StringBuffer sb = new StringBuffer(cv.toString()).append(cv2);
- for (;;) {
- if (!operands.hasNext()) {
- operand = null;
- break;
- }
- operand = (Java.Rvalue) operands.next();
- Object cv3 = this.getConstantValue(operand);
- if (cv3 == null) break;
- sb.append(cv3);
- }
- cv = sb.toString();
- }
- } else
- {
- operand = null;
- }
- // Break long string constants up into UTF8-able chunks.
- final String[] ss = UnitCompiler.makeUTF8Able(cv.toString());
- for (int i = 0; i < ss.length; ++i) {
- final String s = ss[i];
- tmp.add(new Compilable() {
- public void compile() throws CompileException {
- UnitCompiler.this.pushConstant(l, s);
- }
- });
- }
- }
- } while (operand != null);
-
- // At this point "tmp" contains an optimized sequence of Strings (representing constant
- // portions) and Rvalues (non-constant portions).
-
- if (tmp.size() <= (operandOnStack ? STRING_CONCAT_LIMIT - 1: STRING_CONCAT_LIMIT)) {
-
- // String concatenation through "a.concat(b).concat(c)".
- for (Iterator it = tmp.iterator(); it.hasNext();) {
- Compilable c = (Compilable) it.next();
- c.compile();
-
- // Concatenate.
- if (operandOnStack) {
- this.writeOpcode(l, Opcode.INVOKEVIRTUAL);
- this.writeConstantMethodrefInfo(
- Descriptor.STRING,
- "concat", // classFD
- "(" + Descriptor.STRING + ")" + Descriptor.STRING // methodMD
- );
- } else
- {
- operandOnStack = true;
- }
- }
- return this.iClassLoader.STRING;
- }
-
- // String concatenation through "new StringBuffer(a).append(b).append(c).append(d).toString()".
- Iterator it = tmp.iterator();
-
- String stringBuilferFD = this.isStringBuilderAvailable ? Descriptor.STRING_BUILDER : Descriptor.STRING_BUFFER;
- // "new StringBuffer(a)":
- if (operandOnStack) {
- this.writeOpcode(l, Opcode.NEW);
- this.writeConstantClassInfo(stringBuilferFD);
- this.writeOpcode(l, Opcode.DUP_X1);
- this.writeOpcode(l, Opcode.SWAP);
- } else
- {
- this.writeOpcode(l, Opcode.NEW);
- this.writeConstantClassInfo(stringBuilferFD);
- this.writeOpcode(l, Opcode.DUP);
- ((Compilable) it.next()).compile();
- }
- this.writeOpcode(l, Opcode.INVOKESPECIAL);
- this.writeConstantMethodrefInfo(
- stringBuilferFD,
- "<init>", // classFD
- "(" + Descriptor.STRING + ")" + Descriptor.VOID_ // methodMD
- );
- while (it.hasNext()) {
- ((Compilable) it.next()).compile();
-
- // "StringBuffer.append(b)":
- this.writeOpcode(l, Opcode.INVOKEVIRTUAL);
- this.writeConstantMethodrefInfo(
- stringBuilferFD,
- "append", // classFD
- "(" + Descriptor.STRING + ")" + stringBuilferFD // methodMD
- );
- }
-
- // "StringBuffer.toString()":
- this.writeOpcode(l, Opcode.INVOKEVIRTUAL);
- this.writeConstantMethodrefInfo(
- stringBuilferFD,
- "toString", // classFD
- "()" + Descriptor.STRING // methodMD
- );
- return this.iClassLoader.STRING;
- }
- interface Compilable { void compile() throws CompileException; }
-
- /**
- * Convert object of type "sourceType" to type "String". JLS2 15.18.1.1
- */
- private void stringConversion(
- Locatable l,
- IClass sourceType
- ) {
- this.writeOpcode(l, Opcode.INVOKESTATIC);
- this.writeConstantMethodrefInfo(
- Descriptor.STRING,
- "valueOf", // classFD
- "(" + ( // methodMD
- sourceType == IClass.BOOLEAN ||
- sourceType == IClass.CHAR ||
- sourceType == IClass.LONG ||
- sourceType == IClass.FLOAT ||
- sourceType == IClass.DOUBLE ? sourceType.getDescriptor() :
- sourceType == IClass.BYTE ||
- sourceType == IClass.SHORT ||
- sourceType == IClass.INT ? Descriptor.INT_ :
- Descriptor.OBJECT
- ) + ")" + Descriptor.STRING
- );
- }
-
- /**
- * Expects the object to initialize on the stack.
- * <p>
- * Notice: This method is used both for explicit constructor invocation (first statement of
- * a constructor body) and implicit constructor invocation (right after NEW).
- *
- * @param optionalEnclosingInstance Used if the target class is an inner class
- */
- private void invokeConstructor(
- Locatable l,
- Java.Scope scope,
- Java.Rvalue optionalEnclosingInstance,
- IClass targetClass,
- Java.Rvalue[] arguments
- ) throws CompileException {
-
- // Find constructors.
- IClass.IConstructor[] iConstructors = targetClass.getDeclaredIConstructors();
- if (iConstructors.length == 0) throw new RuntimeException("SNO: Target class \"" + targetClass.getDescriptor() + "\" has no constructors");
-
- IClass.IConstructor iConstructor = (IClass.IConstructor) this.findMostSpecificIInvocable(
- l,
- iConstructors, // iInvocables
- arguments // arguments
- );
-
- // Check exceptions that the constructor may throw.
- IClass[] thrownExceptions = iConstructor.getThrownExceptions();
- for (int i = 0; i < thrownExceptions.length; ++i) {
- this.checkThrownException(
- l,
- thrownExceptions[i],
- scope
- );
- }
-
- // Pass enclosing instance as a synthetic parameter.
- if (optionalEnclosingInstance != null) {
- IClass outerIClass = targetClass.getOuterIClass();
- if (outerIClass != null) {
- IClass eiic = this.compileGetValue(optionalEnclosingInstance);
- if (!outerIClass.isAssignableFrom(eiic)) this.compileError("Type of enclosing instance (\"" + eiic + "\") is not assignable to \"" + outerIClass + "\"", l.getLocation());
- }
- }
-
- // Pass local variables to constructor as synthetic parameters.
- {
- IClass.IField[] syntheticFields = targetClass.getSyntheticIFields();
-
- // Determine enclosing function declarator and type declaration.
- Java.TypeBodyDeclaration scopeTBD;
- Java.TypeDeclaration scopeTypeDeclaration;
- {
- Java.Scope s = scope;
- for (; !(s instanceof Java.TypeBodyDeclaration); s = s.getEnclosingScope());
- scopeTBD = (Java.TypeBodyDeclaration) s;
- scopeTypeDeclaration = scopeTBD.getDeclaringType();
- }
-
- if (!(scopeTypeDeclaration instanceof Java.ClassDeclaration)) {
- if (syntheticFields.length > 0) throw new RuntimeException("SNO: Target class has synthetic fields");
- } else {
- Java.ClassDeclaration scopeClassDeclaration = (Java.ClassDeclaration) scopeTypeDeclaration;
- for (int i = 0; i < syntheticFields.length; ++i) {
- IClass.IField sf = syntheticFields[i];
- if (!sf.getName().startsWith("val$")) continue;
- IClass.IField eisf = (IClass.IField) scopeClassDeclaration.syntheticFields.get(sf.getName());
- if (eisf != null) {
- if (scopeTBD instanceof Java.MethodDeclarator) {
- this.load(l, this.resolve(scopeClassDeclaration), 0);
- this.writeOpcode(l, Opcode.GETFIELD);
- this.writeConstantFieldrefInfo(
- this.resolve(scopeClassDeclaration).getDescriptor(),
- sf.getName(), // classFD
- sf.getDescriptor() // fieldFD
- );
- } else
- if (scopeTBD instanceof Java.ConstructorDeclarator) {
- Java.ConstructorDeclarator constructorDeclarator = (Java.ConstructorDeclarator) scopeTBD;
- Java.LocalVariable syntheticParameter = (Java.LocalVariable) constructorDeclarator.syntheticParameters.get(sf.getName());
- if (syntheticParameter == null) {
- this.compileError("Compiler limitation: Constructor cannot access local variable \"" + sf.getName().substring(4) + "\" declared in an enclosing block because none of the methods accesses it. As a workaround, declare a dummy method that accesses the local variable.", l.getLocation());
- this.writeOpcode(l, Opcode.ACONST_NULL);
- } else {
- this.load(l, syntheticParameter);
- }
- } else {
- this.compileError("Compiler limitation: Initializers cannot access local variables declared in an enclosing block.", l.getLocation());
- this.writeOpcode(l, Opcode.ACONST_NULL);
- }
- } else {
- String localVariableName = sf.getName().substring(4);
- Java.LocalVariable lv;
- DETERMINE_LV: {
- Java.Scope s;
-
- // Does one of the enclosing blocks declare a local variable with that name?
- for (s = scope; s instanceof Java.BlockStatement; s = s.getEnclosingScope()) {
- Java.BlockStatement bs = (Java.BlockStatement) s;
- Java.Scope es = bs.getEnclosingScope();
- if (!(es instanceof Java.Block)) continue;
- Java.Block b = (Java.Block) es;
-
- for (Iterator it = b.statements.iterator();;) {
- Java.BlockStatement bs2 = (Java.BlockStatement) it.next();
- if (bs2 == bs) break;
- if (bs2 instanceof Java.LocalVariableDeclarationStatement) {
- Java.LocalVariableDeclarationStatement lvds = ((Java.LocalVariableDeclarationStatement) bs2);
- Java.VariableDeclarator[] vds = lvds.variableDeclarators;
- for (int j = 0; j < vds.length; ++j) {
- if (vds[j].name.equals(localVariableName)) {
- lv = this.getLocalVariable(lvds, vds[j]);
- break DETERMINE_LV;
- }
- }
- }
- }
- }
-
- // Does the declaring function declare a parameter with that name?
- while (!(s instanceof Java.FunctionDeclarator)) s = s.getEnclosingScope();
- Java.FunctionDeclarator fd = (Java.FunctionDeclarator) s;
- for (int j = 0; j < fd.formalParameters.length; ++j) {
- Java.FunctionDeclarator.FormalParameter fp = fd.formalParameters[j];
- if (fp.name.equals(localVariableName)) {
- lv = this.getLocalVariable(fp);
- break DETERMINE_LV;
- }
- }
- throw new RuntimeException("SNO: Synthetic field \"" + sf.getName() + "\" neither maps a synthetic field of an enclosing instance nor a local variable");
- }
- this.load(l, lv);
- }
- }
- }
- }
-
- // Evaluate constructor arguments.
- IClass[] parameterTypes = iConstructor.getParameterTypes();
- for (int i = 0; i < arguments.length; ++i) {
- this.assignmentConversion(
- l, // l
- this.compileGetValue(arguments[i]), // sourceType
- parameterTypes[i], // targetType
- this.getConstantValue(arguments[i]) // optionalConstantValue
- );
- }
-
- // Invoke!
- // Notice that the method descriptor is "iConstructor.getDescriptor()" prepended with the
- // synthetic parameters.
- this.writeOpcode(l, Opcode.INVOKESPECIAL);
- this.writeConstantMethodrefInfo(
- targetClass.getDescriptor(),
- "<init>", // classFD
- iConstructor.getDescriptor() // methodMD
- );
- }
-
- /*package*/ IClass.IField[] getIFields(final Java.FieldDeclaration fd) {
- IClass.IField[] res = new IClass.IField[fd.variableDeclarators.length];
- for (int i = 0; i < res.length; ++i) {
- final Java.VariableDeclarator vd = fd.variableDeclarators[i];
- res[i] = this.resolve(fd.getDeclaringType()).new IField() {
-
- // Implement IMember.
- public Access getAccess() {
- switch (fd.modifiers & Mod.PPP) {
- case Mod.PRIVATE:
- return Access.PRIVATE;
- case Mod.PROTECTED:
- return Access.PROTECTED;
- case Mod.PACKAGE:
- return Access.DEFAULT;
- case Mod.PUBLIC:
- return Access.PUBLIC;
- default:
- throw new RuntimeException("Invalid access");
- }
- }
-
- // Implement "IField".
- public boolean isStatic() { return (fd.modifiers & Mod.STATIC) != 0; }
- public IClass getType() throws CompileException {
- return UnitCompiler.this.getType(fd.type).getArrayIClass(vd.brackets, UnitCompiler.this.iClassLoader.OBJECT);
- }
- public String getName() { return vd.name; }
- public Object getConstantValue() throws CompileException {
- if (
- (fd.modifiers & Mod.FINAL) != 0 &&
- vd.optionalInitializer instanceof Java.Rvalue
- ) {
- Object constantInitializerValue = UnitCompiler.this.getConstantValue((Java.Rvalue) vd.optionalInitializer);
- if (constantInitializerValue != null) return UnitCompiler.this.assignmentConversion(
- (Locatable) vd.optionalInitializer, // l
- constantInitializerValue, // value
- this.getType() // targetType
- );
- }
- return null;
- }
- };
- }
- return res;
- }
-
- /**
- * Determine the non-constant-final initializer of the given {@link Java.VariableDeclarator}.
- * @return <code>null</code> if the variable is declared without an initializer or if the initializer is constant-final
- */
- Java.ArrayInitializerOrRvalue getNonConstantFinalInitializer(Java.FieldDeclaration fd, Java.VariableDeclarator vd) throws CompileException {
-
- // Check if optional initializer exists.
- if (vd.optionalInitializer == null) return null;
-
- // Check if initializer is constant-final.
- if (
- (fd.modifiers & Mod.STATIC) != 0 &&
- (fd.modifiers & Mod.FINAL) != 0 &&
- vd.optionalInitializer instanceof Java.Rvalue &&
- this.getConstantValue((Java.Rvalue) vd.optionalInitializer) != null
- ) return null;
-
- return vd.optionalInitializer;
- }
-
- private Java.Atom reclassify(Java.AmbiguousName an) throws CompileException {
- if (an.reclassified == null) {
- an.reclassified = this.reclassifyName(
- an.getLocation(),
- (Java.Scope) an.getEnclosingBlockStatement(),
- an.identifiers, an.n
- );
- }
- return an.reclassified;
- }
-
- /**
- * JLS 6.5.2.2
- * <p>
- * Reclassify the ambiguous name consisting of the first <code>n</code> of the
- * <code>identifers</code>.
- * @param location
- * @param scope
- * @param identifiers
- * @param n
- * @throws CompileException
- */
- private Java.Atom reclassifyName(
- Location location,
- Java.Scope scope,
- final String[] identifiers,
- int n
- ) throws CompileException {
-
- if (n == 1) return this.reclassifyName(
- location,
- scope,
- identifiers[0]
- );
-
- // 6.5.2.2
- Java.Atom lhs = this.reclassifyName(
- location,
- scope,
- identifiers, n - 1
- );
- String rhs = identifiers[n - 1];
-
- // 6.5.2.2.1
- if (UnitCompiler.DEBUG) System.out.println("lhs = " + lhs);
- if (lhs instanceof Java.Package) {
- String className = ((Java.Package) lhs).name + '.' + rhs;
- IClass result = findClassByName(location, className);
- if (result != null) return new Java.SimpleType(location, result);
-
- return new Java.Package(location, className);
- }
-
- // 6.5.2.2.3.2 EXPRESSION.length
- if (rhs.equals("length") && this.getType(lhs).isArray()) {
- Java.ArrayLength al = new Java.ArrayLength(location, this.toRvalueOrCE(lhs));
- if (!(scope instanceof Java.BlockStatement)) {
- this.compileError("\".length\" only allowed in expression context");
- return al;
- }
- al.setEnclosingBlockStatement((Java.BlockStatement) scope);
- return al;
- }
-
- IClass lhsType = this.getType(lhs);
-
- // Notice: Don't need to check for 6.5.2.2.2.1 TYPE.METHOD and 6.5.2.2.3.1
- // EXPRESSION.METHOD here because that has been done before.
-
- {
- IClass.IField field = this.findIField(lhsType, rhs, location);
- if (field != null) {
- // 6.5.2.2.2.2 TYPE.FIELD
- // 6.5.2.2.3.2 EXPRESSION.FIELD
- Java.FieldAccess fa = new Java.FieldAccess(
- location,
- lhs,
- field
- );
- fa.setEnclosingBlockStatement((Java.BlockStatement) scope);
- return fa;
- }
- }
-
- IClass[] classes = lhsType.getDeclaredIClasses();
- for (int i = 0; i < classes.length; ++i) {
- final IClass memberType = classes[i];
- String name = Descriptor.toClassName(memberType.getDescriptor());
- name = name.substring(name.lastIndexOf('$') + 1);
- if (name.equals(rhs)) {
-
- // 6.5.2.2.2.3 TYPE.TYPE
- // 6.5.2.2.3.3 EXPRESSION.TYPE
- return new Java.SimpleType(location, memberType);
- }
- }
-
- this.compileError("\"" + rhs + "\" is neither a method, a field, nor a member class of \"" + lhsType + "\"", location);
- return new Java.Atom(location) {
- public String toString() { return Java.join(identifiers, "."); }
- public final void accept(Visitor.AtomVisitor visitor) {}
- };
- }
-
- private IClass findClassByName(Location location, String className) throws CompileException {
- IClass res = this.findClass(className);
- if(res != null) return res;
- try {
- return this.iClassLoader.loadIClass(Descriptor.fromClassName(className));
- } catch (ClassNotFoundException ex) {
- if (ex.getException() instanceof CompileException) throw (CompileException) ex.getException();
- throw new CompileException(className, location, ex);
- }
- }
-
- /**
- * JLS 6.5.2.1
- * @param location
- * @param scope
- * @param identifier
- * @throws CompileException
- */
- private Java.Atom reclassifyName(
- Location location,
- Java.Scope scope,
- final String identifier
- ) throws CompileException {
-
- // Determine scope block statement, type body declaration, type and compilation unit.
- Java.BlockStatement scopeBlockStatement = null;
- Java.TypeBodyDeclaration scopeTBD = null;
- Java.AbstractTypeDeclaration scopeTypeDeclaration = null;
- Java.CompilationUnit scopeCompilationUnit;
- {
- Java.Scope s = scope;
- if (s instanceof Java.BlockStatement) scopeBlockStatement = (Java.BlockStatement) s;
- while (
- (s instanceof Java.BlockStatement || s instanceof Java.CatchClause)
- && !(s instanceof Java.TypeBodyDeclaration)
- ) s = s.getEnclosingScope();
- if (s instanceof Java.TypeBodyDeclaration) {
- scopeTBD = (Java.TypeBodyDeclaration) s;
- s = s.getEnclosingScope();
- }
- if (s instanceof Java.TypeDeclaration) {
- scopeTypeDeclaration = (Java.AbstractTypeDeclaration) s;
- s = s.getEnclosingScope();
- }
- while (!(s instanceof Java.CompilationUnit)) s = s.getEnclosingScope();
- scopeCompilationUnit = (Java.CompilationUnit) s;
- }
-
- // 6.5.2.1.BL1
-
- // 6.5.2.BL1.B1.B1.1 (JLS3: 6.5.2.BL1.B1.B1.1) / 6.5.6.1.1 Local variable.
- // 6.5.2.BL1.B1.B1.2 (JLS3: 6.5.2.BL1.B1.B1.2) / 6.5.6.1.1 Parameter.
- {
- Java.Scope s = scope;
- if (s instanceof Java.BlockStatement) {
- Java.LocalVariable lv = ((Java.BlockStatement) s).findLocalVariable(identifier);
- if (lv != null) {
- Java.LocalVariableAccess lva = new Java.LocalVariableAccess(location, lv);
- if (!(scope instanceof Java.BlockStatement)) throw new RuntimeException("SNO: Local variable access in non-block statement context!?");
- lva.setEnclosingBlockStatement((Java.BlockStatement) scope);
- return lva;
- }
- s = s.getEnclosingScope();
- }
- while (s instanceof Java.BlockStatement || s instanceof Java.CatchClause) s = s.getEnclosingScope();
- if (s instanceof Java.FunctionDeclarator) {
- s = s.getEnclosingScope();
- if (s instanceof Java.InnerClassDeclaration) {
- Java.InnerClassDeclaration icd = (Java.InnerClassDeclaration) s;
- s = s.getEnclosingScope();
- if (s instanceof Java.AnonymousClassDeclaration) s = s.getEnclosingScope();
- while (s instanceof Java.BlockStatement) {
- Java.LocalVariable lv = ((Java.BlockStatement) s).findLocalVariable(identifier);
- if (lv != null) {
- if (!lv.finaL) this.compileError("Cannot access non-final local variable \"" + identifier + "\" from inner class");
- final IClass lvType = lv.type;
- IClass.IField iField = new SimpleIField(
- this.resolve(icd),
- "val$" + identifier,
- lvType
- );
- icd.defineSyntheticField(iField);
- Java.FieldAccess fa = new Java.FieldAccess(
- location, // location
- new Java.QualifiedThisReference( // lhs
- location, // location
- new Java.SimpleType(location, this.resolve(icd)) // qualification
- ),
- iField // field
- );
- fa.setEnclosingBlockStatement((Java.BlockStatement) scope);
- return fa;
- }
- s = s.getEnclosingScope();
- while (s instanceof Java.BlockStatement) s = s.getEnclosingScope();
- if (!(s instanceof Java.FunctionDeclarator)) break;
- s = s.getEnclosingScope();
- if (!(s instanceof Java.InnerClassDeclaration)) break;
- icd = (Java.InnerClassDeclaration) s;
- s = s.getEnclosingScope();
- }
- }
- }
- }
-
- // 6.5.2.BL1.B1.B1.3 (JLS3: 6.5.2.BL1.B1.B1.3) / 6.5.6.1.2.1 Field.
- Java.BlockStatement enclosingBlockStatement = null;
- for (Java.Scope s = scope; !(s instanceof Java.CompilationUnit); s = s.getEnclosingScope()) {
- if (s instanceof Java.BlockStatement && enclosingBlockStatement == null) enclosingBlockStatement = (Java.BlockStatement) s;
- if (s instanceof Java.TypeDeclaration) {
- final Java.AbstractTypeDeclaration enclosingTypeDecl = (Java.AbstractTypeDeclaration)s;
- final IClass etd = UnitCompiler.this.resolve(enclosingTypeDecl);
- final IClass.IField f = this.findIField(etd, identifier, location);
- if (f != null) {
- if (f.isStatic()) {
- this.warning("IASF", "Implicit access to static field \"" + identifier + "\" of declaring class (better write \"" + f.getDeclaringIClass() + '.' + f.getName() + "\")", location);
- } else
- if (f.getDeclaringIClass() == etd) {
- this.warning("IANSF", "Implicit access to non-static field \"" + identifier + "\" of declaring class (better write \"this." + f.getName() + "\")", location);
- } else {
- this.warning("IANSFEI", "Implicit access to non-static field \"" + identifier + "\" of enclosing instance (better write \"" + f.getDeclaringIClass() + ".this." + f.getName() + "\")", location);
- }
-
- Java.SimpleType ct = new Java.SimpleType(scopeTypeDeclaration.getLocation(), (IClass) etd);
- Java.Atom lhs;
- if (scopeTBD.isStatic()) {
-
- // Field access in static method context.
- lhs = ct;
- } else
- {
-
- // Field access in non-static method context.
- if (f.isStatic()) {
-
- // Access to static field.
- lhs = ct;
- } else {
-
- // Access to non-static field.
- lhs = new Java.QualifiedThisReference(location, ct);
- }
- }
- Java.Rvalue res = new Java.FieldAccess(
- location,
- lhs,
- f
- );
- res.setEnclosingBlockStatement(enclosingBlockStatement);
- return res;
- }
- }
- }
-
- // JLS3 6.5.2.BL1.B1.B2.1 Static field imported through single static import.
- {
- Object o = this.singleStaticImports.get(identifier);
- if (o instanceof IField) {
- FieldAccess fieldAccess = new FieldAccess(location, new SimpleType(location, ((IField) o).getDeclaringIClass()), (IField) o);
- fieldAccess.setEnclosingBlockStatement(enclosingBlockStatement);
- return fieldAccess;
- }
- }
-
- // JLS3 6.5.2.BL1.B1.B2.2 Static field imported through static-import-on-demand.
- {
- IField importedField = null;
- for (Iterator it = this.staticImportsOnDemand.iterator(); it.hasNext();) {
- IClass iClass = (IClass) it.next();
- IField[] flds = iClass.getDeclaredIFields();
- for (int i = 0 ; i < flds.length; ++i) {
- IField f = flds[i];
- if (f.getName().equals(identifier)) {
- if (!UnitCompiler.this.isAccessible(f, enclosingBlockStatement)) continue; // JLS3 7.5.4 Static-Import-on-Demand Declaration
- if (importedField != null) UnitCompiler.this.compileError("Ambiguous static field import: \"" + importedField.toString() + "\" vs. \"" + f.toString() + "\"");
- importedField = f;
- }
- }
- }
- if (importedField != null) {
- if (!importedField.isStatic()) UnitCompiler.this.compileError("Cannot static-import non-static field");
- FieldAccess fieldAccess = new FieldAccess(location, new SimpleType(location, importedField.getDeclaringIClass()), importedField);
- fieldAccess.setEnclosingBlockStatement(enclosingBlockStatement);
- return fieldAccess;
- }
- }
-
- // Hack: "java" MUST be a package, not a class.
- if (identifier.equals("java")) return new Java.Package(location, identifier);
-
- // 6.5.2.BL1.B1.B2.1 (JLS3: 6.5.2.BL1.B1.B3.2) Local class.
- {
- Java.LocalClassDeclaration lcd = this.findLocalClassDeclaration(scope, identifier);
- if (lcd != null) return new Java.SimpleType(location, this.resolve(lcd));
- }
-
- // 6.5.2.BL1.B1.B2.2 (JLS3: 6.5.2.BL1.B1.B3.3) Member type.
- if (scopeTypeDeclaration != null) {
- IClass memberType = this.findMemberType(UnitCompiler.this.resolve(scopeTypeDeclaration), identifier, location);
- if (memberType != null) return new Java.SimpleType(location, memberType);
- }
-
- // 6.5.2.BL1.B1.B3.1 (JLS3: 6.5.2.BL1.B1.B4.1) Single type import.
- {
- IClass iClass = this.importSingleType(identifier, location);
- if (iClass != null) return new Java.SimpleType(location, iClass);
- }
-
- // 6.5.2.BL1.B1.B3.2 (JLS3: 6.5.2.BL1.B1.B3.1) Package member class/interface declared in this compilation unit.
- // Notice that JLS2 looks this up AFTER local class, member type, single type import, while
- // JLS3 looks this up BEFORE local class, member type, single type import.
- {
- Java.PackageMemberTypeDeclaration pmtd = scopeCompilationUnit.getPackageMemberTypeDeclaration(identifier);
- if (pmtd != null) return new Java.SimpleType(location, this.resolve((Java.AbstractTypeDeclaration) pmtd));
- }
-
- // 6.5.2.BL1.B1.B4 Class or interface declared in same package.
- // Notice: Why is this missing in JLS3?
- {
- String className = (
- scopeCompilationUnit.optionalPackageDeclaration == null ?
- identifier :
- scopeCompilationUnit.optionalPackageDeclaration.packageName + '.' + identifier
- );
- IClass result = findClassByName(location, className);
- if (result != null) return new Java.SimpleType(location, result);
- }
-
- // 6.5.2.BL1.B1.B5 (JLS3: 6.5.2.BL1.B1.B4.2), 6.5.2.BL1.B1.B6 Type-import-on-demand.
- {
- IClass importedClass = this.importTypeOnDemand(identifier, location);
- if (importedClass != null) {
- return new Java.SimpleType(location, importedClass);
- }
- }
-
- // JLS3 6.5.2.BL1.B1.B4.3 Type imported through single static import.
- {
- Object o = this.singleStaticImports.get(identifier);
- if (o instanceof IClass) return new SimpleType(null, (IClass) o);
- }
-
- // JLS3 6.5.2.BL1.B1.B4.4 Type imported through static-import-on-demand.
- {
- IClass importedType = null;
- for (Iterator it = this.staticImportsOnDemand.iterator(); it.hasNext();) {
- IClass ic = (IClass) it.next();
- IClass[] memberTypes = ic.getDeclaredIClasses();
- for (int i = 0; i < memberTypes.length; ++i) {
- IClass mt = memberTypes[i];
- if (!UnitCompiler.this.isAccessible(mt, scopeBlockStatement)) continue;
- if (mt.getDescriptor().endsWith('$' + identifier + ';')) {
- if (importedType != null) UnitCompiler.this.compileError("Ambiguous static type import: \"" + importedType.toString() + "\" vs. \"" + mt.toString() + "\"");
- importedType = mt;
- }
- }
- }
- if (importedType != null) return new Java.SimpleType(null, importedType);
- }
-
- // 6.5.2.BL1.B1.B7 Package name
- return new Java.Package(location, identifier);
- }
-
- private void determineValue(Java.FieldAccessExpression fae) throws CompileException {
- if (fae.value != null) return;
-
- IClass lhsType = this.getType(fae.lhs);
-
- if (fae.fieldName.equals("length") && lhsType.isArray()) {
- fae.value = new Java.ArrayLength(
- fae.getLocation(),
- this.toRvalueOrCE(fae.lhs)
- );
- } else {
- IClass.IField iField = this.findIField(lhsType, fae.fieldName, fae.getLocation());
- if (iField == null) {
- this.compileError("\"" + this.getType(fae.lhs).toString() + "\" has no field \"" + fae.fieldName + "\"", fae.getLocation());
- fae.value = new Java.Rvalue(fae.getLocation()) {
-// public IClass compileGet() throws CompileException { return this.iClassLoader.OBJECT; }
- public String toString() { return "???"; }
- public final void accept(Visitor.AtomVisitor visitor) {}
- public final void accept(Visitor.RvalueVisitor visitor) {}
- };
- return;
- }
-
- fae.value = new Java.FieldAccess(
- fae.getLocation(),
- fae.lhs,
- iField
- );
- }
- fae.value.setEnclosingBlockStatement(fae.getEnclosingBlockStatement());
- }
-
- /** "super.fld", "Type.super.fld" */
- private void determineValue(Java.SuperclassFieldAccessExpression scfae) throws CompileException {
- if (scfae.value != null) return;
-
- Rvalue lhs;
- {
- Java.ThisReference tr = new Java.ThisReference(scfae.getLocation());
- tr.setEnclosingBlockStatement(scfae.getEnclosingBlockStatement());
- IClass type;
- if (scfae.optionalQualification != null) {
- type = UnitCompiler.this.getType(scfae.optionalQualification);
- } else
- {
- type = this.getType(tr);
- }
- lhs = new Java.Cast(scfae.getLocation(), new SimpleType(scfae.getLocation(), type.getSuperclass()), tr);
- }
-
- IClass.IField iField = this.findIField(this.getType(lhs), scfae.fieldName, scfae.getLocation());
- if (iField == null) {
- this.compileError("Class has no field \"" + scfae.fieldName + "\"", scfae.getLocation());
- scfae.value = new Java.Rvalue(scfae.getLocation()) {
- public String toString() { return "???"; }
- public final void accept(Visitor.AtomVisitor visitor) {}
- public final void accept(Visitor.RvalueVisitor visitor) {}
- };
- return;
- }
- scfae.value = new Java.FieldAccess(
- scfae.getLocation(),
- lhs,
- iField
- );
- scfae.value.setEnclosingBlockStatement(scfae.getEnclosingBlockStatement());
- }
-
- /**
- * Find named methods of "targetType", examine the argument types and choose the
- * most specific method. Check that only the allowed exceptions are thrown.
- * <p>
- * Notice that the returned {@link IClass.IMethod} may be declared in an enclosing type.
- *
- * @return The selected {@link IClass.IMethod} or <code>null</code>
- */
- public IClass.IMethod findIMethod(Java.MethodInvocation mi) throws CompileException {
- IClass.IMethod iMethod;
- FIND_METHOD: {
-
- // Method declared by enclosing type declarations?
- if (mi.optionalTarget == null) {
- for (Java.Scope s = mi.getEnclosingBlockStatement(); !(s instanceof Java.CompilationUnit); s = s.getEnclosingScope()) {
- if (s instanceof Java.TypeDeclaration) {
- Java.TypeDeclaration td = (Java.TypeDeclaration) s;
-
- // Find methods with specified name.
- iMethod = this.findIMethod(
- (Locatable) mi, // loc
- this.resolve(td), // targetType
- mi.methodName, // methodName
- mi.arguments // arguments
- );
- if (iMethod != null) break FIND_METHOD;
- }
- }
- }
-
- // Method declared by the target's type?
- if (mi.optionalTarget != null) {
-
- // Find methods with specified name.
- iMethod = this.findIMethod(
- (Locatable) mi, // loc
- this.getType(mi.optionalTarget), // targetType
- mi.methodName, // methodName
- mi.arguments // arguments
- );
- if (iMethod != null) break FIND_METHOD;
- }
-
- // Static method declared through single static import?
- {
- Object o = this.singleStaticImports.get(mi.methodName);
- if (o instanceof List) {
- IClass declaringIClass = ((IMethod) ((List) o).get(0)).getDeclaringIClass();
- iMethod = this.findIMethod(
- (Locatable) mi, // l
- declaringIClass, // targetType
- mi.methodName, // methodName
- mi.arguments // arguments
- );
- if (iMethod != null) break FIND_METHOD;
- }
- }
-
- // Static method declared through static-import-on-demand?
- iMethod = null;
- for (Iterator it = this.staticImportsOnDemand.iterator(); it.hasNext();) {
- IClass iClass = (IClass) it.next();
- IMethod im = this.findIMethod(
- (Locatable) mi, // l
- iClass, // targetType
- mi.methodName, // methodName
- mi.arguments // arguments
- );
- if (im != null) {
- if (iMethod != null) UnitCompiler.this.compileError("Ambiguous static method import: \"" + iMethod.toString() + "\" vs. \"" + im.toString() + "\"");
- iMethod = im;
- }
- }
- if (iMethod != null) break FIND_METHOD;
-
- this.compileError("A method named \"" + mi.methodName + "\" is not declared in any enclosing class nor any supertype, nor through a static import", mi.getLocation());
- return fakeIMethod(this.iClassLoader.OBJECT, mi.methodName, mi.arguments);
- }
-
- this.checkThrownExceptions(mi, iMethod);
- return iMethod;
- }
-
- /**
- * Find a {@link IClass.IMethod} in the given <code>targetType</code>, its superclasses or
- * superinterfaces with the given <code>name</code> and for the given <code>arguments</code>.
- * If more than one such method exists, choose the most specific one (JLS 15.11.2).
- *
- * @return <code>null</code> if no appropriate method could be found
- */
- private IClass.IMethod findIMethod(
- Locatable loc,
- IClass targetType,
- String methodName,
- Rvalue[] arguments
- ) throws CompileException {
-
- // Get all methods
- List ms = new ArrayList();
- this.getIMethods(targetType, methodName, ms);
- if (ms.size() == 0) return null;
-
- // Determine arguments' types, choose the most specific method
- return (IClass.IMethod) this.findMostSpecificIInvocable(
- loc, // loc
- (IClass.IMethod[]) ms.toArray(new IClass.IMethod[ms.size()]), // iInvocables
- arguments // arguments
- );
- }
-
- private IMethod fakeIMethod(IClass targetType, final String name, Rvalue[] arguments) throws CompileException {
- final IClass[] pts = new IClass[arguments.length];
- for (int i = 0; i < arguments.length; ++i) pts[i] = this.getType(arguments[i]);
- return targetType.new IMethod() {
- public String getName() { return name; }
- public IClass getReturnType() throws CompileException { return IClass.INT; }
- public boolean isStatic() { return false; }
- public boolean isAbstract() { return false; }
- public IClass[] getParameterTypes() throws CompileException { return pts; }
- public IClass[] getThrownExceptions() throws CompileException { return new IClass[0]; }
- public Access getAccess() { return Access.PUBLIC; }
- };
- }
-
- /**
- * Add all methods with the given <code>methodName</code> that are declared
- * by the <code>type</code>, its superclasses and all their superinterfaces
- * to the result list <code>v</code>.
- * @param type
- * @param methodName
- * @param v
- * @throws CompileException
- */
- public void getIMethods(
- IClass type,
- String methodName,
- List v // IMethod
- ) throws CompileException {
-
- // Check methods declared by this type.
- {
- IClass.IMethod[] ims = type.getDeclaredIMethods(methodName);
- for (int i = 0; i < ims.length; ++i) v.add(ims[i]);
- }
-
- // Check superclass.
- IClass superclass = type.getSuperclass();
- if (superclass != null) this.getIMethods(superclass, methodName, v);
-
- // Check superinterfaces.
- IClass[] interfaces = type.getInterfaces();
- for (int i = 0; i < interfaces.length; ++i) this.getIMethods(interfaces[i], methodName, v);
-
- // JLS2 6.4.3
- if (superclass == null && interfaces.length == 0 && type.isInterface()) {
- IClass.IMethod[] oms = this.iClassLoader.OBJECT.getDeclaredIMethods(methodName);
- for (int i = 0; i < oms.length; ++i) {
- IClass.IMethod om = oms[i];
- if (!om.isStatic() && om.getAccess() == Access.PUBLIC) v.add(om);
- }
- }
- }
-
- public IClass.IMethod findIMethod(Java.SuperclassMethodInvocation scmi) throws CompileException {
- Java.ClassDeclaration declaringClass;
- for (Java.Scope s = scmi.getEnclosingBlockStatement();; s = s.getEnclosingScope()) {
- if (s instanceof Java.FunctionDeclarator) {
- Java.FunctionDeclarator fd = (Java.FunctionDeclarator) s;
- if ((fd.modifiers & Mod.STATIC) != 0) this.compileError("Superclass method cannot be invoked in static context", scmi.getLocation());
- }
- if (s instanceof Java.ClassDeclaration) {
- declaringClass = (Java.ClassDeclaration) s;
- break;
- }
- }
- IClass superclass = this.resolve(declaringClass).getSuperclass();
- IMethod iMethod = this.findIMethod(
- (Locatable) scmi, // l
- superclass, // targetType
- scmi.methodName, // methodName
- scmi.arguments // arguments
- );
- if (iMethod == null) {
- this.compileError("Class \"" + superclass + "\" has no method named \"" + scmi.methodName + "\"", scmi.getLocation());
- return fakeIMethod(superclass, scmi.methodName, scmi.arguments);
- }
- this.checkThrownExceptions(scmi, iMethod);
- return iMethod;
- }
-
- /**
- * Determine the arguments' types, determine the applicable invocables and choose the most
- * specific invocable.
- *
- * @param iInvocables Length must be greater than zero
- *
- * @return The selected {@link IClass.IInvocable}
- * @throws CompileException
- */
- private IClass.IInvocable findMostSpecificIInvocable(
- Locatable l,
- final IInvocable[] iInvocables,
- Rvalue[] arguments
- ) throws CompileException {
-
- // Determine arguments' types.
- final IClass[] argumentTypes = new IClass[arguments.length];
- for (int i = 0; i < arguments.length; ++i) {
- argumentTypes[i] = this.getType(arguments[i]);
- }
-
- IInvocable ii = this.findMostSpecificIInvocable(l, iInvocables, argumentTypes, false);
- if (ii != null) return ii;
-
- ii = this.findMostSpecificIInvocable(l, iInvocables, argumentTypes, true);
- if (ii != null) return ii;
-
- // Report a nice compile error.
- StringBuffer sb = new StringBuffer("No applicable constructor/method found for ");
- if (argumentTypes.length == 0) {
- sb.append("zero actual parameters");
- } else {
- sb.append("actual parameters \"").append(argumentTypes[0]);
- for (int i = 1; i < argumentTypes.length; ++i) {
- sb.append(", ").append(argumentTypes[i]);
- }
- sb.append("\"");
- }
- sb.append("; candidates are: ").append('"' + iInvocables[0].toString() + '"');
- for (int i = 1; i < iInvocables.length; ++i) {
- sb.append(", ").append('"' + iInvocables[i].toString() + '"');
- }
- this.compileError(sb.toString(), l.getLocation());
-
- // Well, returning a "fake" IInvocable is a bit tricky, because the iInvocables
- // can be of different types.
- if (iInvocables[0] instanceof IClass.IConstructor) {
- return iInvocables[0].getDeclaringIClass().new IConstructor() {
- public IClass[] getParameterTypes() { return argumentTypes; }
- public Access getAccess() { return Access.PUBLIC; }
- public IClass[] getThrownExceptions() { return new IClass[0]; }
- };
- } else
- if (iInvocables[0] instanceof IClass.IMethod) {
- return iInvocables[0].getDeclaringIClass().new IMethod() {
- public boolean isStatic() { return true; }
- public boolean isAbstract() { return false; }
- public IClass getReturnType() { return IClass.INT; }
- public String getName() { return ((IClass.IMethod) iInvocables[0]).getName(); }
- public Access getAccess() { return Access.PUBLIC; }
- public IClass[] getParameterTypes() { return argumentTypes; }
- public IClass[] getThrownExceptions() { return new IClass[0]; }
- };
- } else
- {
- return iInvocables[0];
- }
- }
-
- /**
- * Determine the applicable invocables and choose the most specific invocable.
- *
- * @return the maximally specific {@link IClass.IInvocable} or <code>null</code> if no {@link IClass.IInvocable} is applicable
- *
- * @throws CompileException
- */
- public IClass.IInvocable findMostSpecificIInvocable(
- Locatable l,
- final IInvocable[] iInvocables,
- final IClass[] argumentTypes,
- boolean boxingPermitted
- ) throws CompileException {
- if (UnitCompiler.DEBUG) {
- System.out.println("Argument types:");
- for (int i = 0; i < argumentTypes.length; ++i) {
- System.out.println(argumentTypes[i]);
- }
- }
-
- // Select applicable methods (15.12.2.1).
- List applicableIInvocables = new ArrayList();
- NEXT_METHOD:
- for (int i = 0; i < iInvocables.length; ++i) {
- IClass.IInvocable ii = iInvocables[i];
-
- // Check parameter count.
- IClass[] parameterTypes = ii.getParameterTypes();
- if (parameterTypes.length != argumentTypes.length) continue;
-
- // Check argument types vs. parameter types.
- if (UnitCompiler.DEBUG) System.out.println("Parameter / argument type check:");
- for (int j = 0; j < argumentTypes.length; ++j) {
- // Is method invocation conversion possible (5.3)?
- if (UnitCompiler.DEBUG) System.out.println(parameterTypes[j] + " <=> " + argumentTypes[j]);
- if (!this.isMethodInvocationConvertible(argumentTypes[j], parameterTypes[j], boxingPermitted)) continue NEXT_METHOD;
- }
-
- // Applicable!
- if (UnitCompiler.DEBUG) System.out.println("Applicable!");
- applicableIInvocables.add(ii);
- }
- if (applicableIInvocables.size() == 0) return null;
-
- // Choose the most specific invocable (15.12.2.2).
- if (applicableIInvocables.size() == 1) {
- return (IClass.IInvocable) applicableIInvocables.get(0);
- }
-
- // Determine the "maximally specific invocables".
- List maximallySpecificIInvocables = new ArrayList();
- for (int i = 0; i < applicableIInvocables.size(); ++i) {
- IClass.IInvocable applicableIInvocable = (IClass.IInvocable) applicableIInvocables.get(i);
- int moreSpecific = 0, lessSpecific = 0;
- for (int j = 0; j < maximallySpecificIInvocables.size(); ++j) {
- IClass.IInvocable mostSpecificIInvocable = (IClass.IInvocable) maximallySpecificIInvocables.get(j);
- if (applicableIInvocable.isMoreSpecificThan(mostSpecificIInvocable)) {
- ++moreSpecific;
- } else
- if (applicableIInvocable.isLessSpecificThan(mostSpecificIInvocable)) {
- ++lessSpecific;
- }
- }
- if (moreSpecific == maximallySpecificIInvocables.size()) {
- maximallySpecificIInvocables.clear();
- maximallySpecificIInvocables.add(applicableIInvocable);
- } else
- if (lessSpecific < maximallySpecificIInvocables.size()) {
- maximallySpecificIInvocables.add(applicableIInvocable);
- } else
- {
- ;
- }
- if (UnitCompiler.DEBUG) System.out.println("maximallySpecificIInvocables=" + maximallySpecificIInvocables);
- }
-
- if (maximallySpecificIInvocables.size() == 1) return (IClass.IInvocable) maximallySpecificIInvocables.get(0);
-
- ONE_NON_ABSTRACT_INVOCABLE:
- if (maximallySpecificIInvocables.size() > 1 && iInvocables[0] instanceof IClass.IMethod) {
- final IClass.IMethod im = (IClass.IMethod) maximallySpecificIInvocables.get(0);
-
- // Check if all methods have the same signature (i.e. the types of all their
- // parameters are identical) and exactly one of the methods is non-abstract
- // (JLS 15.12.2.2.BL2.B1).
- IClass.IMethod theNonAbstractMethod = null;
- {
- Iterator it = maximallySpecificIInvocables.iterator();
- IClass.IMethod m = (IClass.IMethod) it.next();
- IClass[] parameterTypesOfFirstMethod = m.getParameterTypes();
- for (;;) {
- if (!m.isAbstract()) {
- if (theNonAbstractMethod != null) {
- IClass declaringIClass = m.getDeclaringIClass();
- IClass theNonAbstractMethodDeclaringIClass = theNonAbstractMethod.getDeclaringIClass();
- if (declaringIClass.isAssignableFrom(theNonAbstractMethodDeclaringIClass)) {
- ;
- } else
- if (theNonAbstractMethodDeclaringIClass.isAssignableFrom(declaringIClass)) {
- theNonAbstractMethod = m;
- } else
- {
- throw new RuntimeException("SNO: More than one non-abstract method with same signature and same declaring class!?");
- }
- }
- }
- if (!it.hasNext()) break;
-
- m = (IClass.IMethod) it.next();
- IClass[] pts = m.getParameterTypes();
- for (int i = 0; i < pts.length; ++i) {
- if (pts[i] != parameterTypesOfFirstMethod[i]) break ONE_NON_ABSTRACT_INVOCABLE;
- }
- }
- }
-
- // JLS 15.12.2.2.BL2.B1.B1
- if (theNonAbstractMethod != null) return theNonAbstractMethod;
-
- // JLS 15.12.2.2.BL2.B1.B2
- Set s = new HashSet();
- {
- IClass[][] tes = new IClass[maximallySpecificIInvocables.size()][];
- Iterator it = maximallySpecificIInvocables.iterator();
- for (int i = 0; i < tes.length; ++i) {
- tes[i] = ((IClass.IMethod) it.next()).getThrownExceptions();
- }
- for (int i = 0; i < tes.length; ++i) {
- EACH_EXCEPTION:
- for (int j = 0; j < tes[i].length; ++j) {
-
- // Check whether "that exception [te1] is declared in the THROWS
- // clause of each of the maximally specific methods".
- IClass te1 = tes[i][j];
- EACH_METHOD:
- for (int k = 0; k < tes.length; ++k) {
- if (k == i) continue;
- for (int m = 0; m < tes[k].length; ++m) {
- IClass te2 = tes[k][m];
- if (te2.isAssignableFrom(te1)) continue EACH_METHOD;
- }
- continue EACH_EXCEPTION;
- }
- s.add(te1);
- }
- }
- }
-
- final IClass[] tes = (IClass[]) s.toArray(new IClass[s.size()]);
- return im.getDeclaringIClass().new IMethod() {
- public String getName() { return im.getName(); }
- public IClass getReturnType() throws CompileException { return im.getReturnType(); }
- public boolean isAbstract() { return im.isAbstract(); }
- public boolean isStatic() { return im.isStatic(); }
- public Access getAccess() { return im.getAccess(); }
- public IClass[] getParameterTypes() throws CompileException { return im.getParameterTypes(); }
- public IClass[] getThrownExceptions() { return tes; }
- };
- }
-
- // JLS 15.12.2.2.BL2.B2
- {
- StringBuffer sb = new StringBuffer("Invocation of constructor/method with actual parameter type(s) \"");
- for (int i = 0; i < argumentTypes.length; ++i) {
- if (i > 0) sb.append(", ");
- sb.append(Descriptor.toString(argumentTypes[i].getDescriptor()));
- }
- sb.append("\" is ambiguous: ");
- for (int i = 0; i < maximallySpecificIInvocables.size(); ++i) {
- if (i > 0) sb.append(" vs. ");
- sb.append("\"" + maximallySpecificIInvocables.get(i) + "\"");
- }
- this.compileError(sb.toString(), l.getLocation());
- }
-
- return (IClass.IMethod) iInvocables[0];
- }
-
- /**
- * Check if "method invocation conversion" (5.3) is possible.
- */
- private boolean isMethodInvocationConvertible(
- IClass sourceType,
- IClass targetType,
- boolean boxingPermitted
- ) throws CompileException {
-
- // 5.3 Identity conversion.
- if (sourceType == targetType) return true;
-
- // 5.3 Widening primitive conversion.
- if (this.isWideningPrimitiveConvertible(sourceType, targetType)) return true;
-
- // 5.3 Widening reference conversion.
- if (this.isWideningReferenceConvertible(sourceType, targetType)) return true;
-
- // JLS3 5.3 A boxing conversion (JLS3 5.1.7) optionally followed by widening reference conversion.
- if (boxingPermitted) {
- IClass boxedType = this.isBoxingConvertible(sourceType);
- if (boxedType != null) {
- return (
- this.isIdentityConvertible(boxedType, targetType) ||
- this.isWideningReferenceConvertible(boxedType, targetType)
- );
- }
- }
-
- // JLS3 5.3 An unboxing conversion (JLS3 5.1.8) optionally followed by a widening primitive conversion.
- if (boxingPermitted) {
- IClass unboxedType = this.isUnboxingConvertible(sourceType);
- if (unboxedType != null) {
- return (
- this.isIdentityConvertible(unboxedType, targetType) ||
- this.isWideningPrimitiveConvertible(unboxedType, targetType)
- );
- }
- }
-
- // 5.3 TODO: FLOAT or DOUBLE value set conversion
-
- return false;
- }
-
- /**
- * @throws CompileException if the {@link Invocation} throws exceptions that are disallowed in the given scope
- */
- private void checkThrownExceptions(Invocation in, IMethod iMethod) throws CompileException {
- IClass[] thrownExceptions = iMethod.getThrownExceptions();
- for (int i = 0; i < thrownExceptions.length; ++i) {
- this.checkThrownException(
- (Locatable) in, // l
- thrownExceptions[i], // type
- (Java.Scope) in.getEnclosingBlockStatement() // scope
- );
- }
- }
-
- /**
- * @throws CompileException if the exception with the given type must not be thrown in the given scope
- */
- private void checkThrownException(
- Locatable l,
- IClass type,
- Java.Scope scope
- ) throws CompileException {
-
- // Thrown object must be assignable to "Throwable".
- if (!this.iClassLoader.THROWABLE.isAssignableFrom(type)) this.compileError("Thrown object of type \"" + type + "\" is not assignable to \"Throwable\"", l.getLocation());
-
- // "RuntimeException" and "Error" are never checked.
- if (
- this.iClassLoader.RUNTIME_EXCEPTION.isAssignableFrom(type) ||
- this.iClassLoader.ERROR.isAssignableFrom(type)
- ) return;
-
- for (;; scope = scope.getEnclosingScope()) {
-
- // Match against enclosing "try...catch" blocks.
- if (scope instanceof Java.TryStatement) {
- Java.TryStatement ts = (Java.TryStatement) scope;
- for (int i = 0; i < ts.catchClauses.size(); ++i) {
- Java.CatchClause cc = (Java.CatchClause) ts.catchClauses.get(i);
- IClass caughtType = this.getType(cc.caughtException.type);
- if (caughtType.isAssignableFrom(type)) return;
- }
- } else
-
- // Match against "throws" clause of declaring function.
- if (scope instanceof Java.FunctionDeclarator) {
- Java.FunctionDeclarator fd = (Java.FunctionDeclarator) scope;
- for (int i = 0; i < fd.thrownExceptions.length; ++i) {
- IClass te = this.getType(fd.thrownExceptions[i]);
- if (te.isAssignableFrom(type)) return;
- }
- break;
- } else
-
- if (scope instanceof Java.TypeBodyDeclaration) {
- break;
- }
- }
-
- this.compileError("Thrown exception of type \"" + type + "\" is neither caught by a \"try...catch\" block nor declared in the \"throws\" clause of the declaring function", l.getLocation());
- }
-
- private IClass getTargetIClass(Java.QualifiedThisReference qtr) throws CompileException {
-
- // Determine target type.
- if (qtr.targetIClass == null) {
- qtr.targetIClass = this.getType(qtr.qualification);
- }
- return qtr.targetIClass;
- }
-
- /**
- * Checks whether the operand is an integer-like local variable.
- */
- Java.LocalVariable isIntLV(Java.Crement c) throws CompileException {
- if (!(c.operand instanceof Java.AmbiguousName)) return null;
- Java.AmbiguousName an = (Java.AmbiguousName) c.operand;
-
- Java.Atom rec = this.reclassify(an);
- if (!(rec instanceof Java.LocalVariableAccess)) return null;
- Java.LocalVariableAccess lva = (Java.LocalVariableAccess) rec;
-
- Java.LocalVariable lv = lva.localVariable;
- if (lv.finaL) this.compileError("Must not increment or decrement \"final\" local variable", lva.getLocation());
- if (
- lv.type == IClass.BYTE ||
- lv.type == IClass.SHORT ||
- lv.type == IClass.INT ||
- lv.type == IClass.CHAR
- ) return lv;
- return null;
- }
-
- private IClass resolve(final Java.TypeDeclaration td) {
- final Java.AbstractTypeDeclaration atd = (Java.AbstractTypeDeclaration) td;
- if (atd.resolvedType == null) atd.resolvedType = new IClass() {
- protected IClass.IMethod[] getDeclaredIMethods2() {
- IClass.IMethod[] res = new IClass.IMethod[atd.declaredMethods.size()];
- int i = 0;
- for (Iterator it = atd.declaredMethods.iterator(); it.hasNext();) {
- res[i++] = UnitCompiler.this.toIMethod((Java.MethodDeclarator) it.next());
- }
- return res;
- }
- private IClass[] declaredClasses = null;
- protected IClass[] getDeclaredIClasses2() {
- if (this.declaredClasses == null) {
- IClass[] mts = new IClass[atd.declaredClassesAndInterfaces.size()];
- int i = 0;
- for (Iterator it = atd.declaredClassesAndInterfaces.iterator(); it.hasNext();) {
- mts[i++] = UnitCompiler.this.resolve((Java.AbstractTypeDeclaration) it.next());
- }
- this.declaredClasses = mts;
- }
- return this.declaredClasses;
- }
- protected IClass getDeclaringIClass2() {
- Java.Scope s = atd;
- for (; !(s instanceof Java.TypeBodyDeclaration); s = s.getEnclosingScope()) {
- if (s instanceof Java.CompilationUnit) return null;
- }
- return UnitCompiler.this.resolve((Java.AbstractTypeDeclaration) s.getEnclosingScope());
- }
- protected IClass getOuterIClass2() throws CompileException {
- Java.AbstractTypeDeclaration oc = (Java.AbstractTypeDeclaration) UnitCompiler.getOuterClass(atd);
- if (oc == null) return null;
- return UnitCompiler.this.resolve(oc);
- }
- protected final String getDescriptor2() {
- return Descriptor.fromClassName(atd.getClassName());
- }
-
- public boolean isArray() { return false; }
- protected IClass getComponentType2() { throw new RuntimeException("SNO: Non-array type has no component type"); }
- public boolean isPrimitive() { return false; }
- public boolean isPrimitiveNumeric() { return false; }
- protected IConstructor[] getDeclaredIConstructors2() {
- if (atd instanceof Java.ClassDeclaration) {
- Java.ConstructorDeclarator[] cs = ((Java.ClassDeclaration) atd).getConstructors();
-
- IClass.IConstructor[] res = new IClass.IConstructor[cs.length];
- for (int i = 0; i < cs.length; ++i) res[i] = UnitCompiler.this.toIConstructor(cs[i]);
- return res;
- }
- return new IClass.IConstructor[0];
- }
- protected IField[] getDeclaredIFields2() {
- if (atd instanceof Java.ClassDeclaration) {
- Java.ClassDeclaration cd = (Java.ClassDeclaration) atd;
- List l = new ArrayList(); // IClass.IField
-
- // Determine variable declarators of type declaration.
- for (int i = 0; i < cd.variableDeclaratorsAndInitializers.size(); ++i) {
- Java.BlockStatement vdoi = (Java.BlockStatement) cd.variableDeclaratorsAndInitializers.get(i);
- if (vdoi instanceof Java.FieldDeclaration) {
- Java.FieldDeclaration fd = (Java.FieldDeclaration) vdoi;
- IClass.IField[] flds = UnitCompiler.this.getIFields(fd);
- for (int j = 0; j < flds.length; ++j) l.add(flds[j]);
- }
- }
- return (IClass.IField[]) l.toArray(new IClass.IField[l.size()]);
- } else
- if (atd instanceof Java.InterfaceDeclaration) {
- Java.InterfaceDeclaration id = (Java.InterfaceDeclaration) atd;
- List l = new ArrayList();
-
- // Determine static fields.
- for (int i = 0; i < id.constantDeclarations.size(); ++i) {
- Java.BlockStatement bs = (Java.BlockStatement) id.constantDeclarations.get(i);
- if (bs instanceof Java.FieldDeclaration) {
- Java.FieldDeclaration fd = (Java.FieldDeclaration) bs;
- IClass.IField[] flds = UnitCompiler.this.getIFields(fd);
- for (int j = 0; j < flds.length; ++j) l.add(flds[j]);
- }
- }
- return (IClass.IField[]) l.toArray(new IClass.IField[l.size()]);
- } else {
- throw new RuntimeException("SNO: AbstractTypeDeclaration is neither ClassDeclaration nor InterfaceDeclaration");
- }
- }
- public IField[] getSyntheticIFields() {
- if (atd instanceof Java.ClassDeclaration) {
- Collection c = ((Java.ClassDeclaration) atd).syntheticFields.values();
- return (IField[]) c.toArray(new IField[c.size()]);
- }
- return new IField[0];
- }
- protected IClass getSuperclass2() throws CompileException {
- if (atd instanceof Java.AnonymousClassDeclaration) {
- IClass bt = UnitCompiler.this.getType(((Java.AnonymousClassDeclaration) atd).baseType);
- return bt.isInterface() ? UnitCompiler.this.iClassLoader.OBJECT : bt;
- }
- if (atd instanceof Java.NamedClassDeclaration) {
- Java.NamedClassDeclaration ncd = (Java.NamedClassDeclaration) atd;
- if (ncd.optionalExtendedType == null) return UnitCompiler.this.iClassLoader.OBJECT;
- IClass superclass = UnitCompiler.this.getType(ncd.optionalExtendedType);
- if (superclass.isInterface()) UnitCompiler.this.compileError("\"" + superclass.toString() + "\" is an interface; classes can only extend a class", td.getLocation());
- return superclass;
- }
- return null;
- }
- public Access getAccess() { return UnitCompiler.modifiers2Access(atd.modifiers); }
- public boolean isFinal() { return (atd.modifiers & Mod.FINAL) != 0; }
- protected IClass[] getInterfaces2() throws CompileException {
- if (atd instanceof Java.AnonymousClassDeclaration) {
- IClass bt = UnitCompiler.this.getType(((Java.AnonymousClassDeclaration) atd).baseType);
- return bt.isInterface() ? new IClass[] { bt } : new IClass[0];
- } else
- if (atd instanceof Java.NamedClassDeclaration) {
- Java.NamedClassDeclaration ncd = (Java.NamedClassDeclaration) atd;
- IClass[] res = new IClass[ncd.implementedTypes.length];
- for (int i = 0; i < res.length; ++i) {
- res[i] = UnitCompiler.this.getType(ncd.implementedTypes[i]);
- if (!res[i].isInterface()) UnitCompiler.this.compileError("\"" + res[i].toString() + "\" is not an interface; classes can only implement interfaces", td.getLocation());
- }
- return res;
- } else
- if (atd instanceof Java.InterfaceDeclaration) {
- Java.InterfaceDeclaration id = (Java.InterfaceDeclaration) atd;
- IClass[] res = new IClass[id.extendedTypes.length];
- for (int i = 0; i < res.length; ++i) {
- res[i] = UnitCompiler.this.getType(id.extendedTypes[i]);
- if (!res[i].isInterface()) UnitCompiler.this.compileError("\"" + res[i].toString() + "\" is not an interface; interfaces can only extend interfaces", td.getLocation());
- }
- return res;
- } else {
- throw new RuntimeException("SNO: AbstractTypeDeclaration is neither ClassDeclaration nor InterfaceDeclaration");
- }
- }
- public boolean isAbstract() {
- return (
- (atd instanceof Java.InterfaceDeclaration)
- || (atd.modifiers & Mod.ABSTRACT) != 0
- );
- }
- public boolean isInterface() { return atd instanceof Java.InterfaceDeclaration; }
- };
-
- return atd.resolvedType;
- }
-
- private void referenceThis(
- Locatable l,
- Java.ClassDeclaration declaringClass,
- Java.TypeBodyDeclaration declaringTypeBodyDeclaration,
- IClass targetIClass
- ) throws CompileException {
- List path = UnitCompiler.getOuterClasses(declaringClass);
-
- if (declaringTypeBodyDeclaration.isStatic()) this.compileError("No current instance available in static context", l.getLocation());
-
- int j;
- TARGET_FOUND: {
- for (j = 0; j < path.size(); ++j) {
-
- // Notice: JLS 15.9.2.BL1.B3.B1.B2 seems to be wrong: Obviously, JAVAC does not
- // only allow
- //
- // O is the nth lexically enclosing class
- //
- // , but also
- //
- // O is assignable from the nth lexically enclosing class
- //
- // However, this strategy bears the risk of ambiguities, because "O" may be
- // assignable from more than one enclosing class.
- if (targetIClass.isAssignableFrom(this.resolve((Java.AbstractTypeDeclaration) path.get(j)))) break TARGET_FOUND;
- }
- this.compileError("\"" + declaringClass + "\" is not enclosed by \"" + targetIClass + "\"", l.getLocation());
- }
-
- int i;
- if (declaringTypeBodyDeclaration instanceof Java.ConstructorDeclarator) {
- if (j == 0) {
- this.writeOpcode(l, Opcode.ALOAD_0);
- return;
- }
-
- Java.ConstructorDeclarator constructorDeclarator = (Java.ConstructorDeclarator) declaringTypeBodyDeclaration;
- String spn = "this$" + (path.size() - 2);
- Java.LocalVariable syntheticParameter = (Java.LocalVariable) constructorDeclarator.syntheticParameters.get(spn);
- if (syntheticParameter == null) throw new RuntimeException("SNO: Synthetic parameter \""+ spn + "\" not found");
- this.load(l, syntheticParameter);
- i = 1;
- } else {
- this.writeOpcode(l, Opcode.ALOAD_0);
- i = 0;
- }
- for (; i < j; ++i) {
- final String fieldName = "this$" + (path.size() - i - 2);
- final Java.InnerClassDeclaration inner = (Java.InnerClassDeclaration) path.get(i);
- IClass iic = this.resolve((Java.AbstractTypeDeclaration) inner);
- final Java.TypeDeclaration outer = (Java.TypeDeclaration) path.get(i + 1);
- final IClass oic = this.resolve((Java.AbstractTypeDeclaration) outer);
- inner.defineSyntheticField(new SimpleIField(
- iic,
- fieldName,
- oic
- ));
- this.writeOpcode(l, Opcode.GETFIELD);
- this.writeConstantFieldrefInfo(
- iic.getDescriptor(),
- fieldName, // classFD
- oic.getDescriptor() // fieldFD
- );
- }
- }
-
- /**
- * Return a list consisting of the given <code>inner</code> class and all its outer classes.
- * @return {@link List} of {@link Java.TypeDeclaration}
- */
- private static List getOuterClasses(Java.TypeDeclaration inner) {
- List path = new ArrayList();
- for (Java.TypeDeclaration ic = inner; ic != null; ic = UnitCompiler.getOuterClass(ic)) path.add(ic);
- return path;
- }
-
- /*package*/ static Java.TypeDeclaration getOuterClass(Java.TypeDeclaration atd) {
-
- // Package member class declaration.
- if (atd instanceof Java.PackageMemberClassDeclaration) return null;
-
- // Local class declaration.
- if (atd instanceof Java.LocalClassDeclaration) {
- Java.Scope s = atd.getEnclosingScope();
- for (; !(s instanceof Java.FunctionDeclarator); s = s.getEnclosingScope());
- if ((s instanceof Java.MethodDeclarator) && (((Java.FunctionDeclarator) s).modifiers & Mod.STATIC) != 0) return null;
- for (; !(s instanceof Java.TypeDeclaration); s = s.getEnclosingScope());
- Java.TypeDeclaration immediatelyEnclosingTypeDeclaration = (Java.TypeDeclaration) s;
- return (
- immediatelyEnclosingTypeDeclaration instanceof Java.ClassDeclaration
- ) ? immediatelyEnclosingTypeDeclaration : null;
- }
-
- // Member class declaration.
- if (
- atd instanceof Java.MemberClassDeclaration &&
- (((Java.MemberClassDeclaration) atd).modifiers & Mod.STATIC) != 0
- ) return null;
-
- // Anonymous class declaration, interface declaration
- Java.Scope s = atd;
- for (; !(s instanceof Java.TypeBodyDeclaration); s = s.getEnclosingScope()) {
- if (s instanceof Java.ConstructorInvocation) return null;
- if (s instanceof Java.CompilationUnit) return null;
- }
- //if (!(s instanceof Java.ClassDeclaration)) return null;
- if (((Java.TypeBodyDeclaration) s).isStatic()) return null;
- return (Java.AbstractTypeDeclaration) s.getEnclosingScope();
- }
-
- private IClass getIClass(Java.ThisReference tr) throws CompileException {
- if (tr.iClass == null) {
-
- // Compile error if in static function context.
- Java.Scope s;
- for (s = tr.getEnclosingBlockStatement(); s instanceof Java.Statement || s instanceof Java.CatchClause; s = s.getEnclosingScope());
- if (s instanceof Java.FunctionDeclarator) {
- Java.FunctionDeclarator function = (Java.FunctionDeclarator) s;
- if ((function.modifiers & Mod.STATIC) != 0) this.compileError("No current instance available in static method", tr.getLocation());
- }
-
- // Determine declaring type.
- while (!(s instanceof Java.TypeDeclaration)) s = s.getEnclosingScope();
- if (!(s instanceof Java.ClassDeclaration)) this.compileError("Only methods of classes can have a current instance", tr.getLocation());
- tr.iClass = this.resolve((Java.ClassDeclaration) s);
- }
- return tr.iClass;
- }
-
- private IClass getReturnType(Java.FunctionDeclarator fd) throws CompileException {
- if (fd.returnType == null) {
- fd.returnType = this.getType(fd.type);
- }
- return fd.returnType;
- }
-
- /*package*/ IClass.IConstructor toIConstructor(final Java.ConstructorDeclarator cd) {
- if (cd.iConstructor != null) return cd.iConstructor;
-
- cd.iConstructor = this.resolve((Java.AbstractTypeDeclaration) cd.getDeclaringType()).new IConstructor() {
-
- // Implement IMember.
- public Access getAccess() {
- switch (cd.modifiers & Mod.PPP) {
- case Mod.PRIVATE:
- return Access.PRIVATE;
- case Mod.PROTECTED:
- return Access.PROTECTED;
- case Mod.PACKAGE:
- return Access.DEFAULT;
- case Mod.PUBLIC:
- return Access.PUBLIC;
- default:
- throw new RuntimeException("Invalid access");
- }
- }
-
- // Implement IInvocable.
- public String getDescriptor() throws CompileException {
- if (!(cd.getDeclaringClass() instanceof Java.InnerClassDeclaration)) return super.getDescriptor();
-
- List l = new ArrayList();
-
- // Convert enclosing instance reference into prepended constructor parameters.
- IClass outerClass = UnitCompiler.this.resolve(cd.getDeclaringClass()).getOuterIClass();
- if (outerClass != null) l.add(outerClass.getDescriptor());
-
- // Convert synthetic fields into prepended constructor parameters.
- for (Iterator it = cd.getDeclaringClass().syntheticFields.values().iterator(); it.hasNext();) {
- IClass.IField sf = (IClass.IField) it.next();
- if (sf.getName().startsWith("val$")) l.add(sf.getType().getDescriptor());
- }
- Java.FunctionDeclarator.FormalParameter[] fps = cd.formalParameters;
- for (int i = 0; i < fps.length; ++i) {
- l.add(UnitCompiler.this.getType(fps[i].type).getDescriptor());
- }
- String[] apd = (String[]) l.toArray(new String[l.size()]);
- return new MethodDescriptor(apd, Descriptor.VOID_).toString();
- }
-
- public IClass[] getParameterTypes() throws CompileException {
- Java.FunctionDeclarator.FormalParameter[] fps = cd.formalParameters;
- IClass[] res = new IClass[fps.length];
- for (int i = 0; i < fps.length; ++i) {
- res[i] = UnitCompiler.this.getType(fps[i].type);
- }
- return res;
- }
- public IClass[] getThrownExceptions() throws CompileException {
- IClass[] res = new IClass[cd.thrownExceptions.length];
- for (int i = 0; i < res.length; ++i) {
- res[i] = UnitCompiler.this.getType(cd.thrownExceptions[i]);
- }
- return res;
- }
-
- public String toString() {
- StringBuffer sb = new StringBuffer();
- sb.append(cd.getDeclaringType().getClassName());
- sb.append('(');
- Java.FunctionDeclarator.FormalParameter[] fps = cd.formalParameters;
- for (int i = 0; i < fps.length; ++i) {
- if (i != 0) sb.append(", ");
- try {
- sb.append(UnitCompiler.this.getType(fps[i].type).toString());
- } catch (CompileException ex) {
- sb.append("???");
- }
- }
- return sb.append(')').toString();
- }
- };
- return cd.iConstructor;
- }
-
- public IClass.IMethod toIMethod(final Java.MethodDeclarator md) {
- if (md.iMethod != null) return md.iMethod;
- md.iMethod = this.resolve((Java.AbstractTypeDeclaration) md.getDeclaringType()).new IMethod() {
-
- // Implement IMember.
- public Access getAccess() {
- switch (md.modifiers & Mod.PPP) {
- case Mod.PRIVATE:
- return Access.PRIVATE;
- case Mod.PROTECTED:
- return Access.PROTECTED;
- case Mod.PACKAGE:
- return Access.DEFAULT;
- case Mod.PUBLIC:
- return Access.PUBLIC;
- default:
- throw new RuntimeException("Invalid access");
- }
- }
-
- // Implement IInvocable.
- public IClass[] getParameterTypes() throws CompileException {
- Java.FunctionDeclarator.FormalParameter[] fps = md.formalParameters;
- IClass[] res = new IClass[fps.length];
- for (int i = 0; i < fps.length; ++i) {
- res[i] = UnitCompiler.this.getType(fps[i].type);
- }
- return res;
- }
- public IClass[] getThrownExceptions() throws CompileException {
- IClass[] res = new IClass[md.thrownExceptions.length];
- for (int i = 0; i < res.length; ++i) {
- res[i] = UnitCompiler.this.getType(md.thrownExceptions[i]);
- }
- return res;
- }
-
- // Implement IMethod.
- public boolean isStatic() { return (md.modifiers & Mod.STATIC) != 0; }
- public boolean isAbstract() { return (md.getDeclaringType() instanceof Java.InterfaceDeclaration) || (md.modifiers & Mod.ABSTRACT) != 0; }
- public IClass getReturnType() throws CompileException {
- return UnitCompiler.this.getReturnType(md);
- }
- public String getName() { return md.name; }
- };
- return md.iMethod;
- }
-
- private IClass.IInvocable toIInvocable(Java.FunctionDeclarator fd) {
- if (fd instanceof Java.ConstructorDeclarator) {
- return this.toIConstructor((Java.ConstructorDeclarator) fd);
- } else
- if (fd instanceof Java.MethodDeclarator) {
- return this.toIMethod((Java.MethodDeclarator) fd);
- } else
- {
- throw new RuntimeException("FunctionDeclarator is neither ConstructorDeclarator nor MethodDeclarator");
- }
- }
-
- /**
- * If the given name was declared in a simple type import, load that class.
- */
- private IClass importSingleType(String simpleTypeName, Location location) throws CompileException {
- String[] ss = this.getSingleTypeImport(simpleTypeName);
- if (ss == null) return null;
-
- IClass iClass = this.loadFullyQualifiedClass(ss);
- if (iClass == null) {
- this.compileError("Imported class \"" + Java.join(ss, ".") + "\" could not be loaded", location);
- return this.iClassLoader.OBJECT;
- }
- return iClass;
- }
-
- /**
- * Check if the given name was imported through a "single type import", e.g.<pre>
- * import java.util.Map</pre>
- *
- * @return the fully qualified name or <code>null</code>
- */
- public String[] getSingleTypeImport(String name) {
- return (String[]) this.singleTypeImports.get(name);
- }
-
- /**
- * 6.5.2.BL1.B1.B5, 6.5.2.BL1.B1.B6 Type-import-on-demand.<br>
- * 6.5.5.1.6 Type-import-on-demand declaration.
- * @return <code>null</code> if the given <code>simpleTypeName</code> cannot be resolved through any of the import-on-demand directives
- */
- public IClass importTypeOnDemand(String simpleTypeName, Location location) throws CompileException {
-
- // Check cache. (A cache for unimportable types is not required, because
- // the class is importable 99.9%.)
- IClass importedClass = (IClass) this.onDemandImportableTypes.get(simpleTypeName);
- if (importedClass != null) return importedClass;
-
- // Cache miss...
- for (Iterator i = this.typeImportsOnDemand.iterator(); i.hasNext();) {
- String[] ss = (String[]) i.next();
- String[] ss2 = concat(ss, simpleTypeName);
- IClass iClass = this.loadFullyQualifiedClass(ss2);
- if (iClass != null) {
- if (importedClass != null && importedClass != iClass) this.compileError("Ambiguous class name: \"" + importedClass + "\" vs. \"" + iClass + "\"", location);
- importedClass = iClass;
- }
- }
- if (importedClass == null) return null;
-
- // Put in cache and return.
- this.onDemandImportableTypes.put(simpleTypeName, importedClass);
- return importedClass;
- }
- private final Map onDemandImportableTypes = new HashMap(); // String simpleTypeName => IClass
- private void declareClassDollarMethod(Java.ClassLiteral cl) {
-
- // Method "class$" is not yet declared; declare it like
- //
- // static java.lang.Class class$(java.lang.String className) {
- // try {
- // return java.lang.Class.forName(className);
- // } catch (java.lang.ClassNotFoundException ex) {
- // throw new java.lang.NoClassDefFoundError(ex.getMessage());
- // }
- // }
- //
- Location loc = cl.getLocation();
- Java.AbstractTypeDeclaration declaringType;
- for (Java.Scope s = cl.getEnclosingBlockStatement();; s = s.getEnclosingScope()) {
- if (s instanceof Java.AbstractTypeDeclaration) {
- declaringType = (Java.AbstractTypeDeclaration) s;
- break;
- }
- }
- Java.Block body = new Java.Block(loc);
-
- // try {
- // return Class.forName(className);
- Java.MethodInvocation mi = new Java.MethodInvocation(
- loc, // location
- new Java.SimpleType(loc, this.iClassLoader.CLASS), // optionalTarget
- "forName", // methodName
- new Java.Rvalue[] { // arguments
- new Java.AmbiguousName(loc, new String[] { "className" } )
- }
- );
-
- IClass classNotFoundExceptionIClass;
- try {
- classNotFoundExceptionIClass = this.iClassLoader.loadIClass("Ljava/lang/ClassNotFoundException;");
- } catch (ClassNotFoundException ex) {
- throw new RuntimeException("Loading class \"ClassNotFoundException\": " + ex.getMessage());
- }
- if (classNotFoundExceptionIClass == null) throw new RuntimeException("SNO: Cannot load \"ClassNotFoundException\"");
-
- IClass noClassDefFoundErrorIClass;
- try {
- noClassDefFoundErrorIClass = this.iClassLoader.loadIClass("Ljava/lang/NoClassDefFoundError;");
- } catch (ClassNotFoundException ex) {
- throw new RuntimeException("Loading class \"NoClassDefFoundError\": " + ex.getMessage());
- }
- if (noClassDefFoundErrorIClass == null) throw new RuntimeException("SNO: Cannot load \"NoClassFoundError\"");
-
- // catch (ClassNotFoundException ex) {
- Java.Block b = new Java.Block(loc);
- // throw new NoClassDefFoundError(ex.getMessage());
- b.addStatement(new Java.ThrowStatement(loc, new Java.NewClassInstance(
- loc, // location
- (Java.Rvalue) null, // optionalQualification
- new Java.SimpleType(loc, noClassDefFoundErrorIClass), // type
- new Java.Rvalue[] { // arguments
- new Java.MethodInvocation(
- loc, // location
- new Java.AmbiguousName(loc, new String[] { "ex"} ), // optionalTarget
- "getMessage", // methodName
- new Java.Rvalue[0] // arguments
- )
- }
- )));
-
- List l = new ArrayList();
- l.add(new Java.CatchClause(
- loc, // location
- new Java.FunctionDeclarator.FormalParameter( // caughtException
- loc, // location
- true, // finaL
- new Java.SimpleType(loc, classNotFoundExceptionIClass), // type
- "ex" // name
- ),
- b // body
- ));
- Java.TryStatement ts = new Java.TryStatement(
- loc, // location
- new Java.ReturnStatement(loc, mi), // body
- l, // catchClauses
- null // optionalFinally
- );
-
- body.addStatement(ts);
-
- // Class class$(String className)
- Java.FunctionDeclarator.FormalParameter fp = new Java.FunctionDeclarator.FormalParameter(
- loc, // location
- false, // finaL
- new Java.SimpleType(loc, this.iClassLoader.STRING), // type
- "className" // name
- );
- Java.MethodDeclarator cdmd = new Java.MethodDeclarator(
- loc, // location
- null, // optionalDocComment
- Mod.STATIC, // modifiers
- new Java.SimpleType(loc, this.iClassLoader.CLASS), // type
- "class$", // name
- new Java.FunctionDeclarator.FormalParameter[] { fp }, // formalParameters
- new Java.Type[0], // thrownExceptions
- body // optionalBody
- );
-
- declaringType.addDeclaredMethod(cdmd);
- declaringType.invalidateMethodCaches();
- }
-
- private IClass pushConstant(Locatable l, Object value) {
- if (
- value instanceof Integer ||
- value instanceof Short ||
- value instanceof Character ||
- value instanceof Byte
- ) {
- int i = (
- value instanceof Character ?
- ((Character) value).charValue() :
- ((Number) value).intValue()
- );
- if (i >= -1 && i <= 5) {
- this.writeOpcode(l, Opcode.ICONST_0 + i);
- } else
- if (i >= Byte.MIN_VALUE && i <= Byte.MAX_VALUE) {
- this.writeOpcode(l, Opcode.BIPUSH);
- this.writeByte((byte) i);
- } else {
- this.writeLDC(l, this.addConstantIntegerInfo(i));
- }
- return IClass.INT;
- }
- if (value instanceof Long) {
- long lv = ((Long) value).longValue();
- if (lv >= 0L && lv <= 1L) {
- this.writeOpcode(l, Opcode.LCONST_0 + (int) lv);
- } else {
- this.writeOpcode(l, Opcode.LDC2_W);
- this.writeConstantLongInfo(lv);
- }
- return IClass.LONG;
- }
- if (value instanceof Float) {
- float fv = ((Float) value).floatValue();
- if (
- Float.floatToIntBits(fv) == Float.floatToIntBits(0.0F) // POSITIVE zero!
- || fv == 1.0F
- || fv == 2.0F
- ) {
- this.writeOpcode(l, Opcode.FCONST_0 + (int) fv);
- } else
- {
- this.writeLDC(l, this.addConstantFloatInfo(fv));
- }
- return IClass.FLOAT;
- }
- if (value instanceof Double) {
- double dv = ((Double) value).doubleValue();
- if (
- Double.doubleToLongBits(dv) == Double.doubleToLongBits(0.0D) // POSITIVE zero!
- || dv == 1.0D
- ) {
- this.writeOpcode(l, Opcode.DCONST_0 + (int) dv);
- } else
- {
- this.writeOpcode(l, Opcode.LDC2_W);
- this.writeConstantDoubleInfo(dv);
- }
- return IClass.DOUBLE;
- }
- if (value instanceof String) {
- String s = (String) value;
- String ss[] = UnitCompiler.makeUTF8Able(s);
- this.writeLDC(l, this.addConstantStringInfo(ss[0]));
- for (int i = 1; i < ss.length; ++i) {
- this.writeLDC(l, this.addConstantStringInfo(ss[i]));
- this.writeOpcode(l, Opcode.INVOKEVIRTUAL);
- this.writeConstantMethodrefInfo(
- Descriptor.STRING,
- "concat", // classFD
- "(" + Descriptor.STRING + ")" + Descriptor.STRING // methodMD
- );
- }
- return this.iClassLoader.STRING;
- }
- if (value instanceof Boolean) {
- this.writeOpcode(l, ((Boolean) value).booleanValue() ? Opcode.ICONST_1 : Opcode.ICONST_0);
- return IClass.BOOLEAN;
- }
- if (value == Java.Rvalue.CONSTANT_VALUE_NULL) {
- this.writeOpcode(l, Opcode.ACONST_NULL);
- return IClass.VOID;
- }
- throw new RuntimeException("Unknown literal type \"" + value.getClass().getName() + "\"");
- }
-
- /**
- * Only strings that can be UTF8-encoded into 65535 bytes can be stored as constant string
- * infos.
- *
- * @param s The string to split into suitable chunks
- * @return the chunks that can be UTF8-encoded into 65535 bytes
- */
- private static String[] makeUTF8Able(String s) {
- if (s.length() < (65536 / 3)) return new String[] { s };
-
- int sLength = s.length(), uTFLength = 0;
- int from = 0;
- List l = new ArrayList();
- for (int i = 0;; i++) {
- if (i == sLength) {
- l.add(s.substring(from));
- break;
- }
- if (uTFLength >= 65532) {
- l.add(s.substring(from, i));
- if (i + (65536 / 3) > sLength) {
- l.add(s.substring(i));
- break;
- }
- from = i;
- uTFLength = 0;
- }
- int c = s.charAt(i);
- if (c >= 0x0001 && c <= 0x007F) {
- ++uTFLength;
- } else
- if (c > 0x07FF) {
- uTFLength += 3;
- } else
- {
- uTFLength += 2;
- }
- }
- return (String[]) l.toArray(new String[l.size()]);
-
- }
- private void writeLDC(Locatable l, short index) {
- if (0 <= index && index <= 255) {
- this.writeOpcode(l, Opcode.LDC);
- this.writeByte((byte) index);
- } else {
- this.writeOpcode(l, Opcode.LDC_W);
- this.writeShort(index);
- }
- }
-
- /**
- * Implements "assignment conversion" (JLS2 5.2).
- */
- private void assignmentConversion(
- Locatable l,
- IClass sourceType,
- IClass targetType,
- Object optionalConstantValue
- ) throws CompileException {
- if (UnitCompiler.DEBUG) System.out.println("assignmentConversion(" + sourceType + ", " + targetType + ", " + optionalConstantValue + ")");
-
- // JLS2 5.1.1 Identity conversion.
- if (this.tryIdentityConversion(sourceType, targetType)) return;
-
- // JLS2 5.1.2 Widening primitive conversion.
- if (this.tryWideningPrimitiveConversion(l, sourceType, targetType)) return;
-
- // JLS2 5.1.4 Widening reference conversion.
- if (this.isWideningReferenceConvertible(sourceType, targetType)) return;
-
- // A boxing conversion (JLS3 5.1.7) optionally followed by a widening reference conversion.
- {
- IClass boxedType = this.isBoxingConvertible(sourceType);
- if (boxedType != null) {
- if (this.tryIdentityConversion(boxedType, targetType)) {
- this.boxingConversion(l, sourceType, boxedType);
- return;
- } else
- if (this.isWideningReferenceConvertible(boxedType, targetType)) {
- this.boxingConversion(l, sourceType, boxedType);
- return;
- }
- }
- }
-
- // An unboxing conversion (JLS3 5.1.8) optionally followed by a widening primitive conversion.
- {
- IClass unboxedType = this.isUnboxingConvertible(sourceType);
- if (unboxedType != null) {
- if (this.tryIdentityConversion(unboxedType, targetType)) {
- this.unboxingConversion(l, sourceType, unboxedType);
- return;
- } else
- if (this.isWideningPrimitiveConvertible(unboxedType, targetType)) {
- this.unboxingConversion(l, sourceType, unboxedType);
- this.tryWideningPrimitiveConversion(l, unboxedType, targetType);
- return;
- }
- }
- }
-
- // 5.2 Special narrowing primitive conversion.
- if (optionalConstantValue != null) {
- if (this.tryConstantAssignmentConversion(
- l,
- optionalConstantValue, // constantValue
- targetType // targetType
- )) return;
- }
-
- this.compileError("Assignment conversion not possible from type \"" + sourceType + "\" to type \"" + targetType + "\"", l.getLocation());
- }
-
- /**
- * Implements "assignment conversion" (JLS2 5.2) on a constant value.
- */
- private Object assignmentConversion(
- Locatable l,
- Object value,
- IClass targetType
- ) throws CompileException {
- Object result = null;
-
- if (targetType == IClass.BOOLEAN) {
- if (value instanceof Boolean) result = value;
- } else
- if (targetType == this.iClassLoader.STRING) {
- if (value instanceof String) result = value;
- } else
- if (targetType == IClass.BYTE) {
- if (value instanceof Byte) {
- result = value;
- } else
- if (value instanceof Short || value instanceof Integer) {
- int x = ((Number) value).intValue();
- if (x >= Byte.MIN_VALUE && x <= Byte.MAX_VALUE) result = new Byte((byte) x);
- } else
- if (value instanceof Character) {
- int x = ((Character) value).charValue();
- if (x >= Byte.MIN_VALUE && x <= Byte.MAX_VALUE) result = new Byte((byte) x);
- }
- } else
- if (targetType == IClass.SHORT) {
- if (value instanceof Byte) {
- result = new Short(((Number) value).shortValue());
- } else
- if (value instanceof Short) {
- result = value;
- } else
- if (value instanceof Character) {
- int x = ((Character) value).charValue();
- if (x >= Short.MIN_VALUE && x <= Short.MAX_VALUE) result = new Short((short) x);
- } else
- if (value instanceof Integer) {
- int x = ((Integer) value).intValue();
- if (x >= Short.MIN_VALUE && x <= Short.MAX_VALUE) result = new Short((short) x);
- }
- } else
- if (targetType == IClass.CHAR) {
- if (value instanceof Short) {
- result = value;
- } else
- if (value instanceof Byte || value instanceof Short || value instanceof Integer) {
- int x = ((Number) value).intValue();
- if (x >= Character.MIN_VALUE && x <= Character.MAX_VALUE) result = new Character((char) x);
- }
- } else
- if (targetType == IClass.INT) {
- if (value instanceof Integer) {
- result = value;
- } else
- if (value instanceof Byte || value instanceof Short) {
- result = new Integer(((Number) value).intValue());
- } else
- if (value instanceof Character) {
- result = new Integer(((Character) value).charValue());
- }
- } else
- if (targetType == IClass.LONG) {
- if (value instanceof Long) {
- result = value;
- } else
- if (value instanceof Byte || value instanceof Short || value instanceof Integer) {
- result = new Long(((Number) value).longValue());
- } else
- if (value instanceof Character) {
- result = new Long(((Character) value).charValue());
- }
- } else
- if (targetType == IClass.FLOAT) {
- if (value instanceof Float) {
- result = value;
- } else
- if (value instanceof Byte || value instanceof Short || value instanceof Integer || value instanceof Long) {
- result = new Float(((Number) value).floatValue());
- } else
- if (value instanceof Character) {
- result = new Float(((Character) value).charValue());
- }
- } else
- if (targetType == IClass.DOUBLE) {
- if (value instanceof Double) {
- result = value;
- } else
- if (value instanceof Byte || value instanceof Short || value instanceof Integer || value instanceof Long || value instanceof Float) {
- result = new Double(((Number) value).doubleValue());
- } else
- if (value instanceof Character) {
- result = new Double(((Character) value).charValue());
- }
- } else
- if (value == Java.Rvalue.CONSTANT_VALUE_NULL && !targetType.isPrimitive()) {
- result = value;
- }
- if (result == null) this.compileError("Cannot convert constant of type \"" + value.getClass().getName() + "\" to type \"" + targetType.toString() + "\"", l.getLocation());
- return result;
- }
-
- /**
- * Implements "unary numeric promotion" (JLS3 5.6.1)
- *
- * @return The promoted type.
- */
- private IClass unaryNumericPromotion(Locatable l, IClass type) throws CompileException {
- type = this.convertToPrimitiveNumericType(l, type);
-
- IClass promotedType = this.unaryNumericPromotionType(l, type);
-
- this.numericPromotion(l, type, promotedType);
- return promotedType;
- }
-
- private void reverseUnaryNumericPromotion(Locatable l, IClass sourceType, IClass targetType) throws CompileException {
- IClass unboxedType = this.isUnboxingConvertible(targetType);
- IClass pt = unboxedType != null ? unboxedType : targetType;
- if (
- !this.tryIdentityConversion(sourceType, pt) &&
- !this.tryNarrowingPrimitiveConversion(
- l, // locatable
- sourceType, // sourceType
- pt // targetType
- )
- ) throw new RuntimeException("SNO: reverse unary numeric promotion failed");
- if (unboxedType != null) this.boxingConversion(l, unboxedType, targetType);
- }
-
- /**
- * If the given type is a primitive type, return that type.
- * If the given type is a primitive wrapper class, unbox the operand on top of the operand
- * stack and return the primitive type.
- * Otherwise, issue a compile error.
- */
- private IClass convertToPrimitiveNumericType(Locatable l, IClass type) throws CompileException {
- if (type.isPrimitiveNumeric()) return type;
- IClass unboxedType = this.isUnboxingConvertible(type);
- if (unboxedType != null) {
- this.unboxingConversion(l, type, unboxedType);
- return unboxedType;
- }
- this.compileError("Object of type \"" + type.toString() + "\" cannot be converted to a numeric type", l.getLocation());
- return type;
- }
-
- private void numericPromotion(Locatable l, IClass sourceType, IClass targetType) {
- if (
- !this.tryIdentityConversion(sourceType, targetType) &&
- !this.tryWideningPrimitiveConversion(
- l, // locatable
- sourceType, // sourceType
- targetType // targetType
- )
- ) throw new RuntimeException("SNO: Conversion failed");
- }
-
- private IClass unaryNumericPromotionType(Locatable l, IClass type) throws CompileException {
- if (!type.isPrimitiveNumeric()) this.compileError("Unary numeric promotion not possible on non-numeric-primitive type \"" + type + "\"", l.getLocation());
-
- return (
- type == IClass.DOUBLE ? IClass.DOUBLE :
- type == IClass.FLOAT ? IClass.FLOAT :
- type == IClass.LONG ? IClass.LONG :
- IClass.INT
- );
- }
-
- /**
- * Implements "binary numeric promotion" (5.6.2)
- *
- * @return The promoted type.
- */
- private IClass binaryNumericPromotion(
- Locatable locatable,
- IClass type1,
- CodeContext.Inserter convertInserter1,
- IClass type2
- ) throws CompileException {
- return this.binaryNumericPromotion(locatable, type1, convertInserter1, type2, this.codeContext.currentInserter());
- }
- /**
- * Implements "binary numeric promotion" (5.6.2)
- *
- * @return The promoted type.
- */
- private IClass binaryNumericPromotion(
- Locatable l,
- IClass type1,
- CodeContext.Inserter convertInserter1,
- IClass type2,
- CodeContext.Inserter convertInserter2
- ) throws CompileException {
- IClass promotedType;
- {
- IClass c1 = this.isUnboxingConvertible(type1);
- IClass c2 = this.isUnboxingConvertible(type2);
- promotedType = this.binaryNumericPromotionType(
- l,
- c1 != null ? c1 : type1,
- c2 != null ? c2 : type2
- );
- }
-
- if (convertInserter1 != null) {
- this.codeContext.pushInserter(convertInserter1);
- try {
- this.numericPromotion(l, this.convertToPrimitiveNumericType(l, type1), promotedType);
- } finally {
- this.codeContext.popInserter();
- }
- }
-
- if (convertInserter2 != null) {
- this.codeContext.pushInserter(convertInserter2);
- try {
- this.numericPromotion(l, this.convertToPrimitiveNumericType(l, type2), promotedType);
- } finally {
- this.codeContext.popInserter();
- }
- }
-
- return promotedType;
- }
-
- private IClass binaryNumericPromotionType(
- Java.Locatable locatable,
- IClass type1,
- IClass type2
- ) throws CompileException {
- if (
- !type1.isPrimitiveNumeric() ||
- !type2.isPrimitiveNumeric()
- ) this.compileError("Binary numeric promotion not possible on types \"" + type1 + "\" and \"" + type2 + "\"", locatable.getLocation());
-
- return (
- type1 == IClass.DOUBLE || type2 == IClass.DOUBLE ? IClass.DOUBLE :
- type1 == IClass.FLOAT || type2 == IClass.FLOAT ? IClass.FLOAT :
- type1 == IClass.LONG || type2 == IClass.LONG ? IClass.LONG :
- IClass.INT
- );
- }
-
- /**
- * Checks whether "identity conversion" (5.1.1) is possible.
- *
- * @return Whether the conversion is possible
- */
- private boolean isIdentityConvertible(
- IClass sourceType,
- IClass targetType
- ) {
- return sourceType == targetType;
- }
-
- /**
- * Implements "identity conversion" (5.1.1).
- *
- * @return Whether the conversion was possible
- */
- private boolean tryIdentityConversion(
- IClass sourceType,
- IClass targetType
- ) {
- return sourceType == targetType;
- }
-
- private boolean isWideningPrimitiveConvertible(
- IClass sourceType,
- IClass targetType
- ) {
- return UnitCompiler.PRIMITIVE_WIDENING_CONVERSIONS.get(
- sourceType.getDescriptor() + targetType.getDescriptor()
- ) != null;
- }
-
- /**
- * Implements "widening primitive conversion" (5.1.2).
- *
- * @return Whether the conversion succeeded
- */
- private boolean tryWideningPrimitiveConversion(
- Locatable l,
- IClass sourceType,
- IClass targetType
- ) {
- byte[] opcodes = (byte[]) UnitCompiler.PRIMITIVE_WIDENING_CONVERSIONS.get(sourceType.getDescriptor() + targetType.getDescriptor());
- if (opcodes != null) {
- this.writeOpcodes(l, opcodes);
- return true;
- }
- return false;
- }
- private static final HashMap PRIMITIVE_WIDENING_CONVERSIONS = new HashMap();
- static { UnitCompiler.fillConversionMap(new Object[] {
- new byte[0],
- Descriptor.BYTE_ + Descriptor.SHORT_,
-
- Descriptor.BYTE_ + Descriptor.INT_,
- Descriptor.SHORT_ + Descriptor.INT_,
- Descriptor.CHAR_ + Descriptor.INT_,
-
- new byte[] { Opcode.I2L },
- Descriptor.BYTE_ + Descriptor.LONG_,
- Descriptor.SHORT_ + Descriptor.LONG_,
- Descriptor.CHAR_ + Descriptor.LONG_,
- Descriptor.INT_ + Descriptor.LONG_,
-
- new byte[] { Opcode.I2F },
- Descriptor.BYTE_ + Descriptor.FLOAT_,
- Descriptor.SHORT_ + Descriptor.FLOAT_,
- Descriptor.CHAR_ + Descriptor.FLOAT_,
- Descriptor.INT_ + Descriptor.FLOAT_,
-
- new byte[] { Opcode.L2F },
- Descriptor.LONG_ + Descriptor.FLOAT_,
-
- new byte[] { Opcode.I2D },
- Descriptor.BYTE_ + Descriptor.DOUBLE_,
- Descriptor.SHORT_ + Descriptor.DOUBLE_,
- Descriptor.CHAR_ + Descriptor.DOUBLE_,
- Descriptor.INT_ + Descriptor.DOUBLE_,
-
- new byte[] { Opcode.L2D },
- Descriptor.LONG_ + Descriptor.DOUBLE_,
-
- new byte[] { Opcode.F2D },
- Descriptor.FLOAT_ + Descriptor.DOUBLE_,
- }, UnitCompiler.PRIMITIVE_WIDENING_CONVERSIONS); }
- private static void fillConversionMap(Object[] array, HashMap map) {
- byte[] opcodes = null;
- for (int i = 0; i < array.length; ++i) {
- Object o = array[i];
- if (o instanceof byte[]) {
- opcodes = (byte[]) o;
- } else {
- map.put(o, opcodes);
- }
- }
- }
-
- /**
- * Checks if "widening reference conversion" (5.1.4) is possible.
- *
- * @return Whether the conversion is possible
- */
- private boolean isWideningReferenceConvertible(
- IClass sourceType,
- IClass targetType
- ) throws CompileException {
- if (
- targetType.isPrimitive() ||
- sourceType == targetType
- ) return false;
-
- return targetType.isAssignableFrom(sourceType);
- }
-
- /**
- * Performs "widening reference conversion" (5.1.4) if possible.
- *
- * @return Whether the conversion was possible
- */
- private boolean tryWideningReferenceConversion(
- IClass sourceType,
- IClass targetType
- ) throws CompileException {
- if (
- targetType.isPrimitive() ||
- sourceType == targetType
- ) return false;
-
- return targetType.isAssignableFrom(sourceType);
- }
-
- /**
- * Check whether "narrowing primitive conversion" (JLS 5.1.3) is possible.
- */
- private boolean isNarrowingPrimitiveConvertible(
- IClass sourceType,
- IClass targetType
- ) {
- return UnitCompiler.PRIMITIVE_NARROWING_CONVERSIONS.containsKey(sourceType.getDescriptor() + targetType.getDescriptor());
- }
-
- /**
- * Implements "narrowing primitive conversion" (JLS 5.1.3).
- *
- * @return Whether the conversion succeeded
- */
- private boolean tryNarrowingPrimitiveConversion(
- Locatable l,
- IClass sourceType,
- IClass targetType
- ) {
- byte[] opcodes = (byte[]) UnitCompiler.PRIMITIVE_NARROWING_CONVERSIONS.get(sourceType.getDescriptor() + targetType.getDescriptor());
- if (opcodes != null) {
- this.writeOpcodes(l, opcodes);
- return true;
- }
- return false;
- }
-
- private static final HashMap PRIMITIVE_NARROWING_CONVERSIONS = new HashMap();
- static { UnitCompiler.fillConversionMap(new Object[] {
- new byte[0],
- Descriptor.BYTE_ + Descriptor.CHAR_,
- Descriptor.SHORT_ + Descriptor.CHAR_,
- Descriptor.CHAR_ + Descriptor.SHORT_,
-
- new byte[] { Opcode.I2B },
- Descriptor.SHORT_ + Descriptor.BYTE_,
- Descriptor.CHAR_ + Descriptor.BYTE_,
- Descriptor.INT_ + Descriptor.BYTE_,
-
- new byte[] { Opcode.I2S },
- Descriptor.INT_ + Descriptor.SHORT_,
- Descriptor.INT_ + Descriptor.CHAR_,
-
- new byte[] { Opcode.L2I, Opcode.I2B },
- Descriptor.LONG_ + Descriptor.BYTE_,
-
- new byte[] { Opcode.L2I, Opcode.I2S },
- Descriptor.LONG_ + Descriptor.SHORT_,
- Descriptor.LONG_ + Descriptor.CHAR_,
-
- new byte[] { Opcode.L2I },
- Descriptor.LONG_ + Descriptor.INT_,
-
- new byte[] { Opcode.F2I, Opcode.I2B },
- Descriptor.FLOAT_ + Descriptor.BYTE_,
-
- new byte[] { Opcode.F2I, Opcode.I2S },
- Descriptor.FLOAT_ + Descriptor.SHORT_,
- Descriptor.FLOAT_ + Descriptor.CHAR_,
-
- new byte[] { Opcode.F2I },
- Descriptor.FLOAT_ + Descriptor.INT_,
-
- new byte[] { Opcode.F2L },
- Descriptor.FLOAT_ + Descriptor.LONG_,
-
- new byte[] { Opcode.D2I, Opcode.I2B },
- Descriptor.DOUBLE_ + Descriptor.BYTE_,
-
- new byte[] { Opcode.D2I, Opcode.I2S },
- Descriptor.DOUBLE_ + Descriptor.SHORT_,
- Descriptor.DOUBLE_ + Descriptor.CHAR_,
-
- new byte[] { Opcode.D2I },
- Descriptor.DOUBLE_ + Descriptor.INT_,
-
- new byte[] { Opcode.D2L },
- Descriptor.DOUBLE_ + Descriptor.LONG_,
-
- new byte[] { Opcode.D2F },
- Descriptor.DOUBLE_ + Descriptor.FLOAT_,
- }, UnitCompiler.PRIMITIVE_NARROWING_CONVERSIONS); }
-
- /**
- * Check if "constant assignment conversion" (JLS 5.2, paragraph 1) is possible.
- * @param constantValue The constant value that is to be converted
- * @param targetType The type to convert to
- */
- private boolean tryConstantAssignmentConversion(
- Locatable l,
- Object constantValue,
- IClass targetType
- ) throws CompileException {
- if (UnitCompiler.DEBUG) System.out.println("isConstantPrimitiveAssignmentConvertible(" + constantValue + ", " + targetType + ")");
-
- int cv;
- if (constantValue instanceof Byte) {
- cv = ((Byte) constantValue).byteValue();
- } else
- if (constantValue instanceof Short) {
- cv = ((Short) constantValue).shortValue();
- } else
- if (constantValue instanceof Integer) {
- cv = ((Integer) constantValue).intValue();
- } else
- if (constantValue instanceof Character) {
- cv = ((Character) constantValue).charValue();
- } else
- {
- return false;
- }
-
- if (targetType == IClass.BYTE ) return cv >= Byte.MIN_VALUE && cv <= Byte.MAX_VALUE;
- if (targetType == IClass.SHORT) return cv >= Short.MIN_VALUE && cv <= Short.MAX_VALUE;
- if (targetType == IClass.CHAR ) return cv >= Character.MIN_VALUE && cv <= Character.MAX_VALUE;
-
- IClassLoader icl = this.iClassLoader;
- if (targetType == icl.BYTE && cv >= Byte.MIN_VALUE && cv <= Byte.MAX_VALUE) {
- this.boxingConversion(l, IClass.BYTE, targetType);
- return true;
- }
- if (targetType == icl.SHORT && cv >= Short.MIN_VALUE && cv <= Short.MAX_VALUE) {
- this.boxingConversion(l, IClass.SHORT, targetType);
- return true;
- }
- if (targetType == icl.CHARACTER && cv >= Character.MIN_VALUE && cv <= Character.MAX_VALUE) {
- this.boxingConversion(l, IClass.CHAR, targetType);
- return true;
- }
-
- return false;
- }
-
- /**
- * Check whether "narrowing reference conversion" (JLS 5.1.5) is possible.
- */
- private boolean isNarrowingReferenceConvertible(
- IClass sourceType,
- IClass targetType
- ) throws CompileException {
- if (sourceType.isPrimitive()) return false;
- if (sourceType == targetType) return false;
-
- // 5.1.5.1
- if (sourceType.isAssignableFrom(targetType)) return true;
-
- // 5.1.5.2
- if (
- targetType.isInterface() &&
- !sourceType.isFinal() &&
- !targetType.isAssignableFrom(sourceType)
- ) return true;
-
- // 5.1.5.3
- if (
- sourceType == this.iClassLoader.OBJECT &&
- targetType.isArray()
- ) return true;
-
- // 5.1.5.4
- if (
- sourceType == this.iClassLoader.OBJECT &&
- targetType.isInterface()
- ) return true;
-
- // 5.1.5.5
- if (
- sourceType.isInterface() &&
- !targetType.isFinal()
- ) return true;
-
- // 5.1.5.6
- if (
- sourceType.isInterface() &&
- targetType.isFinal() &&
- sourceType.isAssignableFrom(targetType)
- ) return true;
-
- // 5.1.5.7
- // TODO: Check for redefinition of methods with same signature but different return type.
- if (
- sourceType.isInterface() &&
- targetType.isInterface() &&
- !targetType.isAssignableFrom(sourceType)
- ) return true;
-
- // 5.1.5.8
- if (sourceType.isArray() && targetType.isArray()) {
- IClass st = sourceType.getComponentType();
- IClass tt = targetType.getComponentType();
- if (
- this.isNarrowingPrimitiveConvertible(st, tt) ||
- this.isNarrowingReferenceConvertible(st, tt)
- ) return true;
- }
-
- return false;
- }
-
- /**
- * Implements "narrowing reference conversion" (5.1.5).
- *
- * @return Whether the conversion succeeded
- */
- private boolean tryNarrowingReferenceConversion(
- Locatable l,
- IClass sourceType,
- IClass targetType
- ) throws CompileException {
- if (!this.isNarrowingReferenceConvertible(sourceType, targetType)) return false;
-
- this.writeOpcode(l, Opcode.CHECKCAST);
- this.writeConstantClassInfo(targetType.getDescriptor());
- return true;
- }
-
- /*
- * @return the boxed type or <code>null</code>
- */
- private IClass isBoxingConvertible(IClass sourceType) {
- IClassLoader icl = this.iClassLoader;
- if (sourceType == IClass.BOOLEAN) return icl.BOOLEAN;
- if (sourceType == IClass.BYTE ) return icl.BYTE;
- if (sourceType == IClass.CHAR ) return icl.CHARACTER;
- if (sourceType == IClass.SHORT ) return icl.SHORT;
- if (sourceType == IClass.INT ) return icl.INTEGER;
- if (sourceType == IClass.LONG ) return icl.LONG;
- if (sourceType == IClass.FLOAT ) return icl.FLOAT;
- if (sourceType == IClass.DOUBLE ) return icl.DOUBLE;
- return null;
- }
-
- private boolean tryBoxingConversion(
- Locatable l,
- IClass sourceType,
- IClass targetType
- ) throws CompileException {
- if (this.isBoxingConvertible(sourceType) == targetType) {
- this.boxingConversion(l, sourceType, targetType);
- return true;
- }
- return false;
- }
-
- /**
- * @param sourceType a primitive type (except VOID)
- * @param targetType the corresponding wrapper type
- */
- private void boxingConversion(Locatable l, IClass sourceType, IClass targetType) throws CompileException {
-
- // In some pre-1.5 JDKs, only some wrapper classes have the static "Target.valueOf(source)" method.
- if (targetType.hasIMethod("valueOf", new IClass[] { sourceType })) {
- this.writeOpcode(l, Opcode.INVOKESTATIC);
- this.writeConstantMethodrefInfo(
- targetType.getDescriptor(),
- "valueOf", // classFD
- '(' + sourceType.getDescriptor() + ')' + targetType.getDescriptor() // methodFD
- );
- return;
- }
- // new Target(source)
- this.writeOpcode(l, Opcode.NEW);
- this.writeConstantClassInfo(targetType.getDescriptor());
- if (Descriptor.hasSize2(sourceType.getDescriptor())) {
- this.writeOpcode(l, Opcode.DUP_X2);
- this.writeOpcode(l, Opcode.DUP_X2);
- this.writeOpcode(l, Opcode.POP);
- } else
- {
- this.writeOpcode(l, Opcode.DUP_X1);
- this.writeOpcode(l, Opcode.SWAP);
- }
- this.writeOpcode(l, Opcode.INVOKESPECIAL);
- this.writeConstantMethodrefInfo(
- targetType.getDescriptor(),
- "<init>", // classFD
- '(' + sourceType.getDescriptor() + ')' + Descriptor.VOID_ // methodMD
- );
- }
-
- /*
- * @return the unboxed type or <code>null</code>
- */
- private IClass isUnboxingConvertible(IClass sourceType) {
- IClassLoader icl = this.iClassLoader;
- if (sourceType == icl.BOOLEAN ) return IClass.BOOLEAN;
- if (sourceType == icl.BYTE ) return IClass.BYTE;
- if (sourceType == icl.CHARACTER) return IClass.CHAR;
- if (sourceType == icl.SHORT ) return IClass.SHORT;
- if (sourceType == icl.INTEGER ) return IClass.INT;
- if (sourceType == icl.LONG ) return IClass.LONG;
- if (sourceType == icl.FLOAT ) return IClass.FLOAT;
- if (sourceType == icl.DOUBLE ) return IClass.DOUBLE;
- return null;
- }
-
- private boolean tryUnboxingConversion(
- Locatable l,
- IClass sourceType,
- IClass targetType
- ) {
- if (this.isUnboxingConvertible(sourceType) == targetType) {
- this.unboxingConversion(l, sourceType, targetType);
- return true;
- }
- return false;
- }
-
- /**
- * @param targetType a primitive type (except VOID)
- * @param sourceType the corresponding wrapper type
- */
- private void unboxingConversion(Locatable l, IClass sourceType, IClass targetType) {
-
- // "source.targetValue()"
- this.writeOpcode(l, Opcode.INVOKEVIRTUAL);
- this.writeConstantMethodrefInfo(
- sourceType.getDescriptor(),
- targetType.toString() + "Value", // classFD
- "()" + targetType.getDescriptor() // methodFD
- );
- }
-
- /**
- * Attempt to load an {@link IClass} by fully-qualified name
- * @param identifiers
- * @return <code>null</code> if a class with the given name could not be loaded
- */
- private IClass loadFullyQualifiedClass(String[] identifiers) throws CompileException {
-
- // Compose the descriptor (like "La/b/c;") and remember the positions of the slashes
- // (2 and 4).
- int[] slashes = new int[identifiers.length - 1];
- StringBuffer sb = new StringBuffer("L");
- for (int i = 0;; ++i) {
- sb.append(identifiers[i]);
- if (i == identifiers.length - 1) break;
- slashes[i] = sb.length();
- sb.append('/');
- }
- sb.append(';');
-
- // Attempt to load the IClass and replace dots with dollar signs, i.e.:
- // La/b/c; La/b$c; La$b$c;
- for (int j = slashes.length - 1;; --j) {
- IClass result;
- try {
- result = this.iClassLoader.loadIClass(sb.toString());
- } catch (ClassNotFoundException ex) {
- if (ex.getException() instanceof CompileException) throw (CompileException) ex.getException();
- throw new CompileException(sb.toString(), null, ex);
- }
- if (result != null) return result;
- if (j < 0) break;
- sb.setCharAt(slashes[j], '$');
- }
- return null;
- }
-
- // Load the value of a local variable onto the stack and return its type.
- private IClass load(
- Locatable l,
- Java.LocalVariable localVariable
- ) {
- this.load(
- l,
- localVariable.type,
- localVariable.localVariableArrayIndex
- );
- return localVariable.type;
- }
- private void load(
- Locatable l,
- IClass type,
- int index
- ) {
- if (index <= 3) {
- this.writeOpcode(l, Opcode.ILOAD_0 + 4 * this.ilfda(type) + index);
- } else
- if (index <= 255) {
- this.writeOpcode(l, Opcode.ILOAD + this.ilfda(type));
- this.writeByte(index);
- } else
- {
- this.writeOpcode(l, Opcode.WIDE);
- this.writeOpcode(l, Opcode.ILOAD + this.ilfda(type));
- this.writeShort(index);
- }
- }
-
- /**
- * Assign stack top value to the given local variable. (Assignment conversion takes effect.)
- * If <copde>optionalConstantValue</code> is not <code>null</code>, then the top stack value
- * is a constant value with that type and value, and a narrowing primitive conversion as
- * described in JLS 5.2 is applied.
- */
- private void store(
- Locatable l,
- IClass valueType,
- Java.LocalVariable localVariable
- ) {
- this.store(
- l, // l
- localVariable.type, // lvType
- localVariable.localVariableArrayIndex // lvIndex
- );
- }
- private void store(
- Locatable l,
- IClass lvType,
- short lvIndex
- ) {
- if (lvIndex <= 3) {
- this.writeOpcode(l, Opcode.ISTORE_0 + 4 * this.ilfda(lvType) + lvIndex);
- } else
- if (lvIndex <= 255) {
- this.writeOpcode(l, Opcode.ISTORE + this.ilfda(lvType));
- this.writeByte(lvIndex);
- } else
- {
- this.writeOpcode(l, Opcode.WIDE);
- this.writeOpcode(l, Opcode.ISTORE + this.ilfda(lvType));
- this.writeShort(lvIndex);
- }
- }
-
- private void dup(Locatable l, int n) {
- switch (n) {
-
- case 0:
- ;
- break;
-
- case 1:
- this.writeOpcode(l, Opcode.DUP);
- break;
-
- case 2:
- this.writeOpcode(l, Opcode.DUP2);
- break;
-
- default:
- throw new RuntimeException("dup(" + n + ")");
- }
- }
- private void dupx(
- Locatable l,
- IClass type,
- int x
- ) {
- if (x < 0 || x > 2) throw new RuntimeException("SNO: x has value " + x);
- int dup = Opcode.DUP + x;
- int dup2 = Opcode.DUP2 + x;
- this.writeOpcode(l, (
- type == IClass.LONG || type == IClass.DOUBLE ?
- dup2 :
- dup
- ));
- }
-
- private void pop(Locatable l, IClass type) {
- if (type == IClass.VOID) return;
- this.writeOpcode(l, (
- type == IClass.LONG || type == IClass.DOUBLE ?
- Opcode.POP2 :
- Opcode.POP
- ));
- }
-
- static int ilfd(IClass t) {
- if (
- t == IClass.BYTE ||
- t == IClass.CHAR ||
- t == IClass.INT ||
- t == IClass.SHORT ||
- t == IClass.BOOLEAN
- ) return 0;
- if (t == IClass.LONG ) return 1;
- if (t == IClass.FLOAT ) return 2;
- if (t == IClass.DOUBLE) return 3;
- throw new RuntimeException("Unexpected type \"" + t + "\"");
- }
- static int ilfd(
- IClass t,
- int opcodeInt,
- int opcodeLong,
- int opcodeFloat,
- int opcodeDouble
- ) {
- if (
- t == IClass.BYTE ||
- t == IClass.CHAR ||
- t == IClass.INT ||
- t == IClass.SHORT ||
- t == IClass.BOOLEAN
- ) return opcodeInt;
- if (t == IClass.LONG ) return opcodeLong;
- if (t == IClass.FLOAT ) return opcodeFloat;
- if (t == IClass.DOUBLE) return opcodeDouble;
- throw new RuntimeException("Unexpected type \"" + t + "\"");
- }
- private int ilfda(IClass t) {
- return !t.isPrimitive() ? 4 : UnitCompiler.ilfd(t);
- }
- static int ilfdabcs(IClass t) {
- if (t == IClass.INT ) return 0;
- if (t == IClass.LONG ) return 1;
- if (t == IClass.FLOAT ) return 2;
- if (t == IClass.DOUBLE) return 3;
- if (!t.isPrimitive() ) return 4;
- if (t == IClass.BOOLEAN || t == IClass.BYTE) return 5;
- if (t == IClass.CHAR ) return 6;
- if (t == IClass.SHORT ) return 7;
- throw new RuntimeException("Unexpected type \"" + t + "\"");
- }
-
- /**
- * Find a named field in the given {@link IClass}.
- * Honor superclasses and interfaces. See JLS 8.3.
- * @return <code>null</code> if no field is found
- */
- private IClass.IField findIField(
- IClass iClass,
- String name,
- Location location
- ) throws CompileException {
-
- // Search for a field with the given name in the current class.
- IClass.IField f = iClass.getDeclaredIField(name);
- if(f != null) return f;
-
- // Examine superclass.
- {
- IClass superclass = iClass.getSuperclass();
- if (superclass != null) f = this.findIField(superclass, name, location);
- }
-
- // Examine interfaces.
- IClass[] ifs = iClass.getInterfaces();
- for (int i = 0; i < ifs.length; ++i) {
- IClass.IField f2 = this.findIField(ifs[i], name, location);
- if (f2 != null) {
- if (f != null) throw new CompileException("Access to field \"" + name + "\" is ambiguous - both \"" + f.getDeclaringIClass() + "\" and \"" + f2.getDeclaringIClass() + "\" declare it", location);
- f = f2;
- }
- }
- return f;
- }
-
- /**
- * Find a named type in the given {@link IClass}.
- * Honor superclasses, interfaces and enclosing type declarations.
- * @return <code>null</code> if no type with the given name is found
- */
- private IClass findMemberType(
- IClass iClass,
- String name,
- Location location
- ) throws CompileException {
- IClass[] types = iClass.findMemberType(name);
- if (types.length == 0) return null;
- if (types.length == 1) return types[0];
-
- StringBuffer sb = new StringBuffer("Type \"" + name + "\" is ambiguous: " + types[0].toString());
- for (int i = 1; i < types.length; ++i) sb.append(" vs. ").append(types[i].toString());
- this.compileError(sb.toString(), location);
- return types[0];
- }
-
- /**
- * Find one class or interface declared in this compilation unit by name.
- *
- * @param className Fully qualified class name, e.g. "pkg1.pkg2.Outer$Inner".
- * @return <code>null</code> if a class with that name is not declared in this compilation unit
- */
- public IClass findClass(String className) {
-
- // Examine package name.
- String packageName = (
- this.compilationUnit.optionalPackageDeclaration == null ? null :
- this.compilationUnit.optionalPackageDeclaration.packageName
- );
- if (packageName != null) {
- if (!className.startsWith(packageName + '.')) return null;
- className = className.substring(packageName.length() + 1);
- }
-
- StringTokenizer st = new StringTokenizer(className, "$");
- Java.TypeDeclaration td = this.compilationUnit.getPackageMemberTypeDeclaration(st.nextToken());
- if (td == null) return null;
- while (st.hasMoreTokens()) {
- td = td.getMemberTypeDeclaration(st.nextToken());
- if (td == null) return null;
- }
- return this.resolve((Java.AbstractTypeDeclaration) td);
- }
-
- /**
- * Equivalent to {@link #compileError(String, Location)} with a
- * <code>null</code> location argument.
- */
- private void compileError(String message) throws CompileException {
- this.compileError(message, null);
- }
-
- /**
- * Issue a compile error with the given message. This is done through the
- * {@link ErrorHandler} that was installed through
- * {@link #setCompileErrorHandler(ErrorHandler)}. Such a handler typically throws
- * a {@link CompileException}, but it may as well decide to return normally. Consequently,
- * the calling code must be prepared that {@link #compileError(String, Location)}
- * returns normally, and must attempt to continue compiling.
- *
- * @param message The message to report
- * @param optionalLocation The location to report
- */
- private void compileError(String message, Location optionalLocation) throws CompileException {
- ++this.compileErrorCount;
- if (this.optionalCompileErrorHandler != null) {
- this.optionalCompileErrorHandler.handleError(message, optionalLocation);
- } else {
- throw new CompileException(message, optionalLocation);
- }
- }
-
- /**
- * Issues a warning with the given message an location an returns. This is done through
- * a {@link WarningHandler} that was installed through
- * {@link #setWarningHandler(WarningHandler)}.
- * <p>
- * The <code>handle</code> argument qulifies the warning and is typically used by
- * the {@link WarningHandler} to suppress individual warnings.
- *
- * @param handle
- * @param message
- * @param optionalLocation
- */
- private void warning(String handle, String message, Location optionalLocation) {
- if (this.optionalWarningHandler != null) this.optionalWarningHandler.handleWarning(handle, message, optionalLocation);
- }
-
- /**
- * Interface type for {@link UnitCompiler#setCompileErrorHandler}.
- */
- public interface ErrorHandler {
- void handleError(String message, Location optionalLocation) throws CompileException;
- }
-
- /**
- * By default, {@link CompileException}s are thrown on compile errors, but an application
- * my install its own (thread-local) {@link ErrorHandler}.
- * <p>
- * Be aware that a single problem during compilation often causes a bunch of compile errors,
- * so a good {@link ErrorHandler} counts errors and throws a {@link CompileException} when
- * a limit is reached.
- * <p>
- * If the given {@link ErrorHandler} does not throw {@link CompileException}s, then
- * {@link #compileUnit(EnumeratorSet)} will throw one when the compilation of the unit
- * is finished, and errors had occurred. In other words: The {@link ErrorHandler} may
- * throw a {@link CompileException} or not, but {@link #compileUnit(EnumeratorSet)} will
- * definitely throw a {@link CompileException} if one or more compile errors have
- * occurred.
- *
- * @param optionalCompileErrorHandler <code>null</code> to restore the default behavior (throwing a {@link CompileException}
- */
- public void setCompileErrorHandler(ErrorHandler optionalCompileErrorHandler) {
- this.optionalCompileErrorHandler = optionalCompileErrorHandler;
- }
-
- /**
- * By default, warnings are discarded, but an application my install a custom
- * {@link WarningHandler}.
- *
- * @param optionalWarningHandler <code>null</code> to indicate that no warnings be issued
- */
- public void setWarningHandler(WarningHandler optionalWarningHandler) {
- this.optionalWarningHandler = optionalWarningHandler;
- }
-
- private CodeContext getCodeContext() {
- CodeContext res = this.codeContext;
- if (res == null) throw new RuntimeException("S.N.O.: Null CodeContext");
- return res;
- }
-
- private CodeContext replaceCodeContext(CodeContext newCodeContext) {
- CodeContext oldCodeContext = this.codeContext;
- this.codeContext = newCodeContext;
- return oldCodeContext;
- }
-
- private CodeContext createDummyCodeContext() {
- return new CodeContext(this.getCodeContext().getClassFile());
- }
-
- private void writeByte(int v) {
- this.codeContext.write((short) -1, (byte) v);
- }
- private void writeShort(int v) {
- this.codeContext.write((short) -1, (byte) (v >> 8), (byte) v);
- }
- private void writeInt(int v) {
- this.codeContext.write((short) -1, (byte) (v >> 24), (byte) (v >> 16), (byte) (v >> 8), (byte) v);
- }
-
- private void writeOpcode(Java.Locatable l, int opcode) {
- this.codeContext.write(l.getLocation().getLineNumber(), (byte) opcode);
- }
- private void writeOpcodes(Java.Locatable l, byte[] opcodes) {
- this.codeContext.write(l.getLocation().getLineNumber(), opcodes);
- }
- private void writeBranch(Java.Locatable l, int opcode, final CodeContext.Offset dst) {
- this.codeContext.writeBranch(l.getLocation().getLineNumber(), opcode, dst);
- }
- private void writeOffset(CodeContext.Offset src, final CodeContext.Offset dst) {
- this.codeContext.writeOffset((short) -1, src, dst);
- }
-
- // Wrappers for "ClassFile.addConstant...Info()". Saves us some coding overhead.
-
- private void writeConstantClassInfo(String descriptor) {
- CodeContext ca = this.codeContext;
- ca.writeShort((short) -1, ca.getClassFile().addConstantClassInfo(descriptor));
- }
- private void writeConstantFieldrefInfo(String classFD, String fieldName, String fieldFD) {
- CodeContext ca = this.codeContext;
- ca.writeShort((short) -1, ca.getClassFile().addConstantFieldrefInfo(classFD, fieldName, fieldFD));
- }
- private void writeConstantMethodrefInfo(String classFD, String methodName, String methodMD) {
- CodeContext ca = this.codeContext;
- ca.writeShort((short) -1, ca.getClassFile().addConstantMethodrefInfo(classFD, methodName, methodMD));
- }
- private void writeConstantInterfaceMethodrefInfo(String classFD, String methodName, String methodMD) {
- CodeContext ca = this.codeContext;
- ca.writeShort((short) -1, ca.getClassFile().addConstantInterfaceMethodrefInfo(classFD, methodName, methodMD));
- }
-/* UNUSED
- private void writeConstantStringInfo(String value) {
- this.codeContext.writeShort((short) -1, this.addConstantStringInfo(value));
- }
-*/
- private short addConstantStringInfo(String value) {
- return this.codeContext.getClassFile().addConstantStringInfo(value);
- }
-/* UNUSED
- private void writeConstantIntegerInfo(int value) {
- this.codeContext.writeShort((short) -1, this.addConstantIntegerInfo(value));
- }
-*/
- private short addConstantIntegerInfo(int value) {
- return this.codeContext.getClassFile().addConstantIntegerInfo(value);
- }
-/* UNUSED
- private void writeConstantFloatInfo(float value) {
- this.codeContext.writeShort((short) -1, this.addConstantFloatInfo(value));
- }
-*/
- private short addConstantFloatInfo(float value) {
- return this.codeContext.getClassFile().addConstantFloatInfo(value);
- }
- private void writeConstantLongInfo(long value) {
- CodeContext ca = this.codeContext;
- ca.writeShort((short) -1, ca.getClassFile().addConstantLongInfo(value));
- }
- private void writeConstantDoubleInfo(double value) {
- CodeContext ca = this.codeContext;
- ca.writeShort((short) -1, ca.getClassFile().addConstantDoubleInfo(value));
- }
-
- public CodeContext.Offset getWhereToBreak(Java.BreakableStatement bs) {
- if (bs.whereToBreak == null) {
- bs.whereToBreak = this.codeContext.new Offset();
- }
- return bs.whereToBreak;
- }
-
- private Java.TypeBodyDeclaration getDeclaringTypeBodyDeclaration(Java.QualifiedThisReference qtr) throws CompileException {
- if (qtr.declaringTypeBodyDeclaration == null) {
-
- // Compile error if in static function context.
- Java.Scope s;
- for (s = qtr.getEnclosingBlockStatement(); !(s instanceof Java.TypeBodyDeclaration); s = s.getEnclosingScope());
- qtr.declaringTypeBodyDeclaration = (Java.TypeBodyDeclaration) s;
- if (qtr.declaringTypeBodyDeclaration.isStatic()) this.compileError("No current instance available in static method", qtr.getLocation());
-
- // Determine declaring type.
- qtr.declaringClass = (Java.ClassDeclaration) qtr.declaringTypeBodyDeclaration.getDeclaringType();
- }
- return qtr.declaringTypeBodyDeclaration;
- }
-
- private Java.ClassDeclaration getDeclaringClass(Java.QualifiedThisReference qtr) throws CompileException {
- if (qtr.declaringClass == null) {
- this.getDeclaringTypeBodyDeclaration(qtr);
- }
- return qtr.declaringClass;
- }
-
- private void referenceThis(Locatable l) {
- this.writeOpcode(l, Opcode.ALOAD_0);
- }
-
- /**
- * Expects "dimExprCount" values of type "integer" on the operand stack.
- * Creates an array of "dimExprCount" + "dims" dimensions of
- * "componentType".
- *
- * @return The type of the created array
- */
- private IClass newArray(
- Locatable l,
- int dimExprCount,
- int dims,
- IClass componentType
- ) {
- if (dimExprCount == 1 && dims == 0 && componentType.isPrimitive()) {
-
- // "new <primitive>[<n>]"
- this.writeOpcode(l, Opcode.NEWARRAY);
- this.writeByte((
- componentType == IClass.BOOLEAN ? 4 :
- componentType == IClass.CHAR ? 5 :
- componentType == IClass.FLOAT ? 6 :
- componentType == IClass.DOUBLE ? 7 :
- componentType == IClass.BYTE ? 8 :
- componentType == IClass.SHORT ? 9 :
- componentType == IClass.INT ? 10 :
- componentType == IClass.LONG ? 11 : -1
- ));
- return componentType.getArrayIClass(this.iClassLoader.OBJECT);
- }
-
- if (dimExprCount == 1) {
- IClass at = componentType.getArrayIClass(dims, this.iClassLoader.OBJECT);
-
- // "new <class-or-interface>[<n>]"
- // "new <anything>[<n>][]..."
- this.writeOpcode(l, Opcode.ANEWARRAY);
- this.writeConstantClassInfo(at.getDescriptor());
- return at.getArrayIClass(this.iClassLoader.OBJECT);
- } else {
- IClass at = componentType.getArrayIClass(dimExprCount + dims, this.iClassLoader.OBJECT);
-
- // "new <anything>[]..."
- // "new <anything>[<n>][<m>]..."
- // "new <anything>[<n>][<m>]...[]..."
- this.writeOpcode(l, Opcode.MULTIANEWARRAY);
- this.writeConstantClassInfo(at.getDescriptor());
- this.writeByte(dimExprCount);
- return at;
- }
- }
-
- /**
- * Short-hand implementation of {@link IClass.IField} that implements a
- * non-constant, non-static, package-accessible field.
- */
- public static class SimpleIField extends IClass.IField {
- private final String name;
- private final IClass type;
-
- public SimpleIField(
- IClass declaringIClass,
- String name,
- IClass type
- ) {
- declaringIClass.super();
- this.name = name;
- this.type = type;
- }
- public Object getConstantValue() { return null; }
- public String getName() { return this.name; }
- public IClass getType() { return this.type; }
- public boolean isStatic() { return false; }
- public Access getAccess() { return Access.DEFAULT; }
- };
-
- private static Access modifiers2Access(short modifiers) {
- return (
- (modifiers & Mod.PUBLIC ) != 0 ? Access.PUBLIC :
- (modifiers & Mod.PROTECTED) != 0 ? Access.PROTECTED :
- (modifiers & Mod.PRIVATE ) != 0 ? Access.PRIVATE :
- Access.DEFAULT
- );
- }
-
- private static String last(String[] sa) {
- if (sa.length == 0) throw new IllegalArgumentException("SNO: Empty string array");
- return sa[sa.length - 1];
- }
-
- private static String[] allButLast(String[] sa) {
- if (sa.length == 0) throw new IllegalArgumentException("SNO: Empty string array");
- String[] tmp = new String[sa.length - 1];
- System.arraycopy(sa, 0, tmp, 0, tmp.length);
- return tmp;
- }
-
- private static String[] concat(String[] sa, String s) {
- String[] tmp = new String[sa.length + 1];
- System.arraycopy(sa, 0, tmp, 0, sa.length);
- tmp[sa.length] = s;
- return tmp;
- }
-
- // Used to write byte code while compiling one constructor/method.
- private CodeContext codeContext = null;
-
- // Used for elaborate compile error handling.
- private ErrorHandler optionalCompileErrorHandler = null;
- private int compileErrorCount = 0;
-
- // Used for elaborate warning handling.
- private WarningHandler optionalWarningHandler = null;
-
- public final Java.CompilationUnit compilationUnit;
-
- private final IClassLoader iClassLoader;
- private final boolean isStringBuilderAvailable;
- private List generatedClassFiles;
- private EnumeratorSet debuggingInformation;
-
- private final Map singleTypeImports = new HashMap(); // String simpleTypeName => String[] fullyQualifiedTypeName
- private final Collection typeImportsOnDemand; // String[] package
- private final Map singleStaticImports = new HashMap(); // String staticMemberName => IField, List of IMethod, or IClass
- private final Collection staticImportsOnDemand = new ArrayList(); // IClass
-}
diff --git a/src/org/codehaus/janino/UnparseVisitor.java b/src/org/codehaus/janino/UnparseVisitor.java
deleted file mode 100644
index 443c463..0000000
--- a/src/org/codehaus/janino/UnparseVisitor.java
+++ /dev/null
@@ -1,775 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino;
-
-import java.io.*;
-import java.util.*;
-
-import org.codehaus.janino.util.AutoIndentWriter;
-
-/**
- * A visitor that unparses (un-compiles) an AST to a {@link Writer}. See
- * {@link #main(String[])} for a usage example.
- */
-public class UnparseVisitor implements Visitor.ComprehensiveVisitor {
- protected final AutoIndentWriter aiw;
- protected final PrintWriter pw;
-
- /**
- * Testing of parsing/unparsing.
- * <p>
- * Reads compilation units from the files named on the command line
- * and unparses them to {@link System#out}.
- */
- public static void main(String[] args) throws Exception {
- Writer w = new BufferedWriter(new OutputStreamWriter(System.out));
- for (int i = 0; i < args.length; ++i) {
- String fileName = args[i];
-
- // Parse each compilation unit.
- FileReader r = new FileReader(fileName);
- Java.CompilationUnit cu;
- try {
- cu = new Parser(new Scanner(fileName, r)).parseCompilationUnit();
- } finally {
- r.close();
- }
-
- // Unparse each compilation unit.
- UnparseVisitor.unparse(cu, w);
- }
- w.flush();
- }
-
- /**
- * Unparse the given {@link Java.CompilationUnit} to the given {@link Writer}.
- */
- public static void unparse(Java.CompilationUnit cu, Writer w) {
- new UnparseVisitor(w).unparseCompilationUnit(cu);
- }
-
- public UnparseVisitor(Writer w) {
- this.aiw = new AutoIndentWriter(w);
- this.pw = new PrintWriter(this.aiw, true);
- }
-
- public void unparseCompilationUnit(Java.CompilationUnit cu) {
- if (cu.optionalPackageDeclaration != null) {
- this.pw.println("package " + cu.optionalPackageDeclaration.packageName + ';');
- }
- for (Iterator it = cu.importDeclarations.iterator(); it.hasNext();) {
- ((Java.CompilationUnit.ImportDeclaration) it.next()).accept(this);
- }
- for (Iterator it = cu.packageMemberTypeDeclarations.iterator(); it.hasNext();) {
- this.unparseTypeDeclaration((Java.PackageMemberTypeDeclaration) it.next());
- this.pw.println();
- }
- }
-
- public void visitSingleTypeImportDeclaration(Java.CompilationUnit.SingleTypeImportDeclaration stid) {
- this.pw.println("import " + Java.join(stid.identifiers, ".") + ';');
- }
- public void visitTypeImportOnDemandDeclaration(Java.CompilationUnit.TypeImportOnDemandDeclaration tiodd) {
- this.pw.println("import " + Java.join(tiodd.identifiers, ".") + ".*;");
- }
- public void visitSingleStaticImportDeclaration(Java.CompilationUnit.SingleStaticImportDeclaration ssid) {
- this.pw.println("import static " + Java.join(ssid.identifiers, ".") + ';');
- }
- public void visitStaticImportOnDemandDeclaration(Java.CompilationUnit.StaticImportOnDemandDeclaration siodd) {
- this.pw.println("import static " + Java.join(siodd.identifiers, ".") + ".*;");
- }
-
- public void visitLocalClassDeclaration(Java.LocalClassDeclaration lcd) {
- this.unparseNamedClassDeclaration(lcd);
- }
- public void visitMemberClassDeclaration(Java.MemberClassDeclaration mcd) {
- this.unparseNamedClassDeclaration(mcd);
- }
- public void visitMemberInterfaceDeclaration(Java.MemberInterfaceDeclaration mid) {
- this.unparseInterfaceDeclaration(mid);
- }
- public void visitPackageMemberClassDeclaration(Java.PackageMemberClassDeclaration pmcd) {
- this.unparseNamedClassDeclaration(pmcd);
- }
- public void visitPackageMemberInterfaceDeclaration(Java.PackageMemberInterfaceDeclaration pmid) {
- this.unparseInterfaceDeclaration(pmid);
- }
- public void visitConstructorDeclarator(Java.ConstructorDeclarator cd) {
- this.unparseDocComment(cd);
- this.unparseModifiers(cd.modifiers);
- Java.ClassDeclaration declaringClass = cd.getDeclaringClass();
- this.pw.print(declaringClass instanceof Java.NamedClassDeclaration ? ((Java.NamedClassDeclaration) declaringClass).name : "UNNAMED");
- this.unparseFunctionDeclaratorRest(cd);
- this.pw.print(' ');
- if (cd.optionalConstructorInvocation != null) {
- this.pw.println('{');
- this.unparseBlockStatement(cd.optionalConstructorInvocation);
- this.pw.println(';');
- for (Iterator it = cd.optionalBody.statements.iterator(); it.hasNext();) {
- this.unparseBlockStatement((Java.BlockStatement) it.next());
- this.pw.println();
- }
- this.pw.print('}');
- } else {
- this.unparseBlockStatement(cd.optionalBody);
- }
- }
- public void visitMethodDeclarator(Java.MethodDeclarator md) {
- this.unparseDocComment(md);
- this.unparseModifiers(md.modifiers);
- this.unparseType(md.type);
- this.pw.print(' ' + md.name);
- this.unparseFunctionDeclaratorRest(md);
- if (md.optionalBody != null) {
- this.pw.print(' ');
- this.unparseBlockStatement(md.optionalBody);
- } else {
- this.pw.print(';');
- }
- }
- public void visitFieldDeclaration(Java.FieldDeclaration fd) {
- this.unparseDocComment(fd);
- this.unparseModifiers(fd.modifiers);
- this.unparseType(fd.type);
- this.pw.print(' ');
- for (int i = 0; i < fd.variableDeclarators.length; ++i) {
- if (i > 0) this.pw.print(", ");
- this.unparseVariableDeclarator(fd.variableDeclarators[i]);
- }
- this.pw.print(';');
- }
- public void visitInitializer(Java.Initializer i) {
- if (i.statiC) this.pw.print("static ");
- this.unparseBlockStatement(i.block);
- }
- public void visitBlock(Java.Block b) {
- this.pw.println('{');
- for (Iterator it = b.statements.iterator(); it.hasNext();) {
- this.unparseBlockStatement((Java.BlockStatement) it.next());
- this.pw.println();
- }
- this.pw.print('}');
- }
- public void visitBreakStatement(Java.BreakStatement bs) {
- this.pw.print("break");
- if (bs.optionalLabel != null) this.pw.print(' ' + bs.optionalLabel);
- this.pw.print(';');
- }
- public void visitContinueStatement(Java.ContinueStatement cs) {
- this.pw.print("continue");
- if (cs.optionalLabel != null) this.pw.print(' ' + cs.optionalLabel);
- this.pw.print(';');
- }
- public void visitDoStatement(Java.DoStatement ds) {
- this.pw.print("do ");
- this.unparseBlockStatement(ds.body);
- this.pw.print("while (");
- this.unparse(ds.condition);
- this.pw.print(");");
- }
- public void visitEmptyStatement(Java.EmptyStatement es) {
- this.pw.print(';');
- }
- public void visitExpressionStatement(Java.ExpressionStatement es) {
- this.unparse(es.rvalue);
- this.pw.print(';');
- }
- public void visitForStatement(Java.ForStatement fs) {
- this.pw.print("for (");
- if (fs.optionalInit != null) {
- this.unparseBlockStatement(fs.optionalInit);
- } else {
- this.pw.print(';');
- }
- if (fs.optionalCondition != null) {
- this.pw.print(' ');
- this.unparse(fs.optionalCondition);
- }
- this.pw.print(';');
- if (fs.optionalUpdate != null) {
- this.pw.print(' ');
- for (int i = 0; i < fs.optionalUpdate.length; ++i) {
- if (i > 0) this.pw.print(", ");
- this.unparse(fs.optionalUpdate[i]);
- }
- }
- this.pw.print(") ");
- this.unparseBlockStatement(fs.body);
- }
- public void visitIfStatement(Java.IfStatement is) {
- this.pw.print("if (");
- this.unparse(is.condition);
- this.pw.print(") ");
- this.unparseBlockStatement(is.thenStatement);
- if (is.optionalElseStatement != null) {
- this.pw.print(" else ");
- this.unparseBlockStatement(is.optionalElseStatement);
- }
- }
- public void visitLabeledStatement(Java.LabeledStatement ls) {
- this.pw.println(ls.label + ':');
- this.unparseBlockStatement(ls.body);
- }
- public void visitLocalClassDeclarationStatement(Java.LocalClassDeclarationStatement lcds) {
- this.unparseTypeDeclaration(lcds.lcd);
- }
- public void visitLocalVariableDeclarationStatement(Java.LocalVariableDeclarationStatement lvds) {
- this.unparseModifiers(lvds.modifiers);
- this.unparseType(lvds.type);
- this.pw.print(' ');
- this.unparseVariableDeclarator(lvds.variableDeclarators[0]);
- for (int i = 1; i < lvds.variableDeclarators.length; ++i) {
- this.pw.print(", ");
- this.unparseVariableDeclarator(lvds.variableDeclarators[i]);
- }
- this.pw.print(';');
- }
- public void visitReturnStatement(Java.ReturnStatement rs) {
- this.pw.print("return");
- if (rs.optionalReturnValue != null) {
- this.pw.print(' ');
- this.unparse(rs.optionalReturnValue);
- }
- this.pw.print(';');
- }
- public void visitSwitchStatement(Java.SwitchStatement ss) {
- this.pw.print("switch (");
- this.unparse(ss.condition);
- this.pw.println(") {");
- for (Iterator it = ss.sbsgs.iterator(); it.hasNext();) {
- Java.SwitchStatement.SwitchBlockStatementGroup sbgs = (Java.SwitchStatement.SwitchBlockStatementGroup) it.next();
- this.aiw.unindent();
- try {
- for (Iterator it2 = sbgs.caseLabels.iterator(); it2.hasNext();) {
- Java.Rvalue rv = (Java.Rvalue) it2.next();
- this.pw.print("case ");
- this.unparse(rv);
- this.pw.println(':');
- }
- if (sbgs.hasDefaultLabel) this.pw.println("default:");
- } finally {
- this.aiw.indent();
- }
- for (Iterator it2 = sbgs.blockStatements.iterator(); it2.hasNext();) {
- this.unparseBlockStatement((Java.BlockStatement) it2.next());
- this.pw.println();
- }
- }
- this.pw.print('}');
- }
- public void visitSynchronizedStatement(Java.SynchronizedStatement ss) {
- this.pw.print("synchronized (");
- this.unparse(ss.expression);
- this.pw.print(") ");
- this.unparseBlockStatement(ss.body);
- }
- public void visitThrowStatement(Java.ThrowStatement ts) {
- this.pw.print("throw ");
- this.unparse(ts.expression);
- this.pw.print(';');
- }
- public void visitTryStatement(Java.TryStatement ts) {
- this.pw.print("try ");
- this.unparseBlockStatement(ts.body);
- for (Iterator it = ts.catchClauses.iterator(); it.hasNext();) {
- Java.CatchClause cc = (Java.CatchClause) it.next();
- this.pw.print(" catch (");
- this.unparseFormalParameter(cc.caughtException);
- this.pw.print(") ");
- this.unparseBlockStatement(cc.body);
- }
- if (ts.optionalFinally != null) {
- this.pw.print(" finally ");
- this.unparseBlockStatement(ts.optionalFinally);
- }
- }
- public void visitWhileStatement(Java.WhileStatement ws) {
- this.pw.print("while (");
- this.unparse(ws.condition);
- this.pw.print(") ");
- this.unparseBlockStatement(ws.body);
- }
- public void unparseVariableDeclarator(Java.VariableDeclarator vd) {
- this.pw.print(vd.name);
- for (int i = 0; i < vd.brackets; ++i) this.pw.print("[]");
- if (vd.optionalInitializer != null) {
- this.pw.print(" = ");
- this.unparseArrayInitializerOrRvalue(vd.optionalInitializer);
- }
- }
- public void unparseFormalParameter(Java.FunctionDeclarator.FormalParameter fp) {
- if (fp.finaL) this.pw.print("final ");
- this.unparseType(fp.type);
- this.pw.print(' ' + fp.name);
- }
- public void visitMethodInvocation(Java.MethodInvocation mi) {
- if (mi.optionalTarget != null) {
- this.unparseLhs(mi.optionalTarget, ".");
- this.pw.print('.');
- }
- this.pw.print(mi.methodName);
- this.unparseFunctionInvocationArguments(mi.arguments);
- }
- public void visitAlternateConstructorInvocation(Java.AlternateConstructorInvocation aci) {
- this.pw.print("this");
- this.unparseFunctionInvocationArguments(aci.arguments);
- }
- public void visitSuperConstructorInvocation(Java.SuperConstructorInvocation sci) {
- if (sci.optionalQualification != null) {
- this.unparseLhs(sci.optionalQualification, ".");
- this.pw.print('.');
- }
- this.pw.print("super");
- this.unparseFunctionInvocationArguments(sci.arguments);
- }
- public void visitNewClassInstance(Java.NewClassInstance nci) {
- if (nci.optionalQualification != null) {
- this.unparseLhs(nci.optionalQualification, ".");
- this.pw.print('.');
- }
- this.pw.print("new " + nci.type.toString());
- this.unparseFunctionInvocationArguments(nci.arguments);
- }
- public void visitAssignment(Java.Assignment a) {
- this.unparseLhs(a.lhs, a.operator);
- this.pw.print(' ' + a.operator + ' ');
- this.unparseRhs(a.rhs, a.operator);
- }
- public void visitAmbiguousName(Java.AmbiguousName an) { this.pw.print(an.toString()); }
- public void visitArrayAccessExpression(Java.ArrayAccessExpression aae) {
- this.unparseLhs(aae.lhs, "[ ]");
- this.pw.print('[');
- this.unparse(aae.index);
- this.pw.print(']');
- }
- public void visitArrayLength(Java.ArrayLength al) {
- this.unparseLhs(al.lhs, ".");
- this.pw.print(".length");
- }
- public void visitArrayType(Java.ArrayType at) {
- this.unparseType(at.componentType);
- this.pw.print("[]");
- }
- public void visitBasicType(Java.BasicType bt) {
- this.pw.print(bt.toString());
- }
- public void visitBinaryOperation(Java.BinaryOperation bo) {
- this.unparseLhs(bo.lhs, bo.op);
- this.pw.print(' ' + bo.op + ' ');
- this.unparseRhs(bo.rhs, bo.op);
- }
- public void visitCast(Java.Cast c) {
- this.pw.print('(');
- this.unparseType(c.targetType);
- this.pw.print(") ");
- this.unparseRhs(c.value, "cast");
- }
- public void visitClassLiteral(Java.ClassLiteral cl) {
- this.unparseType(cl.type);
- this.pw.print(".class");
- }
- public void visitConditionalExpression(Java.ConditionalExpression ce) {
- this.unparseLhs(ce.lhs, "?:");
- this.pw.print(" ? ");
- this.unparseLhs(ce.mhs, "?:");
- this.pw.print(" : ");
- this.unparseRhs(ce.rhs, "?:");
- }
- public void visitCrement(Java.Crement c) {
- if (c.pre) {
- this.pw.print(c.operator);
- this.unparseUnaryOperation(c.operand, c.operator + "x");
- } else
- {
- this.unparseUnaryOperation(c.operand, "x" + c.operator);
- this.pw.print(c.operator);
- }
- }
- public void visitFieldAccess(Java.FieldAccess fa) {
- this.unparseLhs(fa.lhs, ".");
- this.pw.print('.' + fa.field.getName());
- }
- public void visitFieldAccessExpression(Java.FieldAccessExpression fae) {
- this.unparseLhs(fae.lhs, ".");
- this.pw.print('.' + fae.fieldName);
- }
- public void visitSuperclassFieldAccessExpression(Java.SuperclassFieldAccessExpression scfae) {
- if (scfae.optionalQualification != null) {
- this.unparseType(scfae.optionalQualification);
- this.pw.print(".super." + scfae.fieldName);
- } else
- {
- this.pw.print("super." + scfae.fieldName);
- }
- }
- public void visitInstanceof(Java.Instanceof io) {
- this.unparseLhs(io.lhs, "instanceof");
- this.pw.print(" instanceof ");
- this.unparseType(io.rhs);
- }
- public void visitLiteral(Java.Literal l) { this.pw.print(l.toString()); }
- public void visitLocalVariableAccess(Java.LocalVariableAccess lva) { this.pw.print(lva.toString()); }
- public void visitNewArray(Java.NewArray na) {
- this.pw.print("new ");
- this.unparseType(na.type);
- for (int i = 0; i < na.dimExprs.length; ++i) {
- this.pw.print('[');
- this.unparse(na.dimExprs[i]);
- this.pw.print(']');
- }
- for (int i = 0; i < na.dims; ++i) {
- this.pw.print("[]");
- }
- }
- public void visitNewInitializedArray(Java.NewInitializedArray nai) {
- this.pw.print("new ");
- this.unparseType(nai.arrayType);
- this.pw.print(" ");
- this.unparseArrayInitializerOrRvalue(nai.arrayInitializer);
- }
- public void visitPackage(Java.Package p) { this.pw.print(p.toString()); }
- public void visitParameterAccess(Java.ParameterAccess pa) { this.pw.print(pa.toString()); }
- public void visitQualifiedThisReference(Java.QualifiedThisReference qtr) {
- this.unparseType(qtr.qualification);
- this.pw.print(".this");
- }
- public void visitReferenceType(Java.ReferenceType rt) { this.pw.print(rt.toString()); }
- public void visitRvalueMemberType(Java.RvalueMemberType rmt) { this.pw.print(rmt.toString()); }
- public void visitSimpleType(Java.SimpleType st) { this.pw.print(st.toString()); }
- public void visitSuperclassMethodInvocation(Java.SuperclassMethodInvocation smi) {
- this.pw.print("super." + smi.methodName);
- this.unparseFunctionInvocationArguments(smi.arguments);
- }
- public void visitThisReference(Java.ThisReference tr) {
- this.pw.print("this");
- }
- public void visitUnaryOperation(Java.UnaryOperation uo) {
- this.pw.print(uo.operator);
- this.unparseUnaryOperation(uo.operand, uo.operator + "x");
- }
- public void visitParenthesizedExpression(Java.ParenthesizedExpression pe) {
- this.pw.print('(');
- this.unparse(pe.value);
- this.pw.print(')');
- }
-
- // Helpers
-
- private void unparseBlockStatement(Java.BlockStatement blockStatement) {
- blockStatement.accept(this);
- }
-
- private void unparseTypeDeclaration(Java.TypeDeclaration typeDeclaration) {
- typeDeclaration.accept(this);
- }
-
- private void unparseType(Java.Type type) {
- ((Java.Atom) type).accept(this);
- }
-
- private void unparse(Java.Atom operand) {
- ((Java.Atom) operand).accept(this);
- }
-
- /**
- * Iff the <code>operand</code> is unnatural for the <code>unaryOperator</code>, enclose the
- * <code>operand</code> in parentheses. Example: "a+b" is an unnatural operand for unary "!x".
- *
- * @param unaryOperator ++x --x +x -x ~x !x x++ x--
- */
- private void unparseUnaryOperation(Java.Rvalue operand, String unaryOperator) {
- int cmp = UnparseVisitor.comparePrecedence(unaryOperator, operand);
- this.unparse(operand, cmp < 0);
- }
-
- /**
- * Iff the <code>lhs</code> is unnatural for the <code>binaryOperator</code>, enclose the
- * <code>lhs</code> in parentheses. Example: "a+b" is an unnatural lhs for operator "*".
- *
- * @param binaryOperator = +=... ?: || && | ^ & == != < > <= >= instanceof << >> >>> + - * / % cast
- */
-
- private void unparseLhs(Java.Atom lhs, String binaryOperator) {
- int cmp = UnparseVisitor.comparePrecedence(binaryOperator, lhs);
- this.unparse(lhs, cmp < 0 || (cmp == 0 && UnparseVisitor.isLeftAssociate(binaryOperator)));
- }
-
-
- /**
- * Iff the <code>rhs</code> is unnatural for the <code>binaryOperator</code>, enclose the
- * <code>rhs</code> in parentheses. Example: "a+b" is an unnatural rhs for operator "*".
- */
- private void unparseRhs(Java.Rvalue rhs, String binaryOperator) {
- int cmp = UnparseVisitor.comparePrecedence(binaryOperator, rhs);
- this.unparse(rhs, cmp < 0 || (cmp == 0 && UnparseVisitor.isRightAssociate(binaryOperator)));
- }
-
- private void unparse(Java.Atom operand, boolean natural) {
- if (!natural) this.pw.print("((( ");
- this.unparse(operand);
- if (!natural) this.pw.print(" )))");
- }
-
- /**
- * Return true iff operator is right associative e.g. <code>a = b = c</code> evaluates as
- * <code>a = (b = c)</code>.
- *
- * @return Return true iff operator is right associative
- */
- private static boolean isRightAssociate(String op) {
- return UnparseVisitor.RIGHT_ASSOCIATIVE_OPERATORS.contains(op);
- }
-
- /**
- * Return true iff operator is left associative e.g. <code>a - b - c</code> evaluates as
- * <code>(a - b) - c</code>.
- *
- * @return Return true iff operator is left associative
- */
- private static boolean isLeftAssociate(String op) {
- return UnparseVisitor.LEFT_ASSOCIATIVE_OPERATORS.contains(op);
- }
-
- /**
- * Returns a value
- * <ul>
- * <li>< 0 iff the <code>operator</code> has lower precedence than the <code>operand</code>
- * <li>==; 0 iff the <code>operator</code> has equal precedence than the <code>operand</code>
- * <li>> 0 iff the <code>operator</code> has higher precedence than the <code>operand</code>
- * </ul>
- */
- private static int comparePrecedence(String operator, Java.Atom operand) {
- if (operand instanceof Java.BinaryOperation) {
- return UnparseVisitor.getOperatorPrecedence(operator) - UnparseVisitor.getOperatorPrecedence(((Java.BinaryOperation) operand).op);
- } else
- if (operand instanceof Java.UnaryOperation) {
- return UnparseVisitor.getOperatorPrecedence(operator) - UnparseVisitor.getOperatorPrecedence(((Java.UnaryOperation) operand).operator + "x");
- } else
- if (operand instanceof Java.ConditionalExpression) {
- return UnparseVisitor.getOperatorPrecedence(operator) - UnparseVisitor.getOperatorPrecedence("?:");
- } else
- if (operand instanceof Java.Instanceof) {
- return UnparseVisitor.getOperatorPrecedence(operator) - UnparseVisitor.getOperatorPrecedence("instanceof");
- } else
- if (operand instanceof Java.Cast) {
- return UnparseVisitor.getOperatorPrecedence(operator) - UnparseVisitor.getOperatorPrecedence("cast");
- } else
- if (operand instanceof Java.MethodInvocation || operand instanceof Java.FieldAccess) {
- return UnparseVisitor.getOperatorPrecedence(operator) - UnparseVisitor.getOperatorPrecedence(".");
- } else
- if (operand instanceof Java.NewArray) {
- return UnparseVisitor.getOperatorPrecedence(operator) - UnparseVisitor.getOperatorPrecedence("new");
- } else
- if (operand instanceof Java.Crement) {
- Java.Crement c = (Java.Crement) operand;
- return UnparseVisitor.getOperatorPrecedence(operator) - UnparseVisitor.getOperatorPrecedence(c.pre ? c.operator + "x" : "x" + c.operator);
- } else
- {
- // All other rvalues (e.g. literal) have higher precedence than any operator.
- return -1;
- }
- }
- private static final int getOperatorPrecedence(String operator) {
- return ((Integer) UnparseVisitor.OPERATOR_PRECEDENCE.get(operator)).intValue();
- }
- private static final Set LEFT_ASSOCIATIVE_OPERATORS = new HashSet();
- private static final Set RIGHT_ASSOCIATIVE_OPERATORS = new HashSet();
- private static final Set UNARY_OPERATORS = new HashSet();
- private static final Map OPERATOR_PRECEDENCE = new HashMap();
- static {
- Object[] ops = {
- UnparseVisitor.RIGHT_ASSOCIATIVE_OPERATORS, "=", "*=", "/=", "%=", "+=", "-=", "<<=", ">>=", ">>>=", "&=", "^=", "|=",
- UnparseVisitor.RIGHT_ASSOCIATIVE_OPERATORS, "?:",
- UnparseVisitor.LEFT_ASSOCIATIVE_OPERATORS, "||",
- UnparseVisitor.LEFT_ASSOCIATIVE_OPERATORS, "&&",
- UnparseVisitor.LEFT_ASSOCIATIVE_OPERATORS, "|",
- UnparseVisitor.LEFT_ASSOCIATIVE_OPERATORS, "^",
- UnparseVisitor.LEFT_ASSOCIATIVE_OPERATORS, "&",
- UnparseVisitor.LEFT_ASSOCIATIVE_OPERATORS, "==", "!=",
- UnparseVisitor.LEFT_ASSOCIATIVE_OPERATORS, "<", ">", "<=", ">=", "instanceof",
- UnparseVisitor.LEFT_ASSOCIATIVE_OPERATORS, "<<", ">>", ">>>",
- UnparseVisitor.LEFT_ASSOCIATIVE_OPERATORS, "+", "-",
- UnparseVisitor.LEFT_ASSOCIATIVE_OPERATORS, "*", "/", "%",
- UnparseVisitor.RIGHT_ASSOCIATIVE_OPERATORS, "cast",
- UnparseVisitor.UNARY_OPERATORS, "++x", "--x", "+x", "-x", "~x", "!x",
- UnparseVisitor.UNARY_OPERATORS, "x++", "x--",
- UnparseVisitor.LEFT_ASSOCIATIVE_OPERATORS, "new",
- UnparseVisitor.LEFT_ASSOCIATIVE_OPERATORS, ".", "[ ]",
- };
- int precedence = 0;
- LOOP1: for (int i = 0;;) {
- Set s = (Set) ops[i++];
- Integer pi = new Integer(++precedence);
- for (;;) {
- if (i == ops.length) break LOOP1;
- if (!(ops[i] instanceof String)) break;
- String op = (String) ops[i++];
- s.add(op);
- UnparseVisitor.OPERATOR_PRECEDENCE.put(op, pi);
- }
- }
- }
-
- private void unparseNamedClassDeclaration(Java.NamedClassDeclaration ncd) {
- this.unparseDocComment(ncd);
- this.unparseModifiers(ncd.modifiers);
- this.pw.print("class " + ncd.name);
- if (ncd.optionalExtendedType != null) {
- this.pw.print(" extends ");
- this.unparseType(ncd.optionalExtendedType);
- }
- if (ncd.implementedTypes.length > 0) this.pw.print(" implements " + Java.join(ncd.implementedTypes, ", "));
- this.pw.println(" {");
- this.unparseClassDeclarationBody(ncd);
- this.pw.print('}');
- }
- private void unparseArrayInitializerOrRvalue(Java.ArrayInitializerOrRvalue aiorv) {
- if (aiorv instanceof Java.Rvalue) {
- this.unparse((Java.Rvalue) aiorv);
- } else
- if (aiorv instanceof Java.ArrayInitializer) {
- Java.ArrayInitializer ai = (Java.ArrayInitializer) aiorv;
- if (ai.values.length == 0) {
- this.pw.print("{}");
- } else
- {
- this.pw.print("{ ");
- this.unparseArrayInitializerOrRvalue(ai.values[0]);
- for (int i = 1; i < ai.values.length; ++i) {
- this.pw.print(", ");
- this.unparseArrayInitializerOrRvalue(ai.values[i]);
- }
- this.pw.print(" }");
- }
- } else
- {
- throw new RuntimeException("Unexpected array initializer or rvalue class " + aiorv.getClass().getName());
- }
- }
-
- public void visitAnonymousClassDeclaration(Java.AnonymousClassDeclaration acd) {
- this.unparseType(acd.baseType);
- this.pw.println(" {");
- this.unparseClassDeclarationBody(acd);
- this.pw.print('}');
- }
- public void visitNewAnonymousClassInstance(Java.NewAnonymousClassInstance naci) {
- if (naci.optionalQualification != null) {
- this.unparseLhs(naci.optionalQualification, ".");
- this.pw.print('.');
- }
- this.pw.print("new " + naci.anonymousClassDeclaration.baseType.toString() + '(');
- for (int i = 0; i < naci.arguments.length; ++i) {
- if (i > 0) this.pw.print(", ");
- this.unparse(naci.arguments[i]);
- }
- this.pw.println(") {");
- this.unparseClassDeclarationBody(naci.anonymousClassDeclaration);
- this.pw.print('}');
- }
- // Multi-line!
- private void unparseClassDeclarationBody(Java.ClassDeclaration cd) {
- for (Iterator it = cd.constructors.iterator(); it.hasNext();) {
- ((Java.ConstructorDeclarator) it.next()).accept(this);
- this.pw.println();
- }
- this.unparseAbstractTypeDeclarationBody(cd);
- for (Iterator it = cd.variableDeclaratorsAndInitializers.iterator(); it.hasNext();) {
- ((Java.TypeBodyDeclaration) it.next()).accept(this);
- this.pw.println();
- }
- }
- private void unparseInterfaceDeclaration(Java.InterfaceDeclaration id) {
- this.unparseDocComment(id);
- this.unparseModifiers(id.modifiers);
- this.pw.print("interface " + id.name);
- if (id.extendedTypes.length > 0) this.pw.print(" extends " + Java.join(id.extendedTypes, ", "));
- this.pw.println(" {");
- this.unparseAbstractTypeDeclarationBody(id);
- for (Iterator it = id.constantDeclarations.iterator(); it.hasNext();) {
- ((Java.TypeBodyDeclaration) it.next()).accept(this);
- this.pw.println();
- }
- this.pw.print('}');
- }
- // Multi-line!
- private void unparseAbstractTypeDeclarationBody(Java.AbstractTypeDeclaration atd) {
- for (Iterator it = atd.declaredMethods.iterator(); it.hasNext();) {
- ((Java.MethodDeclarator) it.next()).accept(this);
- this.pw.println();
- }
- for (Iterator it = atd.declaredClassesAndInterfaces.iterator(); it.hasNext();) {
- ((Java.TypeBodyDeclaration) it.next()).accept(this);
- this.pw.println();
- }
- }
- private void unparseFunctionDeclaratorRest(Java.FunctionDeclarator fd) {
- this.pw.print('(');
- for (int i = 0; i < fd.formalParameters.length; ++i) {
- if (i > 0) this.pw.print(", ");
- this.unparseFormalParameter(fd.formalParameters[i]);
- }
- this.pw.print(')');
- if (fd.thrownExceptions.length > 0) this.pw.print(" throws " + Java.join(fd.thrownExceptions, ", "));
- }
- private void unparseDocComment(Java.DocCommentable dc) {
- String optionalDocComment = dc.getDocComment();
- if (optionalDocComment != null) {
- this.pw.println();
- this.pw.print("/**");
- this.aiw.setPrefix(" *");
- try {
- this.pw.print(optionalDocComment);
- } finally {
- this.aiw.setPrefix(null);
- }
- this.pw.println("*/");
- }
- }
- private void unparseModifiers(short modifiers) {
- if (modifiers != 0) {
- this.pw.print(Mod.shortToString(modifiers) + ' ');
- }
- }
- private void unparseFunctionInvocationArguments(Java.Rvalue[] arguments) {
- this.pw.print('(');
- for (int i = 0; i < arguments.length; ++i) {
- if (i > 0) this.pw.print(", ");
- this.unparse(arguments[i]);
- }
- this.pw.print(')');
- }
-
-}
diff --git a/src/org/codehaus/janino/Visitor.java b/src/org/codehaus/janino/Visitor.java
deleted file mode 100644
index 019e7bb..0000000
--- a/src/org/codehaus/janino/Visitor.java
+++ /dev/null
@@ -1,138 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino;
-
-/**
- * Basis for the "visitor" pattern as described in "Gamma, Helm, Johnson,
- * Vlissides: Design Patterns".
- */
-public class Visitor {
- public interface ComprehensiveVisitor
- extends ImportVisitor, TypeDeclarationVisitor, TypeBodyDeclarationVisitor, BlockStatementVisitor, AtomVisitor {
- }
-
- public interface ImportVisitor {
- void visitSingleTypeImportDeclaration(Java.CompilationUnit.SingleTypeImportDeclaration stid);
- void visitTypeImportOnDemandDeclaration(Java.CompilationUnit.TypeImportOnDemandDeclaration tiodd);
- void visitSingleStaticImportDeclaration(Java.CompilationUnit.SingleStaticImportDeclaration ssid);
- void visitStaticImportOnDemandDeclaration(Java.CompilationUnit.StaticImportOnDemandDeclaration siodd);
- }
-
- public interface TypeDeclarationVisitor {
- void visitAnonymousClassDeclaration(Java.AnonymousClassDeclaration acd);
- void visitLocalClassDeclaration(Java.LocalClassDeclaration lcd);
- void visitPackageMemberClassDeclaration(Java.PackageMemberClassDeclaration pmcd);
- void visitMemberInterfaceDeclaration(Java.MemberInterfaceDeclaration mid);
- void visitPackageMemberInterfaceDeclaration(Java.PackageMemberInterfaceDeclaration pmid);
- void visitMemberClassDeclaration(Java.MemberClassDeclaration mcd);
- }
-
- public interface TypeBodyDeclarationVisitor {
- void visitMemberInterfaceDeclaration(Java.MemberInterfaceDeclaration mid);
- void visitMemberClassDeclaration(Java.MemberClassDeclaration mcd);
- void visitConstructorDeclarator(Java.ConstructorDeclarator cd);
- void visitInitializer(Java.Initializer i);
- void visitMethodDeclarator(Java.MethodDeclarator md);
- void visitFieldDeclaration(Java.FieldDeclaration fd);
- }
-
- public interface BlockStatementVisitor {
- void visitInitializer(Java.Initializer i);
- void visitFieldDeclaration(Java.FieldDeclaration fd);
- void visitLabeledStatement(Java.LabeledStatement ls);
- void visitBlock(Java.Block b);
- void visitExpressionStatement(Java.ExpressionStatement es);
- void visitIfStatement(Java.IfStatement is);
- void visitForStatement(Java.ForStatement fs);
- void visitWhileStatement(Java.WhileStatement ws);
- void visitTryStatement(Java.TryStatement ts);
- void visitSwitchStatement(Java.SwitchStatement ss);
- void visitSynchronizedStatement(Java.SynchronizedStatement ss);
- void visitDoStatement(Java.DoStatement ds);
- void visitLocalVariableDeclarationStatement(Java.LocalVariableDeclarationStatement lvds);
- void visitReturnStatement(Java.ReturnStatement rs);
- void visitThrowStatement(Java.ThrowStatement ts);
- void visitBreakStatement(Java.BreakStatement bs);
- void visitContinueStatement(Java.ContinueStatement cs);
- void visitEmptyStatement(Java.EmptyStatement es);
- void visitLocalClassDeclarationStatement(Java.LocalClassDeclarationStatement lcds);
- void visitAlternateConstructorInvocation(Java.AlternateConstructorInvocation aci);
- void visitSuperConstructorInvocation(Java.SuperConstructorInvocation sci);
- }
-
- public interface AtomVisitor extends RvalueVisitor, TypeVisitor {
- void visitPackage(Java.Package p);
- }
-
- public interface TypeVisitor {
- void visitArrayType(Java.ArrayType at);
- void visitBasicType(Java.BasicType bt);
- void visitReferenceType(Java.ReferenceType rt);
- void visitRvalueMemberType(Java.RvalueMemberType rmt);
- void visitSimpleType(Java.SimpleType st);
- }
-
- public interface RvalueVisitor extends LvalueVisitor {
- void visitArrayLength(Java.ArrayLength al);
- void visitAssignment(Java.Assignment a);
- void visitUnaryOperation(Java.UnaryOperation uo);
- void visitBinaryOperation(Java.BinaryOperation bo);
- void visitCast(Java.Cast c);
- void visitClassLiteral(Java.ClassLiteral cl);
- void visitConditionalExpression(Java.ConditionalExpression ce);
- void visitCrement(Java.Crement c);
- void visitInstanceof(Java.Instanceof io);
- void visitMethodInvocation(Java.MethodInvocation mi);
- void visitSuperclassMethodInvocation(Java.SuperclassMethodInvocation smi);
- void visitLiteral(Java.Literal l);
- void visitNewAnonymousClassInstance(Java.NewAnonymousClassInstance naci);
- void visitNewArray(Java.NewArray na);
- void visitNewInitializedArray(Java.NewInitializedArray nia);
- void visitNewClassInstance(Java.NewClassInstance nci);
- void visitParameterAccess(Java.ParameterAccess pa);
- void visitQualifiedThisReference(Java.QualifiedThisReference qtr);
- void visitThisReference(Java.ThisReference tr);
- }
-
- public interface LvalueVisitor {
- void visitAmbiguousName(Java.AmbiguousName an);
- void visitArrayAccessExpression(Java.ArrayAccessExpression aae);
- void visitFieldAccess(Java.FieldAccess fa);
- void visitFieldAccessExpression(Java.FieldAccessExpression fae);
- void visitSuperclassFieldAccessExpression(Java.SuperclassFieldAccessExpression scfae);
- void visitLocalVariableAccess(Java.LocalVariableAccess lva);
- void visitParenthesizedExpression(Java.ParenthesizedExpression pe);
- }
-}
diff --git a/src/org/codehaus/janino/WarningHandler.java b/src/org/codehaus/janino/WarningHandler.java
deleted file mode 100644
index 8446374..0000000
--- a/src/org/codehaus/janino/WarningHandler.java
+++ /dev/null
@@ -1,42 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino;
-
-/**
- * Interface type for {@link UnitCompiler#setWarningHandler(WarningHandler)}.
- */
-public interface WarningHandler {
- void handleWarning(String handle, String message, Location optionalLocation);
-}
diff --git a/src/org/codehaus/janino/package.html b/src/org/codehaus/janino/package.html
deleted file mode 100644
index 868d100..0000000
--- a/src/org/codehaus/janino/package.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<html><body>
- The classes in this package pose the core of the Janino Java<sup>TM</sup>
- compiler.
- <p>
- The package comprises a scanner ({@link org.codehaus.janino.Scanner}, a parser
- ({@link org.codehaus.janino.Parser}) and a class file library. The parser builds a
- syntax tree from the "Java.*" classes that represents the parsed code. The
- {@link org.codehaus.janino.UnitCompiler#compileUnit} method compiles this syntax
- tree into a {@link org.codehaus.janino.util.ClassFile} object, which can write
- Java<sup>TM</sup> bytecode to an "OutputStream".
-</body></html>
diff --git a/src/org/codehaus/janino/samples/ClassBodyDemo.java b/src/org/codehaus/janino/samples/ClassBodyDemo.java
deleted file mode 100644
index b0438cf..0000000
--- a/src/org/codehaus/janino/samples/ClassBodyDemo.java
+++ /dev/null
@@ -1,96 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino.samples;
-
-import java.io.*;
-import java.lang.reflect.*;
-
-import org.codehaus.janino.*;
-
-public class ClassBodyDemo {
- public static void main(String[] args) throws Exception {
- if (args.length > 0 && args[0].equals("-help")) {
- System.out.println("Usage: ClassBodyDemo <class-body> { <argument> }");
- System.out.println(" ClassBodyDemo -help");
- System.out.println("If <class-body> starts with a '@', then the class body is read");
- System.out.println("from the named file.");
- System.out.println("The <class-body> must declare a method \"public static main(String[])\"");
- System.out.println("to which the <argument>s are passed. If the return type of that method is");
- System.out.println("not VOID, then the returned value is printed to STDOUT.");
- System.exit(0);
- }
-
- int i = 0;
-
- // Get class body.
- if (i >= args.length) {
- System.err.println("Class body missing; try \"-help\".");
- }
- String classBody = args[i++];
- if (classBody.startsWith("@")) classBody = ClassBodyDemo.readFileToString(classBody.substring(1));
-
- // Get arguments.
- String[] arguments = new String[args.length - i];
- System.arraycopy(args, i, arguments, 0, arguments.length);
-
- // Compile the class body.
- Class c = new ClassBodyEvaluator(classBody).getClazz();
-
- // Invoke the "public static main(String[])" method.
- Method m = c.getMethod("main", new Class[] { String[].class });
- Integer returnValue = (Integer) m.invoke(null, new Object[] { arguments });
-
- // If non-VOID, print the return value.
- if (m.getReturnType() != Void.TYPE) System.out.println(DemoBase.toString(returnValue));
- }
-
- private ClassBodyDemo() {}
-
- private static String readFileToString(String fileName) throws IOException {
- Reader r = new FileReader(fileName);
- try {
- StringBuffer sb = new StringBuffer();
- char[] ca = new char[1024];
- for (;;) {
- int cnt = r.read(ca, 0, ca.length);
- if (cnt == -1) break;
- sb.append(ca, 0, cnt);
- }
- return sb.toString();
- } finally {
- r.close();
- }
- }
-}
diff --git a/src/org/codehaus/janino/samples/DeclarationCounter.java b/src/org/codehaus/janino/samples/DeclarationCounter.java
deleted file mode 100644
index fb647d0..0000000
--- a/src/org/codehaus/janino/samples/DeclarationCounter.java
+++ /dev/null
@@ -1,99 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino.samples;
-
-import java.io.*;
-
-import org.codehaus.janino.*;
-import org.codehaus.janino.util.*;
-
-/**
- * An example application for the {@link org.codehaus.janino.util.Traverser}:
- * Reads, scans and parses the files named on the command line and counts
- * several kinds of declarations.
- */
-public class DeclarationCounter extends Traverser {
- public static void main(String[] args) throws Scanner.ScanException, IOException, Parser.ParseException {
- DeclarationCounter dc = new DeclarationCounter();
- for (int i = 0; i < args.length; ++i) {
- String fileName = args[i];
-
- // Parse each compilation unit.
- FileReader r = new FileReader(fileName);
- Java.CompilationUnit cu;
- try {
- cu = new Parser(new Scanner(fileName, r)).parseCompilationUnit();
- } finally {
- r.close();
- }
-
- // Traverse it and count declarations.
- dc.traverseCompilationUnit(cu);
- }
-
- System.out.println("Class declarations: " + dc.classDeclarationCount);
- System.out.println("Interface declarations: " + dc.interfaceDeclarationCount);
- System.out.println("Fields: " + dc.fieldCount);
- System.out.println("Local variables: " + dc.localVariableCount);
- }
-
- // Count class declarations.
- public void traverseClassDeclaration(Java.ClassDeclaration cd) {
- ++this.classDeclarationCount;
- super.traverseClassDeclaration(cd);
- }
- private int classDeclarationCount = 0;
-
- // Count interface declarations.
- public void traverseInterfaceDeclaration(Java.InterfaceDeclaration id) {
- ++this.interfaceDeclarationCount;
- super.traverseInterfaceDeclaration(id);
- }
- private int interfaceDeclarationCount = 0;
-
- // Count fields.
- public void traverseFieldDeclaration(Java.FieldDeclaration fd) {
- this.fieldCount += fd.variableDeclarators.length;
- super.traverseFieldDeclaration(fd);
- }
- private int fieldCount = 0;
-
- // Count local variables.
- public void traverseLocalVariableDeclarationStatement(Java.LocalVariableDeclarationStatement lvds) {
- this.localVariableCount += lvds.variableDeclarators.length;
- super.traverseLocalVariableDeclarationStatement(lvds);
- }
- private int localVariableCount = 0;
-}
diff --git a/src/org/codehaus/janino/samples/DemoBase.java b/src/org/codehaus/janino/samples/DemoBase.java
deleted file mode 100644
index 68958b5..0000000
--- a/src/org/codehaus/janino/samples/DemoBase.java
+++ /dev/null
@@ -1,154 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino.samples;
-
-import java.util.*;
-import java.lang.reflect.*;
-
-/**
- * Common base class for the "...Demo" classes that demostrate Janino.
- */
-
-public class DemoBase {
- protected DemoBase() {}
-
- public static Object createObject(
- Class type,
- String value
- ) throws
- NoSuchMethodException,
- InstantiationException,
- InvocationTargetException,
- IllegalAccessException {
-
- // Wrap primitive parameters.
- if (type.isPrimitive()) {
- type = (
- type == boolean.class ? Boolean.class :
- type == char.class ? Character.class :
- type == byte.class ? Byte.class :
- type == short.class ? Short.class :
- type == int.class ? Integer.class :
- type == long.class ? Long.class :
- type == float.class ? Float.class :
- type == double.class ? Double.class : void.class
- );
- }
-
- // Construct object, assuming it has a default constructor or a
- // constructor with one single "String" argument.
- if (value.equals("")) {
- return type.getConstructor(new Class[0]).newInstance(new Object[0]);
- } else {
- return type.getConstructor(new Class[] { String.class }).newInstance(new Object[] { value });
- }
- }
-
- public static String[] explode(String s) {
- StringTokenizer st = new StringTokenizer(s, ",");
- List l = new ArrayList();
- while (st.hasMoreTokens()) l.add(st.nextToken());
- return (String[]) l.toArray(new String[l.size()]);
- }
-
- public static Class stringToType(String s) {
- int brackets = 0;
- while (s.endsWith("[]")) {
- ++brackets;
- s = s.substring(0, s.length() - 2);
- }
-
- if (brackets == 0) {
- // "Class.forName("C")" does not work.
- if (s.equals("void" )) return void.class;
- if (s.equals("boolean")) return boolean.class;
- if (s.equals("char" )) return char.class;
- if (s.equals("byte" )) return byte.class;
- if (s.equals("short" )) return short.class;
- if (s.equals("int" )) return int.class;
- if (s.equals("long" )) return long.class;
- if (s.equals("float" )) return float.class;
- if (s.equals("double" )) return double.class;
- }
-
- // Automagically convert primitive type names.
- if (s.equals("void" )) { s = "V"; } else
- if (s.equals("boolean")) { s = "Z"; } else
- if (s.equals("char" )) { s = "C"; } else
- if (s.equals("byte" )) { s = "B"; } else
- if (s.equals("short" )) { s = "S"; } else
- if (s.equals("int" )) { s = "I"; } else
- if (s.equals("long" )) { s = "J"; } else
- if (s.equals("float" )) { s = "F"; } else
- if (s.equals("double" )) { s = "D"; }
-
- while (--brackets >= 0) s = '[' + s;
- try {
- return Class.forName(s);
- } catch (ClassNotFoundException ex) {
- ex.printStackTrace();
- System.exit(1);
- throw new RuntimeException(); // Never reached.
- }
- }
-
- public static Class[] stringToTypes(String s) {
- StringTokenizer st = new StringTokenizer(s, ",");
- List l = new ArrayList();
- while (st.hasMoreTokens()) l.add(DemoBase.stringToType(st.nextToken()));
- Class[] res = new Class[l.size()];
- l.toArray(res);
- return res;
- }
-
- public static String toString(Object o) {
- if (o == null) return "(null)";
-
- // Pretty-print array.
- Class clazz = o.getClass();
- if (clazz.isArray()) {
- StringBuffer sb = new StringBuffer(clazz.getComponentType().toString()).append("[] { ");
- for (int i = 0; i < Array.getLength(o); ++i) {
- if (i > 0) sb.append(", ");
- sb.append(DemoBase.toString(Array.get(o, i)));
- }
- sb.append(" }");
- return sb.toString();
- }
-
- // Apply default "toString()" method.
- return o.toString();
- }
-}
diff --git a/src/org/codehaus/janino/samples/ExpressionDemo.java b/src/org/codehaus/janino/samples/ExpressionDemo.java
deleted file mode 100644
index decdb86..0000000
--- a/src/org/codehaus/janino/samples/ExpressionDemo.java
+++ /dev/null
@@ -1,129 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino.samples;
-
-import org.codehaus.janino.*;
-
-/**
- * A test program that allows you to play around with the
- * {@link org.codehaus.janino.ExpressionEvaluator ExpressionEvaluator} class.
- */
-
-public class ExpressionDemo extends DemoBase {
- public static void main(String[] args) throws Exception {
- Class optionalExpressionType = null;
- String[] parameterNames = { };
- Class[] parameterTypes = { };
- Class[] thrownExceptions = new Class[0];
- String[] optionalDefaultImports = null;
-
- int i;
- for (i = 0; i < args.length; ++i) {
- String arg = args[i];
- if (!arg.startsWith("-")) break;
- if (arg.equals("-et")) {
- optionalExpressionType = DemoBase.stringToType(args[++i]);
- } else
- if (arg.equals("-pn")) {
- parameterNames = DemoBase.explode(args[++i]);
- } else
- if (arg.equals("-pt")) {
- parameterTypes = DemoBase.stringToTypes(args[++i]);
- } else
- if (arg.equals("-te")) {
- thrownExceptions = DemoBase.stringToTypes(args[++i]);
- } else
- if (arg.equals("-di")) {
- optionalDefaultImports = DemoBase.explode(args[++i]);
- } else
- if (arg.equals("-help")) {
- System.err.println("Usage: ExpressionDemo { <option> } <expression> { <parameter-value> }");
- System.err.println("Compiles and evaluates the given expression and prints its value.");
- System.err.println("Valid options are");
- System.err.println(" -et <expression-type> (default: any)");
- System.err.println(" -pn <comma-separated-parameter-names> (default: none)");
- System.err.println(" -pt <comma-separated-parameter-types> (default: none)");
- System.err.println(" -te <comma-separated-thrown-exception-types> (default: none)");
- System.err.println(" -di <comma-separated-default-imports> (default: none)");
- System.err.println(" -help");
- System.err.println("The number of parameter names, types and values must be identical.");
- System.exit(0);
- } else
- {
- System.err.println("Invalid command line option \"" + arg + "\"; try \"-help\".");
- System.exit(0);
- }
- }
-
- if (i >= args.length) {
- System.err.println("Expression missing; try \"-help\".");
- System.exit(1);
- }
- String expression = args[i++];
-
- if (parameterTypes.length != parameterNames.length) {
- System.err.println("Parameter type count (" + parameterTypes.length + ") and parameter name count (" + parameterNames.length + ") do not match; try \"-help\".");
- System.exit(1);
- }
-
- // One command line argument for each parameter.
- if (args.length - i != parameterNames.length) {
- System.err.println("Parameter value count (" + (args.length - i) + ") and parameter name count (" + parameterNames.length + ") do not match; try \"-help\".");
- System.exit(1);
- }
-
- // Convert command line arguments to parameter values.
- Object[] parameterValues = new Object[parameterNames.length];
- for (int j = 0; j < parameterNames.length; ++j) {
- parameterValues[j] = DemoBase.createObject(parameterTypes[j], args[i + j]);
- }
-
- // Create "ExpressionEvaluator" object.
- ExpressionEvaluator ee = new ExpressionEvaluator();
- ee.setExpressionType(optionalExpressionType);
- ee.setDefaultImports(optionalDefaultImports);
- ee.setParameters(parameterNames, parameterTypes);
- ee.setThrownExceptions(thrownExceptions);
- ee.cook(expression);
-
- // Evaluate expression with actual parameter values.
- Object res = ee.evaluate(parameterValues);
-
- // Print expression result.
- System.out.println("Result = " + DemoBase.toString(res));
- }
-
- private ExpressionDemo() {}
-}
diff --git a/src/org/codehaus/janino/samples/ScriptDemo.java b/src/org/codehaus/janino/samples/ScriptDemo.java
deleted file mode 100644
index 8f7d298..0000000
--- a/src/org/codehaus/janino/samples/ScriptDemo.java
+++ /dev/null
@@ -1,126 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino.samples;
-
-import org.codehaus.janino.*;
-
-/**
- * A test program that allows you to play around with the
- * {@link org.codehaus.janino.ScriptEvaluator ScriptEvaluator} class.
- */
-
-public class ScriptDemo extends DemoBase {
- public static void main(String[] args) throws Exception {
- Class returnType = void.class;
- String[] parameterNames = {};
- Class[] parameterTypes = {};
-
- int i;
- for (i = 0; i < args.length; ++i) {
- String arg = args[i];
- if (!arg.startsWith("-")) break;
- if (arg.equals("-rt")) {
- returnType = DemoBase.stringToType(args[++i]);
- } else
- if (arg.equals("-pn")) {
- parameterNames = DemoBase.explode(args[++i]);
- } else
- if (arg.equals("-pt")) {
- parameterTypes = DemoBase.stringToTypes(args[++i]);
- } else
- if (arg.equals("-help")) {
- ScriptDemo.usage();
- System.exit(0);
- } else
- {
- System.err.println("Invalid command line option \"" + arg + "\".");
- ScriptDemo.usage();
- System.exit(0);
- }
- }
-
- if (i == args.length) {
- System.err.println("Script missing on command line; try \"-help\".");
- System.exit(1);
- }
- String script = args[i++];
-
- if (parameterTypes.length != parameterNames.length) {
- System.err.println("Parameter type count and parameter name count do not match.");
- ScriptDemo.usage();
- System.exit(1);
- }
-
- // One command line argument for each parameter.
- if (args.length - i != parameterNames.length) {
- System.err.println("Argument and parameter count do not match.");
- ScriptDemo.usage();
- System.exit(1);
- }
-
- // Convert command line arguments to parameter values.
- Object[] parameterValues = new Object[parameterNames.length];
- for (int j = 0; j < parameterNames.length; ++j) {
- parameterValues[j] = DemoBase.createObject(parameterTypes[j], args[i + j]);
- }
-
- // Create "ScriptEvaluator" object.
- ScriptEvaluator se = new ScriptEvaluator(
- script,
- returnType,
- parameterNames,
- parameterTypes
- );
-
- // Evaluate script with actual parameter values.
- Object res = se.evaluate(parameterValues);
-
- // Print script return value.
- System.out.println("Result = " + DemoBase.toString(res));
- }
-
- private ScriptDemo() {}
-
- private static void usage() {
- System.err.println("Usage: ScriptDemo { <option> } <script> { <parameter-value> }");
- System.err.println("Valid options are");
- System.err.println(" -rt <return-type>");
- System.err.println(" -pn <comma-separated-parameter-names>");
- System.err.println(" -pt <comma-separated-parameter-types>");
- System.err.println(" -help");
- System.err.println("The number of parameter names, types and values must be identical.");
- System.err.println("The default is no parameters.");
- }
-}
diff --git a/src/org/codehaus/janino/samples/ShippingCost.java b/src/org/codehaus/janino/samples/ShippingCost.java
deleted file mode 100644
index f9fe8d5..0000000
--- a/src/org/codehaus/janino/samples/ShippingCost.java
+++ /dev/null
@@ -1,72 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino.samples;
-
-import org.codehaus.janino.*;
-
-/**
- * Sample application which demonstrates how to use the
- * {@link org.codehaus.janino.ExpressionEvaluator ExpressionEvaluator} class.
- */
-
-public class ShippingCost {
- public static void main(String[] args) throws Exception {
- if (args.length != 1) {
- System.err.println("Usage: <total>");
- System.err.println("Computes the shipping costs from the double value \"total\".");
- System.err.println("If \"total\" is less than 100.0, then the result is 7.95, else the result is 0.");
- System.exit(1);
- }
-
- // Convert command line argument to parameter "total".
- Object[] parameterValues = new Object[] { new Double(args[0]) };
-
- // Create "ExpressionEvaluator" object.
- ExpressionEvaluator ee = new ExpressionEvaluator(
- "total >= 100.0 ? 0.0 : 7.95", // expression
- double.class, // optionalExpressionType
- new String[] { "total" }, // parameterNames,
- new Class[] { double.class }, // parameterTypes
- new Class[0], // thrownExceptions
- null // optionalClassLoader
- );
-
- // Evaluate expression with actual parameter values.
- Object res = ee.evaluate(parameterValues);
-
- // Print expression result.
- System.out.println("Result = " + (res == null ? "(null)" : res.toString()));
- }
-}
diff --git a/src/org/codehaus/janino/samples/package.html b/src/org/codehaus/janino/samples/package.html
deleted file mode 100644
index 90ce689..0000000
--- a/src/org/codehaus/janino/samples/package.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<html><body>
- Sample applications for the Janino Java<sup>TM</sup> compiler.
-</body></html>
diff --git a/src/org/codehaus/janino/tools/Disassembler.java b/src/org/codehaus/janino/tools/Disassembler.java
deleted file mode 100644
index 80d50dc..0000000
--- a/src/org/codehaus/janino/tools/Disassembler.java
+++ /dev/null
@@ -1,1425 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino.tools;
-
-import java.io.*;
-import java.util.*;
-
-/**
- * A Java bytecode disassembler, comparable to JAVAP, which is part of
- * Sun's JDK.
- * <p>
- * Notice that this tool does not depend on any other classes or libraries (other than the
- * standard JDK library).
- */
-
-public class Disassembler {
- private IndentPrintWriter ipw = new IndentPrintWriter(System.out);
- private boolean verbose = false;
- private File sourceDirectory = new File(".");
-
- /**
- * Usage:
- * <pre>
- * java new.janino.tools.Disassembler [ -o <i>output-file</i> ] [ -help ]
- * </pre>
- * @param args
- * @throws IOException
- */
- public static void main(String[] args) throws IOException {
- Disassembler d = new Disassembler();
- int i;
- for (i = 0; i < args.length; ++i) {
- String arg = args[i];
- if (arg.charAt(0) != '-') break;
- if (arg.equals("-o")) {
- d.setOut(new FileOutputStream(args[++i]));
- } else
- if (arg.equals("-verbose")) {
- d.setVerbose(true);
- } else
- if (arg.equals("-src")) {
- d.setSourceDirectory(new File(args[++i]));
- } else
- if (arg.equals("-help")) {
- System.out.println("Usage: java jexpr.Jdisasm [ -o <output-file> ] [ -verbose ] [ -src <source-dir> ] <class-file> ...");
- System.exit(0);
- } else
- {
- System.err.println("Unrecognized command line option \"" + arg + "\"; try \"-help\".");
- }
- }
- if (i == args.length) {
- System.err.println("Class file name missing, try \"-help\".");
- System.exit(1);
- }
- for (; i < args.length; ++i) {
- d.disasm(new File(args[i]));
- }
- }
-
- public Disassembler() {}
-
- public void setOut(OutputStream os) {
- this.ipw = new IndentPrintWriter(os);
- }
- public void setVerbose(boolean verbose) {
- this.verbose = verbose;
- }
- public void setSourceDirectory(File sourceDirectory) {
- this.sourceDirectory = sourceDirectory;
- }
-
-// void print(byte b) { this.ipw.print(b); }
-// void print(short s) { this.ipw.print(s); }
- void print(int i) { this.ipw.print(i); }
-// void print(long l) { this.ipw.print(l); }
-// void print(float f) { this.ipw.print(f); }
-// void print(double d) { this.ipw.print(d); }
- void print(String s) { this.ipw.print(s); }
- void println() { this.ipw.println(); }
- void println(String s) { this.ipw.println(s); }
- void indent(String s) {
- this.ipw.print(s);
- this.ipw.indent();
- }
- void indentln(String s) {
- this.ipw.println(s);
- this.ipw.indent();
- }
- void unindent(String s) {
- this.ipw.unindent();
- this.ipw.print(s);
- }
- void unindentln(String s) {
- this.ipw.unindent();
- this.ipw.println(s);
- }
-
- /**
- * Disassemble one Java<sup>TM</sup> class file to {@link System#out}.
- *
- * @param file
- * @throws IOException
- */
- public void disasm(File file) throws IOException {
- InputStream is = new FileInputStream(file);
- try {
- disasm(is);
- } finally {
- try { is.close(); } catch (IOException ex) {}
- }
- }
-
- public void disasm(InputStream is) throws IOException {
- this.disasmClassFile(new DataInputStream(is));
- this.println();
- this.ipw.flush();
- }
-
- private void disasmClassFile(DataInputStream dis) throws IOException {
- this.indentln("ClassFile {"); {
- this.println("magic = 0x" + Integer.toHexString(dis.readInt()));
- this.println("minor_version = " + dis.readShort());
- this.println("major_version = " + dis.readShort());
-
- this.constantPool = new ConstantPoolInfo[dis.readShort()];
- for (short i = 1; i < this.constantPool.length;) {
- ConstantPoolInfo cpi = readConstantPoolInfo(dis);
- this.constantPool[i++] = cpi;
- for (int j = cpi.getSizeInConstantPool(); j > 1; --j) {
- this.constantPool[i++] = null;
- }
- }
- this.indentln("constant_pool[] = {"); {
- for (short i = 1; i < this.constantPool.length;) {
- this.print(i + ": ");
- ConstantPoolInfo cpi = this.constantPool[i];
- cpi.print(); // Must be invoked only after "this.constantPool" is initialized.
- this.println();
- i += cpi.getSizeInConstantPool();
- }
- } this.unindentln("}");
-
- this.println("access_flags = " + decodeAccess(dis.readShort()));
-
- short thisClass = dis.readShort();
- this.indent("this_class = " + thisClass + " ("); {
- this.printConstantPoolEntry(thisClass);
- } this.unindentln(")");
-
- short superClass = dis.readShort();
- this.indent("super_class = " + superClass + " ("); {
- this.printConstantPoolEntry(superClass);
- } this.unindentln(")");
-
- this.indentln("interfaces[] = {"); {
- short interfacesCount = dis.readShort();
- for (short i = 0; i < interfacesCount; ++i) {
- this.printConstantPoolEntry(null, dis.readShort());
- this.println();
- }
- } this.unindentln("}");
-
- this.indentln("fields[] = {"); {
- short fieldsCount = dis.readShort();
- for (short i = 0; i < fieldsCount; ++i) {
- disasmFieldInfo(dis);
- this.println();
- }
- } this.unindentln("}");
-
- MethodInfo[] methodInfos;
- {
- short methodsCount = dis.readShort();
- methodInfos = new MethodInfo[methodsCount];
- for (int i = 0; i < methodsCount; ++i) methodInfos[i] = this.readMethodInfo(dis);
- }
-
- AttributeInfo[] attributes;
- {
- short attributesCount = dis.readShort();
- attributes = new AttributeInfo[attributesCount];
- for (short i = 0; i < attributesCount; ++i) attributes[i] = this.readAttributeInfo(dis);
- }
-
- Map sourceLines = new HashMap();
- READ_SOURCE_LINES: {
- for (int i = 0; i < attributes.length; ++i) {
- if (attributes[i] instanceof SourceFileAttribute) {
- ConstantPoolInfo cpi = Disassembler.this.getConstantPoolEntry(((SourceFileAttribute) attributes[i]).sourceFileIndex);
- if (cpi instanceof ConstantUtf8Info) {
- String sourceFile = ((ConstantUtf8Info) cpi).getValue();
- LineNumberReader lnr;
- try {
- lnr = new LineNumberReader(new FileReader(new File(this.sourceDirectory, sourceFile)));
- } catch (FileNotFoundException ex) {
- ;
- break READ_SOURCE_LINES;
- }
- try {
- for (;;) {
- String sl = lnr.readLine();
- if (sl == null) break;
- sourceLines.put(new Integer(lnr.getLineNumber()), sl);
- }
- } finally {
- lnr.close();
- }
- }
- }
- }
- }
-
- this.indentln("methods[] = {"); {
- for (short i = 0; i < methodInfos.length; ++i) {
- methodInfos[i].print(sourceLines);
- this.println();
- }
- } this.unindentln("}");
-
- this.indentln("attributes[] = {"); {
- for (short i = 0; i < attributes.length; ++i) {
- attributes[i].print();
- this.println();
- }
- } this.unindentln("}");
- } this.unindent("}");
- }
-
- private ConstantPoolInfo readConstantPoolInfo(final DataInputStream dis) throws IOException {
- byte tag = dis.readByte();
- switch (tag) {
- case 7:
- {
- final short nameIndex = dis.readShort();
- return new ConstantPoolInfo() {
- public void print() {
- Disassembler.this.print("CONSTANT_Class_info { ");
- Disassembler.this.printConstantPoolEntry("name_index", nameIndex);
- Disassembler.this.print(" }");
- }
- };
- }
- case 9:
- {
- final short classIndex = dis.readShort();
- final short nameAndTypeIndex = dis.readShort();
- return new ConstantPoolInfo() {
- public void print() {
- Disassembler.this.indentln("CONSTANT_Fieldref_info {"); {
- Disassembler.this.printConstantPoolEntry("class_index", classIndex);
- Disassembler.this.println();
- Disassembler.this.printConstantPoolEntry("name_and_type_index", nameAndTypeIndex);
- Disassembler.this.println();
- } Disassembler.this.unindent("}");
- }
- };
- }
- case 10:
- {
- final short classIndex = dis.readShort();
- final short nameAndTypeIndex = dis.readShort();
- return new ConstantPoolInfo() {
- public void print() {
- Disassembler.this.indentln("CONSTANT_Methodref_info {"); {
- Disassembler.this.printConstantPoolEntry("class_index", classIndex);
- Disassembler.this.println();
- Disassembler.this.printConstantPoolEntry("name_and_type_index", nameAndTypeIndex);
- Disassembler.this.println();
- } Disassembler.this.unindent("}");
- }
- };
- }
- case 11:
- {
- final short classIndex = dis.readShort();
- final short nameAndTypeIndex = dis.readShort();
- return new ConstantPoolInfo() {
- public void print() {
- Disassembler.this.indentln("CONSTANT_InterfaceMethodref_info {"); {
- Disassembler.this.printConstantPoolEntry("class_index", classIndex);
- Disassembler.this.println();
- Disassembler.this.printConstantPoolEntry("name_and_type_index", nameAndTypeIndex);
- Disassembler.this.println();
- } Disassembler.this.unindent("}");
- }
- };
- }
- case 8:
- {
- final short stringIndex = dis.readShort();
- return new ConstantPoolInfo() {
- public void print() {
- ConstantPoolInfo cpi = Disassembler.this.getConstantPoolEntry(stringIndex);
- String s;
- if (cpi == null) {
- s = "INVALID CONSTANT POOL INDEX";
- } else
- if (!(cpi instanceof ConstantUtf8Info)) {
- s = "STRING CONSTANT VALUE IS NOT UTF8";
- } else {
- s = ((ConstantUtf8Info) cpi).getValue();
- if (s.length() > 80) {
- s = Disassembler.stringToJavaLiteral(s.substring(0, 80)) + "... (" + s.length() + " chars)";
- } else {
- s = Disassembler.stringToJavaLiteral(s);
- }
- }
- if (Disassembler.this.verbose) {
- Disassembler.this.print("CONSTANT_String_info { string_index = " + stringIndex + " (" + s + ") }");
- } else {
- Disassembler.this.print(s);
- }
- }
- };
- }
- case 3:
- {
- final int bytes = dis.readInt();
- return new ConstantPoolInfo() {
- public void print() {
- Disassembler.this.print("CONSTANT_Integer_info { bytes = " + bytes + " }");
- }
- };
- }
- case 4:
- {
- final float bytes = dis.readFloat();
- return new ConstantPoolInfo() {
- public void print() {
- Disassembler.this.print("CONSTANT_Float_info { bytes = " + bytes + " }");
- }
- };
- }
- case 5:
- {
- final long bytes = dis.readLong();
- return new ConstantPoolInfo() {
- public void print() {
- Disassembler.this.print("CONSTANT_Long_info { high_bytes/low_bytes = " + bytes + " }");
- }
- public int getSizeInConstantPool() { return 2; }
- };
- }
- case 6:
- {
- final double bytes = dis.readDouble();
- return new ConstantPoolInfo() {
- public void print() {
- Disassembler.this.print("CONSTANT_Double_info { high_bytes/low_bytes = " + bytes + " }");
- }
- public int getSizeInConstantPool() { return 2; }
- };
- }
- case 12:
- {
- final short nameIndex = dis.readShort();
- final short descriptorIndex = dis.readShort();
- return new ConstantPoolInfo() {
- public void print() {
- Disassembler.this.indentln("CONSTANT_NameAndType_info {"); {
- Disassembler.this.printConstantPoolEntry("name_index", nameIndex);
- Disassembler.this.println();
- Disassembler.this.printConstantPoolEntry("descriptor_index", descriptorIndex);
- Disassembler.this.println();
- } Disassembler.this.unindent("}");
- }
- };
- }
- case 1:
- return new ConstantUtf8Info(dis.readUTF());
- default:
- throw new RuntimeException("Invalid cp_info tag \"" + (int) tag + "\"");
- }
- }
-
- private static String stringToJavaLiteral(String s) {
- for (int i = 0; i < s.length();) {
- char c = s.charAt(i);
- int idx = "\r\n\"\t\b".indexOf(c);
- if (idx == -1) {
- ++i;
- } else {
- s = s.substring(0, i) + '\\' + "rn\"tb".charAt(idx) + s.substring(i + 1);
- i += 2;
- }
- if (i >= 80) break;
- }
- return '"' + s + '"';
- }
-
- private void disasmFieldInfo(DataInputStream dis) throws IOException {
- this.indentln("field_info {"); {
- this.println("access_flags = " + decodeAccess(dis.readShort()));
-
- this.printConstantPoolEntry("name_index", dis.readShort());
- this.println();
-
- this.printConstantPoolEntry("descriptor_index", dis.readShort());
- this.println();
-
- this.indentln("attributes[] = {"); {
- short attributesCount = dis.readShort();
- for (short i = 0; i < attributesCount; ++i) {
- disasmAttributeInfo(dis);
- this.println();
- }
- } this.unindentln("}");
- } this.unindent("}");
- }
-
- private MethodInfo readMethodInfo(DataInputStream dis) throws IOException {
- final short accessFlags = dis.readShort();
- final short nameIndex = dis.readShort();
- final short descriptorIndex = dis.readShort();
- final AttributeInfo[] attributeInfos;
- {
- short attributesCount = dis.readShort();
- attributeInfos = new AttributeInfo[attributesCount];
- for (short i = 0; i < attributesCount; ++i) attributeInfos[i] = this.readAttributeInfo(dis);
- }
- return new MethodInfo() {
- public void print(Map sourceLines) {
- Disassembler.this.indentln("method_info {"); {
- Disassembler.this.println("access_flags = " + decodeAccess(accessFlags));
-
- Disassembler.this.printConstantPoolEntry("name_index", nameIndex);
- Disassembler.this.println();
-
- Disassembler.this.printConstantPoolEntry("descriptor_index", descriptorIndex);
- Disassembler.this.println();
-
- Disassembler.this.indentln("attributes[] = {"); {
- for (short i = 0; i < attributeInfos.length; ++i) {
- AttributeInfo ai = attributeInfos[i];
- if (ai instanceof SourceRelatedAttributeInfo) {
- ((SourceRelatedAttributeInfo) ai).print(sourceLines);
- } else {
- ai.print();
- }
- Disassembler.this.println();
- }
- } Disassembler.this.unindentln("}");
- } Disassembler.this.unindent("}");
- }
- };
- }
- private interface MethodInfo {
- public void print(
- Map sourceLines // Integer lineNumber => String line
- );
- }
-
- private void disasmAttributeInfo(DataInputStream dis) throws IOException {
- this.readAttributeInfo(dis).print();
- }
-
- private AttributeInfo readAttributeInfo(DataInputStream dis) throws IOException {
-
- // Determine attribute name.
- short attributeNameIndex = dis.readShort();
- String attributeName;
- {
- ConstantPoolInfo cpi = Disassembler.this.getConstantPoolEntry(attributeNameIndex);
- if (cpi == null) {
- attributeName = "INVALID CONSTANT POOL INDEX";
- } else
- if (!(cpi instanceof ConstantUtf8Info)) {
- attributeName = "ATTRIBUTE NAME IS NOT UTF8";
- } else {
- attributeName = ((ConstantUtf8Info) cpi).getValue();
- }
- }
-
- // Read attribute body into byte array and create a DataInputStream.
- int attributeLength = dis.readInt();
- final byte[] ba = new byte[attributeLength];
- if (dis.read(ba) != ba.length) throw new EOFException();
- ByteArrayInputStream bais = new ByteArrayInputStream(ba);
- DataInputStream dis2 = new DataInputStream(bais);
-
- // Parse the attribute body.
- AttributeInfo res = this.readAttributeBody(attributeName, dis2);
-
- // Check for extraneous bytes.
- int av = bais.available();
- if (av > 0) throw new RuntimeException(av + " extraneous bytes in attribute \"" + attributeName + "\"");
-
- return res;
- }
- private AttributeInfo readAttributeBody(
- final String attributeName,
- final DataInputStream dis
- ) throws IOException {
- if (attributeName.equals("ConstantValue")) {
- final short constantValueIndex = dis.readShort();
- return new AttributeInfo() {
- public void print() {
- Disassembler.this.indent("ConstantValue " + constantValueIndex + " ("); {
- Disassembler.this.printConstantPoolEntry(constantValueIndex);
- } Disassembler.this.unindent(")");
- }
- };
- } else
- if (attributeName.equals("Code")) {
- final short maxStack = dis.readShort();
- final short maxLocals = dis.readShort();
- final byte[] code = readByteArray(dis, dis.readInt());
- final ExceptionTableEntry[] exceptionTable = readExceptionTable(dis);
- final AttributeInfo[] attributes = readAttributes(dis);
- return new SourceRelatedAttributeInfo() {
- public void print(Map sourceLines) {
- Disassembler.this.indentln("Code {"); {
- Disassembler.this.println("max_stack = " + maxStack);
- Disassembler.this.println("max_locals = " + maxLocals);
-
- Disassembler.this.indentln("code = { "); {
- LocalVariableTableAttribute localVariableTableAttribute = null;
- LineNumberTableAttribute lineNumberTableAttribute = null;
- for (int i = 0; i < attributes.length; ++i) {
- AttributeInfo a = attributes[i];
- if (a instanceof LocalVariableTableAttribute) {
- if (localVariableTableAttribute != null) throw new RuntimeException("Duplicate LocalVariableTable attribute");
- localVariableTableAttribute = (LocalVariableTableAttribute) a;
- }
- if (a instanceof LineNumberTableAttribute) {
- if (lineNumberTableAttribute != null) throw new RuntimeException("Duplicate LineNumberTable attribute");
- lineNumberTableAttribute = (LineNumberTableAttribute) a;
- }
- }
- try {
- disasmBytecode(
- new ByteArrayInputStream(code),
- localVariableTableAttribute,
- lineNumberTableAttribute,
- sourceLines
- );
- } catch (IOException ignored) {
- ;
- }
- } Disassembler.this.unindentln("}");
-
- Disassembler.this.indentln("exception_table = {"); {
- for (int i = 0; i < exceptionTable.length; ++i) {
- exceptionTable[i].print();
- Disassembler.this.println();
- }
- } Disassembler.this.unindentln("}");
-
- Disassembler.this.indentln("attributes[] = {"); {
- for (int i = 0; i < attributes.length; ++i) {
- attributes[i].print();
- Disassembler.this.println();
- }
- } Disassembler.this.unindentln("}");
- } Disassembler.this.unindent("}");
- }
- };
- } else
- if (attributeName.equals("Exceptions")) {
- final short[] exceptionIndexTable = readShortArray(dis, dis.readShort());
- return new AttributeInfo() {
- public void print() {
- Disassembler.this.indentln("Exceptions {"); {
- Disassembler.this.indentln("exception_index_table = {"); {
- for (short i = 0; i < exceptionIndexTable.length; ++i) {
- short exceptionIndex = exceptionIndexTable[i];
- Disassembler.this.print(exceptionIndex + " (");
- Disassembler.this.printConstantPoolEntry(exceptionIndex);
- Disassembler.this.println("),");
- }
- } Disassembler.this.unindentln("}");
- } Disassembler.this.unindent("}");
- }
- };
- } else
- if (attributeName.equals("InnerClasses")) {
- final short[] data = readShortArray(dis, 4 * dis.readShort());
- return new AttributeInfo() {
- public void print() {
- Disassembler.this.indentln("InnerClasses {"); {
- Disassembler.this.indentln("classes = {"); {
- for (int i = 0; i < data.length; i += 4) {
- Disassembler.this.indentln("{"); {
- Disassembler.this.printConstantPoolEntry("inner_class_info_index", data[i]);
- Disassembler.this.println();
-
- short outerClassInfoIndex = data[i + 1];
- if (outerClassInfoIndex == 0) {
- Disassembler.this.print("(not a member)");
- } else {
- Disassembler.this.printConstantPoolEntry("outer_class_info_index", outerClassInfoIndex);
- }
- Disassembler.this.println();
-
- short innerNameIndex = data[i + 2];
- if (innerNameIndex == 0) {
- Disassembler.this.print("(anonymous)");
- } else {
- Disassembler.this.printConstantPoolEntry("inner_name_index", innerNameIndex);
- }
- Disassembler.this.println();
-
- Disassembler.this.println("inner_class_access_flags = " + decodeAccess(data[i + 3]));
- } Disassembler.this.unindentln(i == data.length - 1 ? "}" : "},");
- }
- } Disassembler.this.unindentln("}");
- } Disassembler.this.unindent("}");
- }
- };
- } else
- if (attributeName.equals("Synthetic")) {
- return new AttributeInfo() {
- public void print() {
- Disassembler.this.print("Synthetic");
- }
- };
- } else
- if (attributeName.equals("SourceFile")) {
- return new SourceFileAttribute(dis.readShort());
- } else
- if (attributeName.equals("LineNumberTable")) {
- return new LineNumberTableAttribute(readShortArray(dis, 2 * dis.readShort()));
- } else
- if (attributeName.equals("LocalVariableTable")) {
- return new LocalVariableTableAttribute(readShortArray(dis, 5 * dis.readShort()));
- } else
- if (attributeName.equals("Deprecated")) {
- return new AttributeInfo() {
- public void print() {
- Disassembler.this.print("Deprecated");
- }
- };
- } else
- {
- final ByteArrayOutputStream baos = new ByteArrayOutputStream();
- for (;;) {
- int c = dis.read();
- if (c == -1) break;
- baos.write(c);
- }
- return new AttributeInfo() {
- public void print() {
- Disassembler.this.indentln(attributeName + " {"); {
- Disassembler.this.print("info = { ");
- for (int i = 0; i < this.info.length; ++i) {
- Disassembler.this.print("0x" + Integer.toHexString(0xff & this.info[i]) + ", ");
- }
- Disassembler.this.println("}");
- } Disassembler.this.unindent("}");
- }
- private byte[] info = baos.toByteArray();
- };
- }
- }
- private interface AttributeInfo {
- public void print();
- }
- private abstract static class SourceRelatedAttributeInfo implements AttributeInfo {
- public void print() {
- throw new UnsupportedOperationException("print");
- }
- public abstract void print(Map sourceLines);
- }
- private class SourceFileAttribute implements AttributeInfo {
- final short sourceFileIndex;
- SourceFileAttribute(short sourceFileIndex) {
- this.sourceFileIndex = sourceFileIndex;
- }
- public void print() {
- Disassembler.this.indentln("SourceFile {"); {
- Disassembler.this.printConstantPoolEntry("sourcefile_index", this.sourceFileIndex);
- Disassembler.this.println();
- } Disassembler.this.unindent("}");
- }
- }
- public class LineNumberTableAttribute implements AttributeInfo {
- private final short[] data;
- public LineNumberTableAttribute(short[] data) {
- this.data = data;
- }
- public void print() {
- Disassembler.this.indentln("LineNumberTable {"); {
- Disassembler.this.indentln("line_number_table = {"); {
- for (short i = 0; i < this.data.length; i += 2) {
- Disassembler.this.print("start_pc = " + this.data[i]);
- Disassembler.this.print(", ");
- Disassembler.this.println("line_number = " + this.data[i + 1]);
- }
- } Disassembler.this.unindentln("}");
- } Disassembler.this.unindent("}");
- }
- public short findLineNumber(short offset) {
- for (short i = 0; i < this.data.length; i += 2) {
- if (this.data[i] == offset) return this.data[i + 1];
- }
- return -1;
- }
- }
- private class LocalVariableTableAttribute implements AttributeInfo {
- public LocalVariableTableAttribute(short[] data) { this.data = data; }
- public void print() {
- Disassembler.this.indentln("LocalVariableTable {"); {
- Disassembler.this.indentln("local_variable_table = {"); {
- for (int i = 0; i < this.data.length; i += 5) {
- Disassembler.this.print("start_pc = " + this.data[i]);
- Disassembler.this.print(", ");
- Disassembler.this.print("length = " + this.data[i + 1]);
- Disassembler.this.print(", ");
- Disassembler.this.printConstantPoolEntry("name_index", this.data[i + 2]);
- Disassembler.this.print(", ");
- Disassembler.this.printConstantPoolEntry("descriptor_index", this.data[i + 3]);
- Disassembler.this.print(", ");
- Disassembler.this.println("index = " + this.data[i + 4]);
- }
- } Disassembler.this.unindentln("}");
- } Disassembler.this.unindent("}");
- }
- public String find(short index, int instructionOffset) {
- for (int i = 0; i < this.data.length; i += 5) {
- short startPC = this.data[i];
- short length = this.data[i + 1];
- if (
- instructionOffset >= startPC &&
- instructionOffset <= startPC + length &&
- index == this.data[i + 4]
- ) {
- String name = ((ConstantUtf8Info) Disassembler.this.getConstantPoolEntry(this.data[i + 2])).getValue();
- String descriptor = ((ConstantUtf8Info) Disassembler.this.getConstantPoolEntry(this.data[i + 3])).getValue();
- return Disassembler.decodeDescriptor(descriptor) + " " + name;
- }
- }
- return "anonymous";
- }
- private short[] data;
- }
- private static byte[] readByteArray(InputStream is, int size) throws IOException {
- byte[] res = new byte[size];
- if (is.read(res) != size) throw new EOFException("EOF in byte array");
- return res;
- }
- private ExceptionTableEntry[] readExceptionTable(DataInputStream dis) throws IOException {
- ExceptionTableEntry[] res = new ExceptionTableEntry[dis.readShort()];
- for (short i = 0; i < res.length; ++i) {
- res[i] = new ExceptionTableEntry(
- dis.readShort(),
- dis.readShort(),
- dis.readShort(),
- dis.readShort()
- );
- }
- return res;
- }
- private class ExceptionTableEntry {
- ExceptionTableEntry(short startPC, short endPC, short handlerPC, short catchType) {
- this.startPC = startPC;
- this.endPC = endPC;
- this.handlerPC = handlerPC;
- this.catchType = catchType;
- }
- public void print() {
- Disassembler.this.print("start_pc = " + this.startPC + ", end_pc = " + this.endPC + ", handler_pc = " + this.handlerPC + ", catch_type = " + this.catchType + " (");
- if (this.catchType == 0) {
- Disassembler.this.print("finally");
- } else {
- Disassembler.this.printConstantPoolEntry(this.catchType);
- }
- Disassembler.this.print(")");
- }
- private short startPC, endPC, handlerPC, catchType;
- }
-
- private AttributeInfo[] readAttributes(DataInputStream dis) throws IOException {
- AttributeInfo[] res = new AttributeInfo[dis.readShort()];
- for (int i = 0; i < res.length; ++i) {
- res[i] = Disassembler.this.readAttributeInfo(dis);
- }
- return res;
- }
-
- private static short[] readShortArray(DataInputStream dis, int size) throws IOException {
- short[] res = new short[size];
- for (int i = 0; i < res.length; ++i) res[i] = dis.readShort();
- return res;
- }
-
- private void disasmBytecode(
- InputStream is,
- LocalVariableTableAttribute localVariableTableAttribute,
- LineNumberTableAttribute lineNumberTableAttribute,
- Map sourceLines // Integer lineNumber => String sourceLine
- ) throws IOException {
- CountingInputStream cis = new CountingInputStream(is);
- DataInputStream dis = new DataInputStream(cis);
-
- for (;;) {
- short instructionOffset = (short) cis.getCount();
-
- int opcode = dis.read();
- if (opcode == -1) return; // EOF
-
- if (lineNumberTableAttribute != null) {
- short lineNumber = lineNumberTableAttribute.findLineNumber(instructionOffset);
- if (lineNumber != -1) {
- String sourceLine = (String) sourceLines.get(new Integer(lineNumber));
- if (sourceLine == null) sourceLine = "(Source line not available)";
- this.println(" Line " + lineNumber + ": " + sourceLine);
- }
- }
- this.print(instructionOffset + ": ");
-
- Instruction instruction = opcodeToInstruction[opcode];
- if (instruction == null) {
- this.println("??? (invalid opcode \"" + opcode + "\")");
- continue;
- }
- disasmInstruction(instruction, dis, instructionOffset, localVariableTableAttribute);
- this.println();
- }
- }
- private void disasmInstruction(
- Instruction instruction,
- DataInputStream dis,
- int instructionOffset,
- LocalVariableTableAttribute localVariableTableAttribute
- ) throws IOException {
- this.print(instruction.getMnemonic());
- Operand[] operands = instruction.getOperands();
- if (operands != null) {
- for (int i = 0; i < operands.length; ++i) {
- Operand operand = operands[i];
- this.print(" ");
- operand.disasm(dis, instructionOffset, localVariableTableAttribute, this);
- }
- }
- }
-
- private static final String[] instructions = new String[] {
- "50 aaload",
- "83 aastore",
- "1 aconst_null",
- "25 aload localvariablearrayindex1",
- "42 aload_0 localvariablearrayindex_0",
- "43 aload_1 localvariablearrayindex_1",
- "44 aload_2 localvariablearrayindex_2",
- "45 aload_3 localvariablearrayindex_3",
- "189 anewarray constantpoolindex2",
- "176 areturn",
- "190 arraylength",
- "58 astore localvariablearrayindex1",
- "75 astore_0 localvariablearrayindex_0",
- "76 astore_1 localvariablearrayindex_1",
- "77 astore_2 localvariablearrayindex_2",
- "78 astore_3 localvariablearrayindex_3",
- "191 athrow",
- "51 baload",
- "84 bastore",
- "16 bipush signedbyte",
- "52 caload",
- "85 castore",
- "192 checkcast constantpoolindex2",
- "144 d2f",
- "142 d2i",
- "143 d2l",
- "99 dadd",
- "49 daload",
- "82 dastore",
- "152 dcmpg",
- "151 dcmpl",
- "14 dconst_0",
- "15 dconst_1",
- "111 ddiv",
- "24 dload localvariablearrayindex1",
- "38 dload_0 localvariablearrayindex_0",
- "39 dload_1 localvariablearrayindex_1",
- "40 dload_2 localvariablearrayindex_2",
- "41 dload_3 localvariablearrayindex_3",
- "107 dmul",
- "119 dneg",
- "115 drem",
- "175 dreturn",
- "57 dstore localvariablearrayindex1",
- "71 dstore_0 localvariablearrayindex_0",
- "72 dstore_1 localvariablearrayindex_1",
- "73 dstore_2 localvariablearrayindex_2",
- "74 dstore_3 localvariablearrayindex_3",
- "103 dsub",
- "89 dup",
- "90 dup_x1",
- "91 dup_x2",
- "92 dup2",
- "93 dup2_x1",
- "94 dup2_x2",
- "141 f2d",
- "139 f2i",
- "140 f2l",
- "98 fadd",
- "48 faload",
- "81 fastore",
- "150 fcmpg",
- "149 fcmpl",
- "11 fconst_0",
- "12 fconst_1",
- "13 fconst_2",
- "110 fdiv",
- "23 fload localvariablearrayindex1",
- "34 fload_0 localvariablearrayindex_0",
- "35 fload_1 localvariablearrayindex_1",
- "36 fload_2 localvariablearrayindex_2",
- "37 fload_3 localvariablearrayindex_3",
- "106 fmul",
- "118 fneg",
- "114 frem",
- "174 freturn",
- "56 fstore localvariablearrayindex1",
- "67 fstore_0 localvariablearrayindex_0",
- "68 fstore_1 localvariablearrayindex_1",
- "69 fstore_2 localvariablearrayindex_2",
- "70 fstore_3 localvariablearrayindex_3",
- "102 fsub",
- "180 getfield constantpoolindex2",
- "178 getstatic constantpoolindex2",
- "167 goto branchoffset2",
- "200 goto_w branchoffset4",
- "145 i2b",
- "146 i2c",
- "135 i2d",
- "134 i2f",
- "133 i2l",
- "147 i2s",
- "96 iadd",
- "46 iaload",
- "126 iand",
- "79 iastore",
- "2 iconst_m1",
- "3 iconst_0",
- "4 iconst_1",
- "5 iconst_2",
- "6 iconst_3",
- "7 iconst_4",
- "8 iconst_5",
- "108 idiv",
- "165 if_acmpeq",
- "166 if_acmpne",
- "159 if_icmpeq branchoffset2",
- "160 if_icmpne branchoffset2",
- "161 if_icmplt branchoffset2",
- "162 if_icmpge branchoffset2",
- "163 if_icmpgt branchoffset2",
- "164 if_icmple branchoffset2",
- "153 ifeq branchoffset2",
- "154 ifne branchoffset2",
- "155 iflt branchoffset2",
- "156 ifge branchoffset2",
- "157 ifgt branchoffset2",
- "158 ifle branchoffset2",
- "199 ifnonnull branchoffset2",
- "198 ifnull branchoffset2",
- "132 iinc localvariablearrayindex1 signedbyte",
- "21 iload localvariablearrayindex1",
- "26 iload_0 localvariablearrayindex_0",
- "27 iload_1 localvariablearrayindex_1",
- "28 iload_2 localvariablearrayindex_2",
- "29 iload_3 localvariablearrayindex_3",
- "104 imul",
- "116 ineg",
- "193 instanceof constantpoolindex2",
- "185 invokeinterface constantpoolindex2 signedbyte signedbyte",
- "183 invokespecial constantpoolindex2",
- "184 invokestatic constantpoolindex2",
- "182 invokevirtual constantpoolindex2",
- "128 ior",
- "112 irem",
- "172 ireturn",
- "120 ishl",
- "122 ishr",
- "54 istore localvariablearrayindex1",
- "59 istore_0 localvariablearrayindex_0",
- "60 istore_1 localvariablearrayindex_1",
- "61 istore_2 localvariablearrayindex_2",
- "62 istore_3 localvariablearrayindex_3",
- "100 isub",
- "124 iushr",
- "130 ixor",
- "168 jsr branchoffset2",
- "201 jsr_w branchoffset4",
- "138 l2d",
- "137 l2f",
- "136 l2i",
- "97 ladd",
- "47 laload",
- "127 land",
- "80 lastore",
- "148 lcmp",
- "9 lconst_0",
- "10 lconst_1",
- "18 ldc constantpoolindex1",
- "19 ldc_w constantpoolindex2",
- "20 ldc2_w constantpoolindex2",
- "109 ldiv",
- "22 lload localvariablearrayindex1",
- "30 lload_0 localvariablearrayindex_0",
- "31 lload_1 localvariablearrayindex_1",
- "32 lload_2 localvariablearrayindex_2",
- "33 lload_3 localvariablearrayindex_3",
- "105 lmul",
- "117 lneg",
- "171 lookupswitch lookupswitch",
- "129 lor",
- "113 lrem",
- "173 lreturn",
- "121 lshl",
- "123 lshr",
- "55 lstore localvariablearrayindex1",
- "63 lstore_0 localvariablearrayindex_0",
- "64 lstore_1 localvariablearrayindex_1",
- "65 lstore_2 localvariablearrayindex_2",
- "66 lstore_3 localvariablearrayindex_3",
- "101 lsub",
- "125 lushr",
- "131 lxor",
- "194 monitorenter",
- "195 monitorexit",
- "197 multianewarray constantpoolindex2 unsignedbyte",
- "187 new constantpoolindex2",
- "188 newarray atype",
- "0 nop",
- "87 pop",
- "88 pop2",
- "181 putfield constantpoolindex2",
- "179 putstatic constantpoolindex2",
- "169 ret localvariablearrayindex1",
- "177 return",
- "53 saload",
- "86 sastore",
- "17 sipush signedshort",
- "95 swap",
- "170 tableswitch tableswitch",
- "196 wide wide",
- };
- private static final String[] wideInstructions = new String[] {
- "21 iload localvariablearrayindex2",
- "23 fload localvariablearrayindex2",
- "25 aload localvariablearrayindex2",
- "22 lload localvariablearrayindex2",
- "24 dload localvariablearrayindex2",
- "54 istore localvariablearrayindex2",
- "56 fstore localvariablearrayindex2",
- "58 astore localvariablearrayindex2",
- "55 lstore localvariablearrayindex2",
- "57 dstore localvariablearrayindex2",
- "169 ret localvariablearrayindex2",
- "132 iinc localvariablearrayindex2 signedshort",
- };
- private static final Instruction[] opcodeToInstruction = new Instruction[256];
- private static final Instruction[] opcodeToWideInstruction = new Instruction[256];
- static {
- compileInstructions(instructions, opcodeToInstruction);
- compileInstructions(wideInstructions, opcodeToWideInstruction);
- }
- private static void compileInstructions(String[] instructions, Instruction[] opcodeToInstruction) {
- for (int j = 0; j < instructions.length; ++j) {
- StringTokenizer st = new StringTokenizer(instructions[j]);
- String os = st.nextToken();
- int opcode = Integer.parseInt(os);
- String mnemonic = st.nextToken();
- Operand[] operands = null;
- if (st.hasMoreTokens()) {
- List l = new ArrayList();
- while (st.hasMoreTokens()) {
- String s = st.nextToken();
- Operand operand;
- if (s.equals("constantpoolindex1")) {
- operand = new Operand() {
- public void disasm(DataInputStream dis, int instructionOffset, LocalVariableTableAttribute localVariableTableAttribute, Disassembler d) throws IOException {
- short index = (short) (0xff & dis.readByte());
- d.printConstantPoolEntry(index);
- }
- };
- } else
- if (s.equals("constantpoolindex2")) {
- operand = new Operand() {
- public void disasm(DataInputStream dis, int instructionOffset, LocalVariableTableAttribute localVariableTableAttribute, Disassembler d) throws IOException {
- d.printConstantPoolEntry(dis.readShort());
- }
- };
- } else
- if (s.equals("localvariablearrayindex1")) {
- operand = new Operand() {
- public void disasm(DataInputStream dis, int instructionOffset, LocalVariableTableAttribute localVariableTableAttribute, Disassembler d) throws IOException {
- short index = dis.readByte();
- d.print(index);
- if (localVariableTableAttribute != null) {
- d.print(" (" + localVariableTableAttribute.find(index, instructionOffset + 2) + ")");
- }
- }
- };
- } else
- if (s.equals("localvariablearrayindex2")) {
- operand = new Operand() {
- public void disasm(DataInputStream dis, int instructionOffset, LocalVariableTableAttribute localVariableTableAttribute, Disassembler d) throws IOException {
- short index = dis.readShort();
- d.print(index);
- if (localVariableTableAttribute != null) {
- d.print(" (" + localVariableTableAttribute.find(index, instructionOffset + 3) + ")");
- }
- }
- };
- } else
- if (s.startsWith("localvariablearrayindex_")) {
- final short index = Short.parseShort(s.substring(s.length() - 1));
- operand = new Operand() {
- public void disasm(DataInputStream dis, int instructionOffset, LocalVariableTableAttribute localVariableTableAttribute, Disassembler d) throws IOException {
- if (localVariableTableAttribute != null) {
- d.print("(" + localVariableTableAttribute.find(index, instructionOffset + 1) + ")");
- }
- }
- };
- } else
- if (s.equals("branchoffset2")) {
- operand = new Operand() {
- public void disasm(DataInputStream dis, int instructionOffset, LocalVariableTableAttribute localVariableTableAttribute, Disassembler d) throws IOException {
- d.print(instructionOffset + dis.readShort());
- }
- };
- } else
- if (s.equals("branchoffset4")) {
- operand = new Operand() {
- public void disasm(DataInputStream dis, int instructionOffset, LocalVariableTableAttribute localVariableTableAttribute, Disassembler d) throws IOException {
- d.print(instructionOffset + dis.readInt());
- }
- };
- } else
- if (s.equals("signedbyte")) {
- operand = new Operand() {
- public void disasm(DataInputStream dis, int instructionOffset, LocalVariableTableAttribute localVariableTableAttribute, Disassembler d) throws IOException {
- d.print(dis.readByte());
- }
- };
- } else
- if (s.equals("unsignedbyte")) {
- operand = new Operand() {
- public void disasm(DataInputStream dis, int instructionOffset, LocalVariableTableAttribute localVariableTableAttribute, Disassembler d) throws IOException {
- d.print(0xff & dis.readByte());
- }
- };
- } else
- if (s.equals("atype")) {
- operand = new Operand() {
- public void disasm(DataInputStream dis, int instructionOffset, LocalVariableTableAttribute localVariableTableAttribute, Disassembler d) throws IOException {
- byte b = dis.readByte();
- d.print(
- b == 4 ? "BOOLEAN" :
- b == 5 ? "CHAR" :
- b == 6 ? "FLOAT" :
- b == 7 ? "DOUBLE" :
- b == 8 ? "BYTE" :
- b == 9 ? "SHORT" :
- b == 10 ? "INT" :
- b == 11 ? "LONG" :
- new Integer(0xff & b).toString()
- );
- }
- };
- } else
- if (s.equals("signedshort")) {
- operand = new Operand() {
- public void disasm(DataInputStream dis, int instructionOffset, LocalVariableTableAttribute localVariableTableAttribute, Disassembler d) throws IOException {
- d.print(dis.readShort());
- }
- };
- } else
- if (s.equals("tableswitch")) {
- operand = new Operand() {
- public void disasm(DataInputStream dis, int instructionOffset, LocalVariableTableAttribute localVariableTableAttribute, Disassembler d) throws IOException {
- int npads = 3 - (instructionOffset % 4);
- for (int i = 0; i < npads; ++i) if (dis.readByte() != (byte) 0) throw new RuntimeException("Non-zero pad byte in \"tableswitch\"");
- d.print("default => " + (instructionOffset + dis.readInt()));
- int low = dis.readInt();
- int high = dis.readInt();
- for (int i = low; i <= high; ++i) {
- int offset = dis.readInt();
- d.print(", " + i + " => " + (instructionOffset + offset));
- }
- }
- };
- } else
- if (s.equals("lookupswitch")) {
- operand = new Operand() {
- public void disasm(DataInputStream dis, int instructionOffset, LocalVariableTableAttribute localVariableTableAttribute, Disassembler d) throws IOException {
- int npads = 3 - (instructionOffset % 4);
- for (int i = 0; i < npads; ++i) {
- byte b = dis.readByte();
- if (b != (byte) 0) d.print("Padding byte #" + i + " is " + (b & 0xff));
- }
- d.print("default => " + (instructionOffset + dis.readInt()));
- int npairs = dis.readInt();
- for (int i = 0; i < npairs; ++i) {
- int match = dis.readInt();
- int offset = dis.readInt();
- d.print(", " + match + " => " + (instructionOffset + offset));
- }
- }
- };
- } else
- if (s.equals("wide")) {
- operand = new Operand() {
- public void disasm(DataInputStream dis, int instructionOffset, LocalVariableTableAttribute localVariableTableAttribute, Disassembler d) throws IOException {
- int subopcode = 0xff & dis.readByte();
- Instruction wideInstruction = opcodeToWideInstruction[subopcode];
- if (wideInstruction == null) throw new RuntimeException("Invalid opcode " + subopcode + " after opcode WIDE");
- d.disasmInstruction(wideInstruction, dis, instructionOffset, localVariableTableAttribute);
- }
- };
- } else
- {
- throw new RuntimeException("Unknown operand \"" + s + "\"");
- }
- l.add(operand);
- }
- operands = (Operand[]) l.toArray(new Operand[l.size()]);
- }
- opcodeToInstruction[opcode] = new Instruction(mnemonic, operands);
- }
- }
-
- private ConstantPoolInfo getConstantPoolEntry(short index) {
- if ((index & 0xffff) < this.constantPool.length) {
- return this.constantPool[index & 0xffff];
- } else {
- return null;
- }
- }
-
- private void printConstantPoolEntry(short index) {
- if (this.verbose) this.print(index + " (");
- if ((index & 0xffff) < this.constantPool.length) {
- ConstantPoolInfo cpi = this.constantPool[index];
- if (cpi == null) {
- this.print("NULL CONSTANT POOL ENTRY");
- } else {
- cpi.print();
- }
- } else {
- this.print("CONSTANT POOL INDEX OUT OF RANGE");
- }
- if (this.verbose) this.print(")");
- }
-
- private void printConstantPoolEntry(String label, short index) {
- if (this.verbose) {
- if (label != null) this.print(label + " = ");
- this.print(index + " (");
- this.printConstantPoolEntry(index);
- this.print(")");
- } else {
- if (label != null) {
- if (label.endsWith("_index")) label = label.substring(0, label.length() - 6);
- this.print(label + " = ");
- }
- this.printConstantPoolEntry(index);
- }
- }
-
- private static class Instruction {
-
- /**
- *
- * @param mnemonic
- * @param operands <code>null</code> is equivalent to "zero operands"
- */
- public Instruction(String mnemonic, Operand[] operands) {
- this.mnemonic = mnemonic;
- this.operands = operands;
- }
- public String getMnemonic() { return this.mnemonic; }
- public Operand[] getOperands() { return this.operands; }
-
- private final String mnemonic;
- private final Operand[] operands;
- }
- private interface Operand {
- void disasm(
- DataInputStream dis,
- int instructionOffset,
- LocalVariableTableAttribute localVariableTableAttribute, Disassembler d
- ) throws IOException;
- }
-
- /**
- * A variant of {@link PrintWriter} that allows for convenient indentation
- * of output lines.
- */
- private static class IndentPrintWriter extends PrintWriter {
- public IndentPrintWriter(OutputStream os) { super(os); }
- public void write(char[] cbuf, int off, int len) {
- this.handleIndentation();
- super.write(cbuf, off, len);
- }
- public void write(String str, int off, int len) {
- this.handleIndentation();
- super.write(str, off, len);
- }
- public void println() { super.println(); this.atBOL = true; }
- public void indent() { ++this.indentation; }
- public void unindent() { --this.indentation; }
-
- private void handleIndentation() {
- if (this.atBOL) {
- for (int i = 0; i < this.indentation; ++i) {
- super.write(INDENTATION_CHARS, 0, INDENTATION_CHARS.length);
- }
- this.atBOL = false;
- }
- }
- private final static char[] INDENTATION_CHARS = new char[] { ' ', ' ' };
-
- private boolean atBOL = true;
- private int indentation = 0;
- }
-
- private abstract static class ConstantPoolInfo {
- public abstract void print();
- public int getSizeInConstantPool() { return 1; }
- }
- private class ConstantUtf8Info extends ConstantPoolInfo {
- public ConstantUtf8Info(String value) {
- this.value = value;
- }
- public void print() {
- Disassembler.this.print(this.value);
- }
- public String getValue() { return this.value; }
- private String value;
- }
-
- private ConstantPoolInfo[] constantPool = null;
-
- private static class CountingInputStream extends InputStream {
- public CountingInputStream(InputStream is) { this.is = is; }
- public int read() throws IOException {
- int res = this.is.read();
- if (res != -1) ++this.count;
- return res;
- }
- public int read(byte[] b, int off, int len) throws IOException {
- int res = super.read(b, off, len);
- if (res != -1) this.count += res;
- return res;
- }
- public long getCount() { return this.count; }
-
- private InputStream is;
- private long count = 0L;
- }
-
- private static String decodeAccess(short n) {
- StringBuffer sb = new StringBuffer();
- if ((n & 0x0007) == 0) { sb.append("package " ); }
- if ((n & 0x0007) == 1) { sb.append("public " ); n &= ~0x0007; }
- if ((n & 0x0007) == 2) { sb.append("private " ); n &= ~0x0007; }
- if ((n & 0x0007) == 4) { sb.append("protected " ); n &= ~0x0007; }
- if ((n & 0x0008) != 0) { sb.append("static " ); n &= ~0x0008; }
- if ((n & 0x0010) != 0) { sb.append("final " ); n &= ~0x0010; }
- if ((n & 0x0020) != 0) { sb.append("super/synchronized "); n &= ~0x0020; }
- if ((n & 0x0040) != 0) { sb.append("volatile " ); n &= ~0x0040; }
- if ((n & 0x0080) != 0) { sb.append("transient " ); n &= ~0x0080; }
- if ((n & 0x0100) != 0) { sb.append("native " ); n &= ~0x0100; }
- if ((n & 0x0200) != 0) { sb.append("interface " ); n &= ~0x0200; }
- if ((n & 0x0400) != 0) { sb.append("abstract " ); n &= ~0x0400; }
- if ((n & 0x0800) != 0) { sb.append("strict " ); n &= ~0x0800; }
- if (n != 0) sb.append("+ " + n + " ");
- return sb.substring(0, sb.length() - 1);
- }
-
- private static String decodeDescriptor(String d) {
- int brackets = 0;
- while (d.charAt(0) == '[') {
- ++brackets;
- d = d.substring(1);
- }
- if (d.length() == 1) {
- int idx = "BCDFIJSZ".indexOf(d.charAt(0));
- if (idx != -1) d = PRIMITIVES[idx];
- } else
- if (d.charAt(0) == 'L' && d.charAt(d.length() - 1) == ';') {
- d = d.substring(1, d.length() - 1);
- }
- for (; brackets > 0; --brackets) d += "[]";
- return d;
- }
- private static final String[] PRIMITIVES = { "byte", "char", "double", "float", "int", "long", "short", "boolean" };
-}
diff --git a/src/org/codehaus/janino/tools/HprofScrubber.java b/src/org/codehaus/janino/tools/HprofScrubber.java
deleted file mode 100644
index 6ea4e32..0000000
--- a/src/org/codehaus/janino/tools/HprofScrubber.java
+++ /dev/null
@@ -1,220 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino.tools;
-
-import java.io.*;
-import java.text.*;
-import java.util.*;
-
-/**
- * Example for object allocation statistics:
- *
- * java -Xrunhprof:heap=sites,monitor=n,cutoff=0,depth=4 MyClass
- */
-public class HprofScrubber {
- private static class Site {
- public final int allocatedBytes;
- public final int allocatedObjects;
- public final int traceNumber;
- public final String className;
- public Site(int allocatedBytes, int allocatedObjects, int traceNumber, String className) {
- this.allocatedBytes = allocatedBytes;
- this.allocatedObjects = allocatedObjects;
- this.traceNumber = traceNumber;
- this.className = className;
- }
- }
-
- private static class Sample {
- public final int count;
- public final int traceNumber;
- public Sample(int count, int traceNumber) {
- this.count = count;
- this.traceNumber = traceNumber;
- }
- }
-
- public static void main(String[] args) throws Exception {
- String fileName = args.length == 0 ? "java.hprof.txt" : args[0];
-
- BufferedReader br = new BufferedReader(new FileReader(fileName));
- try {
- Map traces = new HashMap(); // Integer number => String[] stackFrames
- List sites = new ArrayList(); // Site
- List samples = new ArrayList(); // Sample
-
- String s = br.readLine();
- while (s != null) {
- if (s.startsWith("SITES BEGIN")) {
- br.readLine();
- br.readLine();
- for (;;) {
- s = br.readLine();
- if (s.startsWith("SITES END")) break;
- StringTokenizer st = new StringTokenizer(s);
- st.nextToken(); // rank
- st.nextToken(); // percent self
- st.nextToken(); // percent accum
- st.nextToken(); // live bytes
- st.nextToken(); // live objects
- sites.add(new Site(
- Integer.parseInt(st.nextToken()), // allocatedBytes
- Integer.parseInt(st.nextToken()), // allocatedObjects
- Integer.parseInt(st.nextToken()), // traceNumber
- st.nextToken() // className
- ));
- }
- } else
- if (s.startsWith("TRACE ") && s.endsWith(":")) {
- int traceNumber = Integer.parseInt(s.substring(6, s.length() - 1));
- List l = new ArrayList();
- for (;;) {
- s = br.readLine();
- if (!s.startsWith("\t")) break;
- l.add(s.substring(1));
- }
- traces.put(
- new Integer(traceNumber),
- l.toArray(new String[l.size()])
- );
- } else
- if (s.startsWith("CPU SAMPLES BEGIN")) {
- br.readLine();
- for (;;) {
- s = br.readLine();
- if (s.startsWith("CPU SAMPLES END")) break;
- StringTokenizer st = new StringTokenizer(s);
- st.nextToken(); // rank
- st.nextToken(); // percent self
- st.nextToken(); // percent accum
- int count = Integer.parseInt(st.nextToken());
- if (count == 0) continue;
- int trace = Integer.parseInt(st.nextToken());
- samples.add(new Sample(count, trace));
- }
- } else {
- s = br.readLine();
- }
- }
-
- HprofScrubber.dumpSites((Site[]) sites.toArray(new Site[sites.size()]), traces);
-
- HprofScrubber.dumpSamples((Sample[]) samples.toArray(new Sample[samples.size()]), traces);
-
- } finally {
- try { br.close(); } catch (IOException e) {}
- }
- }
-
- private static void dumpSites(Site[] ss, Map traces) {
- Arrays.sort(ss, new Comparator() {
- public int compare(Object o1, Object o2) {
- return ((Site) o2).allocatedBytes - ((Site) o1).allocatedBytes;
- }
- });
-
- int totalAllocatedBytes = 0, totalAllocatedObjects = 0;
- for (int i = 0; i < ss.length; ++i) {
- Site site = ss[i];
- totalAllocatedBytes += site.allocatedBytes;
- totalAllocatedObjects += site.allocatedObjects;
- }
-
- System.out.println(" percent alloc'ed");
- System.out.println("rank self accum bytes objects class name");
- System.out.println("Total: " + totalAllocatedBytes + " " + totalAllocatedObjects);
-
- double accumulatedPercentage = 0.0;
- MessageFormat mf = new MessageFormat("{0,number,00000} {1,number,00.00}% {2,number,00.00}% {3,number,000000000} {4,number,000000000} {5}");
- for (int i = 0; i < ss.length; ++i) {
- Site site = ss[i];
- double selfPercentage = 100.0 * ((double) site.allocatedBytes / (double) totalAllocatedBytes);
- accumulatedPercentage += selfPercentage;
- // System.out.println((i + 1) + " " + selfPercentage + "% " + accumulatedPercentage + "% " + site.allocatedBytes + " " + site.allocatedObjects + " " + site.className);
- System.out.println(mf.format(
- new Object[] {
- new Integer(i + 1),
- new Double(selfPercentage),
- new Double(accumulatedPercentage),
- new Integer(site.allocatedBytes),
- new Integer(site.allocatedObjects),
- site.className
- },
- new StringBuffer(),
- new FieldPosition(0)
- ));
- String[] stackFrames = (String[]) traces.get(new Integer(site.traceNumber));
- if (stackFrames != null) {
- for (int j = 0; j < stackFrames.length; ++j) {
- System.out.println(" " + stackFrames[j]);
- }
- }
- }
- }
-
- private static void dumpSamples(Sample[] ss, Map traces) {
- int totalCount = 0;
- for (int i = 0; i < ss.length; ++i) totalCount += ss[i].count;
-
- System.out.println(" percent");
- System.out.println("rank self accum count");
- System.out.println("Total: " + totalCount);
-
- double accumulatedPercentage = 0.0;
- MessageFormat mf = new MessageFormat("{0,number,00000} {1,number,00.00}% {2,number,00.00}% {3,number,000000000}");
- for (int i = 0; i < ss.length; ++i) {
- Sample sample = ss[i];
- double selfPercentage = 100.0 * ((double) sample.count / (double) totalCount);
- accumulatedPercentage += selfPercentage;
-// System.out.println((i + 1) + " " + selfPercentage + "% " + accumulatedPercentage + "% " + site.allocatedBytes + " " + site.allocatedObjects + " " + site.className);
- System.out.println(mf.format(
- new Object[] {
- new Integer(i + 1),
- new Double(selfPercentage),
- new Double(accumulatedPercentage),
- new Integer(sample.count)
- },
- new StringBuffer(),
- new FieldPosition(0)
- ));
- String[] stackFrames = (String[]) traces.get(new Integer(sample.traceNumber));
- if (stackFrames != null) {
- for (int j = 0; j < stackFrames.length; ++j) {
- System.out.println(" " + stackFrames[j]);
- }
- }
- }
- }
-}
diff --git a/src/org/codehaus/janino/tools/JGrep.java b/src/org/codehaus/janino/tools/JGrep.java
deleted file mode 100644
index d770aa8..0000000
--- a/src/org/codehaus/janino/tools/JGrep.java
+++ /dev/null
@@ -1,692 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino.tools;
-
-import java.util.*;
-import java.io.*;
-
-import org.codehaus.janino.*;
-import org.codehaus.janino.Scanner; // Resolve ambiguity with JDK 1.5's "java.util.Scanner".
-import org.codehaus.janino.util.*;
-import org.codehaus.janino.util.enumerator.*;
-import org.codehaus.janino.util.iterator.*;
-import org.codehaus.janino.util.resource.*;
-
-
-/**
- * Reads a set of compilation units from the file system and searches it for specific
- * Java<sup>TM</sup> constructs, e.g. invocations of a particular method.
- *
- * Usage:
- * <pre>
- * java org.codehaus.janino.JGrep \
- * [ -dirs <i>directory-name-patterns</i> ] \
- * [ -files <i>file-name-patterns</i> ] \
- * { <i>directory-path</i> } \
- * -method-invocation <i>class.method(arg-types)</i>
- * java org.codehaus.janino.JGrep -help
- * </pre>
- *
- * If "-dirs" is not given, then all <i>directory-path</i>es are scanned for files.
- * The <i>directory-name-patterns</i> work as described in
- * {@link org.codehaus.janino.util.StringPattern#parseCombinedPattern(String)}.
- * <p>
- * If "-files" is not given, then all files ending in ".java" are read. The
- * <i>file-name-patterns</i> work as described in
- * {@link org.codehaus.janino.util.StringPattern#parseCombinedPattern(String)}.
- */
-public class JGrep {
- private static final boolean DEBUG = false;
- private List parsedCompilationUnits = new ArrayList(); // UnitCompiler
-
- /**
- * Command line interface.
- */
- public static void main(String[] args) {
- int idx = 0;
-
- StringPattern[] directoryNamePatterns = StringPattern.PATTERNS_ALL;
- StringPattern[] fileNamePatterns = new StringPattern[] { new StringPattern("*.java") };
- File[] classPath = new File[] { new File(".") };
- File[] optionalExtDirs = null;
- File[] optionalBootClassPath = null;
- String optionalCharacterEncoding = null;
- boolean verbose = false;
-
- for (; idx < args.length; ++idx) {
- String arg = args[idx];
- if (arg.charAt(0) != '-') break;
- if (arg.equals("-dirs")) {
- directoryNamePatterns = StringPattern.parseCombinedPattern(args[++idx]);
- } else
- if (arg.equals("-files")) {
- fileNamePatterns = StringPattern.parseCombinedPattern(args[++idx]);
- } else
- if (arg.equals("-classpath")) {
- classPath = PathResourceFinder.parsePath(args[++idx]);
- } else
- if (arg.equals("-extdirs")) {
- optionalExtDirs = PathResourceFinder.parsePath(args[++idx]);
- } else
- if (arg.equals("-bootclasspath")) {
- optionalBootClassPath = PathResourceFinder.parsePath(args[++idx]);
- } else
- if (arg.equals("-encoding")) {
- optionalCharacterEncoding = args[++idx];
- } else
- if (arg.equals("-verbose")) {
- verbose = true;
- } else
- if (arg.equals("-help")) {
- for (int j = 0; j < JGrep.USAGE.length; ++j) System.out.println(JGrep.USAGE[j]);
- System.exit(1);
- } else
- {
- System.err.println("Unexpected command-line argument \"" + arg + "\", try \"-help\".");
- System.exit(1);
- /* NEVER REACHED */ return;
- }
- }
-
- // { directory-path }
- File[] rootDirectories;
- {
- int first = idx;
- for (; idx < args.length && args[idx].charAt(0) != '-'; ++idx);
- if (idx == first) {
- System.err.println("No <directory-path>es given, try \"-help\".");
- System.exit(1);
- /* NEVER REACHED */ return;
- }
- rootDirectories = new File[idx - first];
- for (int i = first; i < idx; ++i) rootDirectories[i - first] = new File(args[i]);
- }
-
- // Create the JGrep object.
- final JGrep jGrep = new JGrep(
- classPath,
- optionalExtDirs,
- optionalBootClassPath,
- optionalCharacterEncoding,
- verbose
- );
-
- List mits = new ArrayList();
- for (; idx < args.length; ++idx) {
- String arg = args[idx];
- if (arg.equals("-method-invocation")) {
- MethodInvocationTarget mit;
- try {
- mit = JGrep.parseMethodInvocationPattern(args[++idx]);
- } catch (Exception ex) {
- System.err.println("Parsing method invocation pattern \"" + args[idx] + "\": " + ex.getMessage());
- System.exit(1);
- /* NEVER REACHED */ return;
- }
- while (idx < args.length - 1) {
- arg = args[idx + 1];
- if (arg.startsWith("predicate:")) {
- String predicateExpression = arg.substring(10);
- try {
- mit.predicates.add(ExpressionEvaluator.createFastExpressionEvaluator(
- new Scanner(null, new StringReader(predicateExpression)), // expression
- JGrep.class.getName() + "PE", // className
- null, // optionalExtendedType
- MethodInvocationPredicate.class, // interfaceToImplement
- new String[] { "uc", "invocation", "method" }, // parameterNames
- null // optionalClassLoader
- ));
- } catch (Exception ex) {
- System.err.println("Compiling predicate expression \"" + predicateExpression + "\": " + ex.getMessage());
- System.exit(1);
- /* NEVER REACHED */ return;
- }
- } else
- if (arg.startsWith("action:")) {
- String action = arg.substring(7);
- try {
- mit.actions.add(Action.getMethodInvocationAction(action));
- } catch (Exception ex) {
- System.err.println("Compiling method invocation action \"" + action + "\": " + ex.getMessage());
- System.exit(1);
- /* NEVER REACHED */ return;
- }
- } else
- {
- break;
- }
- ++idx;
- }
- mits.add(mit);
- } else
- {
- System.err.println("Unexpected command-line argument \"" + arg + "\", try \"-help\".");
- System.exit(1);
- /* NEVER REACHED */ return;
- }
- }
-
- // JGrep the root directories.
- try {
- jGrep.jGrep(
- rootDirectories,
- directoryNamePatterns,
- fileNamePatterns,
- mits // methodInvocationTargets
- );
- } catch (Exception e) {
- System.err.println(e.toString());
- System.exit(1);
- }
- }
-
- private static final class Action extends Enumerator {
- public static final Action PRINT_LOCATION_AND_MATCH = new Action("print-location-and-match");
- public static final Action PRINT_LOCATION = new Action("print-location");
-
- private Action(String name) { super(name); }
- public static Action fromString(String name) throws EnumeratorFormatException {
- return (Action) Enumerator.fromString(name, Action.class);
- }
-
- static MethodInvocationAction getMethodInvocationAction(String action) throws CompileException, Parser.ParseException, Scanner.ScanException {
- if ("print-location-and-match".equals(action)) {
- return new MethodInvocationAction() { public void execute(UnitCompiler uc, Java.Invocation invocation, IClass.IMethod method) { System.out.println(invocation.getLocation() + ": " + method); } };
- } else
- if ("print-location".equals(action)) {
- return new MethodInvocationAction() { public void execute(UnitCompiler uc, Java.Invocation invocation, IClass.IMethod method) { System.out.println(invocation.getLocation()); } };
- } else
- {
- return (MethodInvocationAction) ScriptEvaluator.createFastScriptEvaluator(
- action, // script
- MethodInvocationAction.class, // interfaceToImplement
- new String[] { "uc", "invocation", "method" } // parameterNames
- );
- }
- }
- }
-
- private static MethodInvocationTarget parseMethodInvocationPattern(String mip) throws Scanner.ScanException, IOException, Parser.ParseException {
- MethodInvocationTarget mit = new MethodInvocationTarget();
- Scanner scanner = new Scanner(null, new StringReader(mip));
- Parser parser = new Parser(scanner);
-
- for (;;) {
- String s = JGrep.readIdentifierPattern(parser);
- if (parser.peekOperator("(")) {
- mit.methodNamePattern = s;
- parser.eatToken();
- List l = new ArrayList();
- if (!parser.peekOperator(")")) {
- for (;;) {
- l.add(JGrep.readIdentifierPattern(parser));
- if (parser.peekOperator(")")) break;
- parser.readOperator(",");
- }
- }
- mit.optionalArgumentTypeNamePatterns = (String[]) l.toArray(new String[l.size()]);
- return mit;
- } else
- if (parser.peekOperator(".")) {
- if (mit.optionalClassNamePattern == null) {
- mit.optionalClassNamePattern = s;
- } else
- {
- mit.optionalClassNamePattern += '.' + s;
- }
- parser.eatToken();
- } else
- if (scanner.peek().isEOF()) {
- mit.methodNamePattern = s;
- return mit;
- }
- }
- }
-
- private static String readIdentifierPattern(Parser p) throws Parser.ParseException, Scanner.ScanException, IOException {
- StringBuffer sb = new StringBuffer();
- if (p.peekOperator("*")) {
- sb.append('*');
- p.eatToken();
- } else
- {
- sb.append(p.readIdentifier());
- }
- for (;;) {
- if (p.peekOperator("*")) {
- sb.append('*');
- p.eatToken();
- } else
- if (p.peekIdentifier()) {
- sb.append(p.readIdentifier());
- } else
- {
- return sb.toString();
- }
- }
- }
- private static class MethodInvocationTarget {
- String optionalClassNamePattern = null;
- String methodNamePattern = null;
- String[] optionalArgumentTypeNamePatterns = null;
- List predicates = new ArrayList(); // MethodInvocationPredicate
- List actions = new ArrayList(); // MethodInvocationAction
-
- void apply(UnitCompiler uc, Java.Invocation invocation, IClass.IMethod method) throws CompileException {
- if (this.optionalClassNamePattern != null) {
- if (!typeMatches(this.optionalClassNamePattern, Descriptor.toClassName(method.getDeclaringIClass().getDescriptor()))) return;
- }
- if (!new StringPattern(this.methodNamePattern).matches(method.getName())) return;
- IClass[] fpts = method.getParameterTypes();
- if (this.optionalArgumentTypeNamePatterns != null) {
- String[] atnps = this.optionalArgumentTypeNamePatterns;
- if (atnps.length != fpts.length) return;
- for (int i = 0; i < atnps.length; ++i) {
- if (!new StringPattern(atnps[i]).matches(Descriptor.toClassName(fpts[i].getDescriptor())));
- }
- }
- for (Iterator it = this.predicates.iterator(); it.hasNext();) {
- MethodInvocationPredicate mip = (MethodInvocationPredicate) it.next();
- try {
- if (!mip.evaluate(uc, invocation, method)) return;
- } catch (Exception ex) {
- return; // Treat exception as a "false" predicate.
- }
- }
- for (Iterator it = this.actions.iterator(); it.hasNext();) {
- MethodInvocationAction mia = (MethodInvocationAction) it.next();
- try {
- mia.execute(uc, invocation, method);
- } catch (Exception ex) {
- ; // Ignore action throwing an exception.
- }
- }
- }
- }
- public interface MethodInvocationPredicate { boolean evaluate(UnitCompiler uc, Java.Invocation invocation, IClass.IMethod method) throws Exception; }
- public interface MethodInvocationAction { void execute(UnitCompiler uc, Java.Invocation invocation, IClass.IMethod method) throws Exception; }
-
- static boolean typeMatches(String pattern, String typeName) {
- return new StringPattern(pattern).matches(
- pattern.indexOf('.') == -1
- ? typeName.substring(typeName.lastIndexOf('.') + 1)
- : typeName
- );
- }
- private static final String[] USAGE = {
- "To be written.", // TODO
-/*
- "Usage:",
- "",
- " java org.codehaus.janino.Compiler [ <option> ] ... <source-file> ...",
- "",
- "Supported <option>s are:",
- " -d <output-dir> Where to save class files",
- " -sourcepath <dirlist> Where to look for other source files",
- " -classpath <dirlist> Where to look for other class files",
- " -extdirs <dirlist> Where to look for other class files",
- " -bootclasspath <dirlist> Where to look for other class files",
- " -encoding <encoding> Encoding of source files, e.g. \"UTF-8\" or \"ISO-8859-1\"",
- " -verbose",
- " -g Generate all debugging info",
- " -g:none Generate no debugging info",
- " -g:{lines,vars,source} Generate only some debugging info",
- " -warn:<pattern-list> Issue certain warnings; examples:",
- " -warn:* Enables all warnings",
- " -warn:IASF Only warn against implicit access to static fields",
- " -warn:*-IASF Enables all warnings, except those against implicit",
- " access to static fields",
- " -warn:*-IA*+IASF Enables all warnings, except those against implicit",
- " accesses, but do warn against implicit access to",
- " static fields",
- " -rebuild Compile all source files, even if the class files",
- " seems up-to-date",
- " -help",
- "",
- "The default encoding in this environment is \"" + new InputStreamReader(new ByteArrayInputStream(new byte[0])).getEncoding() + "\".",
-*/
- };
-
- private /*final*/ IClassLoader iClassLoader;
- private /*final*/ String optionalCharacterEncoding;
- private /*final*/ Benchmark benchmark;
-
- public JGrep(
- File[] classPath,
- File[] optionalExtDirs,
- File[] optionalBootClassPath,
- String optionalCharacterEncoding,
- boolean verbose
- ) {
- this(
- JGrep.createJavacLikePathIClassLoader( // iClassLoader
- optionalBootClassPath,
- optionalExtDirs,
- classPath
- ),
- optionalCharacterEncoding, // optionalCharacterEncoding
- verbose // verbose
- );
-
- this.benchmark.report("*** JGrep - search Java(TM) source files for specific language constructs");
- this.benchmark.report("*** For more information visit http://janino.codehaus.org");
- this.benchmark.report("Class path", classPath );
- this.benchmark.report("Ext dirs", optionalExtDirs );
- this.benchmark.report("Boot class path", optionalBootClassPath );
- this.benchmark.report("Character encoding", optionalCharacterEncoding);
- }
-
- public JGrep(
- IClassLoader iClassLoader,
- final String optionalCharacterEncoding,
- boolean verbose
- ) {
- this.iClassLoader = new JGrepIClassLoader(iClassLoader);
- this.optionalCharacterEncoding = optionalCharacterEncoding;
- this.benchmark = new Benchmark(verbose);
- }
-
- /**
- * Create an {@link IClassLoader} that looks for classes in the given "boot class
- * path", then in the given "extension directories", and then in the given
- * "class path".
- * <p>
- * The default for the <code>optionalBootClassPath</code> is the path defined in
- * the system property "sun.boot.class.path", and the default for the
- * <code>optionalExtensionDirs</code> is the path defined in the "java.ext.dirs"
- * system property.
- */
- private static IClassLoader createJavacLikePathIClassLoader(
- final File[] optionalBootClassPath,
- final File[] optionalExtDirs,
- final File[] classPath
- ) {
- ResourceFinder bootClassPathResourceFinder = new PathResourceFinder(
- optionalBootClassPath == null ?
- PathResourceFinder.parsePath(System.getProperty("sun.boot.class.path")):
- optionalBootClassPath
- );
- ResourceFinder extensionDirectoriesResourceFinder = new JarDirectoriesResourceFinder(
- optionalExtDirs == null ?
- PathResourceFinder.parsePath(System.getProperty("java.ext.dirs")):
- optionalExtDirs
- );
- ResourceFinder classPathResourceFinder = new PathResourceFinder(classPath);
-
- // We can load classes through "ResourceFinderIClassLoader"s, which means
- // they are read into "ClassFile" objects, or we can load classes through
- // "ClassLoaderIClassLoader"s, which means they are loaded into the JVM.
- //
- // In my environment, the latter is slightly faster. No figures about
- // resource usage yet.
- //
- // In applications where the generated classes are not loaded into the
- // same JVM instance, we should avoid to use the
- // ClassLoaderIClassLoader, because that assumes that final fields have
- // a constant value, even if not compile-time-constant but only
- // initialization-time constant. The classical example is
- // "File.separator", which is non-blank final, but not compile-time-
- // constant.
- if (true) {
- IClassLoader icl;
- icl = new ResourceFinderIClassLoader(bootClassPathResourceFinder, null);
- icl = new ResourceFinderIClassLoader(extensionDirectoriesResourceFinder, icl);
- icl = new ResourceFinderIClassLoader(classPathResourceFinder, icl);
- return icl;
- } else {
- ClassLoader cl;
-
- cl = SimpleCompiler.BOOT_CLASS_LOADER;
- cl = new ResourceFinderClassLoader(bootClassPathResourceFinder, cl);
- cl = new ResourceFinderClassLoader(extensionDirectoriesResourceFinder, cl);
- cl = new ResourceFinderClassLoader(classPathResourceFinder, cl);
-
- return new ClassLoaderIClassLoader(cl);
- }
- }
-
- public void jGrep(
- File[] rootDirectories,
- final StringPattern[] directoryNamePatterns,
- final StringPattern[] fileNamePatterns,
- List methodInvocationTargets // MethodInvocationTarget
- ) throws Scanner.ScanException, Parser.ParseException, CompileException, IOException {
- this.benchmark.report("Root dirs", rootDirectories );
- this.benchmark.report("Directory name patterns", directoryNamePatterns );
- this.benchmark.report("File name patterns", fileNamePatterns);
-
- this.jGrep(DirectoryIterator.traverseDirectories(
- rootDirectories, // rootDirectories
- new FilenameFilter() { // directoryNameFilter
- public boolean accept(File dir, String name) {
- return StringPattern.matches(directoryNamePatterns, name);
- }
- },
- new FilenameFilter() { // fileNameFilter
- public boolean accept(File dir, String name) {
- return StringPattern.matches(fileNamePatterns, name);
- }
- }
- ), methodInvocationTargets);
- }
-
- public void jGrep(Iterator sourceFilesIterator, final List methodInvocationTargets)
- throws Scanner.ScanException, Parser.ParseException, CompileException, IOException {
-
- // Parse the given source files.
- this.benchmark.beginReporting();
- int sourceFileCount = 0;
- try {
-
- // Parse all source files.
- while (sourceFilesIterator.hasNext()) {
- File sourceFile = (File) sourceFilesIterator.next();
- UnitCompiler uc = new UnitCompiler(this.parseCompilationUnit(
- sourceFile, // sourceFile
- this.optionalCharacterEncoding // optionalCharacterEncoding
- ), this.iClassLoader);
- this.parsedCompilationUnits.add(uc);
- ++sourceFileCount;
- }
- } finally {
- this.benchmark.endReporting("Parsed " + sourceFileCount + " source file(s)");
- }
-
- // Traverse the parsed compilation units.
- this.benchmark.beginReporting();
- try {
- for (Iterator it = this.parsedCompilationUnits.iterator(); it.hasNext();) {
- final UnitCompiler uc = (UnitCompiler) it.next();
- this.benchmark.beginReporting("Grepping \"" + uc.compilationUnit.optionalFileName + "\"");
- class UCE extends RuntimeException { final CompileException ce; UCE(CompileException ce) { this.ce = ce; } }
- try {
- new Traverser() {
-
- // "method(...)", "x.method(...)"
- public void traverseMethodInvocation(Java.MethodInvocation mi) {
- try {
- this.match(mi, uc.findIMethod(mi));
- } catch (CompileException ex) {
- throw new UCE(ex);
- }
- super.traverseMethodInvocation(mi);
- }
-
- // "super.method(...)"
- public void traverseSuperclassMethodInvocation(Java.SuperclassMethodInvocation scmi) {
- try {
- this.match(scmi, uc.findIMethod(scmi));
- } catch (CompileException ex) {
- throw new UCE(ex);
- }
- super.traverseSuperclassMethodInvocation(scmi);
- }
-
- // new Xyz(...)
- public void traverseNewClassInstance(Java.NewClassInstance nci) {
- // System.out.println(nci.getLocation() + ": " + nci);
- super.traverseNewClassInstance(nci);
- }
-
- // new Xyz(...) {}
- public void traverseNewAnonymousClassInstance(Java.NewAnonymousClassInstance naci) {
- // System.out.println(naci.getLocation() + ": " + naci);
- super.traverseNewAnonymousClassInstance(naci);
- }
-
- // Explicit constructor invocation ("this(...)", "super(...)").
- public void traverseConstructorInvocation(Java.ConstructorInvocation ci) {
- // System.out.println(ci.getLocation() + ": " + ci);
- super.traverseConstructorInvocation(ci);
- }
-
- private void match(Java.Invocation invocation, IClass.IMethod method) throws CompileException {
- for (Iterator it2 = methodInvocationTargets.iterator(); it2.hasNext();) {
- MethodInvocationTarget mit = (MethodInvocationTarget) it2.next();
- mit.apply(uc, invocation, method);
- }
- }
- }.traverseCompilationUnit(uc.compilationUnit);
- } catch (UCE uce) {
- throw uce.ce;
- } finally {
- this.benchmark.endReporting();
- }
- }
- } finally {
- this.benchmark.endReporting("Traversed " + sourceFileCount + " compilation units");
- }
- }
-
- /**
- * Read one compilation unit from a file and parse it.
- * <p>
- * The <code>inputStream</code> is closed before the method returns.
- * @return the parsed compilation unit
- */
- private Java.CompilationUnit parseCompilationUnit(
- File sourceFile,
- String optionalCharacterEncoding
- ) throws Scanner.ScanException, Parser.ParseException, IOException {
- InputStream is = new BufferedInputStream(new FileInputStream(sourceFile));
- try {
- Parser parser = new Parser(new Scanner(sourceFile.getPath(), is, optionalCharacterEncoding));
-
- this.benchmark.beginReporting("Parsing \"" + sourceFile + "\"");
- try {
- return parser.parseCompilationUnit();
- } finally {
- this.benchmark.endReporting();
- }
- } finally {
- try { is.close(); } catch (IOException ex) {}
- }
- }
-
- /**
- * Construct the name of a file that could store the byte code of the class with the given
- * name.
- * <p>
- * If <code>optionalDestinationDirectory</code> is non-null, the returned path is the
- * <code>optionalDestinationDirectory</code> plus the package of the class (with dots replaced
- * with file separators) plus the class name plus ".class". Example:
- * "destdir/pkg1/pkg2/Outer$Inner.class"
- * <p>
- * If <code>optionalDestinationDirectory</code> is null, the returned path is the
- * directory of the <code>sourceFile</code> plus the class name plus ".class". Example:
- * "srcdir/Outer$Inner.class"
- * @param className E.g. "pkg1.pkg2.Outer$Inner"
- * @param sourceFile E.g. "srcdir/Outer.java"
- * @param optionalDestinationDirectory E.g. "destdir"
- */
- public static File getClassFile(String className, File sourceFile, File optionalDestinationDirectory) {
- if (optionalDestinationDirectory != null) {
- return new File(optionalDestinationDirectory, ClassFile.getClassFileResourceName(className));
- } else {
- int idx = className.lastIndexOf('.');
- return new File(sourceFile.getParentFile(), ClassFile.getClassFileResourceName(className.substring(idx + 1)));
- }
- }
-
- /**
- * A specialized {@link IClassLoader} that loads {@link IClass}es from the following
- * sources:
- * <ol>
- * <li>An already-parsed compilation unit
- * <li>A class file in the output directory (if existant and younger than source file)
- * <li>A source file in any of the source path directories
- * <li>The parent class loader
- * </ol>
- * Notice that the {@link JGrepIClassLoader} is an inner class of {@link JGrep} and
- * heavily uses {@link JGrep}'s members.
- */
- private class JGrepIClassLoader extends IClassLoader {
-
- /**
- * @param optionalParentIClassLoader {@link IClassLoader} through which {@link IClass}es are to be loaded
- */
- public JGrepIClassLoader(IClassLoader optionalParentIClassLoader) {
- super(optionalParentIClassLoader);
- super.postConstruct();
- }
-
- /**
- * @param type field descriptor of the {@IClass} to load, e.g. "Lpkg1/pkg2/Outer$Inner;"
- */
- protected IClass findIClass(final String type) {
- if (JGrep.DEBUG) System.out.println("type = " + type);
-
- // Class type.
- String className = Descriptor.toClassName(type); // E.g. "pkg1.pkg2.Outer$Inner"
- if (JGrep.DEBUG) System.out.println("2 className = \"" + className + "\"");
-
- // Do not attempt to load classes from package "java".
- if (className.startsWith("java.")) return null;
-
- // Check the already-parsed compilation units.
- for (int i = 0; i < JGrep.this.parsedCompilationUnits.size(); ++i) {
- UnitCompiler uc = (UnitCompiler) JGrep.this.parsedCompilationUnits.get(i);
- IClass res = uc.findClass(className);
- if (res != null) {
- this.defineIClass(res);
- return res;
- }
- }
- return null;
- }
- }
-}
-
-
diff --git a/src/org/codehaus/janino/tools/package.html b/src/org/codehaus/janino/tools/package.html
deleted file mode 100644
index 22b7a62..0000000
--- a/src/org/codehaus/janino/tools/package.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<html><body>
- Auxiliary command line tools related to JANINO.
-</body></html>
diff --git a/src/org/codehaus/janino/util/AutoIndentWriter.java b/src/org/codehaus/janino/util/AutoIndentWriter.java
deleted file mode 100644
index 393b6d2..0000000
--- a/src/org/codehaus/janino/util/AutoIndentWriter.java
+++ /dev/null
@@ -1,92 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino.util;
-
-import java.io.*;
-
-/**
- * A {@link java.io.FilterWriter} that automatically indents lines by looking at
- * trailing opening braces ('{') and leading closing braces ('}').
- */
-public class AutoIndentWriter extends FilterWriter {
- private static final String LINE_SEPARATOR = System.getProperty("line.separator");
- private int previousChar = -1;
- private int indentation = 0;
- private String prefix = null;
-
- public AutoIndentWriter(Writer out) {
- super(out);
- }
-
- public void write(int c) throws IOException {
- if (AutoIndentWriter.isLineSeparatorChar(c)) {
- if (this.previousChar == '{') this.indent();
- } else
- if (AutoIndentWriter.isLineSeparatorChar(this.previousChar)) {
- if (c == '}') this.unindent();
- for (int i = 0; i < this.indentation; ++i) this.out.write(" ");
- if (this.prefix != null) this.out.write(this.prefix);
- }
- super.write(c);
- this.previousChar = c;
- }
-
- public void unindent() {
- --this.indentation;
- }
-
- public void indent() {
- ++this.indentation;
- }
-
- /**
- * The prefix, if non-null, is printed between the indentation space and
- * the line data.
- */
- public void setPrefix(String prefix) {
- this.prefix = prefix;
- }
-
- public void write(char[] cbuf, int off, int len) throws IOException {
- for (; len > 0; --len) this.write(cbuf[off++]);
- }
- public void write(String str, int off, int len) throws IOException {
- for (; len > 0; --len) this.write(str.charAt(off++));
- }
-
- private static boolean isLineSeparatorChar(int c) {
- return AutoIndentWriter.LINE_SEPARATOR.indexOf(c) != -1;
- }
-}
diff --git a/src/org/codehaus/janino/util/Benchmark.java b/src/org/codehaus/janino/util/Benchmark.java
deleted file mode 100644
index a7fb7d8..0000000
--- a/src/org/codehaus/janino/util/Benchmark.java
+++ /dev/null
@@ -1,220 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino.util;
-
-import java.util.*;
-
-/**
- * Implements a scheme for benchmarking, i.e. for determining and/or reporting the time elapsed
- * between the beginning and the end of an activity.
- * <p>
- * The measurement is done by invoking {@link #begin()} and later calling {@link #end()} whichs
- * returns the time elapsed since the call to {@link #begin()}.
- * <p>
- * Notice that calls to {@link #begin()} and {@link #end()} can be nested, and each call to
- * {@link #end()} refers to the matching {@link #begin()} call. To ensure that all calls match,
- * the preferred way to write a benchmark is
- * <pre>
- * ...
- * Benchmark b = new Benchmark();
- * ...
- * b.begin();
- * try {
- * ....
- * } finally {
- * long ms = b.end();
- * }
- * </pre>
- * This code layout also makes it visually easy to write correct pairs of {@link #begin()} /
- * {@link #end()} pairs.
- * <p>
- * The pair {@link #beginReporting()} and {@link #endReporting()} do basically the same, but
- * report the benchmarking information through an internal {@link Reporter} object. The default
- * {@link Reporter} prints its messages by <code>System.out.println()</code>.
- * <p>
- * Reporting is only enabled if the Benchmark object was created through {@link #Benchmark(boolean)}
- * with a <code>true</code> argument.
- */
-public class Benchmark {
- private final Stack beginTimes = new Stack(); // Long
-
- public Benchmark() {
- this.reportingEnabled = false;
- this.reporter = null;
- }
-
- /**
- * @see Benchmark
- */
- public void begin() {
- this.beginTimes.push(new Long(System.currentTimeMillis()));
- }
-
- /**
- * @see Benchmark
- */
- public long end() {
- return System.currentTimeMillis() - ((Long) this.beginTimes.pop()).longValue();
- }
-
- // Reporting-related methods and fields.
-
- /**
- * Set up a {@link Benchmark} with a default {@link Reporter} that reports to
- * <code>System.out</code>.
- */
- public Benchmark(boolean reportingEnabled) {
- this.reportingEnabled = reportingEnabled;
- this.reporter = new Reporter() {
- public void report(String message) { System.out.println(message); }
- };
- }
-
- /**
- * Set up a {@link Benchmark} with a custom {@link Reporter}.
- */
- public Benchmark(
- boolean reportingEnabled,
- Reporter reporter
- ) {
- this.reportingEnabled = reportingEnabled;
- this.reporter = reporter;
- }
-
- private final boolean reportingEnabled;
- private final Reporter reporter;
-
- /**
- * Interface used to report messages.
- */
- public interface Reporter {
- void report(String message);
- }
-
- /**
- * Begin a benchmark (see {@link #begin()}) and report the fact.
- */
- public void beginReporting() {
- if (!this.reportingEnabled) return;
-
- this.reportIndented("Beginning...");
- this.begin();
- }
-
- /**
- * Begin a benchmark (see {@link #begin()}) and report the fact.
- */
- public void beginReporting(String message) {
- if (!this.reportingEnabled) return;
- this.reportIndented(message + "...");
- this.begin();
- }
-
- /**
- * End a benchmark (see {@link #end()}) and report the fact.
- */
- public void endReporting() {
- if (!this.reportingEnabled) return;
- this.reportIndented("... took " + this.end() + " ms");
- }
-
- /**
- * End a benchmark (see {@link #begin()}) and report the fact.
- */
- public void endReporting(String message) {
- if (!this.reportingEnabled) return;
- this.reportIndented("... took " + this.end() + " ms: " + message);
- }
-
- /**
- * Report the given message.
- */
- public void report(String message) {
- if (!this.reportingEnabled) return;
- this.reportIndented(message);
- }
-
- /**
- * Report the <code>title</code>, a colon, a space, and the pretty-printed
- * {@link Object}.
- * @param optionalTitle
- * @param o
- */
- public void report(String optionalTitle, Object o) {
- if (!this.reportingEnabled) return;
-
- String prefix = optionalTitle == null ? "" : (
- optionalTitle
- + ": "
- + (optionalTitle.length() < Benchmark.PAD.length() ? Benchmark.PAD.substring(optionalTitle.length()) : "")
- );
-
- if (o == null) {
- this.reportIndented(prefix + "(undefined)");
- } else
- if (o.getClass().isArray()) {
- Object[] oa = (Object[]) o;
- if (oa.length == 0) {
- this.reportIndented(prefix + "(empty)");
- } else
- if (oa.length == 1) {
- this.reportIndented(prefix + oa[0].toString());
- } else {
- this.reportIndented(optionalTitle == null ? "Array:" : optionalTitle + ':');
- this.begin();
- try {
- for (int i = 0; i < oa.length; ++i) this.report(null, oa[i]);
- } finally {
- this.end();
- }
- }
- } else
- {
- this.reportIndented(prefix + o.toString());
- }
- }
- private static final String PAD = " ";
-
- /**
- * Report a message through {@link #reporter}, indent by N spaces where N is the current
- * benchmark stack depth.
- */
- private void reportIndented(String message) {
- StringBuffer sb = new StringBuffer();
- for (int i = this.beginTimes.size(); i > 0; --i) sb.append(" ");
- sb.append(message);
- this.reporter.report(sb.toString());
- }
-}
diff --git a/src/org/codehaus/janino/util/CausedException.java b/src/org/codehaus/janino/util/CausedException.java
deleted file mode 100644
index efe4249..0000000
--- a/src/org/codehaus/janino/util/CausedException.java
+++ /dev/null
@@ -1,107 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino.util;
-
-import java.io.*;
-import java.lang.reflect.*;
-
-/**
- * For compatibility with pre-1.4 JDKs, this class mimics
- */
-public class CausedException extends Exception {
- private Throwable optionalCause = null;
- private static Method INIT_CAUSE; // Null for pre-1.4 JDKs.
- static {
- try {
- CausedException.INIT_CAUSE = Exception.class.getDeclaredMethod("initCause", new Class[] { Throwable.class });
- } catch (NoSuchMethodException e) {
- CausedException.INIT_CAUSE = null;
- }
- }
-
- public CausedException() {
- }
-
- public CausedException(String message) {
- super(message);
- }
-
- public CausedException(String message, Throwable optionalCause) {
- super(message);
- this.initCause(optionalCause);
- }
-
- public CausedException(Throwable optionalCause) {
- super(optionalCause == null ? null : optionalCause.getMessage());
- this.initCause(optionalCause);
- }
-
- public Throwable initCause(Throwable optionalCause) {
- if (CausedException.INIT_CAUSE == null) {
- this.optionalCause = optionalCause;
- } else
- {
- try {
- CausedException.INIT_CAUSE.invoke(this, new Object[] { optionalCause});
- } catch (IllegalArgumentException e) {
- throw new RuntimeException("Calling \"initCause()\"");
- } catch (IllegalAccessException e) {
- throw new RuntimeException("Calling \"initCause()\"");
- } catch (InvocationTargetException e) {
- throw new RuntimeException("Calling \"initCause()\"");
- }
- }
- return this;
- }
-
- public Throwable getCause() {
- return this.optionalCause;
- }
-
- public void printStackTrace(PrintStream ps) {
- super.printStackTrace(ps);
- if (this.optionalCause == null) return;
-
- ps.print("Caused by: ");
- this.optionalCause.printStackTrace(ps);
- }
- public void printStackTrace(PrintWriter pw) {
- super.printStackTrace(pw);
- if (this.optionalCause == null) return;
-
- pw.print("Caused by: ");
- this.optionalCause.printStackTrace(pw);
- }
-}
diff --git a/src/org/codehaus/janino/util/ClassFile.java b/src/org/codehaus/janino/util/ClassFile.java
deleted file mode 100644
index f3910fe..0000000
--- a/src/org/codehaus/janino/util/ClassFile.java
+++ /dev/null
@@ -1,1514 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino.util;
-
-import java.io.*;
-import java.util.*;
-
-import org.codehaus.janino.Descriptor;
-
-
-/**
- * An object that represents the Java<sup>TM</sup> "class file" format.
- * <p>
- * {@link #ClassFile(InputStream)} creates a {@link ClassFile} object from the bytecode
- * read from the given {@link InputStream}.
- * <p>
- * {@link #store(OutputStream)} generates Java<sup>TM</sup> bytecode
- * which is suitable for being processed by a Java<sup>TM</sup> virtual
- * machine.
- */
-public class ClassFile {
-
- /**
- * Construct from parsed components.
- * @param accessFlags as defined by {@link org.codehaus.janino.Mod}
- * @param thisClassFD the field descriptor for this class
- * @param superclassFD the field descriptor for the extended class (e.g. "Ljava/lang/Object;")
- * @param interfaceFDs the field descriptors for the implemented interfaces
- */
- public ClassFile(
- short accessFlags,
- String thisClassFD,
- String superclassFD,
- String[] interfaceFDs
- ) {
- this.majorVersion = ClassFile.MAJOR_VERSION_JDK_1_1;
- this.minorVersion = ClassFile.MINOR_VERSION_JDK_1_1;
-
- this.constantPool = new ArrayList();
- this.constantPool.add(null); // Add fake "0" index entry.
- this.constantPoolMap = new HashMap();
-
- this.accessFlags = accessFlags;
- this.thisClass = this.addConstantClassInfo(thisClassFD);
- this.superclass = this.addConstantClassInfo(superclassFD);
- this.interfaces = new short[interfaceFDs.length];
- for (int i = 0; i < interfaceFDs.length; ++i) {
- this.interfaces[i] = this.addConstantClassInfo(interfaceFDs[i]);
- }
-
- this.fieldInfos = new ArrayList();
- this.methodInfos = new ArrayList();
- this.attributes = new ArrayList();
- }
-
- /**
- * Adds a "SourceFile" attribute to this class file. (Does not check whether one exists already.)
- * @param sourceFileName
- */
- public void addSourceFileAttribute(String sourceFileName) {
- this.attributes.add(new SourceFileAttribute(
- this.addConstantUtf8Info("SourceFile"), // attributeNameIndex
- this.addConstantUtf8Info(sourceFileName) // sourceFileIndex
- ));
- }
-
- public void addDeprecatedAttribute() {
- this.attributes.add(new DeprecatedAttribute(this.addConstantUtf8Info("Deprecated")));
- }
-
- /**
- * Find the "InnerClasses" attribute of this class file
- * @return <code>null</code> if this class has no "InnerClasses" attribute
- */
- public InnerClassesAttribute getInnerClassesAttribute() {
- Short ni = (Short) this.constantPoolMap.get(new ConstantUtf8Info("InnerClasses"));
- if (ni == null) return null;
-
- for (Iterator it = this.attributes.iterator(); it.hasNext();) {
- AttributeInfo ai = (AttributeInfo) it.next();
- if (ai.nameIndex == ni.shortValue() && ai instanceof InnerClassesAttribute) return (InnerClassesAttribute) ai;
- }
- return null;
- }
-
- /**
- * Create an "InnerClasses" attribute if it does not exist, then add the given entry
- * to the "InnerClasses" attribute.
- * @param e
- */
- public void addInnerClassesAttributeEntry(InnerClassesAttribute.Entry e) {
- InnerClassesAttribute ica = this.getInnerClassesAttribute();
- if (ica == null) {
- ica = new InnerClassesAttribute(this.addConstantUtf8Info("InnerClasses"));
- this.attributes.add(ica);
- }
- ica.getEntries().add(e);
- return;
- }
-
- /**
- * Read "class file" data from a {@link InputStream} and construct a
- * {@link ClassFile} object from it.
- * <p>
- * If the {@link ClassFile} is created with this constructor, then most modifying operations
- * lead to a {@link UnsupportedOperationException}; only fields, methods and
- * attributes can be added.
- * @param inputStream
- * @throws IOException
- * @throws ClassFormatError
- */
- public ClassFile(InputStream inputStream) throws IOException, ClassFormatError {
- DataInputStream dis = inputStream instanceof DataInputStream ? (DataInputStream) inputStream : new DataInputStream(inputStream);
-
- int magic = dis.readInt(); // magic
- if (magic != ClassFile.CLASS_FILE_MAGIC) throw new ClassFormatError("Invalid magic number");
-
- this.minorVersion = dis.readShort(); // minor_version
- this.majorVersion = dis.readShort(); // major_version
- if (!ClassFile.isRecognizedVersion(this.majorVersion, this.minorVersion)) throw new ClassFormatError("Unrecognized class file format version " + this.majorVersion + "/" + this.minorVersion);
-
- this.constantPool = new ArrayList();
- this.constantPoolMap = new HashMap();
- this.loadConstantPool(dis); // constant_pool_count, constant_pool
-
- this.accessFlags = dis.readShort(); // access_flags
- this.thisClass = dis.readShort(); // this_class
- this.superclass = dis.readShort(); // super_class
- this.interfaces = ClassFile.readShortArray(dis); // interfaces_count, interfaces
-
- this.fieldInfos = Collections.unmodifiableList(this.loadFields(dis)); // fields_count, fields
- this.methodInfos = Collections.unmodifiableList(this.loadMethods(dis)); // methods_count, methods
- this.attributes = Collections.unmodifiableList(this.loadAttributes(dis)); // attributes_count, attributes
- }
-
- /**
- * @return The fully qualified name of this class, e.g. "pkg1.pkg2.Outer$Inner"
- */
- public String getThisClassName() {
- return this.getConstantClassName(this.thisClass).replace('/', '.');
- }
-
- /**
- * Sets the major and minor class file version numbers (JVMS 4.1). The class file version
- * defaults to the JDK 1.1 values (45.3) which execute on virtually every JVM.
- * @param majorVersion
- * @param minorVersion
- */
- public void setVersion(short majorVersion, short minorVersion) {
- this.majorVersion = majorVersion;
- this.minorVersion = minorVersion;
- }
-
- /**
- * Returns the current major class file version number.
- */
- public short getMajorVersion() {
- return this.majorVersion;
- }
-
- /**
- * Returns the current minor class file version number.
- */
- public short getMinorVersion() {
- return this.minorVersion;
- }
-
- public static boolean isRecognizedVersion(short majorVersion, short minorVersion) {
- return (
- (majorVersion == ClassFile.MAJOR_VERSION_JDK_1_1 && minorVersion == ClassFile.MINOR_VERSION_JDK_1_1) ||
- (majorVersion == ClassFile.MAJOR_VERSION_JDK_1_2 && minorVersion == ClassFile.MINOR_VERSION_JDK_1_2) ||
- (majorVersion == ClassFile.MAJOR_VERSION_JDK_1_3 && minorVersion == ClassFile.MINOR_VERSION_JDK_1_3) ||
- (majorVersion == ClassFile.MAJOR_VERSION_JDK_1_4 && minorVersion == ClassFile.MINOR_VERSION_JDK_1_4) ||
- (majorVersion == ClassFile.MAJOR_VERSION_JDK_1_5 && minorVersion == ClassFile.MINOR_VERSION_JDK_1_5)
- );
- }
-
- /**
- * Add a "CONSTANT_Class_info" structure to the class file.
- *
- * @see <a href="http://java.sun.com/docs/books/vmspec/2nd-edition/html/ClassFile.doc.html#1221">JVM specification, section 4.4.1</a>
- */
- public short addConstantClassInfo(String typeFD) {
- String s;
- if (Descriptor.isClassOrInterfaceReference(typeFD)) {
- s = Descriptor.toInternalForm(typeFD);
- } else
- if (Descriptor.isArrayReference(typeFD)) {
- s = typeFD;
- } else
- {
- throw new RuntimeException("\"" + Descriptor.toString(typeFD) + "\" is neither a class nor an array");
- }
-
- return this.addToConstantPool(new ConstantClassInfo(this.addConstantUtf8Info(s)));
- }
-
- /**
- * Add a "CONSTANT_Fieldref_info" structure to the class file.
- *
- * @see <a href="http://java.sun.com/docs/books/vmspec/2nd-edition/html/ClassFile.doc.html#42041">JVM specification, section 4.4.2</a>
- */
- public short addConstantFieldrefInfo(
- String classFD,
- String fieldName,
- String fieldFD
- ) {
- return this.addToConstantPool(new ConstantFieldrefInfo(
- this.addConstantClassInfo(classFD),
- this.addConstantNameAndTypeInfo(fieldName, fieldFD)
- ));
- }
-
- /**
- * Add a "CONSTANT_Methodref_info" structure to the class file.
- *
- * @see <a href="http://java.sun.com/docs/books/vmspec/2nd-edition/html/ClassFile.doc.html#42041">JVM specification, section 4.4.2</a>
- */
- public short addConstantMethodrefInfo(
- String classFD,
- String methodName,
- String methodMD
- ) {
- return this.addToConstantPool(new ConstantMethodrefInfo(
- this.addConstantClassInfo(classFD),
- this.addConstantNameAndTypeInfo(methodName, methodMD)
- ));
- }
-
- /**
- * Add a "CONSTANT_InterfaceMethodref_info" structure to the class file.
- *
- * @see <a href="http://java.sun.com/docs/books/vmspec/2nd-edition/html/ClassFile.doc.html#42041">JVM specification, section 4.4.2</a>
- */
- public short addConstantInterfaceMethodrefInfo(
- String classFD,
- String methodName,
- String methodMD
- ) {
- return this.addToConstantPool(new ConstantInterfaceMethodrefInfo(
- this.addConstantClassInfo(classFD),
- this.addConstantNameAndTypeInfo(methodName, methodMD)
- ));
- }
-
- /**
- * Add a "CONSTANT_String_info" structure to the class file.
- *
- * @see <a href="http://java.sun.com/docs/books/vmspec/2nd-edition/html/ClassFile.doc.html#29297">JVM specification, section 4.4.3</a>
- */
- public short addConstantStringInfo(String string) {
- return this.addToConstantPool(new ConstantStringInfo(this.addConstantUtf8Info(string)));
- }
-
- /**
- * Add a "CONSTANT_Integer_info" structure to the class file.
- *
- * @see <a href="http://java.sun.com/docs/books/vmspec/2nd-edition/html/ClassFile.doc.html#21942">JVM specification, section 4.4.4</a>
- */
- public short addConstantIntegerInfo(final int value) {
- return this.addToConstantPool(new ConstantIntegerInfo(value));
- }
-
- /**
- * Add a "CONSTANT_Float_info" structure to the class file.
- *
- * @see <a href="http://java.sun.com/docs/books/vmspec/2nd-edition/html/ClassFile.doc.html#21942">JVM specification, section 4.4.4</a>
- */
- public short addConstantFloatInfo(final float value) {
- return this.addToConstantPool(new ConstantFloatInfo(value));
- }
-
- /**
- * Add a "CONSTANT_Long_info" structure to the class file.
- *
- * @see <a href="http://java.sun.com/docs/books/vmspec/2nd-edition/html/ClassFile.doc.html#1348">JVM specification, section 4.4.5</a>
- */
- public short addConstantLongInfo(final long value) {
- return this.addToConstantPool(new ConstantLongInfo(value));
- }
-
- /**
- * Add a "CONSTANT_Double_info" structure to the class file.
- *
- * @see <a href="http://java.sun.com/docs/books/vmspec/2nd-edition/html/ClassFile.doc.html#1348">JVM specification, section 4.4.5</a>
- */
- public short addConstantDoubleInfo(final double value) {
- return this.addToConstantPool(new ConstantDoubleInfo(value));
- }
-
- /**
- * Add a "CONSTANT_NameAndType_info" structure to the class file.
- *
- * @see <a href="http://java.sun.com/docs/books/vmspec/2nd-edition/html/ClassFile.doc.html#1327">JVM specification, section 4.4.6</a>
- */
- private short addConstantNameAndTypeInfo(String name, String descriptor) {
- return this.addToConstantPool(new ConstantNameAndTypeInfo(
- this.addConstantUtf8Info(name),
- this.addConstantUtf8Info(descriptor)
- ));
- }
-
- /**
- * Add a "CONSTANT_Utf8_info" structure to the class file.
- *
- * @see <a href="http://java.sun.com/docs/books/vmspec/2nd-edition/html/ClassFile.doc.html#7963">JVM specification, section 4.4.7</a>
- */
- public short addConstantUtf8Info(final String s) {
- return this.addToConstantPool(new ConstantUtf8Info(s));
- }
-
- /**
- * Convenience method that adds a String, Integer, Float, Long or Double ConstantInfo.
- */
- private short addConstantSIFLDInfo(Object cv) {
- if (cv instanceof String) {
- return this.addConstantStringInfo((String) cv);
- } else
- if (
- cv instanceof Byte ||
- cv instanceof Short ||
- cv instanceof Integer
- ) {
- return this.addConstantIntegerInfo(((Number) cv).intValue());
- } else
- if (cv instanceof Boolean) {
- return this.addConstantIntegerInfo(((Boolean) cv).booleanValue() ? 1 : 0);
- } else
- if (cv instanceof Character) {
- return this.addConstantIntegerInfo(((Character) cv).charValue());
- } else
- if (cv instanceof Float) {
- return this.addConstantFloatInfo(((Float) cv).floatValue());
- } else
- if (cv instanceof Long) {
- return this.addConstantLongInfo(((Long) cv).longValue());
- } else
- if (cv instanceof Double) {
- return this.addConstantDoubleInfo(((Double) cv).doubleValue());
- } else
- {
- throw new RuntimeException("Unexpected constant value type \"" + cv.getClass().getName() + "\"");
- }
- }
-
- private short addToConstantPool(ConstantPoolInfo cpi) {
- Short index = (Short) this.constantPoolMap.get(cpi);
- if (index != null) return index.shortValue();
-
- short res = (short) this.constantPool.size();
- this.constantPool.add(cpi);
- if (cpi.isWide()) this.constantPool.add(null);
-
- this.constantPoolMap.put(cpi, new Short(res));
- return res;
- }
-
- public FieldInfo addFieldInfo(
- short accessFlags,
- String fieldName,
- String fieldTypeFD,
- Object optionalConstantValue
- ) {
- List attributes = new ArrayList();
- if (optionalConstantValue != null) {
- attributes.add(new ConstantValueAttribute(
- this.addConstantUtf8Info("ConstantValue"),
- this.addConstantSIFLDInfo(optionalConstantValue)
- ));
- }
- FieldInfo fi = new FieldInfo(
- accessFlags, // accessFlags
- this.addConstantUtf8Info(fieldName), // nameIndex
- this.addConstantUtf8Info(fieldTypeFD), // descriptorIndex
- attributes // attributes
- );
- this.fieldInfos.add(fi);
- return fi;
- }
-
- public MethodInfo addMethodInfo(
- short accessFlags,
- String methodName,
- String methodMD
- ) {
- MethodInfo mi = new MethodInfo(
- accessFlags, // accessFlags
- this.addConstantUtf8Info(methodName), // nameIndex
- this.addConstantUtf8Info(methodMD), // desriptorIndex
- new ArrayList() // attributes
- );
- this.methodInfos.add(mi);
- return mi;
- }
-
- public ConstantPoolInfo getConstantPoolInfo(short index) {
- return (ConstantPoolInfo) this.constantPool.get(0xffff & index);
- }
-
- /**
- * @param index Index to a <code>CONSTANT_Class_info</code> in the constant pool
- * @return The name of the denoted class in "internal form" (see JVMS 4.2)
- */
- public String getConstantClassName(short index) {
- ConstantClassInfo cci = (ConstantClassInfo) this.getConstantPoolInfo(index);
- ConstantUtf8Info cui = (ConstantUtf8Info) this.getConstantPoolInfo(cci.nameIndex);
- return cui.s;
- }
-
- /**
- * @param index Index to a <code>CONSTANT_Utf8_info</code> in the constant pool
- * @return The string represented by the structure
- */
- public String getConstantUtf8(short index) {
- ConstantUtf8Info cui = (ConstantUtf8Info) this.getConstantPoolInfo(index);
- return cui.s;
- }
-
- /**
- * u4 length, u1[length]
- */
- private static byte[] readLengthAndBytes(DataInputStream dis) throws IOException {
- byte[] ba = new byte[dis.readInt()];
- dis.readFully(ba);
- return ba;
- }
-
- /**
- * u2 length, u2[length]
- */
- private static short[] readShortArray(DataInputStream dis) throws IOException {
- short count = dis.readShort();
- short[] result = new short[count];
- for (int i = 0; i < count; ++i) result[i] = dis.readShort();
- return result;
- }
-
- /**
- * u2 constant_pool_count, constant_pool[constant_pool_count]
- */
- private void loadConstantPool(DataInputStream dis) throws IOException {
- this.constantPool.clear();
- this.constantPoolMap.clear();
-
- short constantPoolCount = dis.readShort(); // constant_pool_count
- this.constantPool.add(null);
- for (short i = 1; i < constantPoolCount; ++i) {
- ConstantPoolInfo cpi = ConstantPoolInfo.loadConstantPoolInfo(dis);
- this.constantPool.add(cpi);
- this.constantPoolMap.put(cpi, new Short(i));
- if (cpi.isWide()) {
- this.constantPool.add(null);
- ++i;
- }
- }
- }
-
- /**
- * u2 fields_count, fields[fields_count]
- */
- private List loadFields(DataInputStream dis) throws IOException {
- short fieldsCount = dis.readShort();
- List fields = new ArrayList(fieldsCount);
- for (int i = 0; i < fieldsCount; ++i) {
- fields.add(new FieldInfo(
- dis.readShort(), // accessFlags
- dis.readShort(), // nameIndex
- dis.readShort(), // descriptorIndex
- this.loadAttributes(dis) // attributes
- ));
- }
- return fields;
- }
-
- /**
- * u2 methods_count, methods[methods_count]
- */
- private List loadMethods(DataInputStream dis) throws IOException {
- short methodsCount = dis.readShort();
- List methods = new ArrayList(methodsCount);
- for (int i = 0; i < methodsCount; ++i) methods.add(this.loadMethodInfo(dis));
- return methods;
- }
-
- /**
- * u2 attributes_count, attributes[attributes_count]
- */
- private List loadAttributes(DataInputStream dis) throws IOException {
- short attributesCount = dis.readShort();
- List attributes = new ArrayList(attributesCount);
- for (int i = 0; i < attributesCount; ++i) attributes.add(this.loadAttribute(dis));
- return attributes;
- }
-
- /**
- * Write {@link ClassFile} to an {@link OutputStream}, in "class file" format.
- * <p>
- * Notice that if an {@link IOException} is thrown, the class file is
- * probably written incompletely and thus invalid. The calling method must take
- * care of this situation, e.g. by closing the output stream and then deleting the
- * file.
- * @param os
- * @throws IOException
- */
- public void store(OutputStream os) throws IOException {
- DataOutputStream dos = os instanceof DataOutputStream ? (DataOutputStream) os : new DataOutputStream(os);
-
- dos.writeInt(ClassFile.CLASS_FILE_MAGIC); // magic
- dos.writeShort(this.minorVersion); // minor_version
- dos.writeShort(this.majorVersion); // major_version
- ClassFile.storeConstantPool(dos, this.constantPool); // constant_pool_count, constant_pool
- dos.writeShort(this.accessFlags); // access_flags
- dos.writeShort(this.thisClass); // this_class
- dos.writeShort(this.superclass); // super_class
- ClassFile.storeShortArray(dos, this.interfaces); // interfaces_count, interfaces
- ClassFile.storeFields(dos, this.fieldInfos); // fields_count, fields
- ClassFile.storeMethods(dos, this.methodInfos); // methods_count, methods
- ClassFile.storeAttributes(dos, this.attributes); // attributes_count, attributes
- }
-
- /**
- * u2 constant_pool_count, constant_pool[constant_pool_count - 1]
- */
- private static void storeConstantPool(DataOutputStream dos, List constantPool) throws IOException {
- dos.writeShort(constantPool.size());
- for (int i = 1; i < constantPool.size(); ++i) {
- ConstantPoolInfo cpi = (ConstantPoolInfo) constantPool.get(i);
- if (cpi == null) continue; // (Double or Long CPI.)
- cpi.store(dos);
- }
- }
-
- /**
- * u2 count, u2[count]
- */
- private static void storeShortArray(DataOutputStream dos, short[] sa) throws IOException {
- dos.writeShort(sa.length);
- for (int i = 0; i < sa.length; ++i) dos.writeShort(sa[i]);
- }
-
- /**
- * u2 fields_count, fields[fields_count]
- */
- private static void storeFields(DataOutputStream dos, List fieldInfos) throws IOException {
- dos.writeShort(fieldInfos.size());
- for (int i = 0; i < fieldInfos.size(); ++i) ((FieldInfo) fieldInfos.get(i)).store(dos);
- }
-
- /**
- * u2 methods_count, methods[methods_count]
- */
- private static void storeMethods(DataOutputStream dos, List methodInfos) throws IOException {
- dos.writeShort(methodInfos.size());
- for (int i = 0; i < methodInfos.size(); ++i) ((MethodInfo) methodInfos.get(i)).store(dos);
- }
-
- /**
- * u2 attributes_count, attributes[attributes_count]
- */
- private static void storeAttributes(DataOutputStream dos, List attributeInfos) throws IOException {
- dos.writeShort(attributeInfos.size());
- for (int i = 0; i < attributeInfos.size(); ++i) ((AttributeInfo) attributeInfos.get(i)).store(dos);
- }
-
- /**
- * Construct the name of a resource that could contain the source code of
- * the class with the given name.
- * <p>
- * 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"
- */
- public 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";
- }
-
- /**
- * Construct the name of a resource that could contain the class file of the
- * class with the given name.
- *
- * @param className Fully qualified class name, e.g. "pkg1.pkg2.Outer$Inner"
- * @return the name of the resource, e.g. "pkg1/pkg2/Outer$Inner.class"
- */
- public static String getClassFileResourceName(String className) {
- return className.replace('.', '/') + ".class";
- }
-
- /**
- * Return the byte code of this {@link ClassFile} as a byte array.
- */
- public byte[] toByteArray() {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- try {
- this.store(baos);
- } catch (IOException ex) {
- // ByteArrayOutputStream should never throw IOExceptions.
- throw new RuntimeException(ex.toString());
- }
- return baos.toByteArray();
- }
-
- private static final int CLASS_FILE_MAGIC = 0xcafebabe;
-
- public final static short MAJOR_VERSION_JDK_1_1 = 45;
- public final static short MINOR_VERSION_JDK_1_1 = 3;
- public final static short MAJOR_VERSION_JDK_1_2 = 46;
- public final static short MINOR_VERSION_JDK_1_2 = 0;
- public final static short MAJOR_VERSION_JDK_1_3 = 47;
- public final static short MINOR_VERSION_JDK_1_3 = 0;
- public final static short MAJOR_VERSION_JDK_1_4 = 48;
- public final static short MINOR_VERSION_JDK_1_4 = 0;
- public final static short MAJOR_VERSION_JDK_1_5 = 49;
- public final static short MINOR_VERSION_JDK_1_5 = 0;
-
- private short majorVersion;
- private short minorVersion;
- public /*final*/ List constantPool; // ConstantPoolInfo
- public /*final*/ short accessFlags;
- public /*final*/ short thisClass;
- public /*final*/ short superclass;
- public /*final*/ short[] interfaces;
- public /*final*/ List fieldInfos; // FieldInfo
- public /*final*/ List methodInfos; // MethodInfo
- private /*final*/ List attributes; // AttributeInfo
-
- // Convenience.
- private /*final*/ Map constantPoolMap; // ConstantPoolInfo => Short
-
- public static abstract class ConstantPoolInfo {
- abstract public void store(DataOutputStream dos) throws IOException;
- abstract public boolean isWide();
-
- private static ConstantPoolInfo loadConstantPoolInfo(DataInputStream dis) throws IOException {
- byte tag = dis.readByte();
-//System.out.println("tag=" + tag);
- switch (tag) {
-
- case 7:
- return new ConstantClassInfo(dis.readShort());
-
- case 9:
- return new ConstantFieldrefInfo(dis.readShort(), dis.readShort());
-
- case 10:
- return new ConstantMethodrefInfo(dis.readShort(), dis.readShort());
-
- case 11:
- return new ConstantInterfaceMethodrefInfo(dis.readShort(), dis.readShort());
-
- case 8:
- return new ConstantStringInfo(dis.readShort());
-
- case 3:
- return new ConstantIntegerInfo(dis.readInt());
-
- case 4:
- return new ConstantFloatInfo(dis.readFloat());
-
- case 5:
- return new ConstantLongInfo(dis.readLong());
-
- case 6:
- return new ConstantDoubleInfo(dis.readDouble());
-
- case 12:
- return new ConstantNameAndTypeInfo(dis.readShort(), dis.readShort());
-
- case 1:
- return new ConstantUtf8Info(dis.readUTF());
-
- default:
- throw new ClassFormatError("Invalid constant pool tag " + tag);
- }
- }
- }
-
- public static abstract class ConstantValuePoolInfo extends ConstantPoolInfo {
- public abstract Object getValue(ClassFile classFile);
- }
-
- public static class ConstantClassInfo extends ConstantPoolInfo {
- private final short nameIndex;
-
- public ConstantClassInfo(short nameIndex) { this.nameIndex = nameIndex; }
-
- // Implement ConstantPoolInfo.
- public boolean isWide() { return false; }
- public void store(DataOutputStream dos) throws IOException {
- dos.writeByte(7);
- dos.writeShort(this.nameIndex);
- }
- public boolean equals(Object o) {
- return o instanceof ConstantClassInfo && ((ConstantClassInfo) o).nameIndex == this.nameIndex;
- }
- public int hashCode() { return this.nameIndex; }
- }
- public static class ConstantFieldrefInfo extends ConstantPoolInfo {
- private final short classIndex;
- private final short nameAndTypeIndex;
-
- public ConstantFieldrefInfo(short classIndex, short nameAndTypeIndex) {
- this.classIndex = classIndex;
- this.nameAndTypeIndex = nameAndTypeIndex;
- }
-
- public short getNameAndTypeIndex() { return this.nameAndTypeIndex; }
-
- // Implement ConstantPoolInfo.
- public boolean isWide() { return false; }
- public void store(DataOutputStream dos) throws IOException {
- dos.writeByte(9);
- dos.writeShort(this.classIndex);
- dos.writeShort(this.nameAndTypeIndex);
- }
- public boolean equals(Object o) {
- return (
- o instanceof ConstantFieldrefInfo &&
- ((ConstantFieldrefInfo) o).classIndex == this.classIndex &&
- ((ConstantFieldrefInfo) o).nameAndTypeIndex == this.nameAndTypeIndex
- );
- }
- public int hashCode() { return this.classIndex + (this.nameAndTypeIndex << 16); }
- }
- public static class ConstantMethodrefInfo extends ConstantPoolInfo {
- private final short classIndex;
- private final short nameAndTypeIndex;
-
- public ConstantMethodrefInfo(short classIndex, short nameAndTypeIndex) {
- this.classIndex = classIndex;
- this.nameAndTypeIndex = nameAndTypeIndex;
- }
-
- public short getNameAndTypeIndex() { return this.nameAndTypeIndex; }
-
- // Implement ConstantPoolInfo.
- public boolean isWide() { return false; }
- public void store(DataOutputStream dos) throws IOException {
- dos.writeByte(10);
- dos.writeShort(this.classIndex);
- dos.writeShort(this.nameAndTypeIndex);
- }
- public boolean equals(Object o) {
- return (
- o instanceof ConstantMethodrefInfo &&
- ((ConstantMethodrefInfo) o).classIndex == this.classIndex &&
- ((ConstantMethodrefInfo) o).nameAndTypeIndex == this.nameAndTypeIndex
- );
- }
- public int hashCode() { return this.classIndex + (this.nameAndTypeIndex << 16); }
- }
- public static class ConstantInterfaceMethodrefInfo extends ConstantPoolInfo {
- private final short classIndex;
- private final short nameAndTypeIndex;
-
- public ConstantInterfaceMethodrefInfo(short classIndex, short nameAndTypeIndex) {
- this.classIndex = classIndex;
- this.nameAndTypeIndex = nameAndTypeIndex;
- }
-
- public short getNameAndTypeIndex() { return this.nameAndTypeIndex; }
-
- // Implement ConstantPoolInfo.
- public boolean isWide() { return false; }
- public void store(DataOutputStream dos) throws IOException {
- dos.writeByte(11);
- dos.writeShort(this.classIndex);
- dos.writeShort(this.nameAndTypeIndex);
- }
- public boolean equals(Object o) {
- return (
- o instanceof ConstantInterfaceMethodrefInfo &&
- ((ConstantInterfaceMethodrefInfo) o).classIndex == this.classIndex &&
- ((ConstantInterfaceMethodrefInfo) o).nameAndTypeIndex == this.nameAndTypeIndex
- );
- }
- public int hashCode() { return this.classIndex + (this.nameAndTypeIndex << 16); }
- }
- static class ConstantStringInfo extends ConstantValuePoolInfo {
- private final short stringIndex;
-
- public ConstantStringInfo(short stringIndex) {
- this.stringIndex = stringIndex;
- }
-
- // Implement ConstantValuePoolInfo.
- public Object getValue(ClassFile classFile) {
- return classFile.getConstantUtf8(this.stringIndex);
- }
-
- // Implement ConstantPoolInfo.
- public boolean isWide() { return false; }
- public void store(DataOutputStream dos) throws IOException {
- dos.writeByte(8);
- dos.writeShort(this.stringIndex);
- }
- public boolean equals(Object o) {
- return o instanceof ConstantStringInfo && ((ConstantStringInfo) o).stringIndex == this.stringIndex;
- }
- public int hashCode() { return this.stringIndex; }
- }
- private static class ConstantIntegerInfo extends ConstantValuePoolInfo {
- private final int value;
-
- public ConstantIntegerInfo(int value) {
- this.value = value;
- }
-
- // Implement ConstantValuePoolInfo.
- public Object getValue(ClassFile classFile) { return new Integer(this.value); }
-
- // Implement ConstantPoolInfo.
- public boolean isWide() { return false; }
- public void store(DataOutputStream dos) throws IOException {
- dos.writeByte(3);
- dos.writeInt(this.value);
- }
- public boolean equals(Object o) {
- return o instanceof ConstantIntegerInfo && ((ConstantIntegerInfo) o).value == this.value;
- }
- public int hashCode() { return this.value; }
- }
- private static class ConstantFloatInfo extends ConstantValuePoolInfo {
- private final float value;
-
- public ConstantFloatInfo(float value) {
- this.value = value;
- }
-
- // Implement ConstantValuePoolInfo.
- public Object getValue(ClassFile classFile) { return new Float(this.value); }
-
- // Implement ConstantPoolInfo.
- public boolean isWide() { return false; }
- public void store(DataOutputStream dos) throws IOException {
- dos.writeByte(4);
- dos.writeFloat(this.value);
- }
- public boolean equals(Object o) {
- return o instanceof ConstantFloatInfo && ((ConstantFloatInfo) o).value == this.value;
- }
- public int hashCode() { return Float.floatToIntBits(this.value); }
- }
- private static class ConstantLongInfo extends ConstantValuePoolInfo {
- private final long value;
-
- public ConstantLongInfo(long value) {
- this.value = value;
- }
-
- // Implement ConstantValuePoolInfo.
- public Object getValue(ClassFile classFile) { return new Long(this.value); }
-
- // Implement ConstantPoolInfo.
- public boolean isWide() { return true; }
- public void store(DataOutputStream dos) throws IOException {
- dos.writeByte(5);
- dos.writeLong(this.value);
- }
- public boolean equals(Object o) {
- return o instanceof ConstantLongInfo && ((ConstantLongInfo) o).value == this.value;
- }
- public int hashCode() { return (int) this.value ^ (int) (this.value >> 32); }
- }
- private static class ConstantDoubleInfo extends ConstantValuePoolInfo {
- private final double value;
-
- public ConstantDoubleInfo(double value) {
- this.value = value;
- }
-
- // Implement ConstantValuePoolInfo.
- public Object getValue(ClassFile classFile) { return new Double(this.value); }
-
- // Implement ConstantPoolInfo.
- public boolean isWide() { return true; }
- public void store(DataOutputStream dos) throws IOException {
- dos.writeByte(6);
- dos.writeDouble(this.value);
- }
- public boolean equals(Object o) {
- return o instanceof ConstantDoubleInfo && ((ConstantDoubleInfo) o).value == this.value;
- }
- public int hashCode() {
- long bits = Double.doubleToLongBits(this.value);
- return (int) bits ^ (int) (bits >> 32);
- }
- }
- public static class ConstantNameAndTypeInfo extends ConstantPoolInfo {
- private final short nameIndex;
- private final short descriptorIndex;
-
- public ConstantNameAndTypeInfo(short nameIndex, short descriptorIndex) {
- this.nameIndex = nameIndex;
- this.descriptorIndex = descriptorIndex;
- }
-
- public short getDescriptorIndex() { return this.descriptorIndex; }
-
- // Implement ConstantPoolInfo.
- public boolean isWide() { return false; }
- public void store(DataOutputStream dos) throws IOException {
- dos.writeByte(12);
- dos.writeShort(this.nameIndex);
- dos.writeShort(this.descriptorIndex);
- }
- public boolean equals(Object o) {
- return (
- o instanceof ConstantNameAndTypeInfo &&
- ((ConstantNameAndTypeInfo) o).nameIndex == this.nameIndex &&
- ((ConstantNameAndTypeInfo) o).descriptorIndex == this.descriptorIndex
- );
- }
- public int hashCode() { return this.nameIndex + (this.descriptorIndex << 16); }
- }
- public static class ConstantUtf8Info extends ConstantPoolInfo {
- private final String s;
-
- public ConstantUtf8Info(String s) {
- if (s == null) throw new RuntimeException();
- this.s = s;
- }
-
- public String getString() { return this.s; }
-
- // Implement ConstantPoolInfo.
- public boolean isWide() { return false; }
- public void store(DataOutputStream dos) throws IOException {
- dos.writeByte(1);
- try {
- dos.writeUTF(this.s);
- } catch (UTFDataFormatException e) {
- throw new ClassFormatError("String constant too long to store in class file");
- }
- }
- public boolean equals(Object o) {
- return o instanceof ConstantUtf8Info && ((ConstantUtf8Info) o).s.equals(this.s);
- }
- public int hashCode() { return this.s.hashCode(); }
- }
-
- /**
- * This class represents a "method_info" structure, as defined by the
- * JVM specification.
- */
- public class MethodInfo {
- private final short accessFlags;
- private final short nameIndex;
- private final short descriptorIndex;
- private final List attributes; // AttributeInfo
-
- /**
- * Initialize the "method_info" structure.
- */
- public MethodInfo(
- short accessFlags,
- short nameIndex,
- short descriptorIndex,
- List attributes
- ) {
- this.accessFlags = accessFlags;
- this.nameIndex = nameIndex;
- this.descriptorIndex = descriptorIndex;
- this.attributes = attributes;
- }
-
- public ClassFile getClassFile() { return ClassFile.this; }
-
- public short getAccessFlags() { return this.accessFlags; }
- public short getNameIndex() { return this.nameIndex; }
- public short getDescriptorIndex() { return this.descriptorIndex; }
- public AttributeInfo[] getAttributes() { return (AttributeInfo[]) this.attributes.toArray(new AttributeInfo[this.attributes.size()]); }
-
- public void addAttribute(AttributeInfo attribute) {
- this.attributes.add(attribute);
- }
-
- /**
- * Write this object to a {@link DataOutputStream}, in the format
- * defined by the JVM specification.
- */
- public void store(DataOutputStream dos) throws IOException {
- dos.writeShort(this.accessFlags); // access_flags
- dos.writeShort(this.nameIndex); // name_index
- dos.writeShort(this.descriptorIndex); // descriptor_index
- ClassFile.storeAttributes(dos, this.attributes); // attributes_count, attributes
- }
- }
-
- private MethodInfo loadMethodInfo(DataInputStream dis) throws IOException {
- return new MethodInfo(
- dis.readShort(), // accessFlags
- dis.readShort(), // nameIndex
- dis.readShort(), // descriptorIndex
- this.loadAttributes(dis) // attributes
- );
- }
-
- public static class FieldInfo {
- public FieldInfo(
- short accessFlags,
- short nameIndex,
- short descriptorIndex,
- List attributes
- ) {
- this.accessFlags = accessFlags;
- this.nameIndex = nameIndex;
- this.descriptorIndex = descriptorIndex;
- this.attributes = attributes;
- }
-
- public short getAccessFlags() { return this.accessFlags; }
- public short getNameIndex() { return this.nameIndex; }
- public short getDescriptorIndex() { return this.descriptorIndex; }
- public AttributeInfo[] getAttributes() { return (AttributeInfo[]) this.attributes.toArray(new AttributeInfo[this.attributes.size()]); }
-
- public void addAttribute(AttributeInfo attribute) {
- this.attributes.add(attribute);
- }
-
- public void store(DataOutputStream dos) throws IOException {
- dos.writeShort(this.accessFlags); // access_flags
- dos.writeShort(this.nameIndex); // name_index
- dos.writeShort(this.descriptorIndex); // descriptor_index
- ClassFile.storeAttributes(dos, this.attributes); // attibutes_count, attributes
- }
-
- private final short accessFlags;
- private final short nameIndex;
- private final short descriptorIndex;
- private final List attributes; // AttributeInfo
- }
-
- /**
- * Representation of a class file attribute (see JVMS 4.7).
- */
- public abstract static class AttributeInfo {
- public AttributeInfo(short nameIndex) {
- this.nameIndex = nameIndex;
- }
- public void store(DataOutputStream dos) throws IOException {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- this.storeBody(new DataOutputStream(baos));
-
- dos.writeShort(this.nameIndex); // attribute_name_index;
- dos.writeInt(baos.size()); // attribute_length
- baos.writeTo(dos); // info
- }
- protected abstract void storeBody(DataOutputStream dos) throws IOException;
-
- private final short nameIndex;
- }
-
- /**
- * Load one class file attribute. The returned object will be of
- * {@link AttributeInfo}-derived type, depending on the attribute's name; e.g. if the
- * name of the attribute is "SourceFile", then the returned object will be of type
- * {@link SourceFileAttribute}.
- */
- private AttributeInfo loadAttribute(DataInputStream dis) throws IOException {
- short attributeNameIndex = dis.readShort(); // attribute_name_index
- int attributeLength = dis.readInt(); // attribute_length
-
- final byte[] ba = new byte[attributeLength];
- dis.readFully(ba);
- ByteArrayInputStream bais = new ByteArrayInputStream(ba);
- DataInputStream bdis = new DataInputStream(bais);
-
- String attributeName = this.getConstantUtf8(attributeNameIndex);
- AttributeInfo result;
- if ("ConstantValue".equals(attributeName)) {
- result = ConstantValueAttribute.loadBody(attributeNameIndex, bdis);
- } else
- if ("Code".equals(attributeName)) {
- result = CodeAttribute.loadBody(attributeNameIndex, this, bdis);
- } else
- if ("Exceptions".equals(attributeName)) {
- result = ExceptionsAttribute.loadBody(attributeNameIndex, bdis);
- } else
- if ("InnerClasses".equals(attributeName)) {
- result = InnerClassesAttribute.loadBody(attributeNameIndex, bdis);
- } else
- if ("Synthetic".equals(attributeName)) {
- result = SyntheticAttribute.loadBody(attributeNameIndex, bdis);
- } else
- if ("SourceFile".equals(attributeName)) {
- result = SourceFileAttribute.loadBody(attributeNameIndex, bdis);
- } else
- if ("LineNumberTable".equals(attributeName)) {
- result = LineNumberTableAttribute.loadBody(attributeNameIndex, bdis);
- } else
- if ("LocalVariableTable".equals(attributeName)) {
- result = LocalVariableTableAttribute.loadBody(attributeNameIndex, bdis);
- } else
- if ("Deprecated".equals(attributeName)) {
- result = DeprecatedAttribute.loadBody(attributeNameIndex, bdis);
- } else
- {
- return new AttributeInfo(attributeNameIndex) {
- protected void storeBody(DataOutputStream dos) throws IOException { dos.write(ba); }
- };
- }
-
- if (bais.available() > 0) throw new ClassFormatError((ba.length - bais.available()) + " bytes of trailing garbage in body of attribute \"" + attributeName + "\"");
-
- return result;
- }
-
- /**
- * Representation of a "ConstantValue" attribute (see JVMS 4.7.2).
- */
- public static class ConstantValueAttribute extends AttributeInfo {
- private final short constantValueIndex;
-
- ConstantValueAttribute(short attributeNameIndex, short constantValueIndex) {
- super(attributeNameIndex);
- this.constantValueIndex = constantValueIndex;
- }
-
- public short getConstantValueIndex() { return this.constantValueIndex; }
-
- private static AttributeInfo loadBody(short attributeNameIndex, DataInputStream dis) throws IOException {
- return new ConstantValueAttribute(
- attributeNameIndex, // attributeNameIndex
- dis.readShort() // constantValueIndex
- );
- }
-
- // Implement "AttributeInfo".
- protected void storeBody(DataOutputStream dos) throws IOException {
- dos.writeShort(this.constantValueIndex);
- }
- }
-
- /**
- * Representation of an "Exceptions" attribute (see JVMS 4.7.4).
- */
- public static class ExceptionsAttribute extends AttributeInfo {
- private final short[] exceptionIndexes;
-
- public ExceptionsAttribute(short attributeNameIndex, short[] exceptionIndexes) {
- super(attributeNameIndex);
- this.exceptionIndexes = exceptionIndexes;
- }
-
- public short[] getExceptionIndexes() {
- short[] eis = new short[this.exceptionIndexes.length];
- System.arraycopy(this.exceptionIndexes, 0, eis, 0, eis.length);
- return eis;
- }
-
- private static AttributeInfo loadBody(short attributeNameIndex, DataInputStream dis) throws IOException {
- return new ExceptionsAttribute(
- attributeNameIndex, // attributeNameIndex
- ClassFile.readShortArray(dis) // exceptionIndexes
- );
- }
-
- // Implement "AttributeInfo".
- protected void storeBody(DataOutputStream dos) throws IOException {
- ClassFile.storeShortArray(dos, this.exceptionIndexes);
- }
- }
-
- /**
- * Representation of an "InnerClasses" attribute (see JVMS 4.7.5).
- */
- public static class InnerClassesAttribute extends AttributeInfo {
- private final List entries; // InnerClassesAttribute.Entry
-
- InnerClassesAttribute(short attributeNameIndex) {
- super(attributeNameIndex);
- this.entries = new ArrayList();
- }
- InnerClassesAttribute(short attributeNameIndex, Entry[] entries) {
- super(attributeNameIndex);
- this.entries = new ArrayList(Arrays.asList(entries));
- }
-
- public List getEntries() {
- return this.entries;
- }
-
- private static AttributeInfo loadBody(short attributeNameIndex, DataInputStream dis) throws IOException {
- Entry[] ics = new Entry[dis.readShort()]; // number_of_classes
- for (short i = 0; i < ics.length; ++i) { // classes
- ics[i] = new InnerClassesAttribute.Entry(
- dis.readShort(), // innerClassInfoIndex
- dis.readShort(), // outerClassInfoIndex
- dis.readShort(), // innerNameIndex
- dis.readShort() // innerClassAccessFlags
- );
- }
- return new InnerClassesAttribute(attributeNameIndex, ics);
- }
-
- // Implement "AttributeInfo".
- protected void storeBody(DataOutputStream dos) throws IOException {
- dos.writeShort(this.entries.size());
- for (Iterator it = this.entries.iterator(); it.hasNext();) {
- Entry e = (Entry) it.next();
- dos.writeShort(e.innerClassInfoIndex);
- dos.writeShort(e.outerClassInfoIndex);
- dos.writeShort(e.innerNameIndex);
- dos.writeShort(e.innerClassAccessFlags);
- }
- }
-
- public static class Entry {
- public final short innerClassInfoIndex, outerClassInfoIndex, innerNameIndex, innerClassAccessFlags;
-
- public Entry(short innerClassInfoIndex, short outerClassInfoIndex, short innerNameIndex, short innerClassAccessFlags) {
- this.innerClassInfoIndex = innerClassInfoIndex;
- this.outerClassInfoIndex = outerClassInfoIndex;
- this.innerNameIndex = innerNameIndex;
- this.innerClassAccessFlags = innerClassAccessFlags;
- }
- }
- }
-
- /**
- * Representation of a "Synthetic" attribute (see JVMS 4.7.6).
- */
- public static class SyntheticAttribute extends AttributeInfo {
- SyntheticAttribute(short attributeNameIndex) {
- super(attributeNameIndex);
- }
-
- private static AttributeInfo loadBody(short attributeNameIndex, DataInputStream dis) {
- return new SyntheticAttribute(
- attributeNameIndex // attributeNameIndex
- );
- }
-
- // Implement "AttributeInfo".
- protected void storeBody(DataOutputStream dos) throws IOException {
- }
- }
-
- /**
- * Representation of a "SourceFile" attribute (see JVMS 4.7.7).
- */
- public static class SourceFileAttribute extends AttributeInfo {
- private final short sourceFileIndex;
-
- public SourceFileAttribute(short attributeNameIndex, short sourceFileIndex) {
- super(attributeNameIndex);
- this.sourceFileIndex = sourceFileIndex;
- }
-
- private static AttributeInfo loadBody(short attributeNameIndex, DataInputStream dis) throws IOException {
- return new SourceFileAttribute(
- attributeNameIndex, // attributeNameIndex
- dis.readShort() // sourceFileNameIndex
- );
- }
-
- // Implement "AttributeInfo".
- protected void storeBody(DataOutputStream dos) throws IOException {
- dos.writeShort(this.sourceFileIndex);
- }
- }
-
- /**
- * Representation of a "LineNumberTable" attribute (see JVMS 4.7.8).
- */
- public static class LineNumberTableAttribute extends AttributeInfo {
- private final Entry[] entries;
-
- public LineNumberTableAttribute(short attributeNameIndex, Entry[] entries) {
- super(attributeNameIndex);
- this.entries = entries;
- }
-
- private static AttributeInfo loadBody(short attributeNameIndex, DataInputStream dis) throws IOException {
- Entry[] lntes = new Entry[dis.readShort()]; // line_number_table_length
- for (short i = 0; i < lntes.length; ++i) { // line_number_table
- lntes[i] = new LineNumberTableAttribute.Entry(
- dis.readShort(), // startPC
- dis.readShort() // lineNumber
- );
- }
- return new LineNumberTableAttribute(attributeNameIndex, lntes);
- }
-
- // Implement "AttributeInfo".
- protected void storeBody(DataOutputStream dos) throws IOException {
- dos.writeShort(this.entries.length); // line_number_table_length
- for (int i = 0; i < this.entries.length; ++i) {
- dos.writeShort(this.entries[i].startPC);
- dos.writeShort(this.entries[i].lineNumber);
- }
- }
-
- public static class Entry {
- public final int startPC, lineNumber;
- public Entry(int startPC, int lineNumber) {
- this.startPC = startPC;
- this.lineNumber = lineNumber;
- }
- }
- }
-
- /**
- * Representation of a "LocalVariableTable" attribute (see JVMS 4.7.9).
- */
- public static class LocalVariableTableAttribute extends AttributeInfo {
- private final Entry[] entries;
-
- LocalVariableTableAttribute(short attributeNameIndex, Entry[] entries) {
- super(attributeNameIndex);
- this.entries = entries;
- }
-
- private static AttributeInfo loadBody(short attributeNameIndex, DataInputStream dis) throws IOException {
- short localVariableTableLength = dis.readShort();
- Entry[] lvtes = new Entry[localVariableTableLength]; // local_variable_table_length
- for (short i = 0; i < localVariableTableLength; ++i) { // local_variable_table
- lvtes[i] = new LocalVariableTableAttribute.Entry(
- dis.readShort(), // startPC
- dis.readShort(), // length
- dis.readShort(), // nameIndex
- dis.readShort(), // descriptorIndex
- dis.readShort() // index
- );
- }
- return new LocalVariableTableAttribute(attributeNameIndex, lvtes);
- }
- // Implement "AttributeInfo".
- protected void storeBody(DataOutputStream dos) throws IOException {
- dos.writeShort(this.entries.length); // local_variable_table_length
- for (int i = 0; i < this.entries.length; ++i) { // local_variable_table
- Entry lnte = this.entries[i];
- dos.writeShort(lnte.startPC); // start_pc;
- dos.writeShort(lnte.length); // length
- dos.writeShort(lnte.nameIndex); // name_index
- dos.writeShort(lnte.descriptorIndex); // descriptor_index
- dos.writeShort(lnte.index); // index
- }
- }
-
- public static class Entry {
- public final short startPC, length, nameIndex, descriptorIndex, index;
-
- public Entry(
- short startPC,
- short length,
- short nameIndex,
- short descriptorIndex,
- short index
- ) {
- this.startPC = startPC;
- this.length = length;
- this.nameIndex = nameIndex;
- this.descriptorIndex = descriptorIndex;
- this.index = index;
- }
- }
- }
-
- /**
- * Representation of a "Deprecated" attribute (see JVMS 4.7.10).
- */
- public static class DeprecatedAttribute extends AttributeInfo {
- public DeprecatedAttribute(short attributeNameIndex) {
- super(attributeNameIndex);
- }
-
- private static AttributeInfo loadBody(short attributeNameIndex, DataInputStream dis) {
- return new DeprecatedAttribute(attributeNameIndex);
- }
-
- // Implement "AttributeInfo".
- protected void storeBody(DataOutputStream dos) throws IOException {
- }
- }
-
- /**
- * Representation of an unmodifiable "Code" attribute, as read from a class file.
- */
- private static class CodeAttribute extends AttributeInfo {
- private final short maxStack;
- private final short maxLocals;
- private final byte[] code;
- private final ExceptionTableEntry[] exceptionTableEntries;
- private final AttributeInfo[] attributes;
-
- private CodeAttribute(
- short attributeNameIndex,
- short maxStack,
- short maxLocals,
- byte[] code,
- ExceptionTableEntry[] exceptionTableEntries,
- AttributeInfo[] attributes
- ) {
- super(attributeNameIndex);
- this.maxStack = maxStack;
- this.maxLocals = maxLocals;
- this.code = code;
- this.exceptionTableEntries = exceptionTableEntries;
- this.attributes = attributes;
- }
-
- public static AttributeInfo loadBody(short attributeNameIndex, ClassFile classFile, DataInputStream dis) throws IOException {
- short maxStack = dis.readShort(); // max_stack
- short maxLocals = dis.readShort(); // max_locals
- byte[] code = ClassFile.readLengthAndBytes(dis); // code_length, code
-
- ExceptionTableEntry[] etes = new ExceptionTableEntry[dis.readShort()]; // exception_table_length
- for (int i = 0; i < etes.length; ++i) { // exception_table
- etes[i] = new ExceptionTableEntry(
- dis.readShort(), // startPC
- dis.readShort(), // endPC
- dis.readShort(), // handlerPC
- dis.readShort() // catchType
- );
- }
-
- AttributeInfo[] attributes = new AttributeInfo[dis.readShort()]; // attributes_count
- for (int i = 0; i < attributes.length; ++i) { // attributes
- attributes[i] = classFile.loadAttribute(dis);
- }
-
- return new CodeAttribute(
- attributeNameIndex, // attributeNameIndex
- maxStack, // maxStack
- maxLocals, // maxLocals
- code, // code
- etes, // exceptionTableEntries
- attributes // attributes
- );
- }
-
- protected void storeBody(DataOutputStream dos) throws IOException {
- dos.writeShort(this.maxStack); // max_stack
- dos.writeShort(this.maxLocals); // max_locals
- dos.writeInt(this.code.length); // code_length
- dos.write(this.code); // code
- dos.writeShort(this.exceptionTableEntries.length); // exception_table_length
- for (int i = 0; i < this.exceptionTableEntries.length; ++i) { // exception_table
- ExceptionTableEntry ete = this.exceptionTableEntries[i];
- dos.writeShort(ete.startPC ); // start_pc
- dos.writeShort(ete.endPC ); // end_pc
- dos.writeShort(ete.handlerPC); // handler_pc
- dos.writeShort(ete.catchType); // catch_type
- }
- dos.writeShort(this.attributes.length); // attributes_count
- for (int i = 0; i < this.attributes.length; ++i) { // attributes
- this.attributes[i].store(dos);
- }
- }
-
- /**
- * Representation of an entry in the "exception_table" of a "Code" attribute (see JVMS
- * 4.7.3).
- */
- private static class ExceptionTableEntry {
- private final short startPC, endPC, handlerPC, catchType;
-
- public ExceptionTableEntry(
- short startPC,
- short endPC,
- short handlerPC,
- short catchType
- ) {
- this.startPC = startPC;
- this.endPC = endPC;
- this.handlerPC = handlerPC;
- this.catchType = catchType;
- }
- }
- }
-}
diff --git a/src/org/codehaus/janino/util/LocatedException.java b/src/org/codehaus/janino/util/LocatedException.java
deleted file mode 100644
index a192444..0000000
--- a/src/org/codehaus/janino/util/LocatedException.java
+++ /dev/null
@@ -1,70 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino.util;
-
-import org.codehaus.janino.Location;
-
-/**
- * An {@link Exception} that is associated with an optional {@link Location} in a source file.
- */
-public class LocatedException extends CausedException {
- private final Location optionalLocation;
-
- public LocatedException(String message, Location optionalLocation) {
- super(message);
- this.optionalLocation = optionalLocation;
- }
-
- public LocatedException(String message, Location optionalLocation, Throwable optionalCause) {
- super(message, optionalCause);
- this.optionalLocation = optionalLocation;
- }
-
- /**
- * Returns the message specified at creation time, preceeded with nicely formatted location
- * information (if any).
- */
- public String getMessage() {
- return this.optionalLocation == null ? super.getMessage() : this.optionalLocation.toString() + ": " + super.getMessage();
- }
-
- /**
- * Returns the {@link Location} object specified at
- * construction time (may be <code>null</code>).
- */
- public Location getLocation() {
- return this.optionalLocation;
- }
-}
\ No newline at end of file
diff --git a/src/org/codehaus/janino/util/MultiIterator.java b/src/org/codehaus/janino/util/MultiIterator.java
deleted file mode 100644
index 921239d..0000000
--- a/src/org/codehaus/janino/util/MultiIterator.java
+++ /dev/null
@@ -1,163 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino.util;
-
-import java.util.*;
-
-/**
- * An {@link java.util.Iterator} that traverses a {@link java.util.Collection} of
- * {@link java.util.Iterator}s.
- */
-public class MultiIterator implements Iterator {
- private static final Iterator AT_END = new Iterator() {
- public boolean hasNext() { return false; }
- public Object next() { throw new NoSuchElementException(); }
- public void remove() { throw new UnsupportedOperationException(); }
- };
-
- private final Iterator outer; // Over Iterators, Collections or arrays
- private Iterator inner = MultiIterator.AT_END;
-
- /**
- * @param iterators An array of {@link Iterator}s
- */
- public MultiIterator(Iterator[] iterators) {
- this.outer = Arrays.asList(iterators).iterator();
- }
-
- /**
- * @param collections An array of {@link Collection}s
- */
- public MultiIterator(Collection[] collections) {
- this.outer = Arrays.asList(collections).iterator();
- }
-
- /**
- * @param arrays An array of arrays
- */
- public MultiIterator(Object[][] arrays) {
- this.outer = Arrays.asList(arrays).iterator();
- }
-
- /**
- * @param collection A {@link Collection} of {@link Collection}s, {@link Iterator}s and/or arrays
- */
- public MultiIterator(Collection collection) {
- this.outer = collection.iterator();
- }
-
- /**
- * @param iterator An iterator over {@link Collection}s, {@link Iterator}s and/or arrays
- */
- public MultiIterator(Iterator iterator) {
- this.outer = iterator;
- }
-
- /**
- * @param array An array of {@link Collection}s, {@link Iterator}s and/or arrays
- */
- public MultiIterator(Object[] array) {
- this.outer = Arrays.asList(array).iterator();
- }
-
- /**
- * Iterates over the given {@link Collection}, prepended with the given {@link Object}.
- */
- public MultiIterator(Object object, Collection collection) {
- this.outer = Arrays.asList(new Object[] {
- new Object[] { object },
- collection
- }).iterator();
- }
-
- /**
- * Iterates over the given {@link Collection}, appended with the given {@link Object}.
- */
- public MultiIterator(Collection collection, Object object) {
- this.outer = Arrays.asList(new Object[] {
- collection,
- new Object[] { object }
- }).iterator();
- }
-
- /**
- * Iterates over the given {@link Iterator}, prepended with the given <code>prefix</code>.
- */
- public MultiIterator(Object prefix, Iterator iterator) {
- this.outer = Arrays.asList(new Object[] {
- new Object[] { prefix },
- iterator
- }).iterator();
- }
-
- /**
- * Iterates over the given {@link Iterator}, appended with the given <code>suffix</code>.
- */
- public MultiIterator(Iterator iterator, Object suffix) {
- this.outer = Arrays.asList(new Object[] {
- iterator,
- new Object[] { suffix }
- }).iterator();
- }
-
- public boolean hasNext() {
- for (;;) {
- if (this.inner.hasNext()) return true;
- if (!this.outer.hasNext()) return false;
- Object o = this.outer.next();
- if (o instanceof Iterator) {
- this.inner = (Iterator) o;
- } else
- if (o instanceof Collection) {
- this.inner = ((Collection) o).iterator();
- } else
- if (o instanceof Object[]) {
- this.inner = Arrays.asList((Object[]) o).iterator();
- } else
- {
- throw new RuntimeException("Unexpected element type \"" + o.getClass().getName() + "\"");
- }
- }
- }
-
- public Object next() {
- if (this.hasNext()) return this.inner.next();
- throw new NoSuchElementException();
- }
-
- public void remove() {
- this.inner.remove();
- }
-}
diff --git a/src/org/codehaus/janino/util/PrimitiveWrapper.java b/src/org/codehaus/janino/util/PrimitiveWrapper.java
deleted file mode 100644
index a52e04c..0000000
--- a/src/org/codehaus/janino/util/PrimitiveWrapper.java
+++ /dev/null
@@ -1,50 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino.util;
-
-/**
- * A helper class that wraps primitive values in their wrapper classes.
- */
-public class PrimitiveWrapper {
- public static Boolean wrap(boolean v) { return v ? Boolean.TRUE : Boolean.FALSE; }
- public static Byte wrap(byte v) { return new Byte(v); }
- public static Short wrap(short v) { return new Short(v); }
- public static Integer wrap(int v) { return new Integer(v); }
- public static Long wrap(long v) { return new Long(v); }
- public static Character wrap(char v) { return new Character(v); }
- public static Float wrap(float v) { return new Float(v); }
- public static Double wrap(double v) { return new Double(v); }
- public static Object wrap(Object v) { return v; }
-}
diff --git a/src/org/codehaus/janino/util/Producer.java b/src/org/codehaus/janino/util/Producer.java
deleted file mode 100644
index 3e24444..0000000
--- a/src/org/codehaus/janino/util/Producer.java
+++ /dev/null
@@ -1,57 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino.util;
-
-/**
- * An object that produces some {@link java.lang.Object} each time the
- * {@link #produce()} method is invoked. This behavior is similar to the
- * {@link java.util.Iterator}, but is represented by one single
- * {@link #produce()} method as opposed to {@link java.util.Iterator}'s
- * two methods {@link java.util.Iterator#hasNext()} and
- * {@link java.util.Iterator#next()}. This simplifies the implementation of
- * certain complex iterations.
- *
- * @see org.codehaus.janino.util.iterator.DirectoryIterator
- * @see org.codehaus.janino.util.iterator.ProducerIterator
- */
-public interface Producer {
-
- /**
- * Produce the next object.
- *
- * @return the next object or <code>null</code> to indicate that no more objects can be produced
- */
- Object produce();
-}
diff --git a/src/org/codehaus/janino/util/ResourceFinderClassLoader.java b/src/org/codehaus/janino/util/ResourceFinderClassLoader.java
deleted file mode 100644
index 23da2a6..0000000
--- a/src/org/codehaus/janino/util/ResourceFinderClassLoader.java
+++ /dev/null
@@ -1,120 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino.util;
-
-import java.io.*;
-
-import org.codehaus.janino.tools.Disassembler;
-import org.codehaus.janino.util.resource.*;
-
-
-/**
- * A {@link ClassLoader} that uses a {@link org.codehaus.janino.util.resource.ResourceFinder}
- * to find ".class" files.
- */
-public class ResourceFinderClassLoader extends ClassLoader {
- private final static boolean DEBUG = false;
-
- private final ResourceFinder resourceFinder;
-
- public ResourceFinderClassLoader(ResourceFinder resourceFinder, ClassLoader parent) {
- super(parent);
- this.resourceFinder = resourceFinder;
- }
-
- public ResourceFinder getResourceFinder() {
- return this.resourceFinder;
- }
-
- /**
- * @throws ClassNotFoundException
- */
- protected Class findClass(String className) throws ClassNotFoundException {
-
- // Find the resource containing the class bytecode.
- Resource classFileResource = this.resourceFinder.findResource(ClassFile.getClassFileResourceName(className));
- if (classFileResource == null) throw new ClassNotFoundException(className);
-
- // Open the class file resource.
- InputStream is;
- try {
- is = classFileResource.open();
- } catch (IOException ex) {
- throw new RuntimeException("Opening class file resource \"" + classFileResource.getFileName() + "\": " + ex.getMessage());
- }
-
- // Read bytecode from the resource into a byte array.
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- try {
- byte[] buffer = new byte[4096];
- for (;;) {
- int bytesRead = is.read(buffer);
- if (bytesRead == -1) break;
- baos.write(buffer, 0, bytesRead);
- }
- } catch (IOException ex) {
- throw new ClassNotFoundException("Reading class file from \"" + classFileResource + "\"", ex);
- } finally {
- try { is.close(); } catch (IOException ex) {}
- }
- byte[] ba = baos.toByteArray();
-
- // Disassemble the the class bytecode(for debugging).
- if (ResourceFinderClassLoader.DEBUG) {
- System.out.println("*** Disassembly of class \"" + className + "\":");
- try {
- new Disassembler().disasm(new ByteArrayInputStream(ba));
- System.out.flush();
- } catch (IOException ex) {
- throw new RuntimeException("SNO: IOException despite ByteArrayInputStream");
- }
- }
-
- // Define the class in this ClassLoader.
- Class clazz = super.defineClass(null, ba, 0, ba.length);
-
- if (!clazz.getName().equals(className)) {
-
- // This is a really complicated case: We may find a class file on
- // the class path that seemingly defines the class we are looking
- // for, but doesn't. This is possible if the underlying file system
- // has case-insensitive file names and/or file names that are
- // limited in length (e.g. DOS 8.3).
- throw new ClassNotFoundException(className);
- }
-
- return clazz;
- }
-}
diff --git a/src/org/codehaus/janino/util/StringPattern.java b/src/org/codehaus/janino/util/StringPattern.java
deleted file mode 100644
index 366b39a..0000000
--- a/src/org/codehaus/janino/util/StringPattern.java
+++ /dev/null
@@ -1,191 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino.util;
-
-import java.util.*;
-
-/**
- * Implementation of a UNIX shell-like string pattern algorithm.
- * <p>
- * Additionally, the concept of the "combined pattern" is supported (see
- * {@link #matches(StringPattern[], String)}.
- */
-public class StringPattern {
-
- /**
- * @see #matches(StringPattern[], String)
- */
- public final static int INCLUDE = 0;
-
- /**
- * @see #matches(StringPattern[], String)
- */
- public final static int EXCLUDE = 1;
-
- private final int mode;
- private final String pattern;
-
- public StringPattern(int mode, String pattern) {
- this.mode = mode;
- this.pattern = pattern;
- }
-
- public StringPattern(String pattern) {
- this.mode = StringPattern.INCLUDE;
- this.pattern = pattern;
- }
-
- public int getMode() { return this.mode; }
-
- /**
- * Match the given <code>text</code> against the pattern represented by the current instance,
- * as follows:
- * <ul>
- * <li>
- * A <code>*</code> in the pattern matches any sequence of zero or more characters in the
- * <code>text</code>
- * </li>
- * <li>
- * A <code>?</code> in the pattern matches exactly one character in the <code>text</code>
- * </li>
- * <li>
- * Any other character in the pattern must appear exactly as it is in the <code>text</code>
- * </ul>
- * Notice: The <code>mode</code> flag of the current instance does not take any effect here.
- */
- public boolean matches(String text) {
- return StringPattern.wildmatch(this.pattern, text);
- }
-
- /**
- * Parse a "combined pattern" into an array of {@link StringPattern}s. A combined pattern
- * string is structured as follows:
- * <pre>
- * combined-pattern :=
- * [ '+' | '-' ] pattern
- * { ( '+' | '-' ) pattern }
- * </pre>
- * If a pattern is preceeded with a '-', then the {@link StringPattern} is created with mode
- * {@link #EXCLUDE}, otherwise with mode {@link #INCLUDE}.
- */
- public static StringPattern[] parseCombinedPattern(String combinedPattern) {
- ArrayList al = new ArrayList();
- for (int k = 0, l; k < combinedPattern.length(); k = l) {
- int patternMode;
- char c = combinedPattern.charAt(k);
- if (c == '+') {
- patternMode = StringPattern.INCLUDE;
- ++k;
- } else
- if (c == '-') {
- patternMode = StringPattern.EXCLUDE;
- ++k;
- } else {
- patternMode = StringPattern.INCLUDE;
- }
- for (l = k; l < combinedPattern.length(); ++l) {
- c = combinedPattern.charAt(l);
- if (c == '+' || c == '-') break;
- }
- al.add(new StringPattern(patternMode, combinedPattern.substring(k, l)));
- }
- return (StringPattern[]) al.toArray(new StringPattern[al.size()]);
- }
-
- /**
- * Match a given <code>text</code> against an array of {@link StringPattern}s (which was
- * typically created by {@link #parseCombinedPattern(String)}.
- * <p>
- * The last matching pattern takes effect; if its mode is {@link #INCLUDE}, then
- * <code>true</code> is returned, if its mode is {@link #EXCLUDE}, then <code>false</code> is
- * returned.
- * <p>
- * If <code>patterns</code> is {@link #PATTERNS_NONE}, or empty, or none of its patterns
- * matches, then <code>false</code> is returned.
- * <p>
- * If <code>patterns</code> is {@link #PATTERNS_ALL}, then <code>true</code> is
- * returned.
- * <p>
- * For backwards compatibility, <code>null</code> patterns are treated like
- * {@link #PATTERNS_NONE}.
- */
- public static boolean matches(StringPattern[] patterns, String text) {
- if (patterns == null) return false; // Backwards compatibility -- previously, "null" was officially documented.
-
- for (int i = patterns.length - 1; i >= 0; --i) {
- if (patterns[i].matches(text)) {
- return patterns[i].getMode() == StringPattern.INCLUDE;
- }
- }
- return false; // No patterns defined or no pattern matches.
- }
- public static StringPattern[] PATTERNS_ALL = new StringPattern[] { new StringPattern("*") };
- public static StringPattern[] PATTERNS_NONE = new StringPattern[0];
-
- public String toString() {
- return (
- this.mode == StringPattern.INCLUDE ? '+' :
- this.mode == StringPattern.EXCLUDE ? '-' :
- '?'
- ) + this.pattern;
- }
-
- private static boolean wildmatch(String pattern, String text) {
- int i;
- for (i = 0; i < pattern.length(); ++i) {
- char c = pattern.charAt(i);
- switch (c) {
-
- case '?':
- if (i == text.length()) return false;
- break;
-
- case '*':
- if (pattern.length() == i + 1) return true; // Optimization for trailing '*'.
- pattern = pattern.substring(i + 1);
- for (; i <= text.length(); ++i) {
- if (StringPattern.wildmatch(pattern, text.substring(i))) return true;
- }
- return false;
-
- default:
- if (i == text.length()) return false;
- if (text.charAt(i) != c) return false;
- break;
- }
- }
- return text.length() == i;
- }
-}
\ No newline at end of file
diff --git a/src/org/codehaus/janino/util/TeeReader.java b/src/org/codehaus/janino/util/TeeReader.java
deleted file mode 100644
index a519281..0000000
--- a/src/org/codehaus/janino/util/TeeReader.java
+++ /dev/null
@@ -1,82 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino.util;
-
-import java.io.*;
-
-/**
- * A {@link java.io.FilterReader} that copies the bytes being passed through
- * to a given {@link java.io.Writer}. This is in analogy with the UNIX "tee" command.
- */
-public class TeeReader extends FilterReader {
- private final Writer out;
- private final boolean closeWriterOnEOF;
-
- public TeeReader(Reader in, Writer out, boolean closeWriterOnEOF) {
- super(in);
- this.out = out;
- this.closeWriterOnEOF = closeWriterOnEOF;
- }
- public void close() throws IOException {
- this.in.close();
- this.out.close();
- }
- public int read() throws IOException {
- int c = this.in.read();
- if (c == -1) {
- if (this.closeWriterOnEOF) {
- this.out.close();
- } else {
- this.out.flush();
- }
- } else {
- this.out.write(c);
- }
- return c;
- }
- public int read(char[] cbuf, int off, int len) throws IOException {
- int bytesRead = this.in.read(cbuf, off, len);
- if (bytesRead == -1) {
- if (this.closeWriterOnEOF) {
- this.out.close();
- } else {
- this.out.flush();
- }
- } else {
- this.out.write(cbuf, off, bytesRead);
- }
- return bytesRead;
- }
-}
diff --git a/src/org/codehaus/janino/util/Traverser.java b/src/org/codehaus/janino/util/Traverser.java
deleted file mode 100644
index 4b4d92b..0000000
--- a/src/org/codehaus/janino/util/Traverser.java
+++ /dev/null
@@ -1,599 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino.util;
-
-import org.codehaus.janino.*;
-import org.codehaus.janino.Java.CompilationUnit.*;
-import org.codehaus.janino.Visitor.ComprehensiveVisitor;
-
-import java.util.*;
-
-/**
- * This class traverses the subnodes of an AST. Derived classes may override
- * individual methods to process specific nodes, e.g.:<pre>
- * LocalClassDeclaration lcd = ...;
- * lcd.accept(new Traverser() {
- * int n = 0;
- * public void traverseMethodDeclarator(Java.MethodDeclarator md) {
- * ++this.n;
- * super.traverseMethodDeclarator(md);
- * }
- * }.comprehensiveVisitor());</pre>
- */
-public class Traverser {
- private final Visitor.ComprehensiveVisitor cv = new Visitor.ComprehensiveVisitor() {
- public final void visitSingleTypeImportDeclaration(Java.CompilationUnit.SingleTypeImportDeclaration stid) { Traverser.this.traverseSingleTypeImportDeclaration(stid); }
- public final void visitTypeImportOnDemandDeclaration(Java.CompilationUnit.TypeImportOnDemandDeclaration tiodd) { Traverser.this.traverseTypeImportOnDemandDeclaration(tiodd); }
- public final void visitSingleStaticImportDeclaration(SingleStaticImportDeclaration ssid) { Traverser.this.traverseSingleStaticImportDeclaration(ssid); }
- public final void visitStaticImportOnDemandDeclaration(StaticImportOnDemandDeclaration siodd) { Traverser.this.traverseStaticImportOnDemandDeclaration(siodd); }
- public final void visitAnonymousClassDeclaration(Java.AnonymousClassDeclaration acd) { Traverser.this.traverseAnonymousClassDeclaration(acd); }
- public final void visitLocalClassDeclaration(Java.LocalClassDeclaration lcd) { Traverser.this.traverseLocalClassDeclaration(lcd); }
- public final void visitPackageMemberClassDeclaration(Java.PackageMemberClassDeclaration pmcd) { Traverser.this.traversePackageMemberClassDeclaration(pmcd); }
- public final void visitMemberInterfaceDeclaration(Java.MemberInterfaceDeclaration mid) { Traverser.this.traverseMemberInterfaceDeclaration(mid); }
- public final void visitPackageMemberInterfaceDeclaration(Java.PackageMemberInterfaceDeclaration pmid) { Traverser.this.traversePackageMemberInterfaceDeclaration(pmid); }
- public final void visitMemberClassDeclaration(Java.MemberClassDeclaration mcd) { Traverser.this.traverseMemberClassDeclaration(mcd); }
- public final void visitConstructorDeclarator(Java.ConstructorDeclarator cd) { Traverser.this.traverseConstructorDeclarator(cd); }
- public final void visitInitializer(Java.Initializer i) { Traverser.this.traverseInitializer(i); }
- public final void visitMethodDeclarator(Java.MethodDeclarator md) { Traverser.this.traverseMethodDeclarator(md); }
- public final void visitFieldDeclaration(Java.FieldDeclaration fd) { Traverser.this.traverseFieldDeclaration(fd); }
- public final void visitLabeledStatement(Java.LabeledStatement ls) { Traverser.this.traverseLabeledStatement(ls); }
- public final void visitBlock(Java.Block b) { Traverser.this.traverseBlock(b); }
- public final void visitExpressionStatement(Java.ExpressionStatement es) { Traverser.this.traverseExpressionStatement(es); }
- public final void visitIfStatement(Java.IfStatement is) { Traverser.this.traverseIfStatement(is); }
- public final void visitForStatement(Java.ForStatement fs) { Traverser.this.traverseForStatement(fs); }
- public final void visitWhileStatement(Java.WhileStatement ws) { Traverser.this.traverseWhileStatement(ws); }
- public final void visitTryStatement(Java.TryStatement ts) { Traverser.this.traverseTryStatement(ts); }
- public final void visitSwitchStatement(Java.SwitchStatement ss) { Traverser.this.traverseSwitchStatement(ss); }
- public final void visitSynchronizedStatement(Java.SynchronizedStatement ss) { Traverser.this.traverseSynchronizedStatement(ss); }
- public final void visitDoStatement(Java.DoStatement ds) { Traverser.this.traverseDoStatement(ds); }
- public final void visitLocalVariableDeclarationStatement(Java.LocalVariableDeclarationStatement lvds) { Traverser.this.traverseLocalVariableDeclarationStatement(lvds); }
- public final void visitReturnStatement(Java.ReturnStatement rs) { Traverser.this.traverseReturnStatement(rs); }
- public final void visitThrowStatement(Java.ThrowStatement ts) { Traverser.this.traverseThrowStatement(ts); }
- public final void visitBreakStatement(Java.BreakStatement bs) { Traverser.this.traverseBreakStatement(bs); }
- public final void visitContinueStatement(Java.ContinueStatement cs) { Traverser.this.traverseContinueStatement(cs); }
- public final void visitEmptyStatement(Java.EmptyStatement es) { Traverser.this.traverseEmptyStatement(es); }
- public final void visitLocalClassDeclarationStatement(Java.LocalClassDeclarationStatement lcds) { Traverser.this.traverseLocalClassDeclarationStatement(lcds); }
- public final void visitPackage(Java.Package p) { Traverser.this.traversePackage(p); }
- public final void visitArrayLength(Java.ArrayLength al) { Traverser.this.traverseArrayLength(al); }
- public final void visitAssignment(Java.Assignment a) { Traverser.this.traverseAssignment(a); }
- public final void visitUnaryOperation(Java.UnaryOperation uo) { Traverser.this.traverseUnaryOperation(uo); }
- public final void visitBinaryOperation(Java.BinaryOperation bo) { Traverser.this.traverseBinaryOperation(bo); }
- public final void visitCast(Java.Cast c) { Traverser.this.traverseCast(c); }
- public final void visitClassLiteral(Java.ClassLiteral cl) { Traverser.this.traverseClassLiteral(cl); }
- public final void visitConditionalExpression(Java.ConditionalExpression ce) { Traverser.this.traverseConditionalExpression(ce); }
- public final void visitCrement(Java.Crement c) { Traverser.this.traverseCrement(c); }
- public final void visitInstanceof(Java.Instanceof io) { Traverser.this.traverseInstanceof(io); }
- public final void visitMethodInvocation(Java.MethodInvocation mi) { Traverser.this.traverseMethodInvocation(mi); }
- public final void visitSuperclassMethodInvocation(Java.SuperclassMethodInvocation smi) { Traverser.this.traverseSuperclassMethodInvocation(smi); }
- public final void visitLiteral(Java.Literal l) { Traverser.this.traverseLiteral(l); }
- public final void visitNewAnonymousClassInstance(Java.NewAnonymousClassInstance naci) { Traverser.this.traverseNewAnonymousClassInstance(naci); }
- public final void visitNewArray(Java.NewArray na) { Traverser.this.traverseNewArray(na); }
- public final void visitNewInitializedArray(Java.NewInitializedArray nia) { Traverser.this.traverseNewInitializedArray(nia); }
- public final void visitNewClassInstance(Java.NewClassInstance nci) { Traverser.this.traverseNewClassInstance(nci); }
- public final void visitParameterAccess(Java.ParameterAccess pa) { Traverser.this.traverseParameterAccess(pa); }
- public final void visitQualifiedThisReference(Java.QualifiedThisReference qtr) { Traverser.this.traverseQualifiedThisReference(qtr); }
- public final void visitThisReference(Java.ThisReference tr) { Traverser.this.traverseThisReference(tr); }
- public final void visitArrayType(Java.ArrayType at) { Traverser.this.traverseArrayType(at); }
- public final void visitBasicType(Java.BasicType bt) { Traverser.this.traverseBasicType(bt); }
- public final void visitReferenceType(Java.ReferenceType rt) { Traverser.this.traverseReferenceType(rt); }
- public final void visitRvalueMemberType(Java.RvalueMemberType rmt) { Traverser.this.traverseRvalueMemberType(rmt); }
- public final void visitSimpleType(Java.SimpleType st) { Traverser.this.traverseSimpleType(st); }
- public final void visitAlternateConstructorInvocation(Java.AlternateConstructorInvocation aci) { Traverser.this.traverseAlternateConstructorInvocation(aci); }
- public final void visitSuperConstructorInvocation(Java.SuperConstructorInvocation sci) { Traverser.this.traverseSuperConstructorInvocation(sci); }
- public final void visitAmbiguousName(Java.AmbiguousName an) { Traverser.this.traverseAmbiguousName(an); }
- public final void visitArrayAccessExpression(Java.ArrayAccessExpression aae) { Traverser.this.traverseArrayAccessExpression(aae); }
- public final void visitFieldAccess(Java.FieldAccess fa) { Traverser.this.traverseFieldAccess(fa); }
- public final void visitFieldAccessExpression(Java.FieldAccessExpression fae) { Traverser.this.traverseFieldAccessExpression(fae); }
- public final void visitSuperclassFieldAccessExpression(Java.SuperclassFieldAccessExpression scfae) { Traverser.this.traverseSuperclassFieldAccessExpression(scfae); }
- public final void visitLocalVariableAccess(Java.LocalVariableAccess lva) { Traverser.this.traverseLocalVariableAccess(lva); }
- public final void visitParenthesizedExpression(Java.ParenthesizedExpression pe) { Traverser.this.traverseParenthesizedExpression(pe); }
- };
-
- public ComprehensiveVisitor comprehensiveVisitor() {
- return this.cv;
- }
-
- // These may be overridden by derived classes.
-
- public void traverseCompilationUnit(Java.CompilationUnit cu) {
-
- // The optionalPackageDeclaration is considered an integral part of
- // the compilation unit and is thus not traversed.
-
- for (Iterator it = cu.importDeclarations.iterator(); it.hasNext();) {
- ((Java.CompilationUnit.ImportDeclaration) it.next()).accept(this.cv);
- }
- for (Iterator it = cu.packageMemberTypeDeclarations.iterator(); it.hasNext();) {
- ((Java.PackageMemberTypeDeclaration) it.next()).accept(this.cv);
- }
- }
-
- public void traverseSingleTypeImportDeclaration(Java.CompilationUnit.SingleTypeImportDeclaration stid) {
- this.traverseImportDeclaration(stid);
- }
-
- public void traverseTypeImportOnDemandDeclaration(Java.CompilationUnit.TypeImportOnDemandDeclaration tiodd) {
- this.traverseImportDeclaration(tiodd);
- }
-
- public void traverseSingleStaticImportDeclaration(Java.CompilationUnit.SingleStaticImportDeclaration stid) {
- this.traverseImportDeclaration(stid);
- }
-
- public void traverseStaticImportOnDemandDeclaration(Java.CompilationUnit.StaticImportOnDemandDeclaration siodd) {
- this.traverseImportDeclaration(siodd);
- }
-
- public void traverseImportDeclaration(Java.CompilationUnit.ImportDeclaration id) {
- this.traverseLocated(id);
- }
-
- public void traverseAnonymousClassDeclaration(Java.AnonymousClassDeclaration acd) {
- acd.baseType.accept((Visitor.TypeVisitor) this.cv);
- this.traverseClassDeclaration(acd);
- }
-
- public void traverseLocalClassDeclaration(Java.LocalClassDeclaration lcd) {
- this.traverseNamedClassDeclaration(lcd);
- }
-
- public void traversePackageMemberClassDeclaration(Java.PackageMemberClassDeclaration pmcd) {
- this.traverseNamedClassDeclaration(pmcd);
- }
-
- public void traverseMemberInterfaceDeclaration(Java.MemberInterfaceDeclaration mid) {
- this.traverseInterfaceDeclaration(mid);
- }
-
- public void traversePackageMemberInterfaceDeclaration(Java.PackageMemberInterfaceDeclaration pmid) {
- this.traverseInterfaceDeclaration(pmid);
- }
-
- public void traverseMemberClassDeclaration(Java.MemberClassDeclaration mcd) {
- this.traverseNamedClassDeclaration(mcd);
- }
-
- public void traverseConstructorDeclarator(Java.ConstructorDeclarator cd) {
- if (cd.optionalConstructorInvocation != null) cd.optionalConstructorInvocation.accept((Visitor.BlockStatementVisitor) this.cv);
- this.traverseFunctionDeclarator(cd);
- }
-
- public void traverseInitializer(Java.Initializer i) {
- i.block.accept(this.cv);
- this.traverseAbstractTypeBodyDeclaration(i);
- }
-
- public void traverseMethodDeclarator(Java.MethodDeclarator md) {
- this.traverseFunctionDeclarator(md);
- }
-
- public void traverseFieldDeclaration(Java.FieldDeclaration fd) {
- fd.type.accept((Visitor.TypeVisitor) this.cv);
- for (int i = 0; i < fd.variableDeclarators.length; ++i) {
- Java.ArrayInitializerOrRvalue optionalInitializer = fd.variableDeclarators[i].optionalInitializer;
- if (optionalInitializer != null) this.traverseArrayInitializerOrRvalue(optionalInitializer);
- }
- this.traverseStatement(fd);
- }
-
- public void traverseLabeledStatement(Java.LabeledStatement ls) {
- ls.body.accept(this.cv);
- this.traverseBreakableStatement(ls);
- }
-
- public void traverseBlock(Java.Block b) {
- for (Iterator it = b.statements.iterator(); it.hasNext();) {
- ((Java.Statement) it.next()).accept(this.cv);
- }
- this.traverseStatement(b);
- }
-
- public void traverseExpressionStatement(Java.ExpressionStatement es) {
- es.rvalue.accept((Visitor.RvalueVisitor) this.cv);
- this.traverseStatement(es);
- }
-
- public void traverseIfStatement(Java.IfStatement is) {
- is.condition.accept((Visitor.RvalueVisitor) this.cv);
- is.thenStatement.accept(this.cv);
- if (is.optionalElseStatement != null) is.optionalElseStatement.accept(this.cv);
- this.traverseStatement(is);
- }
-
- public void traverseForStatement(Java.ForStatement fs) {
- if (fs.optionalInit != null) fs.optionalInit.accept(this.cv);
- if (fs.optionalCondition != null) fs.optionalCondition.accept((Visitor.RvalueVisitor) this.cv);
- if (fs.optionalUpdate != null) {
- for (int i = 0; i < fs.optionalUpdate.length; ++i) fs.optionalUpdate[i].accept((Visitor.RvalueVisitor) this.cv);
- }
- fs.body.accept(this.cv);
- this.traverseContinuableStatement(fs);
- }
-
- public void traverseWhileStatement(Java.WhileStatement ws) {
- ws.condition.accept((Visitor.RvalueVisitor) this.cv);
- ws.body.accept(this.cv);
- this.traverseContinuableStatement(ws);
- }
-
- public void traverseTryStatement(Java.TryStatement ts) {
- ts.body.accept(this.cv);
- for (Iterator it = ts.catchClauses.iterator(); it.hasNext();) {
- ((Java.CatchClause) it.next()).body.accept(this.cv);
- }
- if (ts.optionalFinally != null) ts.optionalFinally.accept(this.cv);
- this.traverseStatement(ts);
- }
-
- public void traverseSwitchStatement(Java.SwitchStatement ss) {
- ss.condition.accept((Visitor.RvalueVisitor) this.cv);
- for (Iterator it = ss.sbsgs.iterator(); it.hasNext();) {
- Java.SwitchStatement.SwitchBlockStatementGroup sbsg = (Java.SwitchStatement.SwitchBlockStatementGroup) it.next();
- for (Iterator it2 = sbsg.caseLabels.iterator(); it2.hasNext();) {
- ((Java.Rvalue) it2.next()).accept((Visitor.RvalueVisitor) this.cv);
- }
- for (Iterator it2 = sbsg.blockStatements.iterator(); it2.hasNext();) {
- ((Java.BlockStatement) it2.next()).accept(this.cv);
- }
- this.traverseLocated(sbsg);
- }
- this.traverseBreakableStatement(ss);
- }
-
- public void traverseSynchronizedStatement(Java.SynchronizedStatement ss) {
- ss.expression.accept((Visitor.RvalueVisitor) this.cv);
- ss.body.accept(this.cv);
- this.traverseStatement(ss);
- }
-
- public void traverseDoStatement(Java.DoStatement ds) {
- ds.body.accept(this.cv);
- ds.condition.accept((Visitor.RvalueVisitor) this.cv);
- this.traverseContinuableStatement(ds);
- }
-
- public void traverseLocalVariableDeclarationStatement(Java.LocalVariableDeclarationStatement lvds) {
- lvds.type.accept((Visitor.TypeVisitor) this.cv);
- for (int i = 0; i < lvds.variableDeclarators.length; ++i) {
- Java.ArrayInitializerOrRvalue optionalInitializer = lvds.variableDeclarators[i].optionalInitializer;
- if (optionalInitializer != null) this.traverseArrayInitializerOrRvalue(optionalInitializer);
- }
- this.traverseStatement(lvds);
- }
-
- public void traverseReturnStatement(Java.ReturnStatement rs) {
- if (rs.optionalReturnValue != null) rs.optionalReturnValue.accept((Visitor.RvalueVisitor) this.cv);
- this.traverseStatement(rs);
- }
-
- public void traverseThrowStatement(Java.ThrowStatement ts) {
- ts.expression.accept((Visitor.RvalueVisitor) this.cv);
- this.traverseStatement(ts);
- }
-
- public void traverseBreakStatement(Java.BreakStatement bs) {
- this.traverseStatement(bs);
- }
-
- public void traverseContinueStatement(Java.ContinueStatement cs) {
- this.traverseStatement(cs);
- }
-
- public void traverseEmptyStatement(Java.EmptyStatement es) {
- this.traverseStatement(es);
- }
-
- public void traverseLocalClassDeclarationStatement(Java.LocalClassDeclarationStatement lcds) {
- lcds.lcd.accept(this.cv);
- this.traverseStatement(lcds);
- }
-
- public void traversePackage(Java.Package p) {
- this.traverseAtom(p);
- }
-
- public void traverseArrayLength(Java.ArrayLength al) {
- al.lhs.accept((Visitor.RvalueVisitor) this.cv);
- this.traverseRvalue(al);
- }
-
- public void traverseAssignment(Java.Assignment a) {
- a.lhs.accept((Visitor.LvalueVisitor) this.cv);
- a.rhs.accept((Visitor.RvalueVisitor) this.cv);
- this.traverseRvalue(a);
- }
-
- public void traverseUnaryOperation(Java.UnaryOperation uo) {
- uo.operand.accept((Visitor.RvalueVisitor) this.cv);
- this.traverseBooleanRvalue(uo);
- }
-
- public void traverseBinaryOperation(Java.BinaryOperation bo) {
- bo.lhs.accept((Visitor.RvalueVisitor) this.cv);
- bo.rhs.accept((Visitor.RvalueVisitor) this.cv);
- this.traverseBooleanRvalue(bo);
- }
-
- public void traverseCast(Java.Cast c) {
- c.targetType.accept((Visitor.TypeVisitor) this.cv);
- c.value.accept((Visitor.RvalueVisitor) this.cv);
- this.traverseRvalue(c);
- }
-
- public void traverseClassLiteral(Java.ClassLiteral cl) {
- cl.type.accept((Visitor.TypeVisitor) this.cv);
- this.traverseRvalue(cl);
- }
-
- public void traverseConditionalExpression(Java.ConditionalExpression ce) {
- ce.lhs.accept((Visitor.RvalueVisitor) this.cv);
- ce.mhs.accept((Visitor.RvalueVisitor) this.cv);
- ce.rhs.accept((Visitor.RvalueVisitor) this.cv);
- this.traverseRvalue(ce);
- }
-
- public void traverseCrement(Java.Crement c) {
- c.operand.accept((Visitor.LvalueVisitor) this.cv);
- this.traverseRvalue(c);
- }
-
- public void traverseInstanceof(Java.Instanceof io) {
- io.lhs.accept((Visitor.RvalueVisitor) this.cv);
- io.rhs.accept((Visitor.TypeVisitor) this.cv);
- this.traverseRvalue(io);
- }
-
- public void traverseMethodInvocation(Java.MethodInvocation mi) {
- if (mi.optionalTarget != null) mi.optionalTarget.accept(this.cv);
- this.traverseInvocation(mi);
- }
-
- public void traverseSuperclassMethodInvocation(Java.SuperclassMethodInvocation smi) {
- this.traverseInvocation(smi);
- }
-
- public void traverseLiteral(Java.Literal l) {
- this.traverseRvalue(l);
- }
-
- public void traverseNewAnonymousClassInstance(Java.NewAnonymousClassInstance naci) {
- if (naci.optionalQualification != null) naci.optionalQualification.accept((Visitor.RvalueVisitor) this.cv);
- naci.anonymousClassDeclaration.accept(this.cv);
- for (int i = 0; i < naci.arguments.length; ++i) naci.arguments[i].accept((Visitor.RvalueVisitor) this.cv);
- this.traverseRvalue(naci);
- }
-
- public void traverseNewArray(Java.NewArray na) {
- na.type.accept((Visitor.TypeVisitor) this.cv);
- for (int i = 0; i < na.dimExprs.length; ++i) na.dimExprs[i].accept((Visitor.RvalueVisitor) this.cv);
- this.traverseRvalue(na);
- }
-
- public void traverseNewInitializedArray(Java.NewInitializedArray nia) {
- nia.arrayType.accept((Visitor.TypeVisitor) this.cv);
- this.traverseArrayInitializerOrRvalue(nia.arrayInitializer);
- }
-
- public void traverseArrayInitializerOrRvalue(Java.ArrayInitializerOrRvalue aiorv) {
- if (aiorv instanceof Java.Rvalue) {
- ((Java.Atom) aiorv).accept(this.cv);
- } else
- if (aiorv instanceof Java.ArrayInitializer) {
- Java.ArrayInitializerOrRvalue[] values = ((Java.ArrayInitializer) aiorv).values;
- for (int i = 0; i < values.length; ++i) this.traverseArrayInitializerOrRvalue(values[i]);
- } else
- {
- throw new RuntimeException("Unexpected array initializer or rvalue class " + aiorv.getClass().getName());
- }
- }
- public void traverseNewClassInstance(Java.NewClassInstance nci) {
- if (nci.optionalQualification != null) nci.optionalQualification.accept((Visitor.RvalueVisitor) this.cv);
- nci.type.accept((Visitor.TypeVisitor) this.cv);
- for (int i = 0; i < nci.arguments.length; ++i) nci.arguments[i].accept((Visitor.RvalueVisitor) this.cv);
- this.traverseRvalue(nci);
- }
-
- public void traverseParameterAccess(Java.ParameterAccess pa) {
- this.traverseRvalue(pa);
- }
-
- public void traverseQualifiedThisReference(Java.QualifiedThisReference qtr) {
- qtr.qualification.accept((Visitor.TypeVisitor) this.cv);
- this.traverseRvalue(qtr);
- }
-
- public void traverseThisReference(Java.ThisReference tr) {
- this.traverseRvalue(tr);
- }
-
- public void traverseArrayType(Java.ArrayType at) {
- at.componentType.accept((Visitor.TypeVisitor) this.cv);
- this.traverseType(at);
- }
-
- public void traverseBasicType(Java.BasicType bt) {
- this.traverseType(bt);
- }
-
- public void traverseReferenceType(Java.ReferenceType rt) {
- this.traverseType(rt);
- }
-
- public void traverseRvalueMemberType(Java.RvalueMemberType rmt) {
- rmt.rvalue.accept((Visitor.RvalueVisitor) this.cv);
- this.traverseType(rmt);
- }
-
- public void traverseSimpleType(Java.SimpleType st) {
- this.traverseType(st);
- }
-
- public void traverseAlternateConstructorInvocation(Java.AlternateConstructorInvocation aci) {
- this.traverseConstructorInvocation(aci);
- }
-
- public void traverseSuperConstructorInvocation(Java.SuperConstructorInvocation sci) {
- if (sci.optionalQualification != null) sci.optionalQualification.accept((Visitor.RvalueVisitor) this.cv);
- this.traverseConstructorInvocation(sci);
- }
-
- public void traverseAmbiguousName(Java.AmbiguousName an) {
- this.traverseLvalue(an);
- }
-
- public void traverseArrayAccessExpression(Java.ArrayAccessExpression aae) {
- aae.lhs.accept((Visitor.RvalueVisitor) this.cv);
- ((Java.Atom) aae.index).accept(this.cv);
- this.traverseLvalue(aae);
- }
-
- public void traverseFieldAccess(Java.FieldAccess fa) {
- fa.lhs.accept(this.cv);
- this.traverseLvalue(fa);
- }
-
- public void traverseFieldAccessExpression(Java.FieldAccessExpression fae) {
- fae.lhs.accept(this.cv);
- this.traverseLvalue(fae);
- }
-
- public void traverseSuperclassFieldAccessExpression(Java.SuperclassFieldAccessExpression scfae) {
- if (scfae.optionalQualification != null) scfae.optionalQualification.accept((Visitor.TypeVisitor) this.cv);
- this.traverseLvalue(scfae);
- }
-
- public void traverseLocalVariableAccess(Java.LocalVariableAccess lva) {
- this.traverseLvalue(lva);
- }
-
- public void traverseParenthesizedExpression(Java.ParenthesizedExpression pe) {
- pe.value.accept((Visitor.RvalueVisitor) this.cv);
- this.traverseLvalue(pe);
- }
-
- public void traverseClassDeclaration(Java.ClassDeclaration cd) {
- for (Iterator it = cd.constructors.iterator(); it.hasNext();) {
- ((Java.ConstructorDeclarator) it.next()).accept(this.cv);
- }
- for (Iterator it = cd.variableDeclaratorsAndInitializers.iterator(); it.hasNext();) {
- ((Java.TypeBodyDeclaration) it.next()).accept(this.cv);
- }
- this.traverseAbstractTypeDeclaration(cd);
- }
-
- public void traverseAbstractTypeDeclaration(Java.AbstractTypeDeclaration atd) {
- for (Iterator it = atd.declaredClassesAndInterfaces.iterator(); it.hasNext();) {
- ((Java.NamedTypeDeclaration) it.next()).accept(this.cv);
- }
- for (Iterator it = atd.declaredMethods.iterator(); it.hasNext();) {
- this.traverseMethodDeclarator((Java.MethodDeclarator) it.next());
- }
- }
-
- public void traverseNamedClassDeclaration(Java.NamedClassDeclaration ncd) {
- for (int i = 0; i < ncd.implementedTypes.length; ++i) {
- ncd.implementedTypes[i].accept((Visitor.TypeVisitor) this.cv);
- }
- if (ncd.optionalExtendedType != null) ncd.optionalExtendedType.accept((Visitor.TypeVisitor) this.cv);
- this.traverseClassDeclaration(ncd);
- }
-
- public void traverseInterfaceDeclaration(Java.InterfaceDeclaration id) {
- for (Iterator it = id.constantDeclarations.iterator(); it.hasNext();) {
- ((Java.TypeBodyDeclaration) it.next()).accept(this.cv);
- }
- for (int i = 0; i < id.extendedTypes.length; ++i) {
- id.extendedTypes[i].accept((Visitor.TypeVisitor) this.cv);
- }
- this.traverseAbstractTypeDeclaration(id);
- }
-
- public void traverseFunctionDeclarator(Java.FunctionDeclarator fd) {
- for (int i = 0; i < fd.formalParameters.length; ++i) {
- fd.formalParameters[i].type.accept((Visitor.TypeVisitor) this.cv);
- }
- if (fd.optionalBody != null) fd.optionalBody.accept(this.cv);
- }
-
- public void traverseAbstractTypeBodyDeclaration(Java.AbstractTypeBodyDeclaration atbd) {
- this.traverseLocated(atbd);
- }
-
- public void traverseStatement(Java.Statement s) {
- this.traverseLocated(s);
- }
-
- public void traverseBreakableStatement(Java.BreakableStatement bs) {
- this.traverseStatement(bs);
- }
-
- public void traverseContinuableStatement(Java.ContinuableStatement cs) {
- this.traverseBreakableStatement(cs);
- }
-
- public void traverseRvalue(Java.Rvalue rv) {
- this.traverseAtom(rv);
- }
-
- public void traverseBooleanRvalue(Java.BooleanRvalue brv) {
- this.traverseRvalue(brv);
- }
-
- public void traverseInvocation(Java.Invocation i) {
- for (int j = 0; j < i.arguments.length; ++j) i.arguments[j].accept((Visitor.RvalueVisitor) this.cv);
- this.traverseRvalue(i);
- }
-
- public void traverseConstructorInvocation(Java.ConstructorInvocation ci) {
- for (int i = 0; i < ci.arguments.length; ++i) ci.arguments[i].accept((Visitor.RvalueVisitor) this.cv);
- this.traverseAtom(ci);
- }
-
- public void traverseLvalue(Java.Lvalue lv) {
- this.traverseRvalue(lv);
- }
-
- public void traverseType(Java.Type t) {
- this.traverseAtom(t);
- }
-
- public void traverseAtom(Java.Atom a) {
- this.traverseLocated(a);
- }
-
- public void traverseLocated(Java.Located l) {
- ;
- }
-}
diff --git a/src/org/codehaus/janino/util/enumerator/Enumerator.java b/src/org/codehaus/janino/util/enumerator/Enumerator.java
deleted file mode 100644
index feca99a..0000000
--- a/src/org/codehaus/janino/util/enumerator/Enumerator.java
+++ /dev/null
@@ -1,143 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino.util.enumerator;
-
-import java.util.*;
-
-/**
- * A class that represents an enumerated value. Its main features are its {@link #toString()} and
- * {@link #fromString(String, Class)} method, which map names to values and vice versa.
- * <p>
- * To use this class, derive from it and define one or more
- * <code>public static final</code> fields, as follows:
- * <pre>
- * public final class Suit extends Enumerator {
- *
- * // Exactly N instances of "Suit" exist to represent the N possible values.
- * public static final Suit CLUBS = new Suit("clubs");
- * public static final Suit DIAMONDS = new Suit("diamonds");
- * public static final Suit HEARTS = new Suit("hearts");
- * public static final Suit SPADES = new Suit("spades");
- *
- * // Optional, if you want to use EumeratorSet arithmetics.
- * public static final EnumeratorSet NONE = new EnumeratorSet(Suit.class ).setName("none");
- * public static final EnumeratorSet ALL = new EnumeratorSet(Suit.class, true).setName("all");
- *
- * // These MUST be declared exactly like this:
- * private Suit(String name) { super(name); }
- * public static Suit fromString(String name) throws EnumeratorFormatException {
- * return (Suit) Enumerator.fromString(name, Suit.class);
- * }
- * }
- * </pre>
- *
- * @see <a href="http://java.sun.com/developer/Books/effectivejava/Chapter5.pdf">Effective Java, Item 21</a>
- * @see org.codehaus.janino.util.enumerator.EnumeratorSet
- */
-public abstract class Enumerator {
- /*package*/ final String name;
-
- /**
- * Class enumeratorClass => Map: String name => Enumerator
- */
- private static final Map instances = Collections.synchronizedMap(new HashMap());
-
- /**
- * Initialize the enumerator to the given value.
- */
- protected Enumerator(String name) {
- if (name == null) throw new NullPointerException();
- this.name = name;
-
- Enumerator.getInstances(this.getClass()).put(name, this);
- }
-
- /**
- * Equality is reference identity.
- */
- public final boolean equals(Object that) {
- return this == that;
- }
-
- /**
- * Enforce {@link Object}'s notion of {@link Object#hashCode()}.
- */
- public final int hashCode() {
- return super.hashCode();
- }
-
- /**
- * Returns a mapping of name to Enumerator for the given enumeratorClass.
- */
- /*package*/ static Map getInstances(Class enumeratorClass) {
- Map m = (Map) Enumerator.instances.get(enumeratorClass);
- if (m != null) return m;
-
- // The map need not be synchronized because it is modified only during initialization
- // of the Enumerator.
- m = new HashMap();
- Enumerator.instances.put(enumeratorClass, m);
- return m;
- }
-
- /**
- * Initialize an {@link Enumerator} from a string.
- * <p>
- * The given string is converted into a value by looking at all instances of the given type
- * created so far.
- * <p>
- * Derived classes should invoke this method as follows:<pre>
- * public class Suit extends Enumerator {
- * ...
- * public static Suit fromString(String name) throws EnumeratorFormatException {
- * return (Suit) Enumerator.fromString(name, Suit.class);
- * }
- * }</pre>
- *
- * @throws EnumeratorFormatException if the string cannot be identified
- */
- protected static final Enumerator fromString(String name, Class enumeratorClass) throws EnumeratorFormatException {
- Enumerator value = (Enumerator) Enumerator.getInstances(enumeratorClass).get(name);
- if (value == null) throw new EnumeratorFormatException(name);
- return value;
- }
-
- /**
- * Returns the <code>name</code> passed to {@link #Enumerator(String)}.
- */
- public String toString() {
- return this.name;
- }
-}
diff --git a/src/org/codehaus/janino/util/enumerator/EnumeratorFormatException.java b/src/org/codehaus/janino/util/enumerator/EnumeratorFormatException.java
deleted file mode 100644
index d5c0016..0000000
--- a/src/org/codehaus/janino/util/enumerator/EnumeratorFormatException.java
+++ /dev/null
@@ -1,45 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino.util.enumerator;
-
-/**
- * Represents a problem related to parsing {@link org.codehaus.janino.util.enumerator.Enumerator}s
- * and {@link org.codehaus.janino.util.enumerator.EnumeratorSet}s, in analogy with
- * {@link EnumeratorFormatException}.
- */
-public class EnumeratorFormatException extends Exception {
- public EnumeratorFormatException() {}
- public EnumeratorFormatException(String message) { super(message); }
-}
diff --git a/src/org/codehaus/janino/util/enumerator/EnumeratorSet.java b/src/org/codehaus/janino/util/enumerator/EnumeratorSet.java
deleted file mode 100644
index ed7581c..0000000
--- a/src/org/codehaus/janino/util/enumerator/EnumeratorSet.java
+++ /dev/null
@@ -1,324 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino.util.enumerator;
-
-import java.util.*;
-
-/**
- * A class that represents an immutable set of {@link Enumerator}s.
- * <p>
- * Its main features are its constructor, which initializes the object from a clear-text string,
- * and its {@link #toString()} method, which reconstructs the clear text values.
- * <p>
- * Sample code can be found in the documentation of {@link Enumerator}.
- */
-public class EnumeratorSet {
- private final Class enumeratorClass;
- private final Set values; // Enumerator-derived class
- /*package*/ String optionalName = null;
-
- private EnumeratorSet(Class enumeratorClass, Set values) {
- this.enumeratorClass = enumeratorClass;
- this.values = values;
- }
-
- /**
- * Construct an empty set for values of the given {@link Enumerator}-derived type.
- */
- public EnumeratorSet(Class enumeratorClass) {
- this(enumeratorClass, new HashSet());
- }
-
- /**
- * Construct a set for values of the given {@link Enumerator}-derived type. If the
- * <code>full</code> flag is <code>true</code>, all possible values are added to the set.
- */
- public EnumeratorSet(Class enumeratorClass, boolean full) {
- this(enumeratorClass, new HashSet());
- if (full) this.values.addAll(Enumerator.getInstances(enumeratorClass).values());
- }
-
- /**
- * Construct a set for values of the given {@link Enumerator}-derived type and initialize it
- * from a string.
- * <p>
- * Equivalent to <code>EnumeratorSet(enumeratorClass, s, ",")</code>.
- */
- public EnumeratorSet(Class enumeratorClass, String s) throws EnumeratorFormatException {
- this(enumeratorClass, s, ",");
- }
-
- /**
- * Construct a set for values of the given {@link Enumerator}-derived type and initialize it
- * from a string.
- * <p>
- * The given string is parsed into tokens; each token is converted into a value as
- * {@link Enumerator#fromString(String, Class)} does and added to this set. Named {@link EnumeratorSet}s
- * declared in the <code>enumeratorClass</code> are also recognized and added. If the string names exactly one
- * of those {@link EnumeratorSet}s declared in the <code>enumeratorClass</code>, then the resulting set
- * inherits the name of theat {@link EnumeratorSet}.
- *
- * @throws EnumeratorFormatException if a token cannot be identified
- */
- public EnumeratorSet(
- Class enumeratorClass,
- String s,
- String delimiter
- ) throws EnumeratorFormatException {
- Set vs = new HashSet();
-
- Map des = Enumerator.getInstances(enumeratorClass);
- Map dess = EnumeratorSet.getNamedEnumeratorSets(enumeratorClass);
-
- StringTokenizer st = new StringTokenizer(s, delimiter);
- while (st.hasMoreTokens()) {
- String name = st.nextToken();
- Enumerator value = (Enumerator) des.get(name);
- if (value != null) {
- vs.add(value);
- continue;
- }
-
- EnumeratorSet es = (EnumeratorSet) dess.get(name);
- if (es != null) {
- if (vs.isEmpty()) {
- vs = es.values;
- this.optionalName = es.optionalName;
- } else
- {
- vs.addAll(es.values);
- }
- continue;
- }
-
- throw new EnumeratorFormatException(name);
- }
-
- this.enumeratorClass = enumeratorClass;
- this.values = vs;
- }
-
- /**
- * Construct a copy of the given set.
- */
- public EnumeratorSet(EnumeratorSet that) {
- this(that.enumeratorClass, that.values);
- }
-
- /**
- * Add the given value to the set.
- *
- * @throws EnumeratorSetTypeException if this set was constructed for a different {@link Enumerator}-derived type
- */
- public EnumeratorSet add(Enumerator value) {
- if (value.getClass() != this.enumeratorClass) throw new EnumeratorSetTypeException("Cannot add value of type \"" + value.getClass() + "\" to set of different type \"" + this.enumeratorClass + "\"");
- Set vs = new HashSet(this.values);
- vs.add(value);
- return new EnumeratorSet(this.enumeratorClass, vs);
- }
-
- /**
- * Add the values of the given set to this set.
- *
- * @throws EnumeratorSetTypeException if this set was constructed for a different {@link Enumerator}-derived type
- */
- public EnumeratorSet add(EnumeratorSet that) {
- if (that.enumeratorClass != this.enumeratorClass) throw new EnumeratorSetTypeException("Cannot add set of type \"" + that.enumeratorClass + "\" to set of different type \"" + this.enumeratorClass + "\"");
- Set vs;
- if (this.values.isEmpty()) {
- vs = that.values;
- } else
- if (that.values.isEmpty()) {
- vs = this.values;
- } else
- {
- vs = new HashSet(this.values);
- vs.addAll(that.values);
- }
- return new EnumeratorSet(this.enumeratorClass, vs);
- }
-
- /**
- * If this {@link EnumeratorSet} contains the given <code>value</code>, return an
- * {@link EnumeratorSet} that lacks the <code>value</code>. Otherwise, return this
- * {@link EnumeratorSet}.
- *
- * @return the reduced set
- *
- * @throws EnumeratorSetTypeException if this set was constructed for a different {@link Enumerator}-derived type
- */
- public EnumeratorSet remove(Enumerator value) {
- if (value.getClass() != this.enumeratorClass) throw new EnumeratorSetTypeException("Cannot remove value of type \"" + value.getClass() + "\" from set of different type \"" + this.enumeratorClass + "\"");
- if (!this.values.contains(value)) return this;
- Set vs = new HashSet(this.values);
- vs.remove(value);
- return new EnumeratorSet(this.enumeratorClass, vs);
- }
-
- /**
- * Return this {@link EnumeratorSet} less <code>that</code> {@link EnumeratorSet}.
- *
- * @return the reduced set
- *
- * @throws EnumeratorSetTypeException if this set was constructed for a different {@link Enumerator}-derived type
- */
- public EnumeratorSet remove(EnumeratorSet that) {
- if (that.enumeratorClass != this.enumeratorClass) throw new EnumeratorSetTypeException("Cannot remove set of type \"" + that.enumeratorClass + "\" from set of different type \"" + this.enumeratorClass + "\"");
- Set vs = new HashSet(this.values);
- vs.removeAll(that.values);
- return new EnumeratorSet(this.enumeratorClass, vs);
- }
-
- /**
- * Check whether this set contains the given value
- *
- * @throws EnumeratorSetTypeException if this set was constructed for a different {@link Enumerator}-derived type
- */
- public boolean contains(Enumerator value) {
- if (value.getClass() != this.enumeratorClass) throw new EnumeratorSetTypeException("Cannot check value of type \"" + value.getClass() + "\" within set of different type \"" + this.enumeratorClass + "\"");
- return this.values.contains(value);
- }
-
- /**
- * Check if this set contains any of the values of the given set.
- * <p>
- * Returns <code>false</code> if either of the two sets is empty.
- *
- * @throws EnumeratorSetTypeException if this set was constructed for a different {@link Enumerator}-derived type
- */
- public boolean containsAnyOf(EnumeratorSet that) {
- if (that.enumeratorClass != this.enumeratorClass) throw new EnumeratorSetTypeException("Cannot compare set of type \"" + that.enumeratorClass + "\" with set of different type \"" + this.enumeratorClass + "\"");
- for (Iterator it = that.values.iterator(); it.hasNext();) {
- if (this.values.contains(it.next())) return true;
- }
- return false;
- }
-
- /**
- * Check if this set contains all values of the given set.
- *
- * @throws EnumeratorSetTypeException if this set was constructed for a different {@link Enumerator}-derived type
- */
- public boolean containsAllOf(EnumeratorSet that) {
- if (that.enumeratorClass != this.enumeratorClass) throw new EnumeratorSetTypeException("Cannot compare set of type \"" + that.enumeratorClass + "\" with set of different type \"" + this.enumeratorClass + "\"");
- return this.values.containsAll(that.values);
- }
-
- /**
- * An {@link EnumeratorSet} can optionally be assigned a name, which is used by
- * {@link #toString()}.
- *
- * @return this object
- */
- public EnumeratorSet setName(String optionalName) {
-
- // Check for non-change.
- if (
- (this.optionalName == optionalName)
- || (this.optionalName != null && this.optionalName.equals(optionalName))
- ) return this;
-
- // Track all named EnumeratorSet instances.
- Map namedEnumeratorSets = EnumeratorSet.getNamedEnumeratorSets(this.enumeratorClass);
- if (this.optionalName != null) namedEnumeratorSets.remove(this.optionalName);
- this.optionalName = optionalName;
- if (this.optionalName != null) namedEnumeratorSets.put(this.optionalName, this);
-
- return this;
- }
-
- /**
- * Returns a map of all {@link EnumeratorSet}s instantiated for the given <code>enumeratorClass</code>.
- *
- * @return String name => EnumeratorSet
- */
- private static Map getNamedEnumeratorSets(Class enumeratorClass) {
- Map m = (Map) EnumeratorSet.namedEnumeratorSets.get(enumeratorClass);
- if (m == null) {
- m = new HashMap();
- EnumeratorSet.namedEnumeratorSets.put(enumeratorClass, m);
- }
- return m;
- }
- private static final Map namedEnumeratorSets = new HashMap(); // Class enumeratorClass => String name => EnumeratorSet
-
- /**
- * Check the values' identity. Notice that the objects' names (see {@link #setName(String)} is
- * not considered.
- */
- public boolean equals(Object that) {
- return that instanceof EnumeratorSet && this.values.equals(((EnumeratorSet) that).values);
- }
-
- public int hashCode() {
- return this.values.hashCode();
- }
-
- /**
- * Convert an {@link EnumeratorSet} to a clear-text string.
- * <p>
- * Identical with <code>toString(",")</code>.
- */
- public String toString() {
- return this.toString(",");
- }
-
- /**
- * Convert an {@link EnumeratorSet} into a clear-text string.
- * <p>
- * If this {@link EnumeratorSet} has a name (see {@link #setName(String)}, then this name is
- * returned.
- * <p>
- * Otherwise, if this {@link EnumeratorSet} is empty, an empty {@link String} is returned.
- * <p>
- * Otherwise, the values' names are concatenated, separated by the given delimiter, and returned.
- */
- public String toString(String delimiter) {
-
- // If this EnumeratorSet has a name, then everything is very simple.
- if (this.optionalName != null) return this.optionalName;
-
- // Return "" for an empty set.
- Iterator it = this.values.iterator();
- if (!it.hasNext()) return "";
-
- // Concatenate the enumerators' names.
- StringBuffer sb = new StringBuffer(((Enumerator) it.next()).name);
- while (it.hasNext()) {
- sb.append(delimiter).append(((Enumerator) it.next()).name);
- }
- return sb.toString();
- }
-}
diff --git a/src/org/codehaus/janino/util/enumerator/EnumeratorSetTypeException.java b/src/org/codehaus/janino/util/enumerator/EnumeratorSetTypeException.java
deleted file mode 100644
index 25f17dd..0000000
--- a/src/org/codehaus/janino/util/enumerator/EnumeratorSetTypeException.java
+++ /dev/null
@@ -1,44 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino.util.enumerator;
-
-/**
- * Indicates that an attempt was made to add or remove values of different type to an
- * {@link org.codehaus.janino.util.enumerator.EnumeratorSet}.
- */
-public class EnumeratorSetTypeException extends RuntimeException {
- public EnumeratorSetTypeException() {}
- public EnumeratorSetTypeException(String message) { super(message); }
-}
diff --git a/src/org/codehaus/janino/util/enumerator/package.html b/src/org/codehaus/janino/util/enumerator/package.html
deleted file mode 100644
index e1dd7ec..0000000
--- a/src/org/codehaus/janino/util/enumerator/package.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<html><body>
- Representation of enumerators and enumerator sets.
-</body></html>
diff --git a/src/org/codehaus/janino/util/iterator/DirectoryIterator.java b/src/org/codehaus/janino/util/iterator/DirectoryIterator.java
deleted file mode 100644
index 917e247..0000000
--- a/src/org/codehaus/janino/util/iterator/DirectoryIterator.java
+++ /dev/null
@@ -1,132 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino.util.iterator;
-
-import java.io.File;
-import java.io.FilenameFilter;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.codehaus.janino.util.Producer;
-
-/**
- * An {@link Iterator} that finds the normal {@link File}s who's names are
- * {@link FilenameFilter#accept(java.io.File, java.lang.String)}ed by the
- * <code>fileNameFilter</code> and
- * <ul>
- * <li>
- * that exist in the given <code>rootDirectory</code>,
- * </li>
- * <li>
- * and those that exist in all subdirectories of the
- * <code>rootDirectory</code> who's names are
- * {@link FilenameFilter#accept(java.io.File, java.lang.String)}ed by the
- * <code>directoryNameFilter</code>
- * </li>
- * </ul>
- */
-public class DirectoryIterator extends ProducerIterator {
- public DirectoryIterator(
- final File rootDirectory,
- final FilenameFilter directoryNameFilter,
- final FilenameFilter fileNameFilter
- ) {
- super(new Producer() {
- private final List stateStack = DirectoryIterator.newArrayList(new State(rootDirectory));
- public Object produce() {
- while (!this.stateStack.isEmpty()) {
- State state = (State) this.stateStack.get(this.stateStack.size() - 1);
- if (state.directories.hasNext()) {
- this.stateStack.add(new State((File) state.directories.next()));
- } else
- if (state.files.hasNext()) {
- return (File) state.files.next();
- } else
- {
- this.stateStack.remove(this.stateStack.size() - 1);
- }
- }
- return null;
- }
-
- class State {
- State(File dir) {
- File[] entries = dir.listFiles();
- if (entries == null) throw new RuntimeException("Directory \"" + dir + "\" could not be read");
- List directoryList = new ArrayList();
- List fileList = new ArrayList();
- for (int i = 0; i < entries.length; ++i) {
- File entry = entries[i];
- if (entry.isDirectory()) {
- if (directoryNameFilter.accept(dir, entry.getName())) directoryList.add(entry);
- } else
- if (entry.isFile()) {
- if (fileNameFilter.accept(dir, entry.getName())) fileList.add(entry);
- }
- }
- this.directories = directoryList.iterator();
- this.files = fileList.iterator();
- }
- final Iterator directories; // File
- final Iterator files; // File
- }
- });
- }
-
- /**
- * Create an {@link Iterator} that return all matching
- * {@link File}s locatable in a <i>set</i> of root directories.
- *
- * @see #DirectoryIterator(File, FilenameFilter, FilenameFilter)
- */
- public static Iterator traverseDirectories(
- File[] rootDirectories,
- FilenameFilter directoryNameFilter,
- FilenameFilter fileNameFilter
- ) {
- List result = new ArrayList();
- for (int i = 0; i < rootDirectories.length; ++i) {
- result.add(new DirectoryIterator(rootDirectories[i], directoryNameFilter, fileNameFilter));
- }
- return new MultiDimensionalIterator(result.iterator(), 2);
- }
-
- private static ArrayList newArrayList(Object initialElement) {
- ArrayList result = new ArrayList();
- result.add(initialElement);
- return result;
- }
-}
diff --git a/src/org/codehaus/janino/util/iterator/EnumerationIterator.java b/src/org/codehaus/janino/util/iterator/EnumerationIterator.java
deleted file mode 100644
index a540108..0000000
--- a/src/org/codehaus/janino/util/iterator/EnumerationIterator.java
+++ /dev/null
@@ -1,51 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino.util.iterator;
-
-import java.util.*;
-
-/**
- * An {@link java.util.Iterator} that iterates over the elements of an
- * {@link java.util.Enumeration}.
- */
-public class EnumerationIterator implements Iterator {
- private final Enumeration e;
-
- public EnumerationIterator(Enumeration e) { this.e = e; }
-
- public boolean hasNext() { return this.e.hasMoreElements(); }
- public Object next() { return this.e.nextElement(); }
- public void remove() { throw new UnsupportedOperationException("remove"); }
-}
diff --git a/src/org/codehaus/janino/util/iterator/FilterIterator.java b/src/org/codehaus/janino/util/iterator/FilterIterator.java
deleted file mode 100644
index 915f6e2..0000000
--- a/src/org/codehaus/janino/util/iterator/FilterIterator.java
+++ /dev/null
@@ -1,52 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino.util.iterator;
-
-import java.util.*;
-
-/**
- * An {@link java.util.Iterator} that retrieves its elements from a delegate
- * {@link java.util.Iterator}. The default implementation simply passes
- * all method invocations to the delegate.
- */
-public abstract class FilterIterator implements Iterator {
- protected final Iterator delegate;
-
- public FilterIterator(Iterator delegate) { this.delegate = delegate; }
-
- public boolean hasNext() { return this.delegate.hasNext(); }
- public Object next() { return this.delegate.next(); }
- public void remove() { this.delegate.remove(); }
-}
diff --git a/src/org/codehaus/janino/util/iterator/FilterListIterator.java b/src/org/codehaus/janino/util/iterator/FilterListIterator.java
deleted file mode 100644
index 7ff914b..0000000
--- a/src/org/codehaus/janino/util/iterator/FilterListIterator.java
+++ /dev/null
@@ -1,71 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino.util.iterator;
-
-import java.util.*;
-
-/**
- * An {@link java.util.ListIterator} that retrieves its elements from a delegate
- * {@link java.util.ListIterator}. The default implementation simply passes
- * all method invocations to the delegate.
- */
-public abstract class FilterListIterator implements ListIterator {
- /** */
- protected final ListIterator delegate;
-
- /** */
- public FilterListIterator(ListIterator delegate) {
- this.delegate = delegate;
- }
-
- /** Calls {@link #delegate}.{@link java.util.ListIterator#hasNext()} */
- public boolean hasNext() { return this.delegate.hasNext(); }
- /** Calls {@link #delegate}.{@link java.util.ListIterator#next()} */
- public Object next() { return this.delegate.next(); }
- /** Calls {@link #delegate}.{@link java.util.ListIterator#hasPrevious()} */
- public boolean hasPrevious() { return this.delegate.hasPrevious(); }
- /** Calls {@link #delegate}.{@link java.util.ListIterator#previous()} */
- public Object previous() { return this.delegate.previous(); }
- /** Calls {@link #delegate}.{@link java.util.ListIterator#nextIndex()} */
- public int nextIndex() { return this.delegate.nextIndex(); }
- /** Calls {@link #delegate}.{@link java.util.ListIterator#previousIndex()} */
- public int previousIndex() { return this.delegate.previousIndex(); }
- /** Calls {@link #delegate}.{@link java.util.ListIterator#remove()} */
- public void remove() { this.delegate.remove(); }
- /** Calls {@link #delegate}.{@link java.util.ListIterator#set(java.lang.Object)} */
- public void set(Object o) { this.delegate.set(o); }
- /** Calls {@link #delegate}.{@link java.util.ListIterator#add(java.lang.Object)} */
- public void add(Object o) { this.delegate.add(o); }
-}
diff --git a/src/org/codehaus/janino/util/iterator/IteratorCollection.java b/src/org/codehaus/janino/util/iterator/IteratorCollection.java
deleted file mode 100644
index a99edd3..0000000
--- a/src/org/codehaus/janino/util/iterator/IteratorCollection.java
+++ /dev/null
@@ -1,82 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino.util.iterator;
-
-import java.util.*;
-
-/**
- * A {@link java.util.Collection} that lazily reads its elements from an
- * {@link java.util.Iterator}.
- * <p>
- * In other words, you can call {@link #iterator()} as often as you want, but the
- * {@link IteratorCollection} will iterate over its delegate only once.
- */
-public class IteratorCollection extends AbstractCollection {
- private final Iterator iterator; // The delegate.
- private final List elements = new ArrayList(); // Lazily-filled collection of the elements delivered by the delegate.
-
- public IteratorCollection(Iterator iterator) {
- this.iterator = iterator;
- }
-
- public Iterator iterator() {
- return new Iterator() {
- private Iterator elementsIterator = IteratorCollection.this.elements.iterator();
- public Object next() {
- if (this.elementsIterator != null) {
- if (this.elementsIterator.hasNext()) return this.elementsIterator.next();
- this.elementsIterator = null;
- }
- Object o = IteratorCollection.this.iterator.next();
- IteratorCollection.this.elements.add(o);
- return o;
- }
- public boolean hasNext() {
- return (
- (this.elementsIterator != null && this.elementsIterator.hasNext())
- || IteratorCollection.this.iterator.hasNext()
- );
- }
- public void remove() {
- throw new UnsupportedOperationException();
- }
- };
- }
- public int size() {
- int size = 0;
- for (Iterator it = this.iterator(); it.hasNext(); it.next()) ++size;
- return size;
- }
-}
diff --git a/src/org/codehaus/janino/util/iterator/MultiDimensionalIterator.java b/src/org/codehaus/janino/util/iterator/MultiDimensionalIterator.java
deleted file mode 100644
index dcb7f42..0000000
--- a/src/org/codehaus/janino/util/iterator/MultiDimensionalIterator.java
+++ /dev/null
@@ -1,107 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino.util.iterator;
-
-import java.util.*;
-
-/**
- * An {@link java.util.Iterator} that iterates over a delegate, which produces
- * arrays, {@link java.util.Collection}s, {@link java.util.Enumeration}s or
- * {@link java.util.Iterator}s. This {@link java.util.Iterator} returns the
- * elements of these objects.
- * <p>
- * The count of dimensions is declared at construction. Count "1" produces an
- * {@link java.util.Iterator} that adds no functionality to its delegate, count
- * "2" produces an {@link Iterator} that behaves as explained above, and so
- * forth.
- */
-public class MultiDimensionalIterator implements Iterator {
- private final Iterator[] nest;
- private static final Iterator EMPTY_ITERATOR = new Iterator() {
- public boolean hasNext() { return false; }
- public Object next() { throw new NoSuchElementException(); }
- public void remove() { throw new UnsupportedOperationException("remove"); }
- };
-
- public MultiDimensionalIterator(Iterator delegate, int dimensionCount) {
- this.nest = new Iterator[dimensionCount];
- this.nest[0] = delegate;
- for (int i = 1; i < dimensionCount; ++i) this.nest[i] = MultiDimensionalIterator.EMPTY_ITERATOR;
- }
-
- /**
- * @throws UniterableElementException
- */
- public boolean hasNext() {
-
- // Unroll this check because it is so performance critical:
- if (this.nest[this.nest.length - 1].hasNext()) return true;
-
- int i = this.nest.length - 2;
- if (i < 0) return false;
-
- for (;;) {
- if (!this.nest[i].hasNext()) {
- if (i == 0) return false;
- --i;
- } else {
- if (i == this.nest.length - 1) return true;
- Object o = this.nest[i].next();
- if (o instanceof Iterator) {
- this.nest[++i] = (Iterator) o;
- } else
- if (o instanceof Object[]) {
- this.nest[++i] = Arrays.asList((Object[]) o).iterator();
- } else
- if (o instanceof Collection) {
- this.nest[++i] = ((Collection) o).iterator();
- } else
- if (o instanceof Enumeration) {
- this.nest[++i] = new EnumerationIterator((Enumeration) o);
- } else
- {
- throw new UniterableElementException();
- }
- }
- }
- }
-
- public Object next() {
- if (!this.hasNext()) throw new NoSuchElementException();
- return this.nest[this.nest.length - 1].next();
- }
-
- public void remove() { throw new UnsupportedOperationException("remove"); }
-}
diff --git a/src/org/codehaus/janino/util/iterator/ProducerIterator.java b/src/org/codehaus/janino/util/iterator/ProducerIterator.java
deleted file mode 100644
index e9e8bc9..0000000
--- a/src/org/codehaus/janino/util/iterator/ProducerIterator.java
+++ /dev/null
@@ -1,75 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino.util.iterator;
-
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
-import org.codehaus.janino.util.Producer;
-
-/**
- * An {@link java.util.Iterator} that iterates over all the objects produced by a delegate
- * {@link org.codehaus.janino.util.Producer}.
- *
- * @see org.codehaus.janino.util.Producer
- */
-public class ProducerIterator implements Iterator {
- private final Producer producer;
-
- private static final Object UNKNOWN = new Object();
- private static final Object AT_END = null;
- private Object nextElement = UNKNOWN;
-
- public ProducerIterator(Producer producer) {
- this.producer = producer;
- }
-
- public boolean hasNext() {
- if (this.nextElement == UNKNOWN) this.nextElement = this.producer.produce();
- return this.nextElement != AT_END;
- }
-
- public Object next() {
- if (this.nextElement == UNKNOWN) this.nextElement = this.producer.produce();
- if (this.nextElement == AT_END) throw new NoSuchElementException();
- Object result = this.nextElement;
- this.nextElement = UNKNOWN;
- return result;
- }
-
- public void remove() {
- throw new UnsupportedOperationException("remove");
- }
-}
diff --git a/src/org/codehaus/janino/util/iterator/ReverseListIterator.java b/src/org/codehaus/janino/util/iterator/ReverseListIterator.java
deleted file mode 100644
index 9e76452..0000000
--- a/src/org/codehaus/janino/util/iterator/ReverseListIterator.java
+++ /dev/null
@@ -1,61 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino.util.iterator;
-
-import java.util.*;
-
-/**
- * A {@link java.util.ListIterator} that reverses the direction of all operations
- * of a delegate {@link java.util.ListIterator}.
- */
-public class ReverseListIterator extends FilterListIterator {
- /** */
- public ReverseListIterator(ListIterator delegate) {
- super(delegate);
- }
-
- /** Calls {@link #delegate}.{@link java.util.ListIterator#hasPrevious()} */
- public boolean hasNext() { return super.hasPrevious(); }
- /** Calls {@link #delegate}.{@link java.util.ListIterator#hasNext()} */
- public boolean hasPrevious() { return super.hasNext(); }
- /** Calls {@link #delegate}.{@link java.util.ListIterator#previous()} */
- public Object next() { return super.previous(); }
- /** Calls {@link #delegate}.{@link java.util.ListIterator#next()} */
- public Object previous() { return super.next(); }
- /** Throws an {@link UnsupportedOperationException}. */
- public int nextIndex() { throw new UnsupportedOperationException(); }
- /** Throws an {@link UnsupportedOperationException}. */
- public int previousIndex() { throw new UnsupportedOperationException(); }
-}
diff --git a/src/org/codehaus/janino/util/iterator/TransformingIterator.java b/src/org/codehaus/janino/util/iterator/TransformingIterator.java
deleted file mode 100644
index 4feba37..0000000
--- a/src/org/codehaus/janino/util/iterator/TransformingIterator.java
+++ /dev/null
@@ -1,56 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino.util.iterator;
-
-import java.util.*;
-
-/**
- * An {@link java.util.Iterator} that transforms its elements on-the-fly.
- */
-public abstract class TransformingIterator extends FilterIterator {
- public TransformingIterator(Iterator delegate) {
- super(delegate);
- }
-
- public final Object next() {
- return this.transform(this.delegate.next());
- }
-
- /**
- * Derived classes must implement this method such that it does the
- * desired transformation.
- */
- protected abstract Object transform(Object o);
-}
diff --git a/src/org/codehaus/janino/util/iterator/TraversingIterator.java b/src/org/codehaus/janino/util/iterator/TraversingIterator.java
deleted file mode 100644
index 1937b56..0000000
--- a/src/org/codehaus/janino/util/iterator/TraversingIterator.java
+++ /dev/null
@@ -1,100 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino.util.iterator;
-
-import java.util.*;
-
-/**
- * An {@link java.util.Iterator} that iterates over a delegate, and while
- * it encounters an array, a {@link java.util.Collection}, an
- * {@link java.util.Enumeration} or a {@link java.util.Iterator} element, it iterates
- * into it recursively.
- * <p>
- * Be aware that {@link #hasNext()} must read ahead one element.
- */
-public class TraversingIterator implements Iterator {
- private final Stack nest = new Stack(); // Iterator
- private Object nextElement = null;
- private boolean nextElementRead = false; // Have we read ahead?
-
- public TraversingIterator(Iterator delegate) {
- this.nest.push(delegate);
- }
-
- public boolean hasNext() {
- return this.nextElementRead || this.readNext();
- }
-
- public Object next() {
- if (!this.nextElementRead && !this.readNext()) throw new NoSuchElementException();
- this.nextElementRead = false;
- return this.nextElement;
- }
-
- /**
- * Reads the next element and stores it in {@link #nextElement}.
- * @return <code>false</code> if no more element can be read.
- */
- private boolean readNext() {
- while (!this.nest.empty()) {
- Iterator it = (Iterator) this.nest.peek();
- if (!it.hasNext()) {
- this.nest.pop();
- continue;
- }
- Object o = it.next();
- if (o instanceof Iterator) {
- this.nest.push(o);
- } else
- if (o instanceof Object[]) {
- this.nest.push(Arrays.asList((Object[]) o).iterator());
- } else
- if (o instanceof Collection) {
- this.nest.push(((Collection) o).iterator());
- } else
- if (o instanceof Enumeration) {
- this.nest.push(new EnumerationIterator((Enumeration) o));
- } else
- {
- this.nextElement = o;
- this.nextElementRead = true;
- return true;
- }
- }
- return false;
- }
-
- public void remove() { throw new UnsupportedOperationException("remove"); }
-}
diff --git a/src/org/codehaus/janino/util/iterator/UniterableElementException.java b/src/org/codehaus/janino/util/iterator/UniterableElementException.java
deleted file mode 100644
index 291fef6..0000000
--- a/src/org/codehaus/janino/util/iterator/UniterableElementException.java
+++ /dev/null
@@ -1,44 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino.util.iterator;
-
-/**
- * Thrown by {@link org.codehaus.janino.util.iterator.MultiDimensionalIterator} to
- * indicate that it has encountered an element that cannot be iterated.
- */
-public class UniterableElementException extends RuntimeException {
- /** */
- public UniterableElementException() {}
-}
diff --git a/src/org/codehaus/janino/util/iterator/package.html b/src/org/codehaus/janino/util/iterator/package.html
deleted file mode 100644
index 6968038..0000000
--- a/src/org/codehaus/janino/util/iterator/package.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<html><body>
- Some generic {@link java.util.Iterator}-related helper classes.
-</body></html>
diff --git a/src/org/codehaus/janino/util/package.html b/src/org/codehaus/janino/util/package.html
deleted file mode 100644
index 95aeb4d..0000000
--- a/src/org/codehaus/janino/util/package.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<html><body>
- Application-independent helper classes.
-</body></html>
diff --git a/src/org/codehaus/janino/util/resource/DirectoryResourceCreator.java b/src/org/codehaus/janino/util/resource/DirectoryResourceCreator.java
deleted file mode 100644
index a2385cc..0000000
--- a/src/org/codehaus/janino/util/resource/DirectoryResourceCreator.java
+++ /dev/null
@@ -1,53 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino.util.resource;
-
-import java.io.*;
-
-/**
- * Creates a resource in a given directory:<pre>
- * <i>destinationDirectory</i>/<i>resourceName</i></pre>
- */
-public class DirectoryResourceCreator extends FileResourceCreator {
- private final File destinationDirectory;
-
- public DirectoryResourceCreator(File destinationDirectory) {
- this.destinationDirectory = destinationDirectory;
- }
-
- protected File getFile(String resourceName) {
- return new File(this.destinationDirectory, resourceName.replace('/', File.separatorChar));
- }
-}
diff --git a/src/org/codehaus/janino/util/resource/DirectoryResourceFinder.java b/src/org/codehaus/janino/util/resource/DirectoryResourceFinder.java
deleted file mode 100644
index 72147f0..0000000
--- a/src/org/codehaus/janino/util/resource/DirectoryResourceFinder.java
+++ /dev/null
@@ -1,85 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino.util.resource;
-
-import java.io.*;
-import java.util.*;
-
-/**
- * A {@link org.codehaus.janino.util.resource.FileResourceFinder} that finds file resources in
- * a directory. The name of the file is constructed by concatenating a dirctory name
- * with the resource name such that slashes in the resource name map to file
- * separators.
- */
-public class DirectoryResourceFinder extends FileResourceFinder {
- private final File directory;
- private final Map subdirectoryNameToFiles = new HashMap(); // String directoryName => Set => File
-
- /**
- * @param directory the directory to use as the search base
- */
- public DirectoryResourceFinder(File directory) {
- this.directory = directory;
- }
-
- public String toString() { return "dir:" + this.directory; }
-
- // Implement FileResourceFinder.
- protected File findResourceAsFile(String resourceName) {
-
- // Determine the subdirectory name (null for no subdirectory).
- int idx = resourceName.lastIndexOf('/');
- String subdirectoryName = (
- idx == -1 ? null :
- resourceName.substring(0, idx).replace('/', File.separatorChar)
- );
-
- // Determine files existing in this subdirectory.
- Set files = (Set) this.subdirectoryNameToFiles.get(subdirectoryName); // String directoryName => Set => File
- if (files == null) {
- File subDirectory = (subdirectoryName == null) ? this.directory : new File(this.directory, subdirectoryName);
- File[] fa = subDirectory.listFiles();
- files = (fa == null) ? Collections.EMPTY_SET : new HashSet(Arrays.asList(fa));
- this.subdirectoryNameToFiles.put(subdirectoryName, files);
- }
-
- // Notice that "File.equals()" performs all the file-system dependent
- // magic like case conversion.
- File file = new File(this.directory, resourceName.replace('/', File.separatorChar));
- if (!files.contains(file)) return null;
-
- return file;
- }
-}
diff --git a/src/org/codehaus/janino/util/resource/FileResource.java b/src/org/codehaus/janino/util/resource/FileResource.java
deleted file mode 100644
index d72d17b..0000000
--- a/src/org/codehaus/janino/util/resource/FileResource.java
+++ /dev/null
@@ -1,55 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino.util.resource;
-
-import java.io.*;
-
-/**
- * Representation of a resource that is a {@link java.io.File}.
- */
-public class FileResource implements Resource {
- public FileResource(File file) { this.file = file; }
-
- // Implement "Resource".
- public final String getFileName() { return this.file.toString(); }
- public final InputStream open() throws IOException { return new FileInputStream(this.file); }
- public final long lastModified() { return this.file.lastModified(); }
-
- public File getFile() { return this.file; }
-
- public String toString() { return this.getFileName(); }
-
- private final File file;
-}
diff --git a/src/org/codehaus/janino/util/resource/FileResourceCreator.java b/src/org/codehaus/janino/util/resource/FileResourceCreator.java
deleted file mode 100644
index e65a309..0000000
--- a/src/org/codehaus/janino/util/resource/FileResourceCreator.java
+++ /dev/null
@@ -1,62 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino.util.resource;
-
-import java.io.*;
-
-/**
- * Stores a stream of bytes in a named resource.
- */
-public abstract class FileResourceCreator implements ResourceCreator {
-
- public final OutputStream createResource(String resourceName) throws IOException {
- File file = this.getFile(resourceName);
-
- // Create directory for class file if it does not exist.
- File dir = file.getParentFile();
- if (dir != null && !dir.isDirectory()) {
- if (!dir.mkdirs()) throw new IOException("Cannot create directory for class file \"" + file + "\"");
- }
-
- // Create the file.
- return new FileOutputStream(file);
- }
-
- public final boolean deleteResource(String resourceName) {
- return this.getFile(resourceName).delete();
- }
-
- protected abstract File getFile(String resourceName);
-}
diff --git a/src/org/codehaus/janino/util/resource/FileResourceFinder.java b/src/org/codehaus/janino/util/resource/FileResourceFinder.java
deleted file mode 100644
index c8816af..0000000
--- a/src/org/codehaus/janino/util/resource/FileResourceFinder.java
+++ /dev/null
@@ -1,57 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino.util.resource;
-
-import java.io.*;
-
-/**
- * This class specializes the {@link org.codehaus.janino.util.resource.ResourceFinder}
- * for finding resources in {@link java.io.File}s.
- * <p>
- * It finds {@link FileResource}s instead of simple
- * {@link Resource}s.
- */
-public abstract class FileResourceFinder extends ResourceFinder {
- public final Resource findResource(String resourceName) {
- File file = this.findResourceAsFile(resourceName);
- if (file == null) return null;
- return new FileResource(file);
- }
-
- /**
- * Converts a given resource resource name into a {@link File}.
- */
- protected abstract File findResourceAsFile(String resourceName);
-}
diff --git a/src/org/codehaus/janino/util/resource/JarDirectoriesResourceFinder.java b/src/org/codehaus/janino/util/resource/JarDirectoriesResourceFinder.java
deleted file mode 100644
index d41c597..0000000
--- a/src/org/codehaus/janino/util/resource/JarDirectoriesResourceFinder.java
+++ /dev/null
@@ -1,80 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino.util.resource;
-
-import java.io.*;
-import java.util.*;
-import java.util.zip.*;
-
-import org.codehaus.janino.util.iterator.*;
-
-/**
- * Finds resources in any of the "*.jar" files that exist in a given set of directories.
- */
-public class JarDirectoriesResourceFinder extends LazyMultiResourceFinder {
-
- /**
- * @param directories The set of directories to search for JAR files.
- */
- public JarDirectoriesResourceFinder(final File[] directories) {
- super(new MultiDimensionalIterator(
-
- // Iterate over directories.
- new TransformingIterator(Arrays.asList(directories).iterator()) {
- protected Object transform(Object o) { // File directory => Iterator ResourceFinder
- File directory = (File) o;
-
- if (!directory.exists()) return Collections.EMPTY_LIST.iterator();
-
- // Iterate over the JAR files in the given directory.
- File[] jarFiles = directory.listFiles(new FilenameFilter() {
- public boolean accept(File dir, String name) { return name.endsWith(".jar"); }
- });
- return new TransformingIterator(Arrays.asList(jarFiles).iterator()) {
- protected Object transform(Object o) { // File jarFile => ResourceFinder
- File zipFile = (File) o;
- try {
- return new ZipFileResourceFinder(new ZipFile(zipFile));
- } catch (IOException e) {
- return ResourceFinder.EMPTY_RESOURCE_FINDER;
- }
- }
- };
- }
- },
- 2
- ));
- }
-}
diff --git a/src/org/codehaus/janino/util/resource/LazyMultiResourceFinder.java b/src/org/codehaus/janino/util/resource/LazyMultiResourceFinder.java
deleted file mode 100644
index eb24f7d..0000000
--- a/src/org/codehaus/janino/util/resource/LazyMultiResourceFinder.java
+++ /dev/null
@@ -1,57 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino.util.resource;
-
-import java.util.*;
-
-import org.codehaus.janino.util.iterator.IteratorCollection;
-
-
-/**
- * A {@link org.codehaus.janino.util.resource.ResourceFinder} that examines a set
- * of {@link org.codehaus.janino.util.resource.ResourceFinder}s lazily as it
- * searches for resources.
- *
- * @see org.codehaus.janino.util.iterator.IteratorCollection
- */
-public class LazyMultiResourceFinder extends MultiResourceFinder {
-
- /**
- * @param resourceFinders delegate {@link ResourceFinder}s
- */
- public LazyMultiResourceFinder(Iterator resourceFinders) {
- super(new IteratorCollection(resourceFinders));
- }
-}
diff --git a/src/org/codehaus/janino/util/resource/MapResourceCreator.java b/src/org/codehaus/janino/util/resource/MapResourceCreator.java
deleted file mode 100644
index 5bdb605..0000000
--- a/src/org/codehaus/janino/util/resource/MapResourceCreator.java
+++ /dev/null
@@ -1,71 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino.util.resource;
-
-import java.io.*;
-import java.util.*;
-
-/**
- * Creates resources as byte arrays in a delegate {@link java.util.Map}.
- */
-public class MapResourceCreator implements ResourceCreator {
- private final Map map;
-
- /**
- * Auto-create the delegate {@link Map}.
- */
- public MapResourceCreator() {
- this.map = new HashMap();
- }
- public MapResourceCreator(Map map) {
- this.map = map;
- }
- public Map getMap() {
- return this.map;
- }
-
- public OutputStream createResource(final String resourceName) throws IOException {
- return new ByteArrayOutputStream() {
- public void close() throws IOException {
- super.close();
- MapResourceCreator.this.map.put(resourceName, this.toByteArray());
- }
- };
- }
-
- public boolean deleteResource(String resourceName) {
- return this.map.remove(resourceName) != null;
- }
-}
diff --git a/src/org/codehaus/janino/util/resource/MapResourceFinder.java b/src/org/codehaus/janino/util/resource/MapResourceFinder.java
deleted file mode 100644
index ec24469..0000000
--- a/src/org/codehaus/janino/util/resource/MapResourceFinder.java
+++ /dev/null
@@ -1,65 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino.util.resource;
-
-import java.io.*;
-import java.util.*;
-
-/**
- * A {@link org.codehaus.janino.util.resource.ResourceFinder} that provides access
- * to resource stored as byte arrays in a {@link java.util.Map}.
- */
-public class MapResourceFinder extends ResourceFinder {
- private final Map map;
- private long lastModified = 0L;
-
- public MapResourceFinder(Map map) {
- this.map = map;
- }
- public void setLastModified(long lastModified) {
- this.lastModified = lastModified;
- }
-
- public final Resource findResource(final String resourceName) {
- final byte[] ba = (byte[]) this.map.get(resourceName);
- if (ba == null) return null;
-
- return new Resource() {
- public InputStream open() throws IOException { return new ByteArrayInputStream(ba); }
- public String getFileName() { return resourceName; }
- public long lastModified() { return MapResourceFinder.this.lastModified; }
- };
- }
-}
diff --git a/src/org/codehaus/janino/util/resource/MultiResourceFinder.java b/src/org/codehaus/janino/util/resource/MultiResourceFinder.java
deleted file mode 100644
index 64e1041..0000000
--- a/src/org/codehaus/janino/util/resource/MultiResourceFinder.java
+++ /dev/null
@@ -1,64 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino.util.resource;
-
-import java.util.*;
-
-/**
- * A {@link org.codehaus.janino.util.resource.ResourceFinder} that finds its resources through a collection of
- * other {@link org.codehaus.janino.util.resource.ResourceFinder}s.
- */
-public class MultiResourceFinder extends ResourceFinder {
- private final Collection resourceFinders; // One for each entry
-
- /**
- * @param resourceFinders The entries of the "path"
- */
- public MultiResourceFinder(Collection resourceFinders) {
- this.resourceFinders = resourceFinders;
- }
-
- // Implement ResourceFinder.
-
- public Resource findResource(String resourceName) {
- for (Iterator it = this.resourceFinders.iterator(); it.hasNext();) {
- ResourceFinder rf = (ResourceFinder) it.next();
- Resource resource = rf.findResource(resourceName);
-//System.err.println("*** " + resourceName + " in " + rf + "? => " + url);
- if (resource != null) return resource;
- }
- return null;
- }
-}
diff --git a/src/org/codehaus/janino/util/resource/PathResourceFinder.java b/src/org/codehaus/janino/util/resource/PathResourceFinder.java
deleted file mode 100644
index 418a3a5..0000000
--- a/src/org/codehaus/janino/util/resource/PathResourceFinder.java
+++ /dev/null
@@ -1,145 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino.util.resource;
-
-import java.io.*;
-import java.util.*;
-import java.util.zip.*;
-
-import org.codehaus.janino.util.iterator.*;
-
-
-/**
- * A {@link org.codehaus.janino.util.resource.ResourceFinder} that finds its resources along a "path"
- * consisting of JAR file names, ZIP file names, and directory names.
- * @see org.codehaus.janino.util.resource.ZipFileResourceFinder
- * @see org.codehaus.janino.util.resource.DirectoryResourceFinder
- */
-public class PathResourceFinder extends LazyMultiResourceFinder {
-
- /**
- * @param entries The entries of the "path"
- */
- public PathResourceFinder(final File[] entries) {
- super(PathResourceFinder.createIterator(Arrays.asList(entries).iterator()));
- }
-
- /**
- * @param entries The entries of the "path" (type must be {@link File})
- */
- public PathResourceFinder(Iterator entries) {
- super(entries);
- }
-
- /**
- * @param path A java-like path, i.e. a "path separator"-separated list of entries.
- */
- public PathResourceFinder(String path) {
- this(PathResourceFinder.parsePath(path));
- }
-
- private static Iterator createIterator(final Iterator entries) {
- return new TransformingIterator(entries) {
- protected Object transform(Object o) {
- return PathResourceFinder.createResourceFinder((File) o);
- }
- };
- }
-
- /**
- * Break a given string up by the system-dependent path-separator character (on UNIX systems,
- * this character is ':'; on Microsoft Windows systems it is ';'). Empty components are
- * ignored.
- * <p>
- * UNIX Examples:
- * <dl>
- * <dt>A:B:C <dd>A, B, C
- * <dt>::B: <dd>B
- * <dt>:A <dd>A
- * <dt>(Empty string) <dd>(Zero components)
- * </dl>
- *
- * @see File#pathSeparatorChar
- */
- public static File[] parsePath(String s) {
- int from = 0;
- List l = new ArrayList(); // File
- for (;;) {
- int to = s.indexOf(File.pathSeparatorChar, from);
- if (to == -1) {
- if (from != s.length()) l.add(new File(s.substring(from)));
- break;
- }
- if (to != from) l.add(new File(s.substring(from, to)));
- from = to + 1;
- }
- return (File[]) l.toArray(new File[l.size()]);
- }
-
- /**
- * A factory method that creates a Java classpath-style ResourceFinder as
- * follows:
- * <table>
- * <tr><th><code>entry</code></th><th>Returned {@link ResourceFinder}</th></tr>
- * <tr><td>"*.jar" file</td><td>{@link ZipFileResourceFinder}</td></tr>
- * <tr><td>"*.zip" file</td><td>{@link ZipFileResourceFinder}</td></tr>
- * <tr><td>directory</td><td>{@link DirectoryResourceFinder}</td></tr>
- * <tr><td>any other</td><td>A {@link ResourceFinder} that never finds a resource</td></tr>
- * </table>
- * @return a valid {@link ResourceFinder}
- */
- private static ResourceFinder createResourceFinder(final File entry) {
-
- // ZIP file or JAR file.
- if (
- (entry.getName().endsWith(".jar") || entry.getName().endsWith(".zip")) &&
- entry.isFile()
- ) {
- try {
- return new ZipFileResourceFinder(new ZipFile(entry));
- } catch (IOException e) {
- return ResourceFinder.EMPTY_RESOURCE_FINDER;
- }
- }
-
- // Directory.
- if (entry.isDirectory()) {
- return new DirectoryResourceFinder(entry);
- }
-
- // Invalid entry.
- return ResourceFinder.EMPTY_RESOURCE_FINDER;
- }
-}
diff --git a/src/org/codehaus/janino/util/resource/Resource.java b/src/org/codehaus/janino/util/resource/Resource.java
deleted file mode 100644
index b237b9a..0000000
--- a/src/org/codehaus/janino/util/resource/Resource.java
+++ /dev/null
@@ -1,73 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino.util.resource;
-
-import java.io.*;
-
-
-/**
- * A {@link Resource} is "something" that is typically found by a
- * {@link org.codehaus.janino.util.resource.ResourceFinder}, can be {@link #open()}ed for
- * reading, and optionally has a {@link #lastModified()} property.
- * <p>
- * There also exists a {@link org.codehaus.janino.util.resource.ResourceCreator} concept which
- * opens a resource for writing, but that happens directly and not through an intermediate
- * {@link Resource} object.
- *
- * @see org.codehaus.janino.util.resource.ResourceFinder
- * @see org.codehaus.janino.util.resource.ResourceCreator
- */
-public interface Resource {
-
- /**
- * Opens the resource. The caller is responsible for closing the
- * {@link java.io.InputStream}.
- */
- InputStream open() throws IOException;
-
- /**
- * Returns a decorative "file name" that can be used for reporting
- * errors and the like. It does not necessarily map to a file in the
- * local file system!
- */
- String getFileName();
-
- /**
- * Returns the time of the last modification, in milliseconds since
- * 1970, or <code>0L</code> if the time of the last modification cannot
- * be determined.
- */
- long lastModified();
-}
diff --git a/src/org/codehaus/janino/util/resource/ResourceCreator.java b/src/org/codehaus/janino/util/resource/ResourceCreator.java
deleted file mode 100644
index c2a097c..0000000
--- a/src/org/codehaus/janino/util/resource/ResourceCreator.java
+++ /dev/null
@@ -1,64 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino.util.resource;
-
-import java.io.*;
-
-/**
- * Opens a resource, characterized by a name, for writing.
- * <p>
- * There also exists a concept {@link org.codehaus.janino.util.resource.ResourceFinder} that
- * finds {@link org.codehaus.janino.util.resource.Resource}s for reading.
- *
- * @see org.codehaus.janino.util.resource.ResourceFinder
- */
-public interface ResourceCreator {
-
- /**
- * Create the designated resource.
- *
- * @param resourceName Designates the resource; typically structured by slashes ("/") like "<code>com/foo/pkg/Bar.class</code>"
- * @return bytes written to this {@link OutputStream} are stored in the resource
- * @throws IOException Problems creating the resource
- */
- public abstract OutputStream createResource(String resourceName) throws IOException;
-
- /**
- * Deletes the resource with the given name.
- *
- * @return <code>false</code> if the resource could not be deleted
- */
- public abstract boolean deleteResource(String resourceName);
-}
diff --git a/src/org/codehaus/janino/util/resource/ResourceFinder.java b/src/org/codehaus/janino/util/resource/ResourceFinder.java
deleted file mode 100644
index c9c04dd..0000000
--- a/src/org/codehaus/janino/util/resource/ResourceFinder.java
+++ /dev/null
@@ -1,79 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino.util.resource;
-
-import java.io.*;
-
-/**
- * Finds a resource by name.
- * <p>
- * Notice that there is a symmetrical concept
- * {@link org.codehaus.janino.util.resource.ResourceCreator} that creates resources for
- * writing.
- *
- * @see org.codehaus.janino.util.resource.ResourceCreator
- */
-public abstract class ResourceFinder {
-
- /**
- * Find a resource by name and open it for reading.
- *
- * @param resourceName Designates the resource; typically structured by slashes ("/") like "<code>com/foo/pkg/Bar.class</code>"
- * @return <code>null</code> if the resource could not be found
- * @throws IOException The resource was found, but there are problems opening it
- */
- public final InputStream findResourceAsStream(String resourceName) throws IOException {
- Resource resource = this.findResource(resourceName);
- if (resource == null) return null;
- return resource.open();
- }
-
- /**
- * Find a resource by name and return it as a {@link Resource} object.
- *
- * @param resourceName Designates the resource; typically structured by slashes ("/") like "<code>com/foo/pkg/Bar.class</code>"
- * @return <code>null</code> if the resource could not be found
- */
- public abstract Resource findResource(String resourceName);
-
- /**
- * This one's useful when a resource finder is required, but cannot be created
- * for some reason.
- */
- public static final ResourceFinder EMPTY_RESOURCE_FINDER = new ResourceFinder() {
- public Resource findResource(String resourceName) { return null; }
- public String toString() { return "invalid entry"; }
- };
-}
diff --git a/src/org/codehaus/janino/util/resource/ZipFileResourceFinder.java b/src/org/codehaus/janino/util/resource/ZipFileResourceFinder.java
deleted file mode 100644
index 490ece2..0000000
--- a/src/org/codehaus/janino/util/resource/ZipFileResourceFinder.java
+++ /dev/null
@@ -1,71 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codehaus.janino.util.resource;
-
-import java.io.*;
-import java.util.zip.*;
-
-/**
- * A {@link org.codehaus.janino.util.resource.ResourceFinder} that finds resources in a ZIP file.
- */
-public class ZipFileResourceFinder extends ResourceFinder {
- private final ZipFile zipFile;
-
- public ZipFileResourceFinder(ZipFile zipFile) {
- this.zipFile = zipFile;
- }
- public String toString() { return "zip:" + this.zipFile.getName(); }
-
- // Implement ResourceFinder.
-
- public Resource findResource(final String resourceName) {
- final ZipEntry ze = this.zipFile.getEntry(resourceName);
- if (ze == null) return null;
- return new Resource() {
- public InputStream open() throws IOException {
- return ZipFileResourceFinder.this.zipFile.getInputStream(ze);
- }
- public String getFileName() {
- return ZipFileResourceFinder.this.zipFile.getName() + ':' + resourceName;
- }
- public long lastModified() {
- long l = ze.getTime();
- return l == -1L ? 0L : l;
- }
-
- public String toString() { return this.getFileName(); }
- };
- }
-}
diff --git a/src/org/codehaus/janino/util/resource/package.html b/src/org/codehaus/janino/util/resource/package.html
deleted file mode 100644
index 7300054..0000000
--- a/src/org/codehaus/janino/util/resource/package.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<html><body>
- Classes related to loading "resources"
- ({@link org.codehaus.janino.util.resource.ResourceFinder}) and
- creating resources
- ({@link org.codehaus.janino.util.resource.ResourceCreator}).
-</body></html>
diff --git a/src/overview.html b/src/overview.html
deleted file mode 100644
index 9842631..0000000
--- a/src/overview.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<body>
- <p>
- <i>Janino</i>, an embedded compiler for the Java<sup>TM</sup>
- programming language.
- </p>
- <p>
- For download, documentation and contact see <a href="http://janino.codehaus.org">http://janino.codehaus.org</a>.
- </p>
-</body>
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/janino.git
More information about the pkg-java-commits
mailing list