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