2362N/A * Copyright (c) 1994, 2004, Oracle and/or its affiliates. All rights reserved. 0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 0N/A * This code is free software; you can redistribute it and/or modify it 0N/A * under the terms of the GNU General Public License version 2 only, as 2362N/A * published by the Free Software Foundation. Oracle designates this 0N/A * particular file as subject to the "Classpath" exception as provided 2362N/A * by Oracle in the LICENSE file that accompanied this code. 0N/A * This code is distributed in the hope that it will be useful, but WITHOUT 0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 0N/A * version 2 for more details (a copy is included in the LICENSE file that 0N/A * accompanied this code). 0N/A * You should have received a copy of the GNU General Public License version 0N/A * 2 along with this work; if not, write to the Free Software Foundation, 0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2362N/A * or visit www.oracle.com if you need additional information or have any 0N/A * This class represents an Java class as it is read from 0N/A * an Java source file. 0N/A * WARNING: The contents of this source file are not part of any 0N/A * supported API. Code that depends on them does so at its own risk: 0N/A * they are subject to change or removal without notice. 0N/A * The toplevel environment, shared with the parser 0N/A * The default constructor 0N/A * The list of class dependencies 0N/A * The field used to represent "this" in all of my code. 0N/A * Last token of class, as reported by parser. 0N/A * Access methods for constructors are distinguished from 0N/A * the constructors themselves by a dummy first argument. 0N/A * A unique type used for this purpose and shared by all 0N/A * constructor access methods within a package-member class is 0N/A * This field is null except in an outermost class containing 0N/A * one or more classes needing such an access method. 0N/A // Check for a package level class which is declared static. 0N/A // Inner classes cannot be static, nor can they be interfaces 0N/A // (which are implicitly static). Static classes and interfaces 0N/A // can only occur as top-level entities. 0N/A // Note that we do not have to check for local classes declared 0N/A // to be static (this is currently caught by the parser) but 0N/A // we check anyway in case the parser is modified to allow this. 0N/A if ((isPublic() || isProtected()) && isInsideLocal()) { 0N/A env.error(where, "warn.public.local.class", this); 0N/A // maybe define an uplevel "A.this" current instance field 0N/A // Set simple, unmangled local name for a local or anonymous class. 0N/A // NOTE: It would be OK to do this unconditionally, as null is the 0N/A // correct value for a member (non-local) class. 0N/A // Check for inner class with same simple name as one of 0N/A // its enclosing classes. Note that 'getLocalName' returns 0N/A // the simple, unmangled source-level name of any class. 0N/A // The previous version of this code was not careful to avoid 0N/A // mangled local class names. This version fixes 4047746. 0N/A // Test above suppresses error for nested anonymous classes, 0N/A // which have an internal "name", but are not named in source code. 0N/A * Return last position in this class. 0N/A * Return absolute name of source file 0N/A * Find or create my "this" argument, which is used for all methods. 0N/A // If doing -xdepend option, save away list of class dependencies 0N/A // making sure to NOT include duplicates or the class we are in 0N/A // (Hashtable's put() makes sure we don't have duplicates) 0N/A * Add a field (check it first) 0N/A // Make sure the access permissions are self-consistent: 0N/A // Cut out the more restrictive modifier(s): 0N/A // Note exemption for synthetic members below. 0N/A // Even if a static passes this test, there is still another 0N/A // check in 'SourceMember.check'. The check is delayed so 0N/A // that the initializer may be inspected more closely, using 0N/A // 'isConstant()'. Part of fix for 4095568. 0N/A // Static inner classes are diagnosed in 'SourceClass.<init>'. 0N/A // f is not allowed to return an array of void 0N/A // arguments can be null if this is an implicit abstract method 0N/A // (arg should be an Identifier now) 0N/A // same check as for fields, below: 0N/A // Fix up the class itself to agree with 0N/A // the inner-class member. 0N/A // REMIND: set type to error 0N/A // Do not check for repeated methods here: Types are not yet resolved. 0N/A // Found a duplicate inner-class member. 0N/A // Duplicate local classes are detected in 0N/A // 'VarDeclarationStatement.checkDeclaration'. 0N/A * Create an environment suitable for checking this class. 0N/A * Make sure the source and imports are set right. 0N/A * Make sure the environment contains no context information. 0N/A * (Actually, throw away env altogether and use toplevelEnv instead.) 0N/A // In some cases, we go to some trouble to create the 'env' argument 0N/A // that is discarded. We should remove the 'env' argument entirely 0N/A // as well as the vestigial code that supports it. See comments on 0N/A // 'newEnvironment' in 'checkInternal' below. 0N/A * A source class never reports deprecation, since the compiler 0N/A * allows access to deprecated features that are being compiled 0N/A * See if the source file of this class is right. 0N/A * @see ClassDefinition#noteUsedBy 0N/A // If this class is not public, watch for cross-file references. 0N/A return;
// already checked 0N/A return;
// intra-file reference 0N/A * Check this class and all its fields. 0N/A // An inaccessible class gets checked when the surrounding 0N/A // block is checked. 0N/A // QUERY: Should this case ever occur? 0N/A // What would invoke checking of a local class aside from 0N/A // checking the surrounding method body? 0N/A // Make sure the outer is checked first. 0N/A // Check this class now, if it has not yet been checked. 0N/A // Cf. Main.compile(). Perhaps this code belongs there somehow. 0N/A // Set it first to avoid vicious circularity: 0N/A // Save context enclosing class for later access 0N/A // by 'ClassDefinition.resolveName.' 0N/A // At present, the call to 'newEnvironment' is not needed. 0N/A // The incoming environment to 'basicCheck' is always passed to 0N/A // 'setupEnv', which discards it completely. This is also the 0N/A // only call to 'newEnvironment', which is now apparently dead code. 0N/A // Validate access for all inner-class components 0N/A // of a qualified name, not just the last one, which 0N/A // is checked below. Yes, this is a dirty hack... 0N/A // Much of this code was cribbed from 'checkSupers'. 0N/A // Part of fix for 4094658. 0N/A // Error localization fails here if interfaces were 0N/A // elided during error recovery from an invalid one. 0N/A // Does the name already exist in an imported package? 0N/A // See JLS 8.1 for the precise rules. 0N/A // Discard package qualification for the import checks. 0N/A // We want this to throw a ClassNotFound exception 0N/A // At least one of e.name1 and e.name2 must be different 0N/A // we want this to happen 0N/A // Make sure that no package with the same fully qualified 0N/A // name exists. This is required by JLS 7.1. We only need 0N/A // to perform this check for top level classes -- it isn't 0N/A // necessary for inner classes. (bug 4101529) 0N/A // This change has been backed out because, on WIN32, it 0N/A // failed to distinguish between java.awt.event and 0N/A // java.awt.Event when looking for a directory. We will 0N/A // add this back in later. 0N/A // if (env.getPackage(nm).exists()) { 0N/A // } catch (java.io.IOException ee) { 0N/A // env.error(where, "io.exception.package", nm); 0N/A // Make sure it was defined in the right file 0N/A * See if the source file of this class is of the right name. 0N/A // one error per offending class is sufficient 0N/A // Set true if superclass (but not necessarily superinterfaces) have 0N/A // been checked. If the superclass is still unresolved, then an error 0N/A // message should have been issued, and we assume that no further 0N/A // resolution is possible. 0N/A * Overrides 'ClassDefinition.getSuperClass'. 0N/A // Superclass may fail to be set because of error recovery, 0N/A // so resolve types here only if 'checkSupers' has not yet 0N/A // completed its checks on the superclass. 0N/A // QUERY: Can we eliminate the need to resolve superclasses on demand? 0N/A // See comments in 'checkSupers' and in 'ClassDefinition.getInnerClass'. 0N/A // We used to report an error here if the superclass was not 0N/A // resolved. Having moved the call to 'checkSupers' from 'basicCheck' 0N/A // into 'resolveTypeStructure', the errors reported here should have 0N/A // already been reported. Furthermore, error recovery can null out 0N/A // the superclass, which would cause a spurious error from the test here. 0N/A * Check that all superclasses and superinterfaces are defined and 0N/A * well formed. Among other checks, verify that the inheritance 0N/A * graph is acyclic. Called from 'resolveTypeStructure'. 0N/A // Interfaces have no superclass. Superinterfaces 0N/A // are checked below, in code shared with the class case. 0N/A // Check superclass. 0N/A // Call to 'getSuperClass(env)' (note argument) attempts 0N/A // 'resolveTypeStructure' if superclass has not successfully 0N/A // been resolved. Since we have just now called 'resolveSupers' 0N/A // (see our call in 'resolveTypeStructure'), it is not clear 0N/A // that this can do any good. Why not 'getSuperClass()' here? 0N/A // Resolve superclass and its ancestors. 0N/A // Access to the superclass should be checked relative 0N/A // to the surrounding context, not as if the reference 0N/A // appeared within the class body. Changed 'canAccess' 0N/A // to 'extendsCanAccess' to fix 4087314. 0N/A // Might it be a better recovery to let the access go through? 0N/A // Might it be a better recovery to let the access go through? 0N/A // If we have a valid superclass, check its 0N/A // supers as well, and so on up to root class. 0N/A // Call to 'enclosingClassOf' will raise 0N/A // 'NullPointerException' if 'def' is null, 0N/A // so omit this check as error recovery. 0N/A // Do we need a similar test for 0N/A // interfaces? See bugid 4038529. 0N/A // Since we resolved the superclass and its 0N/A // ancestors above, we should not discover 0N/A // any unresolved classes on the superclass 0N/A // chain. It should thus be sufficient to 0N/A // call 'getSuperClass()' (no argument) here. 0N/A // Superclass not resolved due to error. 0N/A // Error is detected in call to 'getClassDefinition'. 0N/A // The class may actually exist but be ambiguous. 0N/A // Call env.resolve(e.name) to see if it is. 0N/A // env.resolve(name) will definitely tell us if the 0N/A // class is ambiguous, but may not necessarily tell 0N/A // us if the class is not found. 0N/A // (part of solution for 4059855) 0N/A }
// The break exits this block 0N/A // Superclass was null on entry, after call to 0N/A // 'resolveSupers'. This should normally not happen, 0N/A // as 'resolveSupers' sets 'superClass' to a non-null 0N/A // value for all named classes, except for one special 0N/A // case: 'java.lang.Object', which has no superclass. 0N/A // checker should have filled it in first 0N/A // At this point, if 'superClass' is null due to an error 0N/A // in the user program, a message should have been issued. 0N/A // Resolve superinterface and its ancestors. 0N/A // Check superinterface access in the correct context. 0N/A // Changed 'canAccess' to 'extendsCanAccess' to fix 4087314. 0N/A // Interface is OK, leave it in the interface list. 0N/A // The interface may actually exist but be ambiguous. 0N/A // Call env.resolve(e.name) to see if it is. 0N/A // env.resolve(name) will definitely tell us if the 0N/A // interface is ambiguous, but may not necessarily tell 0N/A // us if the interface is not found. 0N/A // (part of solution for 4059855) 0N/A }
// The break exits this block 0N/A // Remove this interface from the list of interfaces 0N/A // as recovery from an error. 0N/A * Check all of the members of this class. 0N/A * Inner classes are checked in the following way. Any class which 0N/A * is immediately contained in a block (anonymous and local classes) 0N/A * is checked along with its containing method; see the 0N/A * SourceMember.check() method for more information. Member classes 0N/A * of this class are checked immediately after this class, unless this 0N/A * class is insideLocal(), in which case, they are checked with the 0N/A * rest of the members. 0N/A // bail out if there were any errors 0N/A // Make sure that all of our member classes have been 0N/A // basicCheck'ed before we check the rest of our members. 0N/A // If our member classes haven't been basicCheck'ed, then they 0N/A // may not have <init> methods. It is important that they 0N/A // have <init> methods so we can process NewInstanceExpressions 0N/A // correctly. This problem didn't occur before 1.2beta1. 0N/A // This is a fix for bug 4082816. 0N/A // System.out.println("Considering " + f + " in " + this); 0N/A // This class should be abstract if there are any abstract methods 0N/A // in our parent classes and interfaces which we do not override. 0N/A // There are odd cases when, even though we cannot access some 0N/A // abstract method from our superclass, that abstract method can 0N/A // still force this class to be abstract. See the discussion in 0N/A // Set the class abstract. 0N/A // Tell the user which methods force this class to be abstract. 0N/A // First list all of the "unimplementable" abstract methods. 0N/A // We couldn't override this method even if we 0N/A // wanted to. Try to make the error message 0N/A // as non-confusing as possible. 0N/A // Now list all of the traditional abstract methods. 0N/A // For each method, check if it is abstract. If it is, 0N/A // output an appropriate error message. 0N/A // Check the instance variables in a pre-pass before any constructors. 0N/A // This lets constructors "in-line" any initializers directly. 0N/A // It also lets us do some definite assignment checks on variables. 0N/A // Do definite assignment checking on blank finals. 0N/A // Other variables do not need such checks. The simple textual 0N/A // ordering constraints implemented by MemberDefinition.canReach() 0N/A // are necessary and sufficient for the other variables. 0N/A // Note that within non-static code, all statics are always 0N/A // definitely assigned, and vice-versa. 0N/A // The following allocates a LocalMember object as a proxy 0N/A // to represent the field. 0N/A // For instance variable checks, use a context with a "this" parameter. 0N/A // Do all the initializers in order, checking the definite 0N/A // assignment of blank finals. Separate static from non-static. 0N/A // Check the rest of the field definitions. 0N/A // (Note: Re-checking a field is a no-op.) 0N/A // When checking a constructor, an explicit call to 0N/A // 'this(...)' makes all blank finals definitely assigned. 0N/A // See 'MethodExpression.checkValue'. 0N/A // May issue multiple messages for the same variable!! 0N/A // (drop vsCon here) 0N/A // (drop vsFld here) 0N/A // Must mark class as checked before visiting inner classes, 0N/A // as they may in turn request checking of the current class 0N/A // as an outer class. Fix for bug id 4056774. 0N/A // Also check other classes in the same nest. 0N/A // All checking of this nest must be finished before any 0N/A // of its classes emit bytecode. 0N/A // Otherwise, the inner classes might not have a chance to 0N/A // add access or class literal fields to the outer class. 0N/A // Note: Since inner classes cannot set up-level variables, 0N/A // the returned vset is always equal to the passed-in vset. 0N/A // Still, we'll return it for the sake of regularity. 0N/A /** Make sure all my blank finals exist now. */ 0N/A * Check this class has its superclass and its interfaces. Also 0N/A * force it to have an <init> method (if it doesn't already have one) 0N/A * and to have all the abstract methods of its parents. 0N/A // Check the existence of the superclass and all interfaces. 0N/A // Also responsible for breaking inheritance cycles. This call 0N/A // has been moved to 'resolveTypeStructure', just after the call 0N/A // to 'resolveSupers', as inheritance cycles must be broken before 0N/A // resolving types within the members. Fixes 4073739. 0N/A // checkSupers(env); 0N/A // Add implicit <init> method, if necessary. 0N/A // QUERY: What keeps us from adding an implicit constructor 0N/A // when the user explicitly declares one? Is it truly guaranteed 0N/A // that the declaration for such an explicit constructor will have 0N/A // been processed by the time we arrive here? In general, 'basicCheck' 0N/A // is called very early, prior to the normal member checking phase. 0N/A // Default constructors inherit the access modifiers of their 0N/A // class. For non-inner classes, this follows from JLS 8.6.7, 0N/A // as the only possible modifier is 'public'. For the sake of 0N/A // robustness in the presence of errors, we ignore any other 0N/A // modifiers. For inner classes, the rule needs to be extended 0N/A // in some way to account for the possibility of private and 0N/A // protected classes. We make the 'obvious' extension, however, 0N/A // the inner classes spec is silent on this issue, and a definitive 0N/A // resolution is needed. See bugid 4087421. 0N/A // WORKAROUND: A private constructor might need an access method, 0N/A // but it is not possible to create one due to a restriction in 0N/A // the verifier. (This is a known problem -- see 4015397.) 0N/A // We therefore do not inherit the 'private' modifier from the class, 0N/A // allowing the default constructor to be package private. This 0N/A // workaround can be observed via reflection, but is otherwise 0N/A // undetectable, as the constructor is always accessible within 0N/A // the class in which its containing (private) class appears. 0N/A // The idea here is that they will be done in javac, but not 0N/A // in javadoc. See the comment for turnOffChecks(), above. 0N/A // Verify the compatibility of all inherited method definitions 0N/A // by collecting all of our inheritable methods. 0N/A * Add a group of methods to this class as miranda methods. 0N/A * For a definition of Miranda methods, see the comment above the 0N/A * method addMirandaMethods() in the file 0N/A //System.out.println("adding miranda method " + newMethod + 0N/A * <em>After parsing is complete</em>, resolve all names 0N/A * except those inside method bodies or initializers. 0N/A * In particular, this is the point at which we find out what 0N/A * kinds of variables and methods there are in the classes, 0N/A * and therefore what is each class's interface to the world. 0N/A * Also perform certain other transformations, such as inserting 0N/A * "this$C" arguments into constructors, and reorganizing structure 0N/A * to flatten qualified member names. 0N/A * Do not perform type-based or name-based consistency checks 0N/A * or normalizations (such as default nullary constructors), 0N/A * and do not attempt to compile code against this class, 0N/A * until after this phase. 0N/A // Resolve immediately enclosing type, which in turn 0N/A // forces resolution of all enclosing type declarations. 0N/A // Do the outer class first, always. 0N/A // (Note: this.resolved is probably true at this point.) 0N/A // Punt if we've already resolved this class, or are currently 0N/A // in the process of doing so. 0N/A // Previously, 'resolved' was set here, and served to prevent 0N/A // duplicate resolutions here as well as its function in 0N/A // 'ClassDefinition.addMember'. Now, 'resolving' serves the 0N/A // former purpose, distinct from that of 'resolved'. 0N/A // Resolve superclass names to class declarations 0N/A // for the immediate superclass and superinterfaces. 0N/A // Check all ancestor superclasses for various 0N/A // errors, verifying definition of all superclasses 0N/A // and superinterfaces. Also breaks inheritance cycles. 0N/A // Calls 'resolveTypeStructure' recursively for ancestors 0N/A // This call used to appear in 'basicCheck', but was not 0N/A // performed early enough. Most of the compiler will barf 0N/A // on inheritance cycles! 0N/A // Undefined classes should be reported by 'checkSupers'. 0N/A // Mark class as resolved. If new members are subsequently 0N/A // added to the class, they will be resolved at that time. 0N/A // See 'ClassDefinition.addMember'. Previously, this variable was 0N/A // set prior to the calls to 'checkSupers' and 'resolveTypeStructure' 0N/A // (which may engender further calls to 'checkSupers'). This could 0N/A // lead to duplicate resolution of implicit constructors, as the call to 0N/A // 'basicCheck' from 'checkSupers' could add the constructor while 0N/A // its class is marked resolved, and thus would resolve the constructor, 0N/A // believing it to be a "late addition". It would then be resolved 0N/A // redundantly during the normal traversal of the members, which 0N/A // immediately follows in the code above. 0N/A // Now we have enough information to detect method repeats. 0N/A // Find the super class 0N/A // Special-case java.lang.Object here (not in the parser). 0N/A // In all other cases, if we have a valid 'superClassId', 0N/A // we return with a valid and non-null 'superClass' value. 0N/A for (
int j =
0; j < i; j++) {
0N/A // Result is never null, as a new 'ClassDeclaration' is 0N/A // created if one with the given name does not exist. 0N/A * During the type-checking of an outer method body or initializer, 0N/A * this routine is called to check a local class body 0N/A * in the proper context. 0N/A * @param sup the named super class or interface (if anonymous) 0N/A * @param args the actual arguments (if anonymous) 0N/A // Run the checks in the lexical context from the outer class. 0N/A // This is now done by 'checkInternal' via its call to 'checkMembers'. 0N/A // getClassDeclaration().setDefinition(this, CS_CHECKED); 0N/A * As with checkLocalClass, run the inline phase for a local class. 0N/A continue;
// inlined inside of constructors only 0N/A // add more constructor arguments for uplevel references 0N/A //((SourceMember)f).addUplevelArguments(false); 0N/A * Check a class which is inside a local class, but is not itself local. 0N/A * Just before checking an anonymous class, decide its true 0N/A * inheritance, and build its (sole, implicit) constructor. 0N/A // Decide now on the superclass. 0N/A // This check has been removed as part of the fix for 4055017. 0N/A // In the anonymous class created to hold the 'class$' method 0N/A // of an interface, 'superClassId' refers to 'java.lang.Object'. 0N/A /*---------------------* 0N/A if (!(superClass == null && superClassId.getName() == idNull)) { 0N/A throw new CompilerError("superclass "+superClass); 0N/A *---------------------*/ 0N/A // allow an interface in the "super class" position 0N/A // Synthesize an appropriate constructor. 0N/A * Convert class modifiers to a string for diagnostic purposes. 0N/A * Accepts modifiers applicable to inner classes and that appear 0N/A * in the InnerClasses attribute only, as well as those that may 0N/A * appear in the class modifier proper. 0N/A {
"PUBLIC",
"PRIVATE",
"PROTECTED",
"STATIC",
"FINAL",
0N/A "INTERFACE",
"ABSTRACT",
"SUPER",
"ANONYMOUS",
"LOCAL",
0N/A "STRICTFP",
"STRICT"};
0N/A * Find or create an access method for a private member, 0N/A * or return null if this is not possible. 0N/A // The 'isSuper' argument is really only meaningful when the 0N/A // target member is a method, in which case an 'invokespecial' 0N/A // is needed. For fields, 'getfield' and 'putfield' instructions 0N/A // are generated in either case, and 'isSuper' currently plays 0N/A // no essential role. Nonetheless, we maintain the distinction 0N/A // consistently for the time being. 0N/A // Find pre-existing access method. 0N/A // In the case of a field access method, we only look for the getter. 0N/A // A getter is always created whenever a setter is. 0N/A // QUERY: Why doesn't the 'MemberDefinition' object for the field 0N/A // itself just have fields for its getter and setter? 0N/A // Distinguish the getter and the setter by the number of 0N/A // This was (nargs == (isStatic ? 0 : 1) + (isUpdate ? 1 : 0)) 0N/A // in order to find a setter as well as a getter. This caused 0N/A // allocation of multiple getters. 0N/A // must find or create the getter before creating the setter 0N/A // If we arrive here, we are creating a new access member. 0N/A // For a constructor, we use the same name as for all 0N/A // constructors ("<init>"), but add a distinguishing 0N/A // argument of an otherwise unused "dummy" type. 0N/A // Get the dummy class, creating it if necessary. 0N/A // Create dummy class. 0N/A // If an interface has a public inner class, the dummy class for 0N/A // the constructor must always be accessible. Fix for 4221648. 0N/A // It is likely that a full check is not really necessary, 0N/A // but it is essential that the class be marked as parsed. 0N/A // Otherwise, we use the name "access$N", for the 0N/A // smallest value of N >= 0 yielding an unused name. 0N/A for (
int i =
0; ; i++) {
0N/A // Since constructors are never static, we don't 0N/A // have to worry about a dummy argument here. 0N/A // All access methods for non-static members get an explicit 0N/A // 'this' pointer as an extra argument, as the access methods 0N/A // themselves must be static. EXCEPTION: Access methods for 0N/A // constructors are non-static. 0N/A // Target is a method, possibly a constructor. 0N/A // Access method is a constructor. 0N/A // Requires a dummy argument. 0N/A // Outer instance link must be the first argument. 0N/A // The following is a sanity check that will catch 0N/A // most cases in which in this requirement is violated. 0N/A // Strip outer 'this' argument. 0N/A // It will be added back when the access method is checked. 0N/A // There is no outer instance. 0N/A // Access method is static. 0N/A // Requires an explicit 'this' argument. 0N/A // Constructor access method is non-static, so 0N/A // 'this' works normally. 0N/A // Remove dummy argument, as it is not 0N/A // passed to the target method. 0N/A // Non-constructor access method is static, so 0N/A // we use the first argument as 'this'. 0N/A // Remove first argument. 0N/A // If true, 'isSuper' forces a non-virtual call. 0N/A // Access methods are now static (constructors excepted), and no longer final. 0N/A // This change was mandated by the interaction of the access method 0N/A // naming conventions and the restriction against overriding final 0N/A // Create the synthetic method within the class in which the referenced 0N/A // private member appears. The 'env' argument to 'makeMemberDefinition' 0N/A // is suspect because it represents the environment at the point at 0N/A // which a reference takes place, while it should represent the 0N/A // environment in which the definition of the synthetic method appears. 0N/A // We get away with this because 'env' is used only to access globals 0N/A // such as 'Environment.error', and also as an argument to 0N/A // 'resolveTypeStructure', which immediately discards it using 0N/A // 'setupEnv'. Apparently, the current definition of 'setupEnv' 0N/A // represents a design change that has not been thoroughly propagated. 0N/A // An access method is declared with same list of exceptions as its 0N/A // target. As the exceptions are simply listed by name, the correctness 0N/A // of this approach requires that the access method be checked 0N/A // (name-resolved) in the same context as its target method This 0N/A // should always be the case. 0N/A // Just to be safe, copy over the name-resolved exceptions from the 0N/A // target so that the context in which the access method is checked 0N/A // The call to 'check' is not needed, as the access method will be 0N/A // checked by the containing class after it is added. This is the 0N/A // idiom followed in the implementation of class literals. (See 0N/A // call below. The access method must be checked in the context in 0N/A // which it is declared, i.e., the class containing the referenced 0N/A // private member, not the (inner) class in which the original member 0N/A // reference occurs. 0N/A // newf.check(env, ctx, new Vset()); 0N/A // } catch (ClassNotFound ee) { 0N/A // env.error(where, "class.not.found", ee.name, this); 0N/A // The comment above is inaccurate. While it is often the case 0N/A // that the containing class will check the access method, this is 0N/A // by no means guaranteed. In fact, an access method may be added 0N/A // after the checking of its class is complete. In this case, however, 0N/A // the context in which the class was checked will have been saved in 0N/A // the class definition object (by the fix for 4095716), allowing us 0N/A // to check the field now, and in the correct context. 0N/A // This fixes bug 4098093. 0N/A //System.out.println("checking late addition: " + this); 0N/A //System.out.println("[Access member '" + 0N/A // newf + "' created for field '" + 0N/A // field +"' in class '" + this + "']"); 0N/A * Find an inner class of 'this', chosen arbitrarily. 0N/A * Result is always an actual class, never an interface. 0N/A * Returns null if none found. 0N/A // Look for an immediate inner class. 0N/A // Look for a class nested within an immediate inner interface. 0N/A // At this point, we have given up on finding a minimally-nested 0N/A // class (which would require a breadth-first traversal). It doesn't 0N/A // really matter which inner class we find. 0N/A // No inner classes. 0N/A * Get helper method for class literal lookup. 0N/A // If we have already created a lookup method, reuse it. 0N/A // If the current class is a nested class, make sure we put the 0N/A // lookup method in the outermost class. Set 'lookup' for the 0N/A // intervening inner classes so we won't have to do the search 0N/A // If we arrive here, there was no existing 'class$' method. 0N/A // The top-level type is an interface. Try to find an existing 0N/A // inner class in which to create the helper method. Any will do. 0N/A // The interface has no inner classes. Create an anonymous 0N/A // inner class to hold the helper method, as an interface must 0N/A // not have any methods. The tests above for prior creation 0N/A // of a 'class$' method assure that only one such class is 0N/A // allocated for each outermost class containing a class 0N/A // literal embedded somewhere within. Part of fix for 4055017. 0N/A // The name of the class-getter stub is "class$" 0N/A // Some sanity checks of questionable value. 0N/A // This check became useless after matchMethod() was modified 0N/A // to not return synthetic methods. 0N/A // lookup = c.matchMethod(toplevelEnv, c, idDClass, strarg); 0N/A //} catch (ClassNotFound ee) { 0N/A // throw new CompilerError("unexpected missing class"); 0N/A //} catch (AmbiguousMember ee) { 0N/A // throw new CompilerError("synthetic name clash"); 0N/A //if (lookup != null && lookup.getClassDefinition() == c) { 0N/A // // Error if method found was not inherited. 0N/A // throw new CompilerError("unexpected duplicate"); 0N/A // Some sanity checks of questionable value. 0N/A /* // The helper function looks like this. 0N/A * // It simply maps a checked exception to an unchecked one. 0N/A * static Class class$(String class$) { 0N/A * try { return Class.forName(class$); } 0N/A * catch (ClassNotFoundException forName) { 0N/A * throw new NoClassDefFoundError(forName.getMessage()); 0N/A // map the exceptions 0N/A // Use default (package) access. If private, an access method would 0N/A // be needed in the event that the class literal belonged to an interface. 0N/A // Also, making it private tickles bug 4098316. 0N/A // If a new class was created to contain the helper method, 0N/A * A list of active ongoing compilations. This list 0N/A * is used to stop two compilations from saving the 0N/A * Compile this class 0N/A * Verify that the modifier bits included in 'required' are 0N/A * all present in 'mods', otherwise signal an internal error. 0N/A * Note that errors in the source program may corrupt the modifiers, 0N/A * thus we rely on the fact that 'CompilerError' exceptions are 0N/A * silently ignored after an error message has been issued. 0N/A // Reverse the order, so that outer levels come first: 0N/A // System.out.println("compile class " + getName()); 0N/A // Generate code for all fields 0N/A //System.out.println("compile field " + field.getName()); 0N/A // bail out if there were any errors 0N/A // Sort the methods in order to make sure both constant pool 0N/A // entries and methods are in a deterministic order from run 0N/A // to run (this allows comparing class files for a fixed point 0N/A // to validate the compiler) 0N/A // Optimize Code and Collect method constants 0N/A // Collect field constants 0N/A // Collect inner class constants 0N/A // If the inner class is local, we do not need to add its 0N/A // outer class here -- the outer_class_info_index is zero. 0N/A // If the local name of the class is idNull, don't bother to 0N/A // add it to the constant pool. We won't need it. 0N/A // Write class information 0N/A // Certain modifiers are implied: 0N/A // 1. Any interface (nested or not) is implicitly deemed to be abstract, 0N/A // whether it is explicitly marked so or not. (Java 1.0.) 0N/A // 2. A interface which is a member of a type is implicitly deemed to 0N/A // be static, whether it is explicitly marked so or not. 0N/A // 3a. A type which is a member of an interface is implicitly deemed 0N/A // to be public, whether it is explicitly marked so or not. 0N/A // 3b. A type which is a member of an interface is implicitly deemed 0N/A // to be static, whether it is explicitly marked so or not. 0N/A // All of these rules are implemented in 'BatchParser.beginClass', 0N/A // but the results are verified here. 0N/A // The VM spec states that ACC_ABSTRACT must be set when 0N/A // ACC_INTERFACE is; this was not done by javac prior to 1.2, 0N/A // and the runtime compensates by setting it. Making sure 0N/A // it is set here will allow the runtime hack to eventually 0N/A // be removed. Rule 2 doesn't apply to transformed modifiers. 0N/A // Contrary to the JVM spec, we only set ACC_SUPER for classes, 0N/A // not interfaces. This is a workaround for a bug in IE3.0, 0N/A // which refuses interfaces with ACC_SUPER on. 0N/A // If this is a nested class, transform access modifiers. 0N/A // If private, transform to default (package) access. 0N/A // If protected, transform to public. 0N/A // M_PRIVATE and M_PROTECTED are already masked off by MM_CLASS above. 0N/A // cmods &= ~(M_PRIVATE | M_PROTECTED); 0N/A // Rule 3a. Note that Rule 3b doesn't apply to transformed modifiers. 0N/A // Transform floating point modifiers. M_STRICTFP 0N/A // of member + status of enclosing class turn into 0N/A // For each inner class name transformation, we have a record 0N/A // with the following fields: 0N/A // u2 inner_class_info_index; // CONSTANT_Class_info index 0N/A // u2 outer_class_info_index; // CONSTANT_Class_info index 0N/A // u2 inner_name_index; // CONSTANT_Utf8_info index 0N/A // u2 inner_class_access_flags; // access_flags bitmask 0N/A // The spec states that outer_class_info_index is 0 iff 0N/A // the inner class is not a member of its enclosing class (i.e. 0N/A // it is a local or anonymous class). The spec also states 0N/A // that if a class is anonymous then inner_name_index should 0N/A // Generate inner_class_info_index. 0N/A // Generate outer_class_info_index. 0N/A // Checking isLocal() should probably be enough here, 0N/A // but the check for isAnonymous is added for good 0N/A // Query: what about if inner.isInsideLocal()? 0N/A // For now we continue to generate a nonzero 0N/A // outer_class_info_index. 0N/A // Generate inner_name_index. 0N/A // Generate inner_class_access_flags. 0N/A // Certain modifiers are implied for nested types. 0N/A // See rules 1, 2, 3a, and 3b enumerated above. 0N/A // All of these rules are implemented in 'BatchParser.beginClass', 0N/A // but are verified here. 0N/A // generate coverage data 0N/A * Print out the dependencies for this class (-xdepend) option 0N/A // Only do this if the -xdepend flag is on 0N/A // Name of java source file this class was in (full path) 0N/A // Class name, fully qualified 0N/A // Inner class names must be mangled, as ordinary '.' qualification 0N/A // is used internally where the spec requires '$' separators. 0N/A // String className = getName().toString(); 0N/A // Line number where class starts in the src file 0N/A // Line number where class ends in the src file (not used yet) 0N/A // First line looks like: 0N/A // CLASS:src,startLine,endLine,className 0N/A // For each class this class is dependent on: 0N/A // CLDEP:className1,className2 0N/A // where className1 is the name of the class we are in, and 0N/A // classname2 is the name of the class className1 0N/A // Mangle name of class dependend on.