blob: 5102ee619f4dcf64d8fcc93cdb0760e36c0de1e2 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1994-2004 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package sun.tools.javac;
27
28import sun.tools.java.*;
29import sun.tools.tree.*;
30
31import java.io.IOException;
32import java.io.InputStream;
33import java.util.Vector;
34import java.util.Enumeration;
35
36/**
37 * Batch file parser, this needs more work.
38 *
39 * WARNING: The contents of this source file are not part of any
40 * supported API. Code that depends on them does so at its own risk:
41 * they are subject to change or removal without notice.
42 */
43@Deprecated
44public
45class BatchParser extends Parser {
46 /**
47 * The current package
48 */
49 protected Identifier pkg;
50
51 /**
52 * The current imports
53 */
54 protected Imports imports;
55
56 /**
57 * The classes defined in this file
58 */
59 protected Vector classes;
60
61
62 /**
63 * The current class
64 */
65 protected SourceClass sourceClass;
66
67 /**
68 * The toplevel environment
69 */
70 protected Environment toplevelEnv;
71
72 /**
73 * Create a batch file parser
74 */
75 public BatchParser(Environment env, InputStream in) throws IOException {
76 super(env, in);
77
78 imports = new Imports(env);
79 classes = new Vector();
80 toplevelEnv = imports.newEnvironment(env);
81 }
82
83 /**
84 * Package declaration
85 */
86 public void packageDeclaration(long where, IdentifierToken t) {
87 Identifier nm = t.getName();
88 //System.out.println("package " + nm);
89 if (pkg == null) {
90 // This code has been changed to pass an IdentifierToken,
91 // rather than an Identifier, to setCurrentPackage(). Imports
92 // now needs the location of the token.
93 pkg = t.getName();
94 imports.setCurrentPackage(t);
95 } else {
96 env.error(where, "package.repeated");
97 }
98 }
99
100 /**
101 * Import class
102 */
103 public void importClass(long pos, IdentifierToken t) {
104 //System.out.println("import class " + t);
105 imports.addClass(t);
106 }
107
108 /**
109 * Import package
110 */
111 public void importPackage(long pos, IdentifierToken t) {
112 //System.out.println("import package " + t);
113 imports.addPackage(t);
114 }
115
116 /**
117 * Define class
118 */
119 public ClassDefinition beginClass(long where, String doc, int mod,
120 IdentifierToken t,
121 IdentifierToken sup,
122 IdentifierToken interfaces[]) {
123
124 // If this class is nested, the modifier bits set here will
125 // be copied into the 'SourceMember' object for the inner class
126 // created during the call to 'makeClassDefinition' below.
127 // When writing the class file, we will look there for the
128 // 'untransformed' modifiers. The modifiers in the ClassDefinition
129 // object will end up as the 'transformed' modifiers. Note that
130 // there are some bits set here that are not legal class modifiers
131 // according to the JVMS, e.g., M_PRIVATE and M_STATIC. These are
132 // masked off while writing the class file, but are preserved in
133 // the InnerClasses attributes.
134
135 if (tracing) toplevelEnv.dtEnter("beginClass: " + sourceClass);
136
137 SourceClass outerClass = sourceClass;
138
139 if (outerClass == null && pkg != null) {
140 t = new IdentifierToken(t.getWhere(),
141 Identifier.lookup(pkg, t.getName()));
142 }
143
144 // The defaults for anonymous and local classes should be documented!
145
146 if ((mod & M_ANONYMOUS) != 0) {
147 mod |= (M_FINAL | M_PRIVATE);
148 }
149 if ((mod & M_LOCAL) != 0) {
150 mod |= M_PRIVATE;
151 }
152
153 // Certain modifiers are implied as follows:
154 //
155 // 1. Any interface (nested or not) is implicitly deemed to be abstract,
156 // whether it is explicitly marked so or not. (Java 1.0.)
157 // 2. A interface which is a member of a type is implicitly deemed to
158 // be static, whether it is explicitly marked so or not. (InnerClasses)
159 // 3a. A type which is a member of an interface is implicitly deemed
160 // to be public, whether it is explicitly marked so or not. (InnerClasses)
161 // 3b. A type which is a member of an interface is implicitly deemed
162 // to be static, whether it is explicitly marked so or not. (InnerClasses)
163
164 if ((mod & M_INTERFACE) != 0) {
165 // Rule 1.
166 mod |= M_ABSTRACT;
167 if (outerClass != null) {
168 // Rule 2.
169 mod |= M_STATIC;
170 }
171 }
172
173 if (outerClass != null && outerClass.isInterface()) {
174 // Rule 3a.
175 // For interface members, neither 'private' nor 'protected'
176 // are legal modifiers. We avoid setting M_PUBLIC in some
177 // cases in order to avoid interfering with error detection
178 // and reporting. This is patched up, after reporting an
179 // error, by 'SourceClass.addMember'.
180 if ((mod & (M_PRIVATE | M_PROTECTED)) == 0)
181 mod |= M_PUBLIC;
182 // Rule 3b.
183 mod |= M_STATIC;
184 }
185
186 // For nested classes, we must transform 'protected' to 'public'
187 // and 'private' to package scope. This must be done later,
188 // because any modifiers set here will be copied into the
189 // 'MemberDefinition' for the nested class, which must represent
190 // the original untransformed modifiers. Also, compile-time
191 // checks should be performed against the actual, untransformed
192 // modifiers. This is in contrast to transformations that implement
193 // implicit modifiers, such as M_STATIC and M_FINAL for fields
194 // of interfaces.
195
196 sourceClass = (SourceClass)
197 toplevelEnv.makeClassDefinition(toplevelEnv, where, t,
198 doc, mod, sup,
199 interfaces, outerClass);
200
201 sourceClass.getClassDeclaration().setDefinition(sourceClass, CS_PARSED);
202 env = new Environment(toplevelEnv, sourceClass);
203
204 if (tracing) toplevelEnv.dtEvent("beginClass: SETTING UP DEPENDENCIES");
205
206 // The code which adds artificial dependencies between
207 // classes in the same source file has been moved to
208 // BatchEnvironment#parseFile().
209
210 if (tracing) toplevelEnv.dtEvent("beginClass: ADDING TO CLASS LIST");
211
212 classes.addElement(sourceClass);
213
214 if (tracing) toplevelEnv.dtExit("beginClass: " + sourceClass);
215
216 return sourceClass;
217 }
218
219 /**
220 * Report the current class under construction.
221 */
222 public ClassDefinition getCurrentClass() {
223 return sourceClass;
224 }
225
226 /**
227 * End class
228 */
229 public void endClass(long where, ClassDefinition c) {
230
231 if (tracing) toplevelEnv.dtEnter("endClass: " + sourceClass);
232
233 // c == sourceClass; don't bother to check
234 sourceClass.setEndPosition(where);
235 SourceClass outerClass = (SourceClass) sourceClass.getOuterClass();
236 sourceClass = outerClass;
237 env = toplevelEnv;
238 if (sourceClass != null)
239 env = new Environment(env, sourceClass);
240
241 if (tracing) toplevelEnv.dtExit("endClass: " + sourceClass);
242 }
243
244 /**
245 * Define a method
246 */
247 public void defineField(long where, ClassDefinition c,
248 String doc, int mod, Type t,
249 IdentifierToken name, IdentifierToken args[],
250 IdentifierToken exp[], Node val) {
251 // c == sourceClass; don't bother to check
252 Identifier nm = name.getName();
253 // Members that are nested classes are not created with 'defineField',
254 // so these transformations do not apply to them. See 'beginClass' above.
255 if (sourceClass.isInterface()) {
256 // Members of interfaces are implicitly public.
257 if ((mod & (M_PRIVATE | M_PROTECTED)) == 0)
258 // For interface members, neither 'private' nor 'protected'
259 // are legal modifiers. Avoid setting M_PUBLIC in some cases
260 // to avoid interfering with later error detection. This will
261 // be fixed up after the error is reported.
262 mod |= M_PUBLIC;
263 // Methods of interfaces are implicitly abstract.
264 // Fields of interfaces are implicitly static and final.
265 if (t.isType(TC_METHOD)) {
266 mod |= M_ABSTRACT;
267 } else {
268 mod |= M_STATIC | M_FINAL;
269 }
270 }
271 if (nm.equals(idInit)) {
272 // The parser reports "idInit" when in reality it has found
273 // that there is no method name at all present.
274 // So, decide if it's really a constructor, or a syntax error.
275 Type rt = t.getReturnType();
276 Identifier retname = !rt.isType(TC_CLASS) ? idStar /*no match*/
277 : rt.getClassName();
278 Identifier clsname = sourceClass.getLocalName();
279 if (clsname.equals(retname)) {
280 t = Type.tMethod(Type.tVoid, t.getArgumentTypes());
281 } else if (clsname.equals(retname.getFlatName().getName())) {
282 // It appears to be a constructor with spurious qualification.
283 t = Type.tMethod(Type.tVoid, t.getArgumentTypes());
284 env.error(where, "invalid.method.decl.qual");
285 } else if (retname.isQualified() || retname.equals(idStar)) {
286 // It appears to be a type name with no method name.
287 env.error(where, "invalid.method.decl.name");
288 return;
289 } else {
290 // We assume the type name is missing, even though the
291 // simple name that's present might have been intended
292 // to be a type: "String (){}" vs. "toString(){}".
293 env.error(where, "invalid.method.decl");
294 return;
295 }
296 }
297
298 if (args == null && t.isType(TC_METHOD)) {
299 args = new IdentifierToken[0];
300 }
301
302 if (exp == null && t.isType(TC_METHOD)) {
303 exp = new IdentifierToken[0];
304 }
305
306 MemberDefinition f = env.makeMemberDefinition(env, where, sourceClass,
307 doc, mod, t, nm,
308 args, exp, val);
309 if (env.dump()) {
310 f.print(System.out);
311 }
312 }
313}