Showing the changes to java/pkg/sun/tools/javac/BatchParser.java (1 of 18352 files). Show all
Unified · Split
| @@ -0,0 +1,313 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1994, 2004, Oracle and/or its affiliates. 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. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package sun.tools.javac; | ||
| 27 | |||
| 28 | import sun.tools.java.*; | ||
| 29 | import sun.tools.tree.*; | ||
| 30 | |||
| 31 | import java.io.IOException; | ||
| 32 | import java.io.InputStream; | ||
| 33 | import java.util.Vector; | ||
| 34 | import 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 | ||
| 44 | public | ||
| 45 | class 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 | } | ||