0001: /*
0002: * Janino - An embedded Java[TM] compiler
0003: *
0004: * Copyright (c) 2006, Arno Unkrig
0005: * All rights reserved.
0006: *
0007: * Redistribution and use in source and binary forms, with or without
0008: * modification, are permitted provided that the following conditions
0009: * are met:
0010: *
0011: * 1. Redistributions of source code must retain the above copyright
0012: * notice, this list of conditions and the following disclaimer.
0013: * 2. Redistributions in binary form must reproduce the above
0014: * copyright notice, this list of conditions and the following
0015: * disclaimer in the documentation and/or other materials
0016: * provided with the distribution.
0017: * 3. The name of the author may not be used to endorse or promote
0018: * products derived from this software without specific prior
0019: * written permission.
0020: *
0021: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
0022: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
0023: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0024: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
0025: * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
0026: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
0027: * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0028: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
0029: * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
0030: * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
0031: * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0032: */
0033:
0034: package org.codehaus.janino;
0035:
0036: import java.util.*;
0037:
0038: import org.codehaus.janino.util.*;
0039: import org.codehaus.janino.util.iterator.*;
0040:
0041: /**
0042: * This wrapper class defines classes that represent the elements of the
0043: * Java<sup>TM</sup> programming language.
0044: * <p>
0045: * Notices:
0046: * <ul>
0047: * <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>.
0048: * <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>.
0049: * </ul>
0050: */
0051:
0052: public class Java {
0053: private Java() {
0054: } // Don't instantiate me.
0055:
0056: public interface Scope {
0057: public Scope getEnclosingScope();
0058: }
0059:
0060: /**
0061: * This interface is implemented by objects which are associated with a
0062: * location in the source code.
0063: */
0064: public interface Locatable {
0065: public Location getLocation();
0066:
0067: /**
0068: * Throw a {@link Parser.ParseException} with the given message and this
0069: * object's location.
0070: *
0071: * @param message The message to report
0072: */
0073: public void throwParseException(String message)
0074: throws Parser.ParseException;
0075: }
0076:
0077: public static abstract class Located implements Locatable {
0078: private final Location location;
0079:
0080: protected Located(Location location) {
0081: this .location = location;
0082: }
0083:
0084: // Implement "Locatable".
0085:
0086: public Location getLocation() {
0087: return this .location;
0088: }
0089:
0090: public void throwParseException(String message)
0091: throws Parser.ParseException {
0092: throw new Parser.ParseException(message, this .location);
0093: }
0094: }
0095:
0096: /**
0097: * Holds the result of {@link Parser#parseCompilationUnit}.
0098: */
0099: public static final class CompilationUnit implements Scope {
0100: public/*final*/String optionalFileName;
0101: public PackageDeclaration optionalPackageDeclaration = null;
0102: public final List importDeclarations = new ArrayList(); // ImportDeclaration
0103: public final List packageMemberTypeDeclarations = new ArrayList(); // PackageMemberTypeDeclaration
0104:
0105: public CompilationUnit(String optionalFileName) {
0106: this .optionalFileName = optionalFileName;
0107: }
0108:
0109: // Implement "Scope".
0110: public Scope getEnclosingScope() {
0111: throw new RuntimeException(
0112: "A compilation unit has no enclosing scope");
0113: }
0114:
0115: public void setPackageDeclaration(
0116: PackageDeclaration packageDeclaration) {
0117: if (this .optionalPackageDeclaration != null)
0118: throw new RuntimeException(
0119: "Re-setting package declaration");
0120: this .optionalPackageDeclaration = packageDeclaration;
0121: }
0122:
0123: public void addImportDeclaration(
0124: CompilationUnit.ImportDeclaration id)
0125: throws Parser.ParseException {
0126:
0127: // Check for conflicting single-type import.
0128: if (id instanceof CompilationUnit.SingleTypeImportDeclaration) {
0129: String[] ss = ((CompilationUnit.SingleTypeImportDeclaration) id).identifiers;
0130: String name = ss[ss.length - 1];
0131: for (Iterator it = this .importDeclarations.iterator(); it
0132: .hasNext();) {
0133: CompilationUnit.ImportDeclaration id2 = (CompilationUnit.ImportDeclaration) it
0134: .next();
0135: if (id2 instanceof CompilationUnit.SingleTypeImportDeclaration) {
0136: String[] ss2 = ((CompilationUnit.SingleTypeImportDeclaration) id2).identifiers;
0137: if (ss2[ss2.length - 1].equals(name)) {
0138: if (!Java.join(ss, ".").equals(
0139: Java.join(ss2, ".")))
0140: id
0141: .throwParseException("Class \""
0142: + name
0143: + "\" was first imported from \""
0144: + Java.join(ss, ".")
0145: + "\", now again from \""
0146: + Java.join(ss2, ".")
0147: + "\"");
0148: }
0149: }
0150: }
0151: }
0152: this .importDeclarations.add(id);
0153: }
0154:
0155: public void addPackageMemberTypeDeclaration(
0156: PackageMemberTypeDeclaration pmtd) {
0157: this .packageMemberTypeDeclarations.add(pmtd);
0158: pmtd.setDeclaringCompilationUnit(this );
0159: }
0160:
0161: /**
0162: * Get all classes and interfaces declared in this compilation unit.
0163: */
0164: public PackageMemberTypeDeclaration[] getPackageMemberTypeDeclarations() {
0165: return (PackageMemberTypeDeclaration[]) this .packageMemberTypeDeclarations
0166: .toArray(new PackageMemberTypeDeclaration[this .packageMemberTypeDeclarations
0167: .size()]);
0168: }
0169:
0170: /**
0171: * Return the package member class or interface declared with the given name.
0172: * @param name Declared (i.e. not the fully qualified) name
0173: * @return <code>null</code> if a package member type with that name is not declared in this compilation unit
0174: */
0175: public PackageMemberTypeDeclaration getPackageMemberTypeDeclaration(
0176: String name) {
0177: for (Iterator it = this .packageMemberTypeDeclarations
0178: .iterator(); it.hasNext();) {
0179: PackageMemberTypeDeclaration pmtd = (PackageMemberTypeDeclaration) it
0180: .next();
0181: if (pmtd.getName().equals(name))
0182: return pmtd;
0183: }
0184: return null;
0185: }
0186:
0187: /**
0188: * Check if the given name was imported through a "single type import", e.g.<pre>
0189: * import java.util.Map</pre>
0190: *
0191: * @return the fully qualified name or <code>null</code>
0192: */
0193: public String[] getSingleTypeImport(String name) {
0194: for (Iterator it = this .importDeclarations.iterator(); it
0195: .hasNext();) {
0196: CompilationUnit.ImportDeclaration id = (CompilationUnit.ImportDeclaration) it
0197: .next();
0198: if (id instanceof CompilationUnit.SingleTypeImportDeclaration) {
0199: String[] ss = ((CompilationUnit.SingleTypeImportDeclaration) id).identifiers;
0200: if (ss[ss.length - 1].equals(name))
0201: return ss;
0202: }
0203: }
0204: return null;
0205: }
0206:
0207: /**
0208: * Represents a type-import-on-demand like<pre>
0209: * import java.util.*;</pre>
0210: */
0211: public static class TypeImportOnDemandDeclaration extends
0212: ImportDeclaration {
0213: public final String[] identifiers;
0214:
0215: public TypeImportOnDemandDeclaration(Location location,
0216: String[] identifiers) {
0217: super (location);
0218: this .identifiers = identifiers;
0219: }
0220:
0221: public final void accept(
0222: Visitor.ComprehensiveVisitor visitor) {
0223: visitor.visitTypeImportOnDemandDeclaration(this );
0224: }
0225: }
0226:
0227: /**
0228: * Represents a single type import like<pre>
0229: * import java.util.Map;</pre>
0230: */
0231: public static class SingleTypeImportDeclaration extends
0232: ImportDeclaration {
0233: public final String[] identifiers;
0234:
0235: public SingleTypeImportDeclaration(Location location,
0236: String[] identifiers) {
0237: super (location);
0238: this .identifiers = identifiers;
0239: }
0240:
0241: public final void accept(
0242: Visitor.ComprehensiveVisitor visitor) {
0243: visitor.visitSingleTypeImportDeclaration(this );
0244: }
0245: }
0246:
0247: public abstract static class ImportDeclaration extends
0248: Java.Located {
0249: public ImportDeclaration(Location location) {
0250: super (location);
0251: }
0252:
0253: public abstract void accept(
0254: Visitor.ComprehensiveVisitor visitor);
0255: }
0256: }
0257:
0258: /**
0259: * Represents a package declaration like<pre>
0260: * package com.acme.tools;</pre>
0261: */
0262: public static class PackageDeclaration extends Located {
0263: public final String packageName;
0264:
0265: public PackageDeclaration(Location location, String packageName) {
0266: super (location);
0267: this .packageName = packageName;
0268: }
0269: }
0270:
0271: public interface TypeDeclaration extends Locatable, Scope {
0272:
0273: /**
0274: * Return the member type with the given name.
0275: * @return <code>null</code> if a member type with that name is not declared
0276: */
0277: MemberTypeDeclaration getMemberTypeDeclaration(String name);
0278:
0279: /**
0280: * Determine the effective class name, e.g. "pkg.Outer$Inner".
0281: */
0282: String getClassName();
0283:
0284: /**
0285: * Creates a unique name for a local class or interface.
0286: */
0287: String createLocalTypeName(String localTypeName);
0288:
0289: /**
0290: * Creates a unique name for an anonymous class.
0291: */
0292: String createAnonymousClassName();
0293:
0294: void accept(Visitor.TypeDeclarationVisitor visitor);
0295: }
0296:
0297: public interface DocCommentable {
0298:
0299: /**
0300: * Returns the doc comment of the object or <code>null</code>.
0301: */
0302: public String getDocComment();
0303:
0304: /**
0305: * Returns <code>true</code> if the object has a doc comment and
0306: * the <code>@#deprecated</code> tag appears in the doc
0307: * comment.
0308: */
0309: public boolean hasDeprecatedDocTag();
0310: }
0311:
0312: /**
0313: * Represents a class or interface declaration on compilation unit level. These are called
0314: * "package member types" because they are immediate members of a package, e.g.
0315: * "java.lang.String".
0316: */
0317: public interface PackageMemberTypeDeclaration extends
0318: NamedTypeDeclaration {
0319: void setDeclaringCompilationUnit(
0320: CompilationUnit declaringCompilationUnit);
0321:
0322: CompilationUnit getDeclaringCompilationUnit();
0323: }
0324:
0325: /**
0326: * Represents a class or interface declaration where the immediately enclosing scope is
0327: * another class or interface declaration.
0328: */
0329: public interface MemberTypeDeclaration extends
0330: NamedTypeDeclaration, TypeBodyDeclaration {
0331: }
0332:
0333: /**
0334: * Represents the declaration of a class or an interface that has a name. (All type
0335: * declarations are named, except for anonymous classes.)
0336: */
0337: public interface NamedTypeDeclaration extends TypeDeclaration {
0338:
0339: /**
0340: * Returns the declared (not the fully qualified) name of the class or interface.
0341: */
0342: public String getName();
0343: }
0344:
0345: /**
0346: * Represents the declaration of an inner class, i.e. a class that exists in the context of
0347: * zero or more "enclosing instances". These are anonymous classes, local classes and member
0348: * classes.
0349: */
0350: interface InnerClassDeclaration extends TypeDeclaration {
0351:
0352: /**
0353: * Inner classes have zero or more synthetic fields that hold references to their enclosing
0354: * context:
0355: * <dl>
0356: * <dt><code>this$<i>n</i></code></dt>
0357: * <dd>
0358: * (Mandatory for non-private non-static member classes; optional for private non-static
0359: * member classes, local classes in non-static context, and anonymous classes in
0360: * non-static context; forbidden for static member classes, local classes in static
0361: * context, and anonymous classes in static context)
0362: * Holds a reference to the immediately enclosing instance. <code><i>n</i></code> is
0363: * N-1 for the Nth nesting level; e.g. the public non-static member class of a
0364: * package member class has a synthetic field <code>this$0</code>.
0365: * </dd>
0366: * <dt><code>val$<i>local-variable-name</i></code></dt>
0367: * <dd>
0368: * (Allowed for local classes and anonymous classes; forbidden for member classes)
0369: * Hold copies of <code>final</code> local variables of the defining context.
0370: * </dd>
0371: * </dl>
0372: * Notice that these fields are not included in the {@link IClass.IField} array returned
0373: * by {@link IClass#getDeclaredIFields()}.
0374: * <p>
0375: * If a synthetic field with the same name exists already, then it must have the same
0376: * type and the redefinition is ignored.
0377: * @param iField
0378: */
0379: void defineSyntheticField(IClass.IField iField)
0380: throws CompileException;
0381: }
0382:
0383: public abstract static class AbstractTypeDeclaration implements
0384: TypeDeclaration {
0385: private final Location location;
0386: public final short modifiers;
0387: public final List declaredMethods = new ArrayList(); // MethodDeclarator
0388: public final List declaredClassesAndInterfaces = new ArrayList(); // MemberTypeDeclaration
0389: private Scope enclosingScope = null;
0390:
0391: /*package*/IClass resolvedType = null;
0392:
0393: public AbstractTypeDeclaration(Location location,
0394: short modifiers) {
0395: this .location = location;
0396: this .modifiers = modifiers;
0397: }
0398:
0399: public void setEnclosingScope(Scope enclosingScope) {
0400: if (this .enclosingScope != null
0401: && enclosingScope != this .enclosingScope)
0402: throw new RuntimeException(
0403: "Enclosing scope is already set for type declaration \""
0404: + this .toString() + "\" at "
0405: + this .getLocation());
0406: this .enclosingScope = enclosingScope;
0407: }
0408:
0409: public Scope getEnclosingScope() {
0410: return this .enclosingScope;
0411: }
0412:
0413: public void addDeclaredMethod(MethodDeclarator method) {
0414: this .declaredMethods.add(method);
0415: method.setDeclaringType(this );
0416: }
0417:
0418: // Implement TypeDeclaration.
0419: public void addMemberTypeDeclaration(MemberTypeDeclaration mcoid) {
0420: this .declaredClassesAndInterfaces.add(mcoid);
0421: mcoid.setDeclaringType(this );
0422: }
0423:
0424: public Collection getMemberTypeDeclarations() {
0425: return this .declaredClassesAndInterfaces;
0426: }
0427:
0428: public MemberTypeDeclaration getMemberTypeDeclaration(
0429: String name) {
0430: for (Iterator it = this .declaredClassesAndInterfaces
0431: .iterator(); it.hasNext();) {
0432: MemberTypeDeclaration mtd = (MemberTypeDeclaration) it
0433: .next();
0434: if (mtd.getName().equals(name))
0435: return mtd;
0436: }
0437: return null;
0438: }
0439:
0440: public String createLocalTypeName(String localTypeName) {
0441: return (this .getClassName() + '$' + ++this .localClassCount
0442: + '$' + localTypeName);
0443: }
0444:
0445: public String createAnonymousClassName() {
0446: return (this .getClassName() + '$' + ++this .anonymousClassCount);
0447: }
0448:
0449: // Implement "Locatable".
0450: public Location getLocation() {
0451: return this .location;
0452: }
0453:
0454: public void throwParseException(String message)
0455: throws Parser.ParseException {
0456: throw new Parser.ParseException(message, this .location);
0457: }
0458:
0459: abstract public String toString();
0460:
0461: public int anonymousClassCount = 0; // For naming anonymous classes.
0462: public int localClassCount = 0; // For naming local classes.
0463: }
0464:
0465: public abstract static class ClassDeclaration extends
0466: AbstractTypeDeclaration {
0467: public final List constructors = new ArrayList(); // ConstructorDeclarator
0468: public final List variableDeclaratorsAndInitializers = new ArrayList(); // TypeBodyDeclaration
0469:
0470: public ClassDeclaration(Location location, short modifiers) {
0471: super (location, modifiers);
0472: }
0473:
0474: public void addConstructor(ConstructorDeclarator cd) {
0475: this .constructors.add(cd);
0476: cd.setDeclaringType(this );
0477: }
0478:
0479: public void addVariableDeclaratorOrInitializer(
0480: TypeBodyDeclaration tbd) {
0481: this .variableDeclaratorsAndInitializers.add(tbd);
0482: tbd.setDeclaringType(this );
0483:
0484: // Clear resolved type cache.
0485: if (this .resolvedType != null)
0486: this .resolvedType.declaredIFields = null;
0487: }
0488:
0489: // Compile time members.
0490:
0491: // Implement InnerClassDeclaration.
0492: public void defineSyntheticField(IClass.IField iField)
0493: throws CompileException {
0494: if (!(this instanceof InnerClassDeclaration))
0495: throw new RuntimeException();
0496:
0497: IClass.IField if2 = (IClass.IField) this .syntheticFields
0498: .get(iField.getName());
0499: if (if2 != null) {
0500: if (iField.getType() != if2.getType())
0501: throw new RuntimeException();
0502: return;
0503: }
0504: this .syntheticFields.put(iField.getName(), iField);
0505: }
0506:
0507: /**
0508: * Return the declared constructors, or the default constructor.
0509: */
0510: ConstructorDeclarator[] getConstructors() {
0511: if (this .constructors.isEmpty()) {
0512: ConstructorDeclarator defaultConstructor = new ConstructorDeclarator(
0513: this .getLocation(), // location
0514: null, // optionalDocComment
0515: Mod.PUBLIC, // modifiers
0516: new FunctionDeclarator.FormalParameter[0], // formalParameters
0517: new Type[0], // thrownExceptions
0518: null, // optionalExplicitConstructorInvocation
0519: new Block(this .getLocation()) // optionalBody
0520: );
0521: defaultConstructor.setDeclaringType(this );
0522: return new ConstructorDeclarator[] { defaultConstructor };
0523: }
0524:
0525: return (ConstructorDeclarator[]) this .constructors
0526: .toArray(new ConstructorDeclarator[this .constructors
0527: .size()]);
0528: }
0529:
0530: // All field names start with "this$" or "val$".
0531: final SortedMap syntheticFields = new TreeMap(); // String name => IClass.IField
0532: }
0533:
0534: public static final class AnonymousClassDeclaration extends
0535: ClassDeclaration implements InnerClassDeclaration {
0536: public final Type baseType; // Base class or interface
0537:
0538: public AnonymousClassDeclaration(Location location,
0539: Type baseType) {
0540: super (location, // location
0541: (short) (Mod.PRIVATE | Mod.FINAL) // modifiers
0542: );
0543: (this .baseType = baseType)
0544: .setEnclosingScope(new EnclosingScopeOfTypeDeclaration(
0545: this ));
0546: }
0547:
0548: public final void accept(Visitor.TypeDeclarationVisitor visitor) {
0549: visitor.visitAnonymousClassDeclaration(this );
0550: }
0551:
0552: // Implement TypeDeclaration.
0553: public String getClassName() {
0554: if (this .myName == null) {
0555: Scope s = this .getEnclosingScope();
0556: for (; !(s instanceof TypeDeclaration); s = s
0557: .getEnclosingScope())
0558: ;
0559: this .myName = ((TypeDeclaration) s)
0560: .createAnonymousClassName();
0561: }
0562: return this .myName;
0563: }
0564:
0565: private String myName = null;
0566:
0567: public String toString() {
0568: return this .getClassName();
0569: }
0570: }
0571:
0572: public abstract static class NamedClassDeclaration extends
0573: ClassDeclaration implements NamedTypeDeclaration,
0574: DocCommentable {
0575: private final String optionalDocComment;
0576: public final String name;
0577: public final Type optionalExtendedType;
0578: public final Type[] implementedTypes;
0579:
0580: public NamedClassDeclaration(Location location,
0581: String optionalDocComment, short modifiers,
0582: String name, Type optionalExtendedType,
0583: Type[] implementedTypes) {
0584: super (location, modifiers);
0585: this .optionalDocComment = optionalDocComment;
0586: this .name = name;
0587: this .optionalExtendedType = optionalExtendedType;
0588: if (optionalExtendedType != null)
0589: optionalExtendedType
0590: .setEnclosingScope(new EnclosingScopeOfTypeDeclaration(
0591: this ));
0592: this .implementedTypes = implementedTypes;
0593: for (int i = 0; i < implementedTypes.length; ++i)
0594: implementedTypes[i]
0595: .setEnclosingScope(new EnclosingScopeOfTypeDeclaration(
0596: this ));
0597: }
0598:
0599: public String toString() {
0600: return this .name;
0601: }
0602:
0603: // Implement NamedTypeDeclaration.
0604: public String getName() {
0605: return this .name;
0606: }
0607:
0608: // Implement DocCommentable.
0609: public String getDocComment() {
0610: return this .optionalDocComment;
0611: }
0612:
0613: public boolean hasDeprecatedDocTag() {
0614: return this .optionalDocComment != null
0615: && this .optionalDocComment.indexOf("@deprecated") != -1;
0616: }
0617: }
0618:
0619: /**
0620: * Lazily determines and returns the enclosing
0621: * {@link org.codehaus.janino.Java.Scope} of the given
0622: * {@link org.codehaus.janino.Java.TypeDeclaration}.
0623: */
0624: public static final class EnclosingScopeOfTypeDeclaration implements
0625: Scope {
0626: public final TypeDeclaration typeDeclaration;
0627:
0628: public EnclosingScopeOfTypeDeclaration(
0629: TypeDeclaration typeDeclaration) {
0630: this .typeDeclaration = typeDeclaration;
0631: }
0632:
0633: public Scope getEnclosingScope() {
0634: return this .typeDeclaration.getEnclosingScope();
0635: }
0636: }
0637:
0638: public static final class MemberClassDeclaration extends
0639: NamedClassDeclaration implements MemberTypeDeclaration,
0640: InnerClassDeclaration {
0641: public MemberClassDeclaration(Location location,
0642: String optionalDocComment, short modifiers,
0643: String name, Type optionalExtendedType,
0644: Type[] implementedTypes) {
0645: super (location, // location
0646: optionalDocComment, // optionalDocComment
0647: modifiers, // modifiers
0648: name, // name
0649: optionalExtendedType, // optionalExtendedType
0650: implementedTypes // implementedTypes
0651: );
0652: }
0653:
0654: // Implement TypeBodyDeclaration.
0655: public void setDeclaringType(TypeDeclaration declaringType) {
0656: this .setEnclosingScope(declaringType);
0657: }
0658:
0659: public TypeDeclaration getDeclaringType() {
0660: return (TypeDeclaration) this .getEnclosingScope();
0661: }
0662:
0663: public boolean isStatic() {
0664: return (this .modifiers & Mod.STATIC) != 0;
0665: }
0666:
0667: // Implement TypeDeclaration.
0668: public String getClassName() {
0669: return (this .getDeclaringType().getClassName() + '$' + this
0670: .getName());
0671: }
0672:
0673: public void accept(Visitor.TypeDeclarationVisitor visitor) {
0674: visitor.visitMemberClassDeclaration(this );
0675: }
0676:
0677: public void accept(Visitor.TypeBodyDeclarationVisitor visitor) {
0678: visitor.visitMemberClassDeclaration(this );
0679: }
0680: }
0681:
0682: public static final class LocalClassDeclaration extends
0683: NamedClassDeclaration implements InnerClassDeclaration {
0684: public LocalClassDeclaration(Location location,
0685: String optionalDocComment, short modifiers,
0686: String name, Type optionalExtendedType,
0687: Type[] implementedTypes) {
0688: super (location, // location
0689: optionalDocComment, // optionalDocComment
0690: modifiers, // modifiers
0691: name, // name
0692: optionalExtendedType, // optionalExtendedType
0693: implementedTypes // implementedTypes
0694: );
0695: }
0696:
0697: // Implement ClassDeclaration.
0698: protected IClass getOuterIClass2() {
0699: Scope s = this .getEnclosingScope();
0700: for (; !(s instanceof FunctionDeclarator); s = s
0701: .getEnclosingScope())
0702: ;
0703: boolean isStaticMethod = (s instanceof MethodDeclarator)
0704: && (((FunctionDeclarator) s).modifiers & Mod.STATIC) != 0;
0705: for (; !(s instanceof TypeDeclaration); s = s
0706: .getEnclosingScope())
0707: ;
0708: TypeDeclaration immediatelyEnclosingTypeDeclaration = (TypeDeclaration) s;
0709: return (immediatelyEnclosingTypeDeclaration instanceof ClassDeclaration && !isStaticMethod) ? (IClass) immediatelyEnclosingTypeDeclaration
0710: : null;
0711: }
0712:
0713: // Implement TypeDeclaration.
0714: public String getClassName() {
0715: for (Scope s = this .getEnclosingScope();; s = s
0716: .getEnclosingScope()) {
0717: if (s instanceof Java.TypeDeclaration)
0718: return ((Java.TypeDeclaration) s).getClassName()
0719: + '$' + this .name;
0720: }
0721: }
0722:
0723: public final void accept(Visitor.TypeDeclarationVisitor visitor) {
0724: visitor.visitLocalClassDeclaration(this );
0725: }
0726: }
0727:
0728: public static final class PackageMemberClassDeclaration extends
0729: NamedClassDeclaration implements
0730: PackageMemberTypeDeclaration {
0731: public PackageMemberClassDeclaration(Location location,
0732: String optionalDocComment, short modifiers,
0733: String name, Type optionalExtendedType,
0734: Type[] implementedTypes) throws Parser.ParseException {
0735: super (location, // location
0736: optionalDocComment, // optionalDocComment
0737: modifiers, // modifiers
0738: name, // name
0739: optionalExtendedType, // optionalExtendedType
0740: implementedTypes // implementedTypes
0741: );
0742:
0743: // Check for forbidden modifiers (JLS 7.6).
0744: if ((modifiers & (Mod.PROTECTED | Mod.PRIVATE | Mod.STATIC)) != 0)
0745: this
0746: .throwParseException("Modifiers \"protected\", \"private\" and \"static\" not allowed in package member class declaration");
0747: }
0748:
0749: // Implement PackageMemberTypeDeclaration.
0750: public void setDeclaringCompilationUnit(
0751: CompilationUnit declaringCompilationUnit) {
0752: this .setEnclosingScope(declaringCompilationUnit);
0753: }
0754:
0755: public CompilationUnit getDeclaringCompilationUnit() {
0756: return (CompilationUnit) this .getEnclosingScope();
0757: }
0758:
0759: // Implement ClassDeclaration.
0760: protected IClass getOuterIClass2() {
0761: return null;
0762: }
0763:
0764: // Implement TypeDeclaration.
0765: public String getClassName() {
0766: String className = this .getName();
0767:
0768: CompilationUnit compilationUnit = (CompilationUnit) this
0769: .getEnclosingScope();
0770: if (compilationUnit.optionalPackageDeclaration != null)
0771: className = compilationUnit.optionalPackageDeclaration.packageName
0772: + '.' + className;
0773:
0774: return className;
0775: }
0776:
0777: public final void accept(Visitor.TypeDeclarationVisitor visitor) {
0778: visitor.visitPackageMemberClassDeclaration(this );
0779: }
0780: }
0781:
0782: public abstract static class InterfaceDeclaration extends
0783: AbstractTypeDeclaration implements NamedTypeDeclaration,
0784: DocCommentable {
0785: private final String optionalDocComment;
0786: public/*final*/String name;
0787:
0788: protected InterfaceDeclaration(Location location,
0789: String optionalDocComment, short modifiers,
0790: String name, Type[] extendedTypes) {
0791: super (location, modifiers);
0792: this .optionalDocComment = optionalDocComment;
0793: this .name = name;
0794: this .extendedTypes = extendedTypes;
0795: for (int i = 0; i < extendedTypes.length; ++i)
0796: extendedTypes[i]
0797: .setEnclosingScope(new EnclosingScopeOfTypeDeclaration(
0798: this ));
0799: }
0800:
0801: public String toString() {
0802: return this .name;
0803: }
0804:
0805: public void addConstantDeclaration(FieldDeclaration fd) {
0806: this .constantDeclarations.add(fd);
0807: fd.setDeclaringType(this );
0808:
0809: // Clear resolved type cache.
0810: if (this .resolvedType != null)
0811: this .resolvedType.declaredIFields = null;
0812: }
0813:
0814: public/*final*/Type[] extendedTypes;
0815: public final List constantDeclarations = new ArrayList(); // FieldDeclaration
0816:
0817: // Set during "compile()".
0818: IClass[] interfaces = null;
0819:
0820: // Implement NamedTypeDeclaration.
0821: public String getName() {
0822: return this .name;
0823: }
0824:
0825: // Implement DocCommentable.
0826: public String getDocComment() {
0827: return this .optionalDocComment;
0828: }
0829:
0830: public boolean hasDeprecatedDocTag() {
0831: return this .optionalDocComment != null
0832: && this .optionalDocComment.indexOf("@deprecated") != -1;
0833: }
0834: }
0835:
0836: public static final class MemberInterfaceDeclaration extends
0837: InterfaceDeclaration implements MemberTypeDeclaration {
0838: public MemberInterfaceDeclaration(Location location,
0839: String optionalDocComment, short modifiers,
0840: String name, Type[] extendedTypes) {
0841: super (location, // location
0842: optionalDocComment, // optionalDocComment
0843: modifiers, // modifiers
0844: name, // name
0845: extendedTypes // extendedTypes
0846: );
0847: }
0848:
0849: // Implement TypeDeclaration.
0850: public String getClassName() {
0851: NamedTypeDeclaration declaringType = (NamedTypeDeclaration) this
0852: .getEnclosingScope();
0853: return (declaringType.getClassName() + '$' + this .getName());
0854: }
0855:
0856: // Implement TypeBodyDeclaration.
0857: public void setDeclaringType(TypeDeclaration declaringType) {
0858: this .setEnclosingScope(declaringType);
0859: }
0860:
0861: public TypeDeclaration getDeclaringType() {
0862: return (TypeDeclaration) this .getEnclosingScope();
0863: }
0864:
0865: public boolean isStatic() {
0866: return (this .modifiers & Mod.STATIC) != 0;
0867: }
0868:
0869: public final void accept(Visitor.TypeDeclarationVisitor visitor) {
0870: visitor.visitMemberInterfaceDeclaration(this );
0871: }
0872:
0873: public final void accept(
0874: Visitor.TypeBodyDeclarationVisitor visitor) {
0875: visitor.visitMemberInterfaceDeclaration(this );
0876: }
0877: }
0878:
0879: public static final class PackageMemberInterfaceDeclaration extends
0880: InterfaceDeclaration implements
0881: PackageMemberTypeDeclaration {
0882: public PackageMemberInterfaceDeclaration(Location location,
0883: String optionalDocComment, short modifiers,
0884: String name, Type[] extendedTypes)
0885: throws Parser.ParseException {
0886: super (location, // location
0887: optionalDocComment, // optionalDocComment
0888: modifiers, // modifiers
0889: name, // name
0890: extendedTypes // extendedTypes
0891: );
0892:
0893: // Check for forbidden modifiers (JLS 7.6).
0894: if ((modifiers & (Mod.PROTECTED | Mod.PRIVATE | Mod.STATIC)) != 0)
0895: this
0896: .throwParseException("Modifiers \"protected\", \"private\" and \"static\" not allowed in package member interface declaration");
0897: }
0898:
0899: // Implement PackageMemberTypeDeclaration.
0900: public void setDeclaringCompilationUnit(
0901: CompilationUnit declaringCompilationUnit) {
0902: this .setEnclosingScope(declaringCompilationUnit);
0903: }
0904:
0905: public CompilationUnit getDeclaringCompilationUnit() {
0906: return (CompilationUnit) this .getEnclosingScope();
0907: }
0908:
0909: // Implement TypeDeclaration.
0910: public String getClassName() {
0911: String className = this .getName();
0912:
0913: CompilationUnit compilationUnit = (CompilationUnit) this
0914: .getEnclosingScope();
0915: if (compilationUnit.optionalPackageDeclaration != null)
0916: className = compilationUnit.optionalPackageDeclaration.packageName
0917: + '.' + className;
0918:
0919: return className;
0920: }
0921:
0922: public final void accept(Visitor.TypeDeclarationVisitor visitor) {
0923: visitor.visitPackageMemberInterfaceDeclaration(this );
0924: }
0925: }
0926:
0927: /**
0928: * Representation of a "ClassBodyDeclaration" or an "InterfaceMemberDeclaration". These are:
0929: * <ul>
0930: * <li>Field declarators
0931: * <li>Method declarators
0932: * <li>Static and non-static initializers
0933: * <li>Member type declarations
0934: * </ul>
0935: */
0936: public interface TypeBodyDeclaration extends Locatable, Scope {
0937: void setDeclaringType(TypeDeclaration declaringType);
0938:
0939: TypeDeclaration getDeclaringType();
0940:
0941: boolean isStatic();
0942:
0943: void accept(Visitor.TypeBodyDeclarationVisitor visitor);
0944: }
0945:
0946: public abstract static class AbstractTypeBodyDeclaration extends
0947: Located implements TypeBodyDeclaration {
0948: private TypeDeclaration declaringType;
0949: public final boolean statiC;
0950:
0951: protected AbstractTypeBodyDeclaration(Location location,
0952: boolean statiC) {
0953: super (location);
0954: this .statiC = statiC;
0955: }
0956:
0957: // Implement TypeBodyDeclaration.
0958: public void setDeclaringType(TypeDeclaration declaringType) {
0959: if (this .declaringType != null && declaringType != null)
0960: throw new RuntimeException(
0961: "Declaring type for type body declaration \""
0962: + this .toString() + "\"at "
0963: + this .getLocation()
0964: + " is already set");
0965: this .declaringType = declaringType;
0966: }
0967:
0968: public TypeDeclaration getDeclaringType() {
0969: return this .declaringType;
0970: }
0971:
0972: public boolean isStatic() {
0973: return this .statiC;
0974: }
0975:
0976: // Implement BlockStatement.
0977: public void setEnclosingScope(Scope enclosingScope) {
0978: this .declaringType = (TypeDeclaration) enclosingScope;
0979: }
0980:
0981: public Scope getEnclosingScope() {
0982: return this .declaringType;
0983: }
0984: }
0985:
0986: /**
0987: * Representation of an instance (JLS2 8.6) or static initializer (JLS2 8.7).
0988: */
0989: public final static class Initializer extends
0990: AbstractTypeBodyDeclaration implements BlockStatement {
0991: public final Block block;
0992:
0993: public Initializer(Location location, boolean statiC,
0994: Block block) {
0995: super (location, statiC);
0996: (this .block = block).setEnclosingScope(this );
0997: }
0998:
0999: // Implement BlockStatement.
1000:
1001: public final void accept(
1002: Visitor.TypeBodyDeclarationVisitor visitor) {
1003: visitor.visitInitializer(this );
1004: }
1005:
1006: public final void accept(Visitor.BlockStatementVisitor visitor) {
1007: visitor.visitInitializer(this );
1008: }
1009: }
1010:
1011: /**
1012: * Abstract base class for {@link Java.ConstructorDeclarator} and
1013: * {@link Java.MethodDeclarator}.
1014: */
1015: public abstract static class FunctionDeclarator extends
1016: AbstractTypeBodyDeclaration implements DocCommentable {
1017: private final String optionalDocComment;
1018: public final short modifiers;
1019: public final Type type;
1020: public final String name;
1021: public final FormalParameter[] formalParameters;
1022: public final Type[] thrownExceptions;
1023: public final Block optionalBody;
1024:
1025: public FunctionDeclarator(Location location,
1026: String optionalDocComment, short modifiers, Type type,
1027: String name, FormalParameter[] formalParameters,
1028: Type[] thrownExceptions, Block optionalBody) {
1029: super (location, (modifiers & Mod.STATIC) != 0);
1030: this .optionalDocComment = optionalDocComment;
1031: this .modifiers = modifiers;
1032: (this .type = type).setEnclosingScope(this );
1033: this .name = name;
1034: this .formalParameters = formalParameters;
1035: for (int i = 0; i < formalParameters.length; ++i)
1036: formalParameters[i].type.setEnclosingScope(this );
1037: this .thrownExceptions = thrownExceptions;
1038: for (int i = 0; i < thrownExceptions.length; ++i)
1039: thrownExceptions[i].setEnclosingScope(this );
1040: this .optionalBody = optionalBody;
1041: if (optionalBody != null)
1042: optionalBody.setEnclosingScope(this );
1043: }
1044:
1045: // Implement "Scope".
1046: public Scope getEnclosingScope() {
1047: return this .getDeclaringType();
1048: }
1049:
1050: // Set by "compile()".
1051: IClass returnType = null;
1052:
1053: // Implement DocCommentable.
1054: public String getDocComment() {
1055: return this .optionalDocComment;
1056: }
1057:
1058: public boolean hasDeprecatedDocTag() {
1059: return this .optionalDocComment != null
1060: && this .optionalDocComment.indexOf("@deprecated") != -1;
1061: }
1062:
1063: public static final class FormalParameter extends Java.Located {
1064: public final boolean finaL;
1065: public final Type type;
1066: public final String name;
1067:
1068: public FormalParameter(Location location, boolean finaL,
1069: Type type, String name) {
1070: super (location);
1071: this .finaL = finaL;
1072: this .type = type;
1073: this .name = name;
1074: }
1075:
1076: public String toString() {
1077: return this .type.toString() + ' ' + this .name;
1078: }
1079:
1080: // Compile time members.
1081:
1082: public Java.LocalVariable localVariable = null;
1083: }
1084: }
1085:
1086: public static final class ConstructorDeclarator extends
1087: FunctionDeclarator {
1088: IClass.IConstructor iConstructor = null;
1089: public ConstructorInvocation optionalConstructorInvocation = null;
1090:
1091: public ConstructorDeclarator(Location location,
1092: String optionalDocComment, short modifiers,
1093: FunctionDeclarator.FormalParameter[] formalParameters,
1094: Type[] thrownExceptions,
1095: ConstructorInvocation optionalConstructorInvocation,
1096: Block optionalBody) {
1097: super (location, // location
1098: optionalDocComment, // optionalDocComment
1099: modifiers, // modifiers
1100: new BasicType(location, BasicType.VOID), // type
1101: "<init>", // name
1102: formalParameters, // formalParameters
1103: thrownExceptions, // thrownExceptions
1104: optionalBody // optionalBody
1105: );
1106: this .optionalConstructorInvocation = optionalConstructorInvocation;
1107: if (optionalConstructorInvocation != null)
1108: optionalConstructorInvocation.setEnclosingScope(this );
1109: }
1110:
1111: public ClassDeclaration getDeclaringClass() {
1112: return (ClassDeclaration) this .getEnclosingScope();
1113: }
1114:
1115: // Compile time members.
1116:
1117: Map syntheticParameters = new HashMap(); // String name => LocalVariable
1118:
1119: // Implement "FunctionDeclarator":
1120:
1121: public String toString() {
1122: StringBuffer sb = new StringBuffer(this .getDeclaringClass()
1123: .getClassName());
1124: sb.append('(');
1125: FunctionDeclarator.FormalParameter[] fps = this .formalParameters;
1126: for (int i = 0; i < fps.length; ++i) {
1127: if (i > 0)
1128: sb.append(", ");
1129: sb.append(fps[i].toString());
1130: }
1131: sb.append(')');
1132: return sb.toString();
1133: }
1134:
1135: public final void accept(
1136: Visitor.TypeBodyDeclarationVisitor visitor) {
1137: visitor.visitConstructorDeclarator(this );
1138: }
1139: }
1140:
1141: public final static class MethodDeclarator extends
1142: FunctionDeclarator {
1143: public MethodDeclarator(Location location,
1144: String optionalDocComment, short modifiers, Type type,
1145: String name,
1146: FunctionDeclarator.FormalParameter[] formalParameters,
1147: Type[] thrownExceptions, Block optionalBody) {
1148: super (location, // location
1149: optionalDocComment, // optionalDocComment
1150: modifiers, // modifiers
1151: type, // type
1152: name, // name
1153: formalParameters, // formalParameters
1154: thrownExceptions, // thrownExceptions
1155: optionalBody);
1156: }
1157:
1158: public String toString() {
1159: StringBuffer sb = new StringBuffer(this .name);
1160: sb.append('(');
1161: FunctionDeclarator.FormalParameter[] fps = this .formalParameters;
1162: for (int i = 0; i < fps.length; ++i) {
1163: if (i > 0)
1164: sb.append(", ");
1165: sb.append(fps[i].toString());
1166: }
1167: sb.append(')');
1168: return sb.toString();
1169: }
1170:
1171: public final void accept(
1172: Visitor.TypeBodyDeclarationVisitor visitor) {
1173: visitor.visitMethodDeclarator(this );
1174: }
1175:
1176: IClass.IMethod iMethod = null;
1177: }
1178:
1179: /**
1180: * This class is derived from "Statement", because it provides for the
1181: * initialization of the field. In other words, "compile()" generates the
1182: * code that initializes the field.
1183: */
1184: public static final class FieldDeclaration extends Statement
1185: implements TypeBodyDeclaration, DocCommentable {
1186: private final String optionalDocComment;
1187: public final short modifiers;
1188: public final Type type;
1189: public final VariableDeclarator[] variableDeclarators;
1190:
1191: public FieldDeclaration(Location location,
1192: String optionalDocComment, short modifiers, Type type,
1193: VariableDeclarator[] variableDeclarators) {
1194: super (location);
1195: this .optionalDocComment = optionalDocComment;
1196: this .modifiers = modifiers;
1197: (this .type = type).setEnclosingScope(this );
1198: this .variableDeclarators = variableDeclarators;
1199: for (int i = 0; i < variableDeclarators.length; ++i) {
1200: VariableDeclarator vd = variableDeclarators[i];
1201: if (vd.optionalInitializer != null)
1202: Java.setEnclosingBlockStatement(
1203: vd.optionalInitializer, this );
1204: }
1205: }
1206:
1207: // Implement TypeBodyDeclaration.
1208: public void setDeclaringType(TypeDeclaration declaringType) {
1209: this .setEnclosingScope(declaringType);
1210: }
1211:
1212: public TypeDeclaration getDeclaringType() {
1213: return (TypeDeclaration) this .getEnclosingScope();
1214: }
1215:
1216: public boolean isStatic() {
1217: return (this .modifiers & Mod.STATIC) != 0;
1218: }
1219:
1220: public String toString() {
1221: StringBuffer sb = new StringBuffer();
1222: sb.append(Mod.shortToString(this .modifiers)).append(' ')
1223: .append(this .type).append(' ').append(
1224: this .variableDeclarators[0]);
1225: for (int i = 1; i < this .variableDeclarators.length; ++i) {
1226: sb.append(", ").append(this .variableDeclarators[i]);
1227: }
1228: return sb.toString();
1229: }
1230:
1231: public final void accept(
1232: Visitor.TypeBodyDeclarationVisitor visitor) {
1233: visitor.visitFieldDeclaration(this );
1234: }
1235:
1236: public final void accept(Visitor.BlockStatementVisitor visitor) {
1237: visitor.visitFieldDeclaration(this );
1238: }
1239:
1240: // Implement DocCommentable.
1241: public String getDocComment() {
1242: return this .optionalDocComment;
1243: }
1244:
1245: public boolean hasDeprecatedDocTag() {
1246: return this .optionalDocComment != null
1247: && this .optionalDocComment.indexOf("@deprecated") != -1;
1248: }
1249: }
1250:
1251: private static void setEnclosingBlockStatement(
1252: ArrayInitializerOrRvalue aiorv,
1253: BlockStatement enclosingBlockStatement) {
1254: if (aiorv instanceof Rvalue) {
1255: ((Rvalue) aiorv)
1256: .setEnclosingBlockStatement(enclosingBlockStatement);
1257: } else if (aiorv instanceof ArrayInitializer) {
1258: ArrayInitializerOrRvalue[] values = ((ArrayInitializer) aiorv).values;
1259: for (int i = 0; i < values.length; ++i)
1260: Java.setEnclosingBlockStatement(values[i],
1261: enclosingBlockStatement);
1262: } else {
1263: throw new RuntimeException(
1264: "Unexpected array or initializer class "
1265: + aiorv.getClass().getName());
1266: }
1267: }
1268:
1269: // Used by FieldDeclaration and LocalVariableDeclarationStatement.
1270: public final static class VariableDeclarator extends Located {
1271: public final String name;
1272: public final int brackets;
1273: public final ArrayInitializerOrRvalue optionalInitializer;
1274:
1275: public VariableDeclarator(Location location, String name,
1276: int brackets,
1277: ArrayInitializerOrRvalue optionalInitializer) {
1278: super (location);
1279: this .name = name;
1280: this .brackets = brackets;
1281: this .optionalInitializer = optionalInitializer;
1282:
1283: // Used both by field declarations an local variable declarations, so naming
1284: // conventions checking (JLS2 6.8) cannot be done here.
1285: }
1286:
1287: public String toString() {
1288: StringBuffer sb = new StringBuffer();
1289: sb.append(this .name);
1290: for (int i = 0; i < this .brackets; ++i)
1291: sb.append("[]");
1292: if (this .optionalInitializer != null)
1293: sb.append(" = ").append(this .optionalInitializer);
1294: return sb.toString();
1295: }
1296:
1297: // Compile time members.
1298:
1299: // Used only if the variable declarator declares a local variable.
1300: public LocalVariable localVariable = null;
1301: }
1302:
1303: /**
1304: * Base of all statements that can appear in a block.
1305: */
1306: public interface BlockStatement extends Locatable, Scope {
1307: void setEnclosingScope(Scope enclosingScope);
1308:
1309: Scope getEnclosingScope();
1310:
1311: void accept(Visitor.BlockStatementVisitor visitor);
1312: }
1313:
1314: public static abstract class Statement extends Located implements
1315: BlockStatement {
1316: private Scope enclosingScope = null;
1317:
1318: protected Statement(Location location) {
1319: super (location);
1320: }
1321:
1322: // Implement "BlockStatement".
1323: public void setEnclosingScope(Scope enclosingScope) {
1324: if (this .enclosingScope != null
1325: && enclosingScope != this .enclosingScope)
1326: throw new RuntimeException(
1327: "Enclosing scope is already set for statement \""
1328: + this .toString() + "\" at "
1329: + this .getLocation());
1330: this .enclosingScope = enclosingScope;
1331: }
1332:
1333: public Scope getEnclosingScope() {
1334: return this .enclosingScope;
1335: }
1336: }
1337:
1338: public final static class LabeledStatement extends
1339: BreakableStatement {
1340: public final String label;
1341: public final Statement body;
1342:
1343: public LabeledStatement(Location location, String label,
1344: Statement body) {
1345: super (location);
1346: this .label = label;
1347: (this .body = body).setEnclosingScope(this );
1348: }
1349:
1350: // Compile time members:
1351:
1352: public final void accept(Visitor.BlockStatementVisitor visitor) {
1353: visitor.visitLabeledStatement(this );
1354: }
1355: }
1356:
1357: /**
1358: * Representation of a Java<sup>TM</sup> "block" (JLS 14.2).
1359: * <p>
1360: * The statements that the block defines are executed in sequence.
1361: */
1362: public final static class Block extends Statement {
1363: public final List statements = new ArrayList(); // BlockStatement
1364:
1365: public Block(Location location) {
1366: super (location);
1367: }
1368:
1369: public void addStatement(BlockStatement statement) {
1370: this .statements.add(statement);
1371: statement.setEnclosingScope(this );
1372: }
1373:
1374: // This one's for some very special compiler trickery...
1375: void addButDontEncloseStatement(BlockStatement statement) {
1376: this .statements.add(statement);
1377: }
1378:
1379: public void addStatements(List statements // BlockStatement
1380: ) {
1381: this .statements.addAll(statements);
1382: for (Iterator it = statements.iterator(); it.hasNext();)
1383: ((BlockStatement) it.next()).setEnclosingScope(this );
1384: }
1385:
1386: public void addButDontEncloseStatements(List statements // BlockStatement
1387: ) {
1388: this .statements.addAll(statements);
1389: }
1390:
1391: public BlockStatement[] getStatements() {
1392: return (BlockStatement[]) this .statements
1393: .toArray(new BlockStatement[this .statements.size()]);
1394: }
1395:
1396: // Compile time members.
1397:
1398: public final void accept(Visitor.BlockStatementVisitor visitor) {
1399: visitor.visitBlock(this );
1400: }
1401: }
1402:
1403: /**
1404: * Base class for statements that can be terminated abnormally with a
1405: * "break" statement.
1406: * <p>
1407: * According to the JLS, statements that can be terminated abnormally with
1408: * a "break" statement are: "COntinuable" statements ("for", "do" and
1409: * "while"), labeled statements, and the "switch" statement.
1410: */
1411: public static abstract class BreakableStatement extends Statement {
1412: protected BreakableStatement(Location location) {
1413: super (location);
1414: }
1415:
1416: CodeContext.Offset whereToBreak = null;
1417: }
1418:
1419: public static abstract class ContinuableStatement extends
1420: BreakableStatement {
1421: protected ContinuableStatement(Location location) {
1422: super (location);
1423: }
1424:
1425: protected CodeContext.Offset whereToContinue = null;
1426: protected boolean bodyHasContinue = false;
1427: }
1428:
1429: public final static class ExpressionStatement extends Statement {
1430: public final Rvalue rvalue;
1431:
1432: public ExpressionStatement(Rvalue rvalue)
1433: throws Parser.ParseException {
1434: super (rvalue.getLocation());
1435: if (!(rvalue instanceof Java.Assignment
1436: || rvalue instanceof Java.Crement
1437: || rvalue instanceof Java.MethodInvocation
1438: || rvalue instanceof Java.SuperclassMethodInvocation || rvalue instanceof Java.NewClassInstance))
1439: this
1440: .throwParseException("This kind of expression is not allowed in an expression statement");
1441: (this .rvalue = rvalue).setEnclosingBlockStatement(this );
1442: }
1443:
1444: // Compile time members:
1445:
1446: public final void accept(Visitor.BlockStatementVisitor visitor) {
1447: visitor.visitExpressionStatement(this );
1448: }
1449: }
1450:
1451: public final static class LocalClassDeclarationStatement extends
1452: Statement {
1453: public final LocalClassDeclaration lcd;
1454:
1455: public LocalClassDeclarationStatement(
1456: Java.LocalClassDeclaration lcd) {
1457: super (lcd.getLocation());
1458: (this .lcd = lcd).setEnclosingScope(this );
1459: }
1460:
1461: public final void accept(Visitor.BlockStatementVisitor visitor) {
1462: visitor.visitLocalClassDeclarationStatement(this );
1463: }
1464: }
1465:
1466: public final static class IfStatement extends Statement {
1467: public final Rvalue condition;
1468: public final BlockStatement thenStatement;
1469: public final BlockStatement optionalElseStatement;
1470:
1471: /**
1472: * Notice that the <code>elseStatement</code> is mandatory; for an if statement without
1473: * an "else" clause, a dummy {@link Java.EmptyStatement} should be passed.
1474: */
1475: public IfStatement(Location location, Rvalue condition,
1476: BlockStatement thenStatement,
1477: BlockStatement optionalElseStatement) {
1478: super (location);
1479: (this .condition = condition)
1480: .setEnclosingBlockStatement(this );
1481: (this .thenStatement = thenStatement)
1482: .setEnclosingScope(this );
1483: this .optionalElseStatement = optionalElseStatement;
1484: if (optionalElseStatement != null)
1485: optionalElseStatement.setEnclosingScope(this );
1486: }
1487:
1488: // Compile time members:
1489:
1490: public final void accept(Visitor.BlockStatementVisitor visitor) {
1491: visitor.visitIfStatement(this );
1492: }
1493: }
1494:
1495: public final static class ForStatement extends ContinuableStatement {
1496: public final BlockStatement optionalInit;
1497: public final Rvalue optionalCondition;
1498: public final Rvalue[] optionalUpdate;
1499: public final BlockStatement body;
1500:
1501: public ForStatement(Location location,
1502: BlockStatement optionalInit, Rvalue optionalCondition,
1503: Rvalue[] optionalUpdate, BlockStatement body) {
1504: super (location);
1505: this .optionalInit = optionalInit;
1506: if (optionalInit != null)
1507: optionalInit.setEnclosingScope(this );
1508: this .optionalCondition = optionalCondition;
1509: if (optionalCondition != null)
1510: optionalCondition.setEnclosingBlockStatement(this );
1511: this .optionalUpdate = optionalUpdate;
1512: if (optionalUpdate != null) {
1513: for (int i = 0; i < optionalUpdate.length; ++i)
1514: optionalUpdate[i].setEnclosingBlockStatement(this );
1515: }
1516: (this .body = body).setEnclosingScope(this );
1517: }
1518:
1519: // Compile time members:
1520:
1521: public final void accept(Visitor.BlockStatementVisitor visitor) {
1522: visitor.visitForStatement(this );
1523: }
1524: }
1525:
1526: public final static class WhileStatement extends
1527: ContinuableStatement {
1528: public final Rvalue condition;
1529: public final BlockStatement body;
1530:
1531: public WhileStatement(Location location, Rvalue condition,
1532: BlockStatement body) {
1533: super (location);
1534: (this .condition = condition)
1535: .setEnclosingBlockStatement(this );
1536: (this .body = body).setEnclosingScope(this );
1537: }
1538:
1539: // Compile time members:
1540:
1541: public final void accept(Visitor.BlockStatementVisitor visitor) {
1542: visitor.visitWhileStatement(this );
1543: }
1544: }
1545:
1546: public final static class TryStatement extends Statement {
1547: public final BlockStatement body;
1548: public final List catchClauses; // CatchClause
1549: public final Block optionalFinally;
1550:
1551: public TryStatement(Location location, BlockStatement body,
1552: List catchClauses, // CatchClause
1553: Block optionalFinally) {
1554: super (location);
1555: (this .body = body).setEnclosingScope(this );
1556: this .catchClauses = catchClauses;
1557: for (Iterator it = catchClauses.iterator(); it.hasNext();)
1558: ((CatchClause) it.next())
1559: .setEnclosingTryStatement(this );
1560: this .optionalFinally = optionalFinally;
1561: if (optionalFinally != null)
1562: optionalFinally.setEnclosingScope(this );
1563: }
1564:
1565: // Compile time members:
1566:
1567: public final void accept(Visitor.BlockStatementVisitor visitor) {
1568: visitor.visitTryStatement(this );
1569: }
1570:
1571: CodeContext.Offset finallyOffset = null;
1572: }
1573:
1574: public static class CatchClause extends Located implements Scope {
1575: public final FunctionDeclarator.FormalParameter caughtException;
1576: public final Block body;
1577: private TryStatement enclosingTryStatement = null;
1578:
1579: public CatchClause(Location location,
1580: FunctionDeclarator.FormalParameter caughtException,
1581: Block body) {
1582: super (location);
1583: (this .caughtException = caughtException).type
1584: .setEnclosingScope(this );
1585: (this .body = body).setEnclosingScope(this );
1586: }
1587:
1588: public void setEnclosingTryStatement(
1589: TryStatement enclosingTryStatement) {
1590: if (this .enclosingTryStatement != null
1591: && enclosingTryStatement != this .enclosingTryStatement)
1592: throw new RuntimeException(
1593: "Enclosing TYR statement already set for catch clause "
1594: + this .toString() + " at "
1595: + this .getLocation());
1596: this .enclosingTryStatement = enclosingTryStatement;
1597: }
1598:
1599: public Scope getEnclosingScope() {
1600: return this .enclosingTryStatement;
1601: }
1602: }
1603:
1604: /**
1605: * 14.10 The "switch" Statement
1606: */
1607: public static final class SwitchStatement extends
1608: BreakableStatement {
1609: public final Rvalue condition;
1610: public final List sbsgs; // SwitchBlockStatementGroup
1611:
1612: public SwitchStatement(Location location, Rvalue condition,
1613: List sbsgs) {
1614: super (location);
1615: (this .condition = condition)
1616: .setEnclosingBlockStatement(this );
1617: this .sbsgs = sbsgs;
1618: for (Iterator it = sbsgs.iterator(); it.hasNext();) {
1619: SwitchBlockStatementGroup sbsg = ((SwitchBlockStatementGroup) it
1620: .next());
1621: for (Iterator it2 = sbsg.caseLabels.iterator(); it2
1622: .hasNext();) {
1623: ((Rvalue) (it2.next()))
1624: .setEnclosingBlockStatement(this );
1625: }
1626: for (Iterator it2 = sbsg.blockStatements.iterator(); it2
1627: .hasNext();) {
1628: ((BlockStatement) (it2.next()))
1629: .setEnclosingScope(this );
1630: }
1631: }
1632: }
1633:
1634: public static class SwitchBlockStatementGroup extends
1635: Java.Located {
1636: public final List caseLabels; // Rvalue
1637: public final boolean hasDefaultLabel;
1638: public final List blockStatements; // BlockStatement
1639:
1640: public SwitchBlockStatementGroup(Location location,
1641: List caseLabels, // Rvalue
1642: boolean hasDefaultLabel, List blockStatements // BlockStatement
1643: ) {
1644: super (location);
1645: this .caseLabels = caseLabels;
1646: this .hasDefaultLabel = hasDefaultLabel;
1647: this .blockStatements = blockStatements;
1648: }
1649: }
1650:
1651: // Compile time members:
1652:
1653: public final void accept(Visitor.BlockStatementVisitor visitor) {
1654: visitor.visitSwitchStatement(this );
1655: }
1656: }
1657:
1658: static class Padder extends CodeContext.Inserter implements
1659: CodeContext.FixUp {
1660: public Padder(CodeContext codeContext) {
1661: codeContext.super ();
1662: }
1663:
1664: public void fixUp() {
1665: int x = this .offset % 4;
1666: if (x != 0) {
1667: CodeContext ca = this .getCodeContext();
1668: ca.pushInserter(this );
1669: {
1670: ca.write((short) -1, new byte[4 - x]);
1671: }
1672: ca.popInserter();
1673: }
1674: }
1675: }
1676:
1677: public final static class SynchronizedStatement extends Statement {
1678: public final Rvalue expression;
1679: public final BlockStatement body;
1680:
1681: public SynchronizedStatement(Location location,
1682: Rvalue expression, BlockStatement body) {
1683: super (location);
1684: (this .expression = expression)
1685: .setEnclosingBlockStatement(this );
1686: (this .body = body).setEnclosingScope(this );
1687: }
1688:
1689: // Compile time members:
1690:
1691: public final void accept(Visitor.BlockStatementVisitor visitor) {
1692: visitor.visitSynchronizedStatement(this );
1693: }
1694:
1695: short monitorLvIndex = -1;
1696: }
1697:
1698: public final static class DoStatement extends ContinuableStatement {
1699: public final BlockStatement body;
1700: public final Rvalue condition;
1701:
1702: public DoStatement(Location location, BlockStatement body,
1703: Rvalue condition) {
1704: super (location);
1705: (this .body = body).setEnclosingScope(this );
1706: (this .condition = condition)
1707: .setEnclosingBlockStatement(this );
1708: }
1709:
1710: // Compile time members:
1711:
1712: public final void accept(Visitor.BlockStatementVisitor visitor) {
1713: visitor.visitDoStatement(this );
1714: }
1715: }
1716:
1717: public final static class LocalVariableDeclarationStatement extends
1718: Statement {
1719: public final short modifiers;
1720: public final Type type;
1721: public final VariableDeclarator[] variableDeclarators;
1722:
1723: /**
1724: * @param modifiers Only "final" allowed.
1725: */
1726: public LocalVariableDeclarationStatement(Location location,
1727: short modifiers, Type type,
1728: VariableDeclarator[] variableDeclarators) {
1729: super (location);
1730: this .modifiers = modifiers;
1731: (this .type = type).setEnclosingScope(this );
1732: this .variableDeclarators = variableDeclarators;
1733: for (int i = 0; i < variableDeclarators.length; ++i) {
1734: VariableDeclarator vd = variableDeclarators[i];
1735: if (vd.optionalInitializer != null)
1736: Java.setEnclosingBlockStatement(
1737: vd.optionalInitializer, this );
1738: }
1739: }
1740:
1741: // Compile time members:
1742:
1743: public final void accept(Visitor.BlockStatementVisitor visitor) {
1744: visitor.visitLocalVariableDeclarationStatement(this );
1745: }
1746:
1747: public String toString() {
1748: StringBuffer sb = new StringBuffer();
1749: if (this .modifiers != 0)
1750: sb.append(Mod.shortToString(this .modifiers))
1751: .append(' ');
1752: sb.append(this .type).append(' ').append(
1753: this .variableDeclarators[0].toString());
1754: for (int i = 1; i < this .variableDeclarators.length; ++i) {
1755: sb.append(", ").append(
1756: this .variableDeclarators[i].toString());
1757: }
1758: return sb.append(';').toString();
1759: }
1760: }
1761:
1762: public final static class ReturnStatement extends Statement {
1763: public final Rvalue optionalReturnValue;
1764:
1765: public ReturnStatement(Location location,
1766: Rvalue optionalReturnValue) {
1767: super (location);
1768: this .optionalReturnValue = optionalReturnValue;
1769: if (optionalReturnValue != null)
1770: optionalReturnValue.setEnclosingBlockStatement(this );
1771: }
1772:
1773: // Compile time members:
1774:
1775: public final void accept(Visitor.BlockStatementVisitor visitor) {
1776: visitor.visitReturnStatement(this );
1777: }
1778: }
1779:
1780: public final static class ThrowStatement extends Statement {
1781: public final Rvalue expression;
1782:
1783: public ThrowStatement(Location location, Rvalue expression) {
1784: super (location);
1785: (this .expression = expression)
1786: .setEnclosingBlockStatement(this );
1787: }
1788:
1789: // Compile time members:
1790:
1791: public final void accept(Visitor.BlockStatementVisitor visitor) {
1792: visitor.visitThrowStatement(this );
1793: }
1794: }
1795:
1796: /**
1797: * Representation of the Java<sup>TM</sup> "break" statement (JLS 14.14).
1798: */
1799: public final static class BreakStatement extends Statement {
1800: public final String optionalLabel;
1801:
1802: public BreakStatement(Location location, String optionalLabel) {
1803: super (location);
1804: this .optionalLabel = optionalLabel;
1805: }
1806:
1807: // Compile time members:
1808:
1809: public final void accept(Visitor.BlockStatementVisitor visitor) {
1810: visitor.visitBreakStatement(this );
1811: }
1812: }
1813:
1814: /**
1815: * Representation of the Java<sup>TM</sup> "continue" statement (JLS
1816: * 14.15).
1817: */
1818: public final static class ContinueStatement extends Statement {
1819: public final String optionalLabel;
1820:
1821: public ContinueStatement(Location location, String optionalLabel) {
1822: super (location);
1823: this .optionalLabel = optionalLabel;
1824: }
1825:
1826: // Compile time members:
1827:
1828: public final void accept(Visitor.BlockStatementVisitor visitor) {
1829: visitor.visitContinueStatement(this );
1830: }
1831: }
1832:
1833: /**
1834: * Represents the "empty statement", i.e. the blank semicolon.
1835: */
1836: public final static class EmptyStatement extends Statement {
1837: public EmptyStatement(Location location) {
1838: super (location);
1839: }
1840:
1841: public final void accept(Visitor.BlockStatementVisitor visitor) {
1842: visitor.visitEmptyStatement(this );
1843: }
1844: }
1845:
1846: /**
1847: * Abstract base class for {@link Java.Type}, {@link Java.Rvalue} and
1848: * {@link Java.Lvalue}.
1849: */
1850: public static abstract class Atom extends Located {
1851: public Atom(Location location) {
1852: super (location);
1853: }
1854:
1855: public Type toType() {
1856: return null;
1857: }
1858:
1859: public Rvalue toRvalue() {
1860: return null;
1861: }
1862:
1863: public Lvalue toLvalue() {
1864: return null;
1865: }
1866:
1867: public abstract String toString();
1868:
1869: // Parse time members:
1870:
1871: public final Type toTypeOrPE() throws Parser.ParseException {
1872: Type result = this .toType();
1873: if (result == null)
1874: this .throwParseException("Expression \""
1875: + this .toString() + "\" is not a type");
1876: return result;
1877: }
1878:
1879: public final Rvalue toRvalueOrPE() throws Parser.ParseException {
1880: Rvalue result = this .toRvalue();
1881: if (result == null)
1882: this .throwParseException("Expression \""
1883: + this .toString() + "\" is not an rvalue");
1884: return result;
1885: }
1886:
1887: public final Lvalue toLvalueOrPE() throws Parser.ParseException {
1888: Lvalue result = this .toLvalue();
1889: if (result == null)
1890: this .throwParseException("Expression \""
1891: + this .toString() + "\" is not an lvalue");
1892: return result;
1893: }
1894:
1895: public abstract void accept(Visitor.AtomVisitor visitor);
1896: }
1897:
1898: /**
1899: * Representation of a Java<sup>TM</sup> type.
1900: */
1901: public static abstract class Type extends Atom {
1902: private Scope enclosingScope = null;
1903:
1904: protected Type(Location location) {
1905: super (location);
1906: }
1907:
1908: /**
1909: * Sets the enclosing scope for this object and all subordinate
1910: * {@link org.codehaus.janino.Java.Type} objects.
1911: */
1912: public void setEnclosingScope(final Scope enclosingScope) {
1913: if (this .enclosingScope != null
1914: && enclosingScope != this .enclosingScope)
1915: throw new RuntimeException(
1916: "Enclosing scope already set for type \""
1917: + this .toString() + "\" at "
1918: + this .getLocation());
1919: this .enclosingScope = enclosingScope;
1920: }
1921:
1922: public Scope getEnclosingScope() {
1923: return this .enclosingScope;
1924: }
1925:
1926: public Type toType() {
1927: return this ;
1928: }
1929:
1930: public abstract void accept(Visitor.TypeVisitor visitor);
1931: }
1932:
1933: public static final class SimpleType extends Type {
1934: public final IClass iClass;
1935:
1936: public SimpleType(Location location, IClass iClass) {
1937: super (location);
1938: this .iClass = iClass;
1939: }
1940:
1941: public String toString() {
1942: return this .iClass.toString();
1943: }
1944:
1945: public final void accept(Visitor.AtomVisitor visitor) {
1946: visitor.visitSimpleType(this );
1947: }
1948:
1949: public final void accept(Visitor.TypeVisitor visitor) {
1950: visitor.visitSimpleType(this );
1951: }
1952: };
1953:
1954: /**
1955: * Representation of a Java<sup>TM</sup> "basic type" (obviously
1956: * equaivalent to a "primitive type") (JLS 4.2).
1957: */
1958: public static final class BasicType extends Type {
1959: public/*final*/int index;
1960:
1961: public BasicType(Location location, int index) {
1962: super (location);
1963: this .index = index;
1964: }
1965:
1966: public String toString() {
1967: switch (this .index) {
1968: case BasicType.VOID:
1969: return "void";
1970: case BasicType.BYTE:
1971: return "byte";
1972: case BasicType.SHORT:
1973: return "short";
1974: case BasicType.CHAR:
1975: return "char";
1976: case BasicType.INT:
1977: return "int";
1978: case BasicType.LONG:
1979: return "long";
1980: case BasicType.FLOAT:
1981: return "float";
1982: case BasicType.DOUBLE:
1983: return "double";
1984: case BasicType.BOOLEAN:
1985: return "boolean";
1986: default:
1987: throw new RuntimeException("Invalid index "
1988: + this .index);
1989: }
1990: }
1991:
1992: public final void accept(Visitor.TypeVisitor visitor) {
1993: visitor.visitBasicType(this );
1994: }
1995:
1996: public final void accept(Visitor.AtomVisitor visitor) {
1997: visitor.visitBasicType(this );
1998: }
1999:
2000: public static final int VOID = 0;
2001: public static final int BYTE = 1;
2002: public static final int SHORT = 2;
2003: public static final int CHAR = 3;
2004: public static final int INT = 4;
2005: public static final int LONG = 5;
2006: public static final int FLOAT = 6;
2007: public static final int DOUBLE = 7;
2008: public static final int BOOLEAN = 8;
2009: }
2010:
2011: public static final class ReferenceType extends Type {
2012: public final String[] identifiers;
2013:
2014: public ReferenceType(Location location, String[] identifiers) {
2015: super (location);
2016: this .identifiers = identifiers;
2017: }
2018:
2019: public String toString() {
2020: return Java.join(this .identifiers, ".");
2021: }
2022:
2023: public final void accept(Visitor.AtomVisitor visitor) {
2024: visitor.visitReferenceType(this );
2025: }
2026:
2027: public final void accept(Visitor.TypeVisitor visitor) {
2028: visitor.visitReferenceType(this );
2029: }
2030: }
2031:
2032: // Helper class for JLS 15.9.1
2033: public static final class RvalueMemberType extends Type {
2034: public final Rvalue rvalue;
2035: public final String identifier;
2036:
2037: /**
2038: * Notice: The <code>rvalue</code> is not a subordinate object!
2039: */
2040: public RvalueMemberType(Location location, Rvalue rvalue,
2041: String identifier) {
2042: super (location);
2043: this .rvalue = rvalue;
2044: this .identifier = identifier;
2045: }
2046:
2047: public String toString() {
2048: return this .identifier;
2049: }
2050:
2051: public final void accept(Visitor.AtomVisitor visitor) {
2052: visitor.visitRvalueMemberType(this );
2053: }
2054:
2055: public final void accept(Visitor.TypeVisitor visitor) {
2056: visitor.visitRvalueMemberType(this );
2057: }
2058: }
2059:
2060: /**
2061: * Representation of a Java<sup>TM</sup> array type (JLS 10.1).
2062: */
2063: public static final class ArrayType extends Type {
2064: public final Type componentType;
2065:
2066: public ArrayType(Type componentType) {
2067: super (componentType.getLocation());
2068: this .componentType = componentType;
2069: }
2070:
2071: public void setEnclosingScope(final Scope enclosingScope) {
2072: super .setEnclosingScope(enclosingScope);
2073: this .componentType.setEnclosingScope(enclosingScope);
2074: }
2075:
2076: public String toString() {
2077: return this .componentType.toString() + "[]";
2078: }
2079:
2080: public final void accept(Visitor.AtomVisitor visitor) {
2081: visitor.visitArrayType(this );
2082: }
2083:
2084: public final void accept(Visitor.TypeVisitor visitor) {
2085: visitor.visitArrayType(this );
2086: }
2087: }
2088:
2089: /**
2090: * Representation of an "rvalue", i.e. an expression that has a type and
2091: * a value, but cannot be assigned to: An expression that can be the
2092: * right-hand-side of an assignment.
2093: */
2094: public static abstract class Rvalue extends Atom implements
2095: ArrayInitializerOrRvalue {
2096: private Java.BlockStatement enclosingBlockStatement = null;
2097:
2098: protected Rvalue(Location location) {
2099: super (location);
2100: }
2101:
2102: /**
2103: * Sets enclosing block statement for this object and all subordinate
2104: * {@link org.codehaus.janino.Java.Rvalue} objects.
2105: */
2106: public final void setEnclosingBlockStatement(
2107: final Java.BlockStatement enclosingBlockStatement) {
2108: this .accept((Visitor.RvalueVisitor) new Traverser() {
2109: public void traverseRvalue(Java.Rvalue rv) {
2110: if (rv.enclosingBlockStatement != null
2111: && enclosingBlockStatement != rv.enclosingBlockStatement)
2112: throw new RuntimeException(
2113: "Enclosing block statement for rvalue \""
2114: + rv + "\" at "
2115: + rv.getLocation()
2116: + " is already set");
2117: rv.enclosingBlockStatement = enclosingBlockStatement;
2118: super .traverseRvalue(rv);
2119: }
2120:
2121: public void traverseAnonymousClassDeclaration(
2122: Java.AnonymousClassDeclaration acd) {
2123: acd.setEnclosingScope(enclosingBlockStatement);
2124: ;
2125: }
2126:
2127: public void traverseType(Java.Type t) {
2128: if (t.enclosingScope != null
2129: && enclosingBlockStatement != t.enclosingScope)
2130: throw new RuntimeException(
2131: "Enclosing scope already set for type \""
2132: + this .toString() + "\" at "
2133: + t.getLocation());
2134: t.enclosingScope = enclosingBlockStatement;
2135: // t.setEnclosingScope(enclosingBlockStatement);
2136: super .traverseType(t);
2137: }
2138: }.cv);
2139: }
2140:
2141: public Java.BlockStatement getEnclosingBlockStatement() {
2142: return this .enclosingBlockStatement;
2143: }
2144:
2145: public Rvalue toRvalue() {
2146: return this ;
2147: }
2148:
2149: static final Object CONSTANT_VALUE_UNKNOWN = new Object();
2150: Object constantValue = Java.Rvalue.CONSTANT_VALUE_UNKNOWN;
2151: public static final Object CONSTANT_VALUE_NULL = new Throwable();
2152:
2153: public abstract void accept(Visitor.RvalueVisitor rvv);
2154:
2155: public final static boolean JUMP_IF_TRUE = true;
2156: public final static boolean JUMP_IF_FALSE = false;
2157: }
2158:
2159: /**
2160: * Base class for {@link Java.Rvalue}s that compile better as conditional
2161: * branches.
2162: */
2163: public static abstract class BooleanRvalue extends Rvalue {
2164: protected BooleanRvalue(Location location) {
2165: super (location);
2166: }
2167: }
2168:
2169: /**
2170: * Representation of an "lvalue", i.e. an expression that has a type and
2171: * a value, and can be assigned to: An expression that can be the
2172: * left-hand-side of an assignment.
2173: */
2174: public static abstract class Lvalue extends Rvalue {
2175: protected Lvalue(Location location) {
2176: super (location);
2177: }
2178:
2179: public Lvalue toLvalue() {
2180: return this ;
2181: }
2182:
2183: public abstract void accept(Visitor.LvalueVisitor lvv);
2184: }
2185:
2186: /**
2187: * This class is special: It does not extend/implement the Atom subclasses,
2188: * but overrides Atom's "to...()" methods.
2189: */
2190: public static final class AmbiguousName extends Lvalue {
2191: public final String[] identifiers;
2192: public final int n;
2193:
2194: public AmbiguousName(Location location, String[] identifiers) {
2195: this (location, identifiers, identifiers.length);
2196: }
2197:
2198: public AmbiguousName(Location location, String[] identifiers,
2199: int n) {
2200: super (location);
2201: this .identifiers = identifiers;
2202: this .n = n;
2203: }
2204:
2205: // Override "Atom.toType()".
2206: private Type type = null;
2207:
2208: public Type toType() {
2209: if (this .type == null) {
2210: String[] is = new String[this .n];
2211: System.arraycopy(this .identifiers, 0, is, 0, this .n);
2212: this .type = new ReferenceType(this .getLocation(), is);
2213: this .type.setEnclosingScope(this
2214: .getEnclosingBlockStatement());
2215: }
2216: return this .type;
2217: }
2218:
2219: // Compile time members.
2220:
2221: public String toString() {
2222: return Java.join(this .identifiers, ".", 0, this .n);
2223: }
2224:
2225: Atom reclassified = null;
2226:
2227: public final void accept(Visitor.AtomVisitor visitor) {
2228: visitor.visitAmbiguousName(this );
2229: }
2230:
2231: public final void accept(Visitor.RvalueVisitor visitor) {
2232: visitor.visitAmbiguousName(this );
2233: }
2234:
2235: public final void accept(Visitor.LvalueVisitor visitor) {
2236: visitor.visitAmbiguousName(this );
2237: }
2238: }
2239:
2240: // Helper class for 6.5.2.1.7, 6.5.2.2.1
2241: public static final class Package extends Atom {
2242: public final String name;
2243:
2244: public Package(Location location, String name) {
2245: super (location);
2246: this .name = name;
2247: }
2248:
2249: public String toString() {
2250: return this .name;
2251: }
2252:
2253: public final void accept(Visitor.AtomVisitor visitor) {
2254: visitor.visitPackage(this );
2255: }
2256: }
2257:
2258: /**
2259: * Representation of a local variable access -- used during compilation.
2260: */
2261: public static final class LocalVariableAccess extends Lvalue {
2262: public/*final*/LocalVariable localVariable;
2263:
2264: public LocalVariableAccess(Location location,
2265: LocalVariable localVariable) {
2266: super (location);
2267: this .localVariable = localVariable;
2268: }
2269:
2270: // Compile time members.
2271:
2272: public String toString() {
2273: return this .localVariable.toString();
2274: }
2275:
2276: public final void accept(Visitor.LvalueVisitor visitor) {
2277: visitor.visitLocalVariableAccess(this );
2278: }
2279:
2280: public final void accept(Visitor.RvalueVisitor visitor) {
2281: visitor.visitLocalVariableAccess(this );
2282: }
2283:
2284: public final void accept(Visitor.AtomVisitor visitor) {
2285: visitor.visitLocalVariableAccess(this );
2286: }
2287: }
2288:
2289: /**
2290: * Representation of an access to a field of a class or an interface. (Does not implement the
2291: * "array length" expression, e.g. "ia.length".)
2292: */
2293: public static final class FieldAccess extends Lvalue {
2294: public final Atom lhs;
2295: public final IClass.IField field;
2296:
2297: public FieldAccess(Location location, Atom lhs,
2298: IClass.IField field) {
2299: super (location);
2300: this .lhs = lhs;
2301: this .field = field;
2302: }
2303:
2304: // Compile time members.
2305:
2306: // Implement "Atom".
2307: public String toString() {
2308: return this .lhs.toString() + '.' + this .field.toString();
2309: }
2310:
2311: public final void accept(Visitor.AtomVisitor visitor) {
2312: visitor.visitFieldAccess(this );
2313: }
2314:
2315: public final void accept(Visitor.RvalueVisitor visitor) {
2316: visitor.visitFieldAccess(this );
2317: }
2318:
2319: public final void accept(Visitor.LvalueVisitor visitor) {
2320: visitor.visitFieldAccess(this );
2321: }
2322: }
2323:
2324: public static final class ArrayLength extends Rvalue {
2325: public final Rvalue lhs;
2326:
2327: public ArrayLength(Location location, Rvalue lhs) {
2328: super (location);
2329: this .lhs = lhs;
2330: }
2331:
2332: // Compile time members.
2333:
2334: // Implement "Atom".
2335: public String toString() {
2336: return this .lhs.toString() + ".length";
2337: }
2338:
2339: public final void accept(Visitor.AtomVisitor visitor) {
2340: visitor.visitArrayLength(this );
2341: }
2342:
2343: public final void accept(Visitor.RvalueVisitor visitor) {
2344: visitor.visitArrayLength(this );
2345: }
2346: }
2347:
2348: /**
2349: * Representation of an access to the innermost enclosing instance.
2350: */
2351: public static final class ThisReference extends Rvalue {
2352:
2353: /**
2354: * Access the declaring class.
2355: * @param location
2356: * @param scope
2357: */
2358: public ThisReference(Location location) {
2359: super (location);
2360: }
2361:
2362: // Compile time members.
2363:
2364: IClass iClass = null;
2365:
2366: // Implement "Atom".
2367: public String toString() {
2368: return "this";
2369: }
2370:
2371: public final void accept(Visitor.AtomVisitor visitor) {
2372: visitor.visitThisReference(this );
2373: }
2374:
2375: public final void accept(Visitor.RvalueVisitor visitor) {
2376: visitor.visitThisReference(this );
2377: }
2378: }
2379:
2380: /**
2381: * Representation of an access to the current object or an enclosing instance.
2382: */
2383: public static final class QualifiedThisReference extends Rvalue {
2384: public final Type qualification;
2385:
2386: /**
2387: * Access the given enclosing instance of the declaring class.
2388: */
2389: public QualifiedThisReference(Location location,
2390: Type qualification) {
2391: super (location);
2392:
2393: if (qualification == null)
2394: throw new NullPointerException();
2395: this .qualification = qualification;
2396: }
2397:
2398: // Compile time members.
2399:
2400: ClassDeclaration declaringClass = null;
2401: TypeBodyDeclaration declaringTypeBodyDeclaration = null;
2402: IClass targetIClass = null;
2403:
2404: // Used at compile time.
2405: // public QualifiedThisReference(
2406: // Location location,
2407: // ClassDeclaration declaringClass,
2408: // TypeBodyDeclaration declaringTypeBodyDeclaration,
2409: // IClass targetIClass
2410: // ) {
2411: // super(location);
2412: // if (declaringClass == null) throw new NullPointerException();
2413: // if (declaringTypeBodyDeclaration == null) throw new NullPointerException();
2414: // if (targetIClass == null) throw new NullPointerException();
2415: //
2416: // this.qualification = null;
2417: // this.declaringClass = declaringClass;
2418: // this.declaringTypeBodyDeclaration = declaringTypeBodyDeclaration;
2419: // this.targetIClass = targetIClass;
2420: // }
2421:
2422: // Implement "Atom".
2423: public String toString() {
2424: return this .qualification.toString() + ".this";
2425: }
2426:
2427: public final void accept(Visitor.AtomVisitor visitor) {
2428: visitor.visitQualifiedThisReference(this );
2429: }
2430:
2431: public final void accept(Visitor.RvalueVisitor visitor) {
2432: visitor.visitQualifiedThisReference(this );
2433: }
2434: }
2435:
2436: public static final class ClassLiteral extends Rvalue {
2437: public final Type type;
2438:
2439: public ClassLiteral(Location location, Type type) {
2440: super (location);
2441: this .type = type;
2442: }
2443:
2444: // Compile time members.
2445:
2446: //Implement "Atom".
2447: public String toString() {
2448: return this .type.toString() + ".class";
2449: }
2450:
2451: public final void accept(Visitor.AtomVisitor visitor) {
2452: visitor.visitClassLiteral(this );
2453: }
2454:
2455: public final void accept(Visitor.RvalueVisitor visitor) {
2456: visitor.visitClassLiteral(this );
2457: }
2458: }
2459:
2460: public static final class Assignment extends Rvalue {
2461: public final Lvalue lhs;
2462: public final String operator;
2463: public final Rvalue rhs;
2464:
2465: public Assignment(Location location, Lvalue lhs,
2466: String operator, Rvalue rhs) {
2467: super (location);
2468: this .lhs = lhs;
2469: this .operator = operator;
2470: this .rhs = rhs;
2471: }
2472:
2473: // Compile time members.
2474:
2475: // Implement "Atom".
2476: public String toString() {
2477: return this .lhs.toString() + ' ' + this .operator + ' '
2478: + this .rhs.toString();
2479: }
2480:
2481: public final void accept(Visitor.AtomVisitor visitor) {
2482: visitor.visitAssignment(this );
2483: }
2484:
2485: public final void accept(Visitor.RvalueVisitor visitor) {
2486: visitor.visitAssignment(this );
2487: }
2488: }
2489:
2490: public static final class ConditionalExpression extends Rvalue {
2491: public final Rvalue lhs, mhs, rhs;
2492:
2493: public ConditionalExpression(Location location, Rvalue lhs,
2494: Rvalue mhs, Rvalue rhs) {
2495: super (location);
2496: this .lhs = lhs;
2497: this .mhs = mhs;
2498: this .rhs = rhs;
2499: }
2500:
2501: // Implement "Atom".
2502: public String toString() {
2503: return this .lhs.toString() + " ? " + this .mhs.toString()
2504: + " : " + this .rhs.toString();
2505: }
2506:
2507: public final void accept(Visitor.AtomVisitor visitor) {
2508: visitor.visitConditionalExpression(this );
2509: }
2510:
2511: public final void accept(Visitor.RvalueVisitor visitor) {
2512: visitor.visitConditionalExpression(this );
2513: }
2514: }
2515:
2516: /**
2517: * Objects of this class represent represent one pre- or post-increment
2518: * or decrement.
2519: */
2520: public static final class Crement extends Rvalue {
2521: public final boolean pre;
2522: public final String operator; // "++" or "--"
2523: public final Lvalue operand;
2524:
2525: public Crement(Location location, String operator,
2526: Lvalue operand) {
2527: super (location);
2528: this .pre = true;
2529: this .operator = operator;
2530: this .operand = operand;
2531: }
2532:
2533: public Crement(Location location, Lvalue operand,
2534: String operator) {
2535: super (location);
2536: this .pre = false;
2537: this .operator = operator;
2538: this .operand = operand;
2539: }
2540:
2541: // Compile time members.
2542:
2543: // Implement "Atom".
2544: public String toString() {
2545: return (this .pre ? this .operator + this .operand
2546: : this .operand + this .operator);
2547: }
2548:
2549: public final void accept(Visitor.AtomVisitor visitor) {
2550: visitor.visitCrement(this );
2551: }
2552:
2553: public final void accept(Visitor.RvalueVisitor visitor) {
2554: visitor.visitCrement(this );
2555: }
2556: }
2557:
2558: /**
2559: * This class implements an array access.
2560: */
2561: public static final class ArrayAccessExpression extends Lvalue {
2562: public final Rvalue lhs;
2563: public final Rvalue index;
2564:
2565: public ArrayAccessExpression(Location location, Rvalue lhs,
2566: Rvalue index) {
2567: super (location);
2568: this .lhs = lhs;
2569: this .index = index;
2570: }
2571:
2572: // Compile time members:
2573:
2574: // Implement "Atom".
2575: public String toString() {
2576: return this .lhs.toString() + '[' + this .index + ']';
2577: }
2578:
2579: public final void accept(Visitor.AtomVisitor visitor) {
2580: visitor.visitArrayAccessExpression(this );
2581: }
2582:
2583: public final void accept(Visitor.RvalueVisitor visitor) {
2584: visitor.visitArrayAccessExpression(this );
2585: }
2586:
2587: public final void accept(Visitor.LvalueVisitor visitor) {
2588: visitor.visitArrayAccessExpression(this );
2589: }
2590: }
2591:
2592: /**
2593: * This class implements class or interface field access, and also the "array length"
2594: * expression "xy.length".
2595: */
2596: public static final class FieldAccessExpression extends Lvalue {
2597: public final Atom lhs;
2598: public final String fieldName;
2599:
2600: public FieldAccessExpression(Location location, Atom lhs,
2601: String fieldName) {
2602: super (location);
2603: this .lhs = lhs;
2604: this .fieldName = fieldName;
2605: }
2606:
2607: // Compile time members:
2608:
2609: // Implement "Atom".
2610: public String toString() {
2611: return this .lhs.toString() + '.' + this .fieldName;
2612: }
2613:
2614: public final void accept(Visitor.AtomVisitor visitor) {
2615: visitor.visitFieldAccessExpression(this );
2616: }
2617:
2618: public final void accept(Visitor.RvalueVisitor visitor) {
2619: visitor.visitFieldAccessExpression(this );
2620: }
2621:
2622: public final void accept(Visitor.LvalueVisitor visitor) {
2623: visitor.visitFieldAccessExpression(this );
2624: }
2625:
2626: Rvalue value = null;
2627: }
2628:
2629: /**
2630: * This class implements the unary operators "+", "-", "~" and "!".
2631: */
2632: public static final class UnaryOperation extends BooleanRvalue {
2633: public final String operator;
2634: public final Rvalue operand;
2635:
2636: public UnaryOperation(Location location, String operator,
2637: Rvalue operand) {
2638: super (location);
2639: this .operator = operator;
2640: this .operand = operand;
2641: }
2642:
2643: // Implement "Atom".
2644: public String toString() {
2645: return this .operator + this .operand.toString();
2646: }
2647:
2648: public final void accept(Visitor.AtomVisitor visitor) {
2649: visitor.visitUnaryOperation(this );
2650: }
2651:
2652: public final void accept(Visitor.RvalueVisitor visitor) {
2653: visitor.visitUnaryOperation(this );
2654: }
2655: }
2656:
2657: public static final class Instanceof extends Rvalue {
2658: public final Rvalue lhs;
2659: public final Type rhs;
2660:
2661: public Instanceof(Location location, Rvalue lhs, Type rhs // ReferenceType or ArrayType
2662: ) {
2663: super (location);
2664: this .lhs = lhs;
2665: this .rhs = rhs;
2666: }
2667:
2668: // Compile time members.
2669:
2670: // Implement "Atom".
2671: public String toString() {
2672: return this .lhs.toString() + " instanceof "
2673: + this .rhs.toString();
2674: }
2675:
2676: public final void accept(Visitor.AtomVisitor visitor) {
2677: visitor.visitInstanceof(this );
2678: }
2679:
2680: public final void accept(Visitor.RvalueVisitor visitor) {
2681: visitor.visitInstanceof(this );
2682: }
2683: }
2684:
2685: /**
2686: * Representation of all non-operand-modifying Java<sup>TM</sup> binary
2687: * operations.
2688: * <p>
2689: * Operations with boolean result:<br>
2690: * <tt>|| && == != < > <= >=</tt>
2691: * <p>
2692: * Operations with non-boolean result:<br>
2693: * <tt>| ^ & * / % + - << >> >>></tt>
2694: */
2695: public static final class BinaryOperation extends BooleanRvalue {
2696: public final Rvalue lhs;
2697: public final String op;
2698: public final Rvalue rhs;
2699:
2700: public BinaryOperation(Location location, Rvalue lhs,
2701: String op, Rvalue rhs) {
2702: super (location);
2703: this .lhs = lhs;
2704: this .op = op;
2705: this .rhs = rhs;
2706: }
2707:
2708: // Compile time members.
2709:
2710: // Implement "Atom".
2711: public String toString() {
2712: return this .lhs.toString() + ' ' + this .op + ' '
2713: + this .rhs.toString();
2714: }
2715:
2716: /**
2717: * Returns an {@link Iterator} over a left-to-right sequence of {@link Java.Rvalue}s.
2718: */
2719: public Iterator unrollLeftAssociation() {
2720: List operands = new ArrayList();
2721: BinaryOperation x = this ;
2722: for (;;) {
2723: operands.add(x.rhs);
2724: Rvalue lhs = x.lhs;
2725: if (lhs instanceof BinaryOperation
2726: && ((BinaryOperation) lhs).op == this .op) {
2727: x = (BinaryOperation) lhs;
2728: } else {
2729: operands.add(lhs);
2730: break;
2731: }
2732: }
2733: return new ReverseListIterator(operands
2734: .listIterator(operands.size()));
2735: }
2736:
2737: public final void accept(Visitor.AtomVisitor visitor) {
2738: visitor.visitBinaryOperation(this );
2739: }
2740:
2741: public final void accept(Visitor.RvalueVisitor visitor) {
2742: visitor.visitBinaryOperation(this );
2743: }
2744: }
2745:
2746: public static final class Cast extends Rvalue {
2747: public final Type targetType;
2748: public final Rvalue value;
2749:
2750: public Cast(Location location, Type targetType, Rvalue value) {
2751: super (location);
2752: this .targetType = targetType;
2753: this .value = value;
2754: }
2755:
2756: // Compile time members.
2757:
2758: // Implement "Atom".
2759: public String toString() {
2760: return '(' + this .targetType.toString() + ") "
2761: + this .value.toString();
2762: }
2763:
2764: public final void accept(Visitor.AtomVisitor visitor) {
2765: visitor.visitCast(this );
2766: }
2767:
2768: public final void accept(Visitor.RvalueVisitor visitor) {
2769: visitor.visitCast(this );
2770: }
2771: }
2772:
2773: public final static class ParenthesizedExpression extends Lvalue {
2774: public final Rvalue value;
2775:
2776: public ParenthesizedExpression(Location location, Rvalue value) {
2777: super (location);
2778: this .value = value;
2779: }
2780:
2781: public String toString() {
2782: return '(' + this .value.toString() + ')';
2783: }
2784:
2785: public void accept(Visitor.AtomVisitor visitor) {
2786: visitor.visitParenthesizedExpression(this );
2787: }
2788:
2789: public void accept(Visitor.RvalueVisitor visitor) {
2790: visitor.visitParenthesizedExpression(this );
2791: }
2792:
2793: public void accept(Visitor.LvalueVisitor visitor) {
2794: visitor.visitParenthesizedExpression(this );
2795: }
2796: }
2797:
2798: public static abstract class ConstructorInvocation extends Atom
2799: implements BlockStatement {
2800: public final Rvalue[] arguments;
2801: private Scope enclosingScope = null;
2802:
2803: protected ConstructorInvocation(Location location,
2804: Rvalue[] arguments) {
2805: super (location);
2806: this .arguments = arguments;
2807: for (int i = 0; i < arguments.length; ++i)
2808: arguments[i].setEnclosingBlockStatement(this );
2809: }
2810:
2811: // Implement BlockStatement
2812: public void setEnclosingScope(Scope enclosingScope) {
2813: if (this .enclosingScope != null && enclosingScope != null)
2814: throw new RuntimeException(
2815: "Enclosing scope is already set for statement \""
2816: + this .toString() + "\" at "
2817: + this .getLocation());
2818: this .enclosingScope = enclosingScope;
2819: }
2820:
2821: public Scope getEnclosingScope() {
2822: return this .enclosingScope;
2823: }
2824: }
2825:
2826: public final static class AlternateConstructorInvocation extends
2827: ConstructorInvocation {
2828: public AlternateConstructorInvocation(Location location,
2829: Rvalue[] arguments) {
2830: super (location, arguments);
2831: }
2832:
2833: // Implement Atom.
2834: public String toString() {
2835: return "this()";
2836: }
2837:
2838: public void accept(Visitor.AtomVisitor visitor) {
2839: ((Visitor.BlockStatementVisitor) visitor)
2840: .visitAlternateConstructorInvocation(this );
2841: }
2842:
2843: // Implement BlockStatement.
2844: public void accept(Visitor.BlockStatementVisitor visitor) {
2845: visitor.visitAlternateConstructorInvocation(this );
2846: }
2847: }
2848:
2849: public final static class SuperConstructorInvocation extends
2850: ConstructorInvocation {
2851: public final Rvalue optionalQualification;
2852:
2853: public SuperConstructorInvocation(Location location,
2854: Rvalue optionalQualification, Rvalue[] arguments) {
2855: super (location, arguments);
2856: this .optionalQualification = optionalQualification;
2857: if (optionalQualification != null)
2858: optionalQualification.setEnclosingBlockStatement(this );
2859: }
2860:
2861: // Implement Atom.
2862: public String toString() {
2863: return "super()";
2864: }
2865:
2866: public void accept(Visitor.AtomVisitor visitor) {
2867: ((Visitor.BlockStatementVisitor) visitor)
2868: .visitSuperConstructorInvocation(this );
2869: }
2870:
2871: // Implement BlockStatement.
2872: public void accept(Visitor.BlockStatementVisitor visitor) {
2873: visitor.visitSuperConstructorInvocation(this );
2874: }
2875: }
2876:
2877: public static final class MethodInvocation extends Invocation {
2878: public final Atom optionalTarget; // null == simple method name.
2879: public final String methodName;
2880:
2881: public MethodInvocation(Location location, Atom optionalTarget,
2882: String methodName, Rvalue[] arguments) {
2883: super (location, arguments);
2884: this .optionalTarget = optionalTarget;
2885: this .methodName = methodName;
2886: }
2887:
2888: // Implement "Atom".
2889: IClass.IMethod iMethod;
2890:
2891: public String toString() {
2892: StringBuffer sb = new StringBuffer();
2893: if (this .optionalTarget != null)
2894: sb.append(this .optionalTarget.toString()).append('.');
2895: sb.append(this .methodName).append('(');
2896: for (int i = 0; i < this .arguments.length; ++i) {
2897: if (i > 0)
2898: sb.append(", ");
2899: sb.append(this .arguments[i].toString());
2900: }
2901: sb.append(')');
2902: return sb.toString();
2903: }
2904:
2905: public final void accept(Visitor.AtomVisitor visitor) {
2906: visitor.visitMethodInvocation(this );
2907: }
2908:
2909: public final void accept(Visitor.RvalueVisitor visitor) {
2910: visitor.visitMethodInvocation(this );
2911: }
2912: }
2913:
2914: public static final class SuperclassMethodInvocation extends
2915: Invocation {
2916: public final String methodName;
2917:
2918: public SuperclassMethodInvocation(Location location,
2919: String methodName, Rvalue[] arguments) {
2920: super (location, arguments);
2921: this .methodName = methodName;
2922: }
2923:
2924: // Implement "Atom".
2925: public String toString() {
2926: return "super." + this .methodName + "()";
2927: }
2928:
2929: public final void accept(Visitor.AtomVisitor visitor) {
2930: visitor.visitSuperclassMethodInvocation(this );
2931: }
2932:
2933: public final void accept(Visitor.RvalueVisitor visitor) {
2934: visitor.visitSuperclassMethodInvocation(this );
2935: }
2936: }
2937:
2938: public static abstract class Invocation extends Rvalue {
2939: public final Rvalue[] arguments;
2940:
2941: protected Invocation(Location location, Rvalue[] arguments) {
2942: super (location);
2943: this .arguments = arguments;
2944: }
2945: }
2946:
2947: public static final class NewClassInstance extends Rvalue {
2948: public final Rvalue optionalQualification;
2949: public final Type type;
2950: public final Rvalue[] arguments;
2951:
2952: public NewClassInstance(Location location,
2953: Rvalue optionalQualification, Type type,
2954: Rvalue[] arguments) {
2955: super (location);
2956: this .optionalQualification = optionalQualification;
2957: this .type = type;
2958: this .arguments = arguments;
2959: }
2960:
2961: // Compile time members.
2962:
2963: protected IClass iClass = null;
2964:
2965: public NewClassInstance(Location location,
2966: Rvalue optionalQualification, IClass iClass,
2967: Rvalue[] arguments) {
2968: super (location);
2969: this .optionalQualification = optionalQualification;
2970: this .type = null;
2971: this .arguments = arguments;
2972: this .iClass = iClass;
2973: }
2974:
2975: // Implement "Atom".
2976: public String toString() {
2977: StringBuffer sb = new StringBuffer();
2978: if (this .optionalQualification != null)
2979: sb.append(this .optionalQualification.toString())
2980: .append('.');
2981: sb.append("new ");
2982: if (this .type != null) {
2983: sb.append(this .type.toString());
2984: } else if (this .iClass != null) {
2985: sb.append(this .iClass.toString());
2986: } else {
2987: sb.append("???");
2988: }
2989: sb.append('(');
2990: for (int i = 0; i < this .arguments.length; ++i) {
2991: if (i > 0)
2992: sb.append(", ");
2993: sb.append(this .arguments[i].toString());
2994: }
2995: sb.append(')');
2996: return sb.toString();
2997: }
2998:
2999: public final void accept(Visitor.AtomVisitor visitor) {
3000: visitor.visitNewClassInstance(this );
3001: }
3002:
3003: public final void accept(Visitor.RvalueVisitor visitor) {
3004: visitor.visitNewClassInstance(this );
3005: }
3006: }
3007:
3008: public static final class NewAnonymousClassInstance extends Rvalue {
3009: public final Rvalue optionalQualification;
3010: public final AnonymousClassDeclaration anonymousClassDeclaration;
3011: public final Rvalue[] arguments;
3012:
3013: public NewAnonymousClassInstance(Location location,
3014: Rvalue optionalQualification,
3015: AnonymousClassDeclaration anonymousClassDeclaration,
3016: Rvalue[] arguments) {
3017: super (location);
3018: this .optionalQualification = optionalQualification;
3019: this .anonymousClassDeclaration = anonymousClassDeclaration;
3020: this .arguments = arguments;
3021: }
3022:
3023: // Implement "Atom".
3024: public String toString() {
3025: StringBuffer sb = new StringBuffer();
3026: if (this .optionalQualification != null)
3027: sb.append(this .optionalQualification.toString())
3028: .append('.');
3029: sb.append("new ").append(
3030: this .anonymousClassDeclaration.baseType.toString())
3031: .append("() { ... }");
3032: return sb.toString();
3033: }
3034:
3035: public final void accept(Visitor.AtomVisitor visitor) {
3036: visitor.visitNewAnonymousClassInstance(this );
3037: }
3038:
3039: public final void accept(Visitor.RvalueVisitor visitor) {
3040: visitor.visitNewAnonymousClassInstance(this );
3041: }
3042: }
3043:
3044: // Used during compile-time.
3045: public static final class ParameterAccess extends Rvalue {
3046: public final FunctionDeclarator.FormalParameter formalParameter;
3047:
3048: public ParameterAccess(Location location,
3049: FunctionDeclarator.FormalParameter formalParameter) {
3050: super (location);
3051: this .formalParameter = formalParameter;
3052: }
3053:
3054: // Implement Atom
3055: public String toString() {
3056: return this .formalParameter.name;
3057: }
3058:
3059: public final void accept(Visitor.AtomVisitor visitor) {
3060: visitor.visitParameterAccess(this );
3061: }
3062:
3063: public final void accept(Visitor.RvalueVisitor visitor) {
3064: visitor.visitParameterAccess(this );
3065: }
3066: }
3067:
3068: public static final class NewArray extends Rvalue {
3069: public final Type type;
3070: public final Rvalue[] dimExprs;
3071: public final int dims;
3072:
3073: public NewArray(Location location, Type type,
3074: Rvalue[] dimExprs, int dims) {
3075: super (location);
3076: this .type = type;
3077: this .dimExprs = dimExprs;
3078: this .dims = dims;
3079: }
3080:
3081: // Implement "Atom".
3082: public String toString() {
3083: return "new " + this .type.toString() + "[]...";
3084: }
3085:
3086: public final void accept(Visitor.AtomVisitor visitor) {
3087: visitor.visitNewArray(this );
3088: }
3089:
3090: // Implement "Rvalue".
3091: public final void accept(Visitor.RvalueVisitor visitor) {
3092: visitor.visitNewArray(this );
3093: }
3094: }
3095:
3096: public static final class NewInitializedArray extends Rvalue {
3097: public final ArrayType arrayType;
3098: public final ArrayInitializer arrayInitializer;
3099:
3100: public NewInitializedArray(Location location,
3101: ArrayType arrayType, ArrayInitializer arrayInitializer) {
3102: super (location);
3103: this .arrayType = arrayType;
3104: this .arrayInitializer = arrayInitializer;
3105: }
3106:
3107: // Implement "Atom".
3108: public String toString() {
3109: return "new " + this .arrayType.toString() + " { ... }";
3110: }
3111:
3112: public final void accept(Visitor.AtomVisitor visitor) {
3113: visitor.visitNewInitializedArray(this );
3114: }
3115:
3116: // Implement "Rvalue".
3117: public final void accept(Visitor.RvalueVisitor visitor) {
3118: visitor.visitNewInitializedArray(this );
3119: }
3120: }
3121:
3122: /**
3123: * Represents a Java<sup>TM</sup> array initializer (JLS 10.6).
3124: * <p>
3125: * Allocates an array and initializes its members with (not necessarily
3126: * constant) values.
3127: */
3128: public static final class ArrayInitializer extends Located
3129: implements ArrayInitializerOrRvalue {
3130: public final ArrayInitializerOrRvalue[] values;
3131:
3132: public ArrayInitializer(Location location,
3133: ArrayInitializerOrRvalue[] values) {
3134: super (location);
3135: this .values = values;
3136: }
3137: }
3138:
3139: public interface ArrayInitializerOrRvalue {
3140: }
3141:
3142: public static final class Literal extends Rvalue {
3143: public final Object value; // The "null" literal has "value == null".
3144:
3145: public Literal(Location location, Object value) {
3146: super (location);
3147: this .value = value;
3148: }
3149:
3150: // Implement "Atom".
3151: public String toString() {
3152: return Scanner.literalValueToString(this .value);
3153: }
3154:
3155: public final void accept(Visitor.AtomVisitor visitor) {
3156: visitor.visitLiteral(this );
3157: }
3158:
3159: public final void accept(Visitor.RvalueVisitor visitor) {
3160: visitor.visitLiteral(this );
3161: }
3162: }
3163:
3164: public static final class ConstantValue extends Rvalue {
3165: public final Object constantValue;
3166:
3167: public ConstantValue(Location location, Object constantValue) {
3168: super (location);
3169: this .constantValue = constantValue == null ? Rvalue.CONSTANT_VALUE_NULL
3170: : constantValue;
3171: }
3172:
3173: // Implement "Atom".
3174: public String toString() {
3175: return this .constantValue.toString();
3176: }
3177:
3178: public final void accept(Visitor.AtomVisitor visitor) {
3179: visitor.visitConstantValue(this );
3180: }
3181:
3182: public final void accept(Visitor.RvalueVisitor visitor) {
3183: visitor.visitConstantValue(this );
3184: }
3185: }
3186:
3187: /**
3188: * Used during resolution.
3189: */
3190: public static class LocalVariable {
3191: public final boolean finaL;
3192: public final IClass type;
3193: public short localVariableArrayIndex = -1; // Used during compilation
3194:
3195: public LocalVariable(boolean finaL, IClass type) {
3196: this .finaL = finaL;
3197: this .type = type;
3198: }
3199: }
3200:
3201: public static String join(Object[] a, String separator) {
3202: return Java.join(a, separator, 0, a.length);
3203: }
3204:
3205: public static String join(Object[] a, String separator, int off,
3206: int len) {
3207: if (a == null)
3208: return ("(null)");
3209: if (off >= len)
3210: return "";
3211: StringBuffer sb = new StringBuffer(a[off].toString());
3212: for (++off; off < len; ++off) {
3213: sb.append(separator);
3214: sb.append(a[off]);
3215: }
3216: return sb.toString();
3217: }
3218: }
|