001 // -*- mode: java -*-
002 /* Copyright 2000, 2001, Compaq Computer Corporation */
003
004 /* IF THIS IS A JAVA FILE, DO NOT EDIT IT!
005
006 Most Java files in this directory which are part of the Javafe AST
007 are automatically generated using the astgen comment (see
008 ESCTools/Javafe/astgen) from the input file 'hierarchy.h'. If you
009 wish to modify AST classes or introduce new ones, modify
010 'hierarchy.j.'
011 */
012
013 package javafe.ast;
014
015 import javafe.util.Assert;
016 import javafe.util.Location;
017 import javafe.util.ErrorSet;
018
019 // Convention: unless otherwise noted, integer fields named "loc" refer
020 // to the location of the first character of the syntactic unit
021
022
023 public class NewInstanceExpr extends Expr
024 {
025 /**
026 * The enclosing instance is the object expression before a new
027 * call ( <enclosingInstance>.new T(...) ). This field may be null
028 * if there is no such expression.
029 *
030 * @note If the type in question is an inner class, then the
031 * type checker will infer a [<C>.]this expression if no expression
032 * is present and place it in this slot. (See ThisExpr for how to
033 * distinguish inferred this expressions.)<p>
034 */
035 public Expr enclosingInstance;
036
037
038 //@ invariant (enclosingInstance == null) == (locDot==Location.NULL);
039 public int locDot;
040
041
042 public /*@ non_null @*/ TypeName type;
043
044 public /*@ non_null @*/ ExprVec args;
045
046
047 /**
048 * If the new expression includes a declaration of an inner class,
049 * then "anonDecl" will be non-null. In this case, the
050 * "superclass" field of "ananDecl" will be null and
051 * "superinterfaces" list of "anonDecl" will be empty. One of
052 * these fields needs to be modified during type checking depending
053 * on whether "type" is a class or an interface.
054 */
055 public ClassDecl anonDecl;
056
057
058 //@ invariant loc != javafe.util.Location.NULL;
059 public int loc;
060
061 //@ invariant locOpenParen != javafe.util.Location.NULL;
062 public int locOpenParen;
063
064
065 public ConstructorDecl decl;
066
067 /*@ public represents startLoc <-
068 @ (enclosingInstance == null) ? loc : enclosingInstance.getStartLoc();
069 @*/
070 public /*@ pure @*/ int getStartLoc() {
071 if (enclosingInstance == null) return loc;
072 else return enclosingInstance.getStartLoc();
073 }
074
075 public /*@ pure @*/ int getEndLoc() {
076 if (decl == null) {
077 if (args.size()==0) return type.getEndLoc();
078 return args.elementAt(args.size()-1).getEndLoc();
079 } else return decl.getEndLoc();
080 }
081
082 //@ requires (enclosingInstance == null) == (locDot==Location.NULL);
083 //
084 //@ requires loc != javafe.util.Location.NULL;
085 //@ requires locOpenParen != javafe.util.Location.NULL;
086 public static /*@non_null*/ NewInstanceExpr make(Expr enclosingInstance,
087 int locDot,
088 /*@ non_null @*/ TypeName type,
089 /*@ non_null @*/ ExprVec args,
090 ClassDecl anonDecl,
091 int loc,
092 int locOpenParen) {
093 NewInstanceExpr result = new NewInstanceExpr(
094 enclosingInstance,
095 locDot,
096 type,
097 args,
098 anonDecl,
099 loc,
100 locOpenParen);
101 return result;
102 }
103
104
105 // Generated boilerplate constructors:
106
107 //@ ensures this.enclosingInstance == enclosingInstance;
108 //@ ensures this.locDot == locDot;
109 //@ ensures this.type == type;
110 //@ ensures this.args == args;
111 //@ ensures this.anonDecl == anonDecl;
112 //@ ensures this.loc == loc;
113 //@ ensures this.locOpenParen == locOpenParen;
114 protected NewInstanceExpr(Expr enclosingInstance, int locDot, /*@ non_null @*/ TypeName type, /*@ non_null @*/ ExprVec args, ClassDecl anonDecl, int loc, int locOpenParen) {
115 super();
116 this.enclosingInstance = enclosingInstance;
117 this.locDot = locDot;
118 this.type = type;
119 this.args = args;
120 this.anonDecl = anonDecl;
121 this.loc = loc;
122 this.locOpenParen = locOpenParen;
123 }
124
125 // Generated boilerplate methods:
126
127 public final int childCount() {
128 int sz = 0;
129 if (this.args != null) sz += this.args.size();
130 return sz + 3;
131 }
132
133 public final Object childAt(int index) {
134 /*throws IndexOutOfBoundsException*/
135 if (index < 0)
136 throw new IndexOutOfBoundsException("AST child index " + index);
137 int indexPre = index;
138
139 int sz;
140
141 if (index == 0) return this.enclosingInstance;
142 else index--;
143
144 if (index == 0) return this.type;
145 else index--;
146
147 sz = (this.args == null ? 0 : this.args.size());
148 if (0 <= index && index < sz)
149 return this.args.elementAt(index);
150 else index -= sz;
151
152 if (index == 0) return this.anonDecl;
153 else index--;
154
155 throw new IndexOutOfBoundsException("AST child index " + indexPre);
156 } //@ nowarn Exception;
157
158 public final /*@non_null*/String toString() {
159 return "[NewInstanceExpr"
160 + " enclosingInstance = " + this.enclosingInstance
161 + " locDot = " + this.locDot
162 + " type = " + this.type
163 + " args = " + this.args
164 + " anonDecl = " + this.anonDecl
165 + " loc = " + this.loc
166 + " locOpenParen = " + this.locOpenParen
167 + "]";
168 }
169
170 public final int getTag() {
171 return TagConstants.NEWINSTANCEEXPR;
172 }
173
174 public final void accept(Visitor v) { v.visitNewInstanceExpr(this); }
175
176 public final Object accept(VisitorArgResult v, Object o) {return v.visitNewInstanceExpr(this, o); }
177
178 public void check() {
179 super.check();
180 if (this.enclosingInstance != null)
181 this.enclosingInstance.check();
182 this.type.check();
183 for(int i = 0; i < this.args.size(); i++)
184 this.args.elementAt(i).check();
185 if (this.anonDecl != null)
186 this.anonDecl.check();
187 }
188
189 }