1 /*
   2  * Copyright (c) 1994, 2015, 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.java;
  27 
  28 import java.util.*;
  29 import java.io.OutputStream;
  30 import java.io.PrintStream;
  31 import sun.tools.tree.Context;
  32 import sun.tools.tree.Vset;
  33 import sun.tools.tree.Expression;
  34 import sun.tools.tree.LocalMember;
  35 import sun.tools.tree.UplevelReference;
  36 
  37 /**
  38  * This class is a Java class definition
  39  *
  40  * WARNING: The contents of this source file are not part of any
  41  * supported API.  Code that depends on them does so at its own risk:
  42  * they are subject to change or removal without notice.
  43  */
  44 @SuppressWarnings("deprecation")
  45 public
  46 class ClassDefinition implements Constants {
  47 
  48     protected Object source;
  49     protected long where;
  50     protected int modifiers;
  51     protected Identifier localName; // for local classes
  52     protected ClassDeclaration declaration;
  53     protected IdentifierToken superClassId;
  54     protected IdentifierToken interfaceIds[];
  55     protected ClassDeclaration superClass;
  56     protected ClassDeclaration interfaces[];
  57     protected ClassDefinition outerClass;
  58     protected MemberDefinition outerMember;
  59     protected MemberDefinition innerClassMember;        // field for me in outerClass
  60     protected MemberDefinition firstMember;
  61     protected MemberDefinition lastMember;
  62     protected boolean resolved;
  63     protected String documentation;
  64     protected boolean error;
  65     protected boolean nestError;
  66     protected UplevelReference references;
  67     protected boolean referencesFrozen;
  68     private Hashtable<Identifier, MemberDefinition> fieldHash = new Hashtable<>(31);
  69     private int abstr;
  70 
  71     // Table of local and anonymous classes whose internal names are constructed
  72     // using the current class as a prefix.  This is part of a fix for
  73     // bugid 4054523 and 4030421.  See also 'Environment.getClassDefinition'
  74     // and 'BatchEnvironment.makeClassDefinition'.  Allocated on demand.
  75     private Hashtable<String, ClassDefinition> localClasses = null;
  76     private final int LOCAL_CLASSES_SIZE = 31;
  77 
  78     // The immediately surrounding context in which the class appears.
  79     // Set at the beginning of checking, upon entry to 'SourceClass.checkInternal'.
  80     // Null for classes that are not local or inside a local class.
  81     // At present, this field exists only for the benefit of 'resolveName' as part
  82     // of the fix for 4095716.
  83     protected Context classContext;
  84 
  85     // The saved class context is now also used in 'SourceClass.getAccessMember'.
  86     // Provide read-only access via this method.  Part of fix for 4098093.
  87     public Context getClassContext() {
  88         return classContext;
  89     }
  90 
  91 
  92     /**
  93      * Constructor
  94      */
  95     protected ClassDefinition(Object source, long where, ClassDeclaration declaration,
  96                               int modifiers, IdentifierToken superClass, IdentifierToken interfaces[]) {
  97         this.source = source;
  98         this.where = where;
  99         this.declaration = declaration;
 100         this.modifiers = modifiers;
 101         this.superClassId = superClass;
 102         this.interfaceIds = interfaces;
 103     }
 104 
 105     /**
 106      * Get the source of the class
 107      */
 108     public final Object getSource() {
 109         return source;
 110     }
 111 
 112     /**
 113      * Check if there were any errors in this class.
 114      */
 115     public final boolean getError() {
 116         return error;
 117     }
 118 
 119     /**
 120      * Mark this class to be erroneous.
 121      */
 122     public final void setError() {
 123         this.error = true;
 124         setNestError();
 125     }
 126 
 127     /**
 128      * Check if there were any errors in our class nest.
 129      */
 130     public final boolean getNestError() {
 131         // Check to see if our error value is set, or if any of our
 132         // outer classes' error values are set.  This will work in
 133         // conjunction with setError(), which sets the error value
 134         // of its outer class, to yield true is any of our nest
 135         // siblings has an error.  This addresses bug 4111488: either
 136         // code should be generated for all classes in a nest, or
 137         // none of them.
 138         return nestError || ((outerClass != null) ? outerClass.getNestError() : false);
 139     }
 140 
 141     /**
 142      * Mark this class, and all siblings in its class nest, to be
 143      * erroneous.
 144      */
 145     public final void setNestError() {
 146         this.nestError = true;
 147         if (outerClass != null) {
 148             // If we have an outer class, set it to be erroneous as well.
 149             // This will work in conjunction with getError(), which checks
 150             // the error value of its outer class, to set the whole class
 151             // nest to be erroneous.  This address bug 4111488: either
 152             // code should be generated for all classes in a nest, or
 153             // none of them.
 154             outerClass.setNestError();
 155         }
 156     }
 157 
 158     /**
 159      * Get the position in the input
 160      */
 161     public final long getWhere() {
 162         return where;
 163     }
 164 
 165     /**
 166      * Get the class declaration
 167      */
 168     public final ClassDeclaration getClassDeclaration() {
 169         return declaration;
 170     }
 171 
 172     /**
 173      * Get the class' modifiers
 174      */
 175     public final int getModifiers() {
 176         return modifiers;
 177     }
 178     public final void subModifiers(int mod) {
 179         modifiers &= ~mod;
 180     }
 181     public final void addModifiers(int mod) {
 182         modifiers |= mod;
 183     }
 184 
 185     // *** DEBUG ***
 186     protected boolean supersCheckStarted = !(this instanceof sun.tools.javac.SourceClass);
 187 
 188     /**
 189      * Get the class' super class
 190      */
 191     public final ClassDeclaration getSuperClass() {
 192         /*---
 193         if (superClass == null && superClassId != null)
 194             throw new CompilerError("getSuperClass "+superClassId);
 195         // There are obscure cases where null is the right answer,
 196         // in order to enable some error reporting later on.
 197         // For example:  class T extends T.N { class N { } }
 198         ---*/
 199 
 200         // *** DEBUG ***
 201         // This method should not be called if the superclass has not been resolved.
 202         if (!supersCheckStarted) throw new CompilerError("unresolved super");
 203 
 204         return superClass;
 205     }
 206 
 207     /**
 208      * Get the super class, and resolve names now if necessary.
 209      *
 210      * It is only possible to resolve names at this point if we are
 211      * a source class.  The provision of this method at this level
 212      * in the class hierarchy is dubious, but see 'getInnerClass' below.
 213      * All other calls to 'getSuperClass(env)' appear in 'SourceClass'.
 214      * NOTE: An older definition of this method has been moved to
 215      * 'SourceClass', where it overrides this one.
 216      *
 217      * @see #resolveTypeStructure
 218      */
 219 
 220     public ClassDeclaration getSuperClass(Environment env) {
 221         return getSuperClass();
 222     }
 223 
 224     /**
 225      * Get the class' interfaces
 226      */
 227     public final ClassDeclaration getInterfaces()[] {
 228         if (interfaces == null)  throw new CompilerError("getInterfaces");
 229         return interfaces;
 230     }
 231 
 232     /**
 233      * Get the class' enclosing class (or null if not inner)
 234      */
 235     public final ClassDefinition getOuterClass() {
 236         return outerClass;
 237     }
 238 
 239     /**
 240      * Set the class' enclosing class.  Must be done at most once.
 241      */
 242     protected final void setOuterClass(ClassDefinition outerClass) {
 243         if (this.outerClass != null)  throw new CompilerError("setOuterClass");
 244         this.outerClass = outerClass;
 245     }
 246 
 247     /**
 248      * Set the class' enclosing current instance pointer.
 249      * Must be done at most once.
 250      */
 251     protected final void setOuterMember(MemberDefinition outerMember) {
 252 
 253         if (isStatic() || !isInnerClass())  throw new CompilerError("setOuterField");
 254         if (this.outerMember != null)  throw new CompilerError("setOuterField");
 255         this.outerMember = outerMember;
 256     }
 257 
 258     /**
 259      * Tell if the class is inner.
 260      * This predicate also returns true for top-level nested types.
 261      * To test for a true inner class as seen by the programmer,
 262      * use <tt>!isTopLevel()</tt>.
 263      */
 264     public final boolean isInnerClass() {
 265         return outerClass != null;
 266     }
 267 
 268     /**
 269      * Tell if the class is a member of another class.
 270      * This is false for package members and for block-local classes.
 271      */
 272     public final boolean isMember() {
 273         return outerClass != null && !isLocal();
 274     }
 275 
 276     /**
 277      * Tell if the class is "top-level", which is either a package member,
 278      * or a static member of another top-level class.
 279      */
 280     public final boolean isTopLevel() {
 281         return outerClass == null || isStatic() || isInterface();
 282     }
 283 
 284     /**
 285      * Tell if the class is local or inside a local class,
 286      * which means it cannot be mentioned outside of its file.
 287      */
 288 
 289     // The comment above is true only because M_LOCAL is set
 290     // whenever M_ANONYMOUS is.  I think it is risky to assume that
 291     // isAnonymous(x) => isLocal(x).
 292 
 293     public final boolean isInsideLocal() {
 294         return isLocal() ||
 295             (outerClass != null && outerClass.isInsideLocal());
 296     }
 297 
 298     /**
 299      * Tell if the class is local or anonymous class, or inside
 300      * such a class, which means it cannot be mentioned outside of
 301      * its file.
 302      */
 303     public final boolean isInsideLocalOrAnonymous() {
 304         return isLocal() || isAnonymous () ||
 305             (outerClass != null && outerClass.isInsideLocalOrAnonymous());
 306     }
 307 
 308     /**
 309      * Return a simple identifier for this class (idNull if anonymous).
 310      */
 311     public Identifier getLocalName() {
 312         if (localName != null) {
 313             return localName;
 314         }
 315         // This is also the name of the innerClassMember, if any:
 316         return getName().getFlatName().getName();
 317     }
 318 
 319     /**
 320      * Set the local name of a class.  Must be a local class.
 321      */
 322     public void setLocalName(Identifier name) {
 323         if (isLocal()) {
 324             localName = name;
 325         }
 326     }
 327 
 328     /**
 329      * If inner, get the field for this class in the enclosing class
 330      */
 331     public final MemberDefinition getInnerClassMember() {
 332         if (outerClass == null)
 333             return null;
 334         if (innerClassMember == null) {
 335             // We must find the field in the outer class.
 336             Identifier nm = getName().getFlatName().getName();
 337             for (MemberDefinition field = outerClass.getFirstMatch(nm);
 338                  field != null; field = field.getNextMatch()) {
 339                 if (field.isInnerClass()) {
 340                     innerClassMember = field;
 341                     break;
 342                 }
 343             }
 344             if (innerClassMember == null)
 345                 throw new CompilerError("getInnerClassField");
 346         }
 347         return innerClassMember;
 348     }
 349 
 350     /**
 351      * If inner, return an innermost uplevel self pointer, if any exists.
 352      * Otherwise, return null.
 353      */
 354     public final MemberDefinition findOuterMember() {
 355         return outerMember;
 356     }
 357 
 358     /**
 359      * See if this is a (nested) static class.
 360      */
 361     public final boolean isStatic() {
 362         return (modifiers & ACC_STATIC) != 0;
 363     }
 364 
 365     /**
 366      * Get the class' top-level enclosing class
 367      */
 368     public final ClassDefinition getTopClass() {
 369         ClassDefinition p, q;
 370         for (p = this; (q = p.outerClass) != null; p = q)
 371             ;
 372         return p;
 373     }
 374 
 375     /**
 376      * Get the class' first field or first match
 377      */
 378     public final MemberDefinition getFirstMember() {
 379         return firstMember;
 380     }
 381     public final MemberDefinition getFirstMatch(Identifier name) {
 382         return fieldHash.get(name);
 383     }
 384 
 385     /**
 386      * Get the class' name
 387      */
 388     public final Identifier getName() {
 389         return declaration.getName();
 390     }
 391 
 392     /**
 393      * Get the class' type
 394      */
 395     public final Type getType() {
 396         return declaration.getType();
 397     }
 398 
 399     /**
 400      * Get the class' documentation
 401      */
 402     public String getDocumentation() {
 403         return documentation;
 404     }
 405 
 406     /**
 407      * Return true if the given documentation string contains a deprecation
 408      * paragraph.  This is true if the string contains the tag @deprecated
 409      * is the first word in a line.
 410      */
 411     public static boolean containsDeprecated(String documentation) {
 412         if (documentation == null) {
 413             return false;
 414         }
 415     doScan:
 416         for (int scan = 0;
 417              (scan = documentation.indexOf(paraDeprecated, scan)) >= 0;
 418              scan += paraDeprecated.length()) {
 419             // make sure there is only whitespace between this word
 420             // and the beginning of the line
 421             for (int beg = scan-1; beg >= 0; beg--) {
 422                 char ch = documentation.charAt(beg);
 423                 if (ch == '\n' || ch == '\r') {
 424                     break;      // OK
 425                 }
 426                 if (!Character.isSpace(ch)) {
 427                     continue doScan;
 428                 }
 429             }
 430             // make sure the char after the word is space or end of line
 431             int end = scan+paraDeprecated.length();
 432             if (end < documentation.length()) {
 433                 char ch = documentation.charAt(end);
 434                 if (!(ch == '\n' || ch == '\r') && !Character.isSpace(ch)) {
 435                     continue doScan;
 436                 }
 437             }
 438             return true;
 439         }
 440         return false;
 441     }
 442 
 443     public final boolean inSamePackage(ClassDeclaration c) {
 444         // find out if the class stored in c is defined in the same
 445         // package as the current class.
 446         return inSamePackage(c.getName().getQualifier());
 447     }
 448 
 449     public final boolean inSamePackage(ClassDefinition c) {
 450         // find out if the class stored in c is defined in the same
 451         // package as the current class.
 452         return inSamePackage(c.getName().getQualifier());
 453     }
 454 
 455     public final boolean inSamePackage(Identifier packageName) {
 456         return (getName().getQualifier().equals(packageName));
 457     }
 458 
 459     /**
 460      * Checks
 461      */
 462     public final boolean isInterface() {
 463         return (getModifiers() & M_INTERFACE) != 0;
 464     }
 465     public final boolean isClass() {
 466         return (getModifiers() & M_INTERFACE) == 0;
 467     }
 468     public final boolean isPublic() {
 469         return (getModifiers() & M_PUBLIC) != 0;
 470     }
 471     public final boolean isPrivate() {
 472         return (getModifiers() & M_PRIVATE) != 0;
 473     }
 474     public final boolean isProtected() {
 475         return (getModifiers() & M_PROTECTED) != 0;
 476     }
 477     public final boolean isPackagePrivate() {
 478         return (modifiers & (M_PUBLIC | M_PRIVATE | M_PROTECTED)) == 0;
 479     }
 480     public final boolean isFinal() {
 481         return (getModifiers() & M_FINAL) != 0;
 482     }
 483     public final boolean isAbstract() {
 484         return (getModifiers() & M_ABSTRACT) != 0;
 485     }
 486     public final boolean isSynthetic() {
 487         return (getModifiers() & M_SYNTHETIC) != 0;
 488     }
 489     public final boolean isDeprecated() {
 490         return (getModifiers() & M_DEPRECATED) != 0;
 491     }
 492     public final boolean isAnonymous() {
 493         return (getModifiers() & M_ANONYMOUS) != 0;
 494     }
 495     public final boolean isLocal() {
 496         return (getModifiers() & M_LOCAL) != 0;
 497     }
 498     public final boolean hasConstructor() {
 499         return getFirstMatch(idInit) != null;
 500     }
 501 
 502 
 503     /**
 504      * Check to see if a class must be abstract.  This method replaces
 505      * isAbstract(env)
 506      */
 507     public final boolean mustBeAbstract(Environment env) {
 508         // If it is declared abstract, return true.
 509         // (Fix for 4110534.)
 510         if (isAbstract()) {
 511             return true;
 512         }
 513 
 514         // Check to see if the class should have been declared to be
 515         // abstract.
 516 
 517         // We make sure that the inherited method collection has been
 518         // performed.
 519         collectInheritedMethods(env);
 520 
 521         // We check for any abstract methods inherited or declared
 522         // by this class.
 523         Iterator<MemberDefinition> methods = getMethods();
 524         while (methods.hasNext()) {
 525             MemberDefinition method = methods.next();
 526 
 527             if (method.isAbstract()) {
 528                 return true;
 529             }
 530         }
 531 
 532         // We check for hidden "permanently abstract" methods in
 533         // our superclasses.
 534         return getPermanentlyAbstractMethods().hasNext();
 535     }
 536 
 537     /**
 538      * Check if this is a super class of another class
 539      */
 540     public boolean superClassOf(Environment env, ClassDeclaration otherClass)
 541                                                                 throws ClassNotFound {
 542         while (otherClass != null) {
 543             if (getClassDeclaration().equals(otherClass)) {
 544                 return true;
 545             }
 546             otherClass = otherClass.getClassDefinition(env).getSuperClass();
 547         }
 548         return false;
 549     }
 550 
 551     /**
 552      * Check if this is an enclosing class of another class
 553      */
 554     public boolean enclosingClassOf(ClassDefinition otherClass) {
 555         while ((otherClass = otherClass.getOuterClass()) != null) {
 556             if (this == otherClass) {
 557                 return true;
 558             }
 559         }
 560         return false;
 561     }
 562 
 563     /**
 564      * Check if this is a sub class of another class
 565      */
 566     public boolean subClassOf(Environment env, ClassDeclaration otherClass) throws ClassNotFound {
 567         ClassDeclaration c = getClassDeclaration();
 568         while (c != null) {
 569             if (c.equals(otherClass)) {
 570                 return true;
 571             }
 572             c = c.getClassDefinition(env).getSuperClass();
 573         }
 574         return false;
 575     }
 576 
 577     /**
 578      * Check if this class is implemented by another class
 579      */
 580     public boolean implementedBy(Environment env, ClassDeclaration c) throws ClassNotFound {
 581         for (; c != null ; c = c.getClassDefinition(env).getSuperClass()) {
 582             if (getClassDeclaration().equals(c)) {
 583                 return true;
 584             }
 585             ClassDeclaration intf[] = c.getClassDefinition(env).getInterfaces();
 586             for (int i = 0 ; i < intf.length ; i++) {
 587                 if (implementedBy(env, intf[i])) {
 588                     return true;
 589                 }
 590             }
 591         }
 592         return false;
 593     }
 594 
 595     /**
 596      * Check to see if a class which implements interface `this' could
 597      * possibly implement the interface `intDef'.  Note that the only
 598      * way that this can fail is if `this' and `intDef' have methods
 599      * which are of the same signature and different return types.  This
 600      * method is used by Environment.explicitCast() to determine if a
 601      * cast between two interfaces is legal.
 602      *
 603      * This method should only be called on a class after it has been
 604      * basicCheck()'ed.
 605      */
 606     public boolean couldImplement(ClassDefinition intDef) {
 607         // Check to see if we could have done the necessary checks.
 608         if (!doInheritanceChecks) {
 609             throw new CompilerError("couldImplement: no checks");
 610         }
 611 
 612         // This method should only be called for interfaces.
 613         if (!isInterface() || !intDef.isInterface()) {
 614             throw new CompilerError("couldImplement: not interface");
 615         }
 616 
 617         // Make sure we are not called before we have collected our
 618         // inheritance information.
 619         if (allMethods == null) {
 620             throw new CompilerError("couldImplement: called early");
 621         }
 622 
 623         // Get the other classes' methods.  getMethods() in
 624         // general can return methods which are not visible to the
 625         // current package.  We need to make sure that these do not
 626         // prevent this class from being implemented.
 627         Iterator<MemberDefinition> otherMethods = intDef.getMethods();
 628 
 629         while (otherMethods.hasNext()) {
 630             // Get one of the methods from intDef...
 631             MemberDefinition method = otherMethods.next();
 632 
 633             Identifier name = method.getName();
 634             Type type = method.getType();
 635 
 636             // See if we implement a method of the same signature...
 637             MemberDefinition myMethod = allMethods.lookupSig(name, type);
 638 
 639             //System.out.println("Comparing\n\t" + myMethod +
 640             //                   "\nand\n\t" + method);
 641 
 642             if (myMethod != null) {
 643                 // We do.  Make sure the methods have the same return type.
 644                 if (!myMethod.sameReturnType(method)) {
 645                     return false;
 646                 }
 647             }
 648         }
 649 
 650         return true;
 651     }
 652 
 653     /**
 654      * Check if another class can be accessed from the 'extends' or 'implements'
 655      * clause of this class.
 656      */
 657     public boolean extendsCanAccess(Environment env, ClassDeclaration c) throws ClassNotFound {
 658 
 659         // Names in the 'extends' or 'implements' clause of an inner class
 660         // are checked as if they appeared in the body of the surrounding class.
 661         if (outerClass != null) {
 662             return outerClass.canAccess(env, c);
 663         }
 664 
 665         // We are a package member.
 666 
 667         ClassDefinition cdef = c.getClassDefinition(env);
 668 
 669         if (cdef.isLocal()) {
 670             // No locals should be in scope in the 'extends' or
 671             // 'implements' clause of a package member.
 672             throw new CompilerError("top local");
 673         }
 674 
 675         if (cdef.isInnerClass()) {
 676             MemberDefinition f = cdef.getInnerClassMember();
 677 
 678             // Access to public member is always allowed.
 679             if (f.isPublic()) {
 680                 return true;
 681             }
 682 
 683             // Private access is ok only from the same class nest.  This can
 684             // happen only if the class represented by 'this' encloses the inner
 685             // class represented by 'f'.
 686             if (f.isPrivate()) {
 687                 return getClassDeclaration().equals(f.getTopClass().getClassDeclaration());
 688             }
 689 
 690             // Protected or default access -- allow access if in same package.
 691             return getName().getQualifier().equals(f.getClassDeclaration().getName().getQualifier());
 692         }
 693 
 694         // Access to public member is always allowed.
 695         if (cdef.isPublic()) {
 696             return true;
 697         }
 698 
 699         // Default access -- allow access if in same package.
 700         return getName().getQualifier().equals(c.getName().getQualifier());
 701     }
 702 
 703     /**
 704      * Check if another class can be accessed from within the body of this class.
 705      */
 706     public boolean canAccess(Environment env, ClassDeclaration c) throws ClassNotFound {
 707         ClassDefinition cdef = c.getClassDefinition(env);
 708 
 709         if (cdef.isLocal()) {
 710             // if it's in scope, it's accessible
 711             return true;
 712         }
 713 
 714         if (cdef.isInnerClass()) {
 715             return canAccess(env, cdef.getInnerClassMember());
 716         }
 717 
 718         // Public access is always ok
 719         if (cdef.isPublic()) {
 720             return true;
 721         }
 722 
 723         // It must be in the same package
 724         return getName().getQualifier().equals(c.getName().getQualifier());
 725     }
 726 
 727     /**
 728      * Check if a field can be accessed from a class
 729      */
 730 
 731     public boolean canAccess(Environment env, MemberDefinition f)
 732                 throws ClassNotFound {
 733 
 734         // Public access is always ok
 735         if (f.isPublic()) {
 736             return true;
 737         }
 738         // Protected access is ok from a subclass
 739         if (f.isProtected() && subClassOf(env, f.getClassDeclaration())) {
 740             return true;
 741         }
 742         // Private access is ok only from the same class nest
 743         if (f.isPrivate()) {
 744             return getTopClass().getClassDeclaration()
 745                 .equals(f.getTopClass().getClassDeclaration());
 746         }
 747         // It must be in the same package
 748         return getName().getQualifier().equals(f.getClassDeclaration().getName().getQualifier());
 749     }
 750 
 751     /**
 752      * Check if a class is entitled to inline access to a class from
 753      * another class.
 754      */
 755     public boolean permitInlinedAccess(Environment env, ClassDeclaration c)
 756                        throws ClassNotFound {
 757 
 758         return (env.opt() && c.equals(declaration)) ||
 759                (env.opt_interclass() && canAccess(env, c));
 760     }
 761 
 762     /**
 763      * Check if a class is entitled to inline access to a method from
 764      * another class.
 765      */
 766     public boolean permitInlinedAccess(Environment env, MemberDefinition f)
 767                        throws ClassNotFound {
 768         return (env.opt()
 769                     && (f.clazz.getClassDeclaration().equals(declaration))) ||
 770                (env.opt_interclass() && canAccess(env, f));
 771     }
 772 
 773     /**
 774      * We know the field is marked protected (and not public) and that
 775      * the field is visible (as per canAccess).  Can we access the field as
 776      * <accessor>.<field>, where <accessor> has the type <accessorType>?
 777      *
 778      * Protected fields can only be accessed when the accessorType is a
 779      * subclass of the current class
 780      */
 781     public boolean protectedAccess(Environment env, MemberDefinition f,
 782                                    Type accessorType)
 783         throws ClassNotFound
 784     {
 785 
 786         return
 787                // static protected fields are accessible
 788                f.isStatic()
 789             || // allow array.clone()
 790                (accessorType.isType(TC_ARRAY) && (f.getName() == idClone)
 791                  && (f.getType().getArgumentTypes().length == 0))
 792             || // <accessorType> is a subtype of the current class
 793                (accessorType.isType(TC_CLASS)
 794                  && env.getClassDefinition(accessorType.getClassName())
 795                          .subClassOf(env, getClassDeclaration()))
 796             || // we are accessing the field from a friendly class (same package)
 797                (getName().getQualifier()
 798                    .equals(f.getClassDeclaration().getName().getQualifier()));
 799     }
 800 
 801 
 802     /**
 803      * Find or create an access method for a private member,
 804      * or return null if this is not possible.
 805      */
 806     public MemberDefinition getAccessMember(Environment env, Context ctx,
 807                                           MemberDefinition field, boolean isSuper) {
 808         throw new CompilerError("binary getAccessMember");
 809     }
 810 
 811     /**
 812      * Find or create an update method for a private member,
 813      * or return null if this is not possible.
 814      */
 815     public MemberDefinition getUpdateMember(Environment env, Context ctx,
 816                                             MemberDefinition field, boolean isSuper) {
 817         throw new CompilerError("binary getUpdateMember");
 818     }
 819 
 820     /**
 821      * Get a field from this class.  Report ambiguous fields.
 822      * If no accessible field is found, this method may return an
 823      * inaccessible field to allow a useful error message.
 824      *
 825      * getVariable now takes the source class `source' as an argument.
 826      * This allows getVariable to check whether a field is inaccessible
 827      * before it signals that a field is ambiguous.  The compiler used to
 828      * signal an ambiguity even when one of the fields involved was not
 829      * accessible.  (bug 4053724)
 830      */
 831     public MemberDefinition getVariable(Environment env,
 832                                         Identifier nm,
 833                                         ClassDefinition source)
 834         throws AmbiguousMember, ClassNotFound {
 835 
 836         return getVariable0(env, nm, source, true, true);
 837     }
 838 
 839     /*
 840      * private fields are never inherited.  package-private fields are
 841      * not inherited across package boundaries.  To capture this, we
 842      * take two booleans as parameters: showPrivate indicates whether
 843      * we have passed a class boundary, and showPackage indicates whether
 844      * we have crossed a package boundary.
 845      */
 846     private MemberDefinition getVariable0(Environment env,
 847                                           Identifier nm,
 848                                           ClassDefinition source,
 849                                           boolean showPrivate,
 850                                           boolean showPackage)
 851         throws AmbiguousMember, ClassNotFound {
 852 
 853         // Check to see if this field is defined in the current class
 854         for (MemberDefinition member = getFirstMatch(nm);
 855              member != null;
 856              member = member.getNextMatch()) {
 857             if (member.isVariable()) {
 858                 if ((showPrivate || !member.isPrivate()) &&
 859                     (showPackage || !member.isPackagePrivate())) {
 860                     // It is defined in this class.
 861                     return member;
 862                 } else {
 863                     // Even though this definition is not inherited,
 864                     // it hides all definitions in supertypes.
 865                     return null;
 866                 }
 867             }
 868         }
 869 
 870         // Find the field in our superclass.
 871         ClassDeclaration sup = getSuperClass();
 872         MemberDefinition field = null;
 873         if (sup != null) {
 874             field =
 875                 sup.getClassDefinition(env)
 876                   .getVariable0(env, nm, source,
 877                                 false,
 878                                 showPackage && inSamePackage(sup));
 879         }
 880 
 881         // Find the field in our superinterfaces.
 882         for (int i = 0 ; i < interfaces.length ; i++) {
 883             // Try to look up the field in an interface.  Since interfaces
 884             // only have public fields, the values of the two boolean
 885             // arguments are not important.
 886             MemberDefinition field2 =
 887                 interfaces[i].getClassDefinition(env)
 888                   .getVariable0(env, nm, source, true, true);
 889 
 890             if (field2 != null) {
 891                 // If we have two different, accessible fields, then
 892                 // we've found an ambiguity.
 893                 if (field != null &&
 894                     source.canAccess(env, field) &&
 895                     field2 != field) {
 896 
 897                     throw new AmbiguousMember(field2, field);
 898                 }
 899                 field = field2;
 900             }
 901         }
 902         return field;
 903     }
 904 
 905     /**
 906      * Tells whether to report a deprecation error for this class.
 907      */
 908     public boolean reportDeprecated(Environment env) {
 909         return (isDeprecated()
 910                 || (outerClass != null && outerClass.reportDeprecated(env)));
 911     }
 912 
 913     /**
 914      * Note that this class is being used somehow by <tt>ref</tt>.
 915      * Report deprecation errors, etc.
 916      */
 917     public void noteUsedBy(ClassDefinition ref, long where, Environment env) {
 918         // (Have this deal with canAccess() checks, too?)
 919         if (reportDeprecated(env)) {
 920             env.error(where, "warn.class.is.deprecated", this);
 921         }
 922     }
 923 
 924    /**
 925      * Get an inner class.
 926      * Look in supers but not outers.
 927      * (This is used directly to resolve expressions like "site.K", and
 928      * inside a loop to resolve lone names like "K" or the "K" in "K.L".)
 929      *
 930      * Called from 'Context' and 'FieldExpression' as well as this class.
 931      *
 932      * @see FieldExpression.checkCommon
 933      * @see resolveName
 934      */
 935     public MemberDefinition getInnerClass(Environment env, Identifier nm)
 936                                                         throws ClassNotFound {
 937         // Note:  AmbiguousClass will not be thrown unless and until
 938         // inner classes can be defined inside interfaces.
 939 
 940         // Check if it is defined in the current class
 941         for (MemberDefinition field = getFirstMatch(nm);
 942                 field != null ; field = field.getNextMatch()) {
 943             if (field.isInnerClass()) {
 944                 if (field.getInnerClass().isLocal()) {
 945                     continue;   // ignore this name; it is internally generated
 946                 }
 947                 return field;
 948             }
 949         }
 950 
 951         // Get it from the super class
 952         // It is likely that 'getSuperClass()' could be made to work here
 953         // but we would have to assure somehow that 'resolveTypeStructure'
 954         // has been called on the current class nest.  Since we can get
 955         // here from 'resolveName', which is called from 'resolveSupers',
 956         // it is possible that the first attempt to resolve the superclass
 957         // will originate here, instead of in the call to 'getSuperClass'
 958         // in 'checkSupers'.  See 'resolveTypeStructure', in which a call
 959         // to 'resolveSupers' precedes the call to 'checkSupers'.  Why is
 960         // name resolution done twice, first in 'resolveName'?
 961         // NOTE: 'SourceMember.resolveTypeStructure' may initiate type
 962         // structure resolution for an inner class.  Normally, this
 963         // occurs during the resolution of the outer class, but fields
 964         // added after the resolution of their containing class will
 965         // be resolved late -- see 'addMember(env,field)' below.
 966         // This should only happen for synthetic members, which should
 967         // never be an inner class.
 968         ClassDeclaration sup = getSuperClass(env);
 969         if (sup != null)
 970             return sup.getClassDefinition(env).getInnerClass(env, nm);
 971 
 972         return null;
 973     }
 974 
 975     /**
 976      * Lookup a method.  This code implements the method lookup
 977      * mechanism specified in JLS 15.11.2.
 978      *
 979      * This mechanism cannot be used to lookup synthetic methods.
 980      */
 981     private MemberDefinition matchMethod(Environment env,
 982                                          ClassDefinition accessor,
 983                                          Identifier methodName,
 984                                          Type[] argumentTypes,
 985                                          boolean isAnonConstCall,
 986                                          Identifier accessPackage)
 987         throws AmbiguousMember, ClassNotFound {
 988 
 989         if (allMethods == null || !allMethods.isFrozen()) {
 990             // This may be too restrictive.
 991             throw new CompilerError("matchMethod called early");
 992             // collectInheritedMethods(env);
 993         }
 994 
 995         // A tentative maximally specific method.
 996         MemberDefinition tentative = null;
 997 
 998         // A list of other methods which may be maximally specific too.
 999         List<MemberDefinition> candidateList = null;
1000 
1001         // Get all the methods inherited by this class which
1002         // have the name `methodName'.
1003         Iterator<MemberDefinition> methods = allMethods.lookupName(methodName);
1004 
1005         while (methods.hasNext()) {
1006             MemberDefinition method = methods.next();
1007 
1008             // See if this method is applicable.
1009             if (!env.isApplicable(method, argumentTypes)) {
1010                 continue;
1011             }
1012 
1013             // See if this method is accessible.
1014             if (accessor != null) {
1015                 if (!accessor.canAccess(env, method)) {
1016                     continue;
1017                 }
1018             } else if (isAnonConstCall) {
1019                 if (method.isPrivate() ||
1020                     (method.isPackagePrivate() &&
1021                      accessPackage != null &&
1022                      !inSamePackage(accessPackage))) {
1023                     // For anonymous constructor accesses, we
1024                     // haven't yet built an accessing class.
1025                     // We disallow anonymous classes from seeing
1026                     // private/package-private inaccessible
1027                     // constructors in their superclass.
1028                     continue;
1029                 }
1030             } else {
1031                 // If accessor is null, we assume that the access
1032                 // is allowed.  Query: is this option used?
1033             }
1034 
1035             if (tentative == null) {
1036                 // `method' becomes our tentative maximally specific match.
1037                 tentative = method;
1038             } else {
1039                 if (env.isMoreSpecific(method, tentative)) {
1040                     // We have found a method which is a strictly better
1041                     // match than `tentative'.  Replace it.
1042                     tentative = method;
1043                 } else {
1044                     // If this method could possibly be another
1045                     // maximally specific method, add it to our
1046                     // list of other candidates.
1047                     if (!env.isMoreSpecific(tentative,method)) {
1048                         if (candidateList == null) {
1049                             candidateList = new ArrayList<>();
1050                         }
1051                         candidateList.add(method);
1052                     }
1053                 }
1054             }
1055         }
1056 
1057         if (tentative != null && candidateList != null) {
1058             // Find out if our `tentative' match is a uniquely
1059             // maximally specific.
1060             Iterator<MemberDefinition> candidates = candidateList.iterator();
1061             while (candidates.hasNext()) {
1062                 MemberDefinition method = candidates.next();
1063                 if (!env.isMoreSpecific(tentative, method)) {
1064                     throw new AmbiguousMember(tentative, method);
1065                 }
1066             }
1067         }
1068 
1069         return tentative;
1070     }
1071 
1072     /**
1073      * Lookup a method.  This code implements the method lookup
1074      * mechanism specified in JLS 15.11.2.
1075      *
1076      * This mechanism cannot be used to lookup synthetic methods.
1077      */
1078     public MemberDefinition matchMethod(Environment env,
1079                                         ClassDefinition accessor,
1080                                         Identifier methodName,
1081                                         Type[] argumentTypes)
1082         throws AmbiguousMember, ClassNotFound {
1083 
1084         return matchMethod(env, accessor, methodName,
1085                            argumentTypes, false, null);
1086     }
1087 
1088     /**
1089      * Lookup a method.  This code implements the method lookup
1090      * mechanism specified in JLS 15.11.2.
1091      *
1092      * This mechanism cannot be used to lookup synthetic methods.
1093      */
1094     public MemberDefinition matchMethod(Environment env,
1095                                         ClassDefinition accessor,
1096                                         Identifier methodName)
1097         throws AmbiguousMember, ClassNotFound {
1098 
1099         return matchMethod(env, accessor, methodName,
1100                            Type.noArgs, false, null);
1101     }
1102 
1103     /**
1104      * A version of matchMethod to be used only for constructors
1105      * when we cannot pass in a sourceClass argument.  We just assert
1106      * our package name.
1107      *
1108      * This is used only for anonymous classes, where we have to look up
1109      * a (potentially) protected constructor with no valid sourceClass
1110      * parameter available.
1111      */
1112     public MemberDefinition matchAnonConstructor(Environment env,
1113                                                  Identifier accessPackage,
1114                                                  Type argumentTypes[])
1115         throws AmbiguousMember, ClassNotFound {
1116 
1117         return matchMethod(env, null, idInit, argumentTypes,
1118                            true, accessPackage);
1119     }
1120 
1121     /**
1122      * Find a method, ie: exact match in this class or any of the super
1123      * classes.
1124      *
1125      * Only called by javadoc.  For now I am holding off rewriting this
1126      * code to rely on collectInheritedMethods(), as that code has
1127      * not gotten along with javadoc in the past.
1128      */
1129     public MemberDefinition findMethod(Environment env, Identifier nm, Type t)
1130     throws ClassNotFound {
1131         // look in the current class
1132         MemberDefinition f;
1133         for (f = getFirstMatch(nm) ; f != null ; f = f.getNextMatch()) {
1134             // Note that non-method types return false for equalArguments().
1135             if (f.getType().equalArguments(t)) {
1136                 return f;
1137             }
1138         }
1139 
1140         // constructors are not inherited
1141         if (nm.equals(idInit)) {
1142             return null;
1143         }
1144 
1145         // look in the super class
1146         ClassDeclaration sup = getSuperClass();
1147         if (sup == null)
1148             return null;
1149 
1150         return sup.getClassDefinition(env).findMethod(env, nm, t);
1151     }
1152 
1153     // We create a stub for this.  Source classes do more work.
1154     protected void basicCheck(Environment env) throws ClassNotFound {
1155         // Do the outer class first.
1156         if (outerClass != null)
1157             outerClass.basicCheck(env);
1158     }
1159 
1160     /**
1161      * Check this class.
1162      */
1163     public void check(Environment env) throws ClassNotFound {
1164     }
1165 
1166     public Vset checkLocalClass(Environment env, Context ctx,
1167                                 Vset vset, ClassDefinition sup,
1168                                 Expression args[], Type argTypes[]
1169                                 ) throws ClassNotFound {
1170         throw new CompilerError("checkLocalClass");
1171     }
1172 
1173     //---------------------------------------------------------------
1174     // The non-synthetic methods defined in this class or in any
1175     // of its parents (class or interface).  This member is used
1176     // to cache work done in collectInheritedMethods for use by
1177     // getMethods() and matchMethod().  It should be accessed by
1178     // no other method without forethought.
1179     MethodSet allMethods = null;
1180 
1181     // One of our superclasses may contain an abstract method which
1182     // we are unable to ever implement.  This happens when there is
1183     // a package-private abstract method in our parent and we are in
1184     // a different package than our parent.  In these cases, we
1185     // keep a list of the "permanently abstract" or "unimplementable"
1186     // methods so that we can correctly detect that this class is
1187     // indeed abstract and so that we can give somewhat comprehensible
1188     // error messages.
1189     private List<MemberDefinition> permanentlyAbstractMethods = new ArrayList<>();
1190 
1191     /**
1192      * This method returns an Iterator of all abstract methods
1193      * in our superclasses which we are unable to implement.
1194      */
1195     protected Iterator<MemberDefinition> getPermanentlyAbstractMethods() {
1196         // This method can only be called after collectInheritedMethods.
1197         if (allMethods == null) {
1198             throw new CompilerError("isPermanentlyAbstract() called early");
1199         }
1200 
1201         return permanentlyAbstractMethods.iterator();
1202     }
1203 
1204     /**
1205      * A flag used by turnOffInheritanceChecks() to indicate if
1206      * inheritance checks are on or off.
1207      */
1208     protected static boolean doInheritanceChecks = true;
1209 
1210     /**
1211      * This is a workaround to allow javadoc to turn off certain
1212      * inheritance/override checks which interfere with javadoc
1213      * badly.  In the future it might be good to eliminate the
1214      * shared sources of javadoc and javac to avoid the need for this
1215      * sort of workaround.
1216      */
1217     public static void turnOffInheritanceChecks() {
1218         doInheritanceChecks = false;
1219     }
1220 
1221     /**
1222      * Add all of the methods declared in or above `parent' to
1223      * `allMethods', the set of methods in the current class.
1224      * `myMethods' is the set of all methods declared in this
1225      * class, and `mirandaMethods' is a repository for Miranda methods.
1226      * If mirandaMethods is null, no mirandaMethods will be
1227      * generated.
1228      *
1229      * For a definition of Miranda methods, see the comment above the
1230      * method addMirandaMethods() which occurs later in this file.
1231      */
1232     private void collectOneClass(Environment env,
1233                                  ClassDeclaration parent,
1234                                  MethodSet myMethods,
1235                                  MethodSet allMethods,
1236                                  MethodSet mirandaMethods) {
1237 
1238         // System.out.println("Inheriting methods from " + parent);
1239 
1240         try {
1241             ClassDefinition pClass = parent.getClassDefinition(env);
1242             Iterator<MemberDefinition> methods = pClass.getMethods(env);
1243             while (methods.hasNext()) {
1244                 MemberDefinition method =
1245                     methods.next();
1246 
1247                 // Private methods are not inherited.
1248                 //
1249                 // Constructors are not inherited.
1250                 //
1251                 // Any non-abstract methods in an interface come
1252                 // from java.lang.Object.  This means that they
1253                 // should have already been added to allMethods
1254                 // when we walked our superclass lineage.
1255                 if (method.isPrivate() ||
1256                     method.isConstructor() ||
1257                     (pClass.isInterface() && !method.isAbstract())) {
1258 
1259                     continue;
1260                 }
1261 
1262                 // Get the components of the methods' signature.
1263                 Identifier name = method.getName();
1264                 Type type = method.getType();
1265 
1266                 // Check for a method of the same signature which
1267                 // was locally declared.
1268                 MemberDefinition override =
1269                     myMethods.lookupSig(name, type);
1270 
1271                 // Is this method inaccessible due to package-private
1272                 // visibility?
1273                 if (method.isPackagePrivate() &&
1274                     !inSamePackage(method.getClassDeclaration())) {
1275 
1276                     if (override != null && this instanceof
1277                         sun.tools.javac.SourceClass) {
1278                         // We give a warning when a class shadows an
1279                         // inaccessible package-private method from
1280                         // its superclass.  This warning is meant
1281                         // to prevent people from relying on overriding
1282                         // when it does not happen.  This warning should
1283                         // probably be removed to be consistent with the
1284                         // general "no warnings" policy of this
1285                         // compiler.
1286                         //
1287                         // The `instanceof' above is a hack so that only
1288                         // SourceClass generates this warning, not a
1289                         // BinaryClass, for example.
1290                         env.error(method.getWhere(),
1291                                   "warn.no.override.access",
1292                                   override,
1293                                   override.getClassDeclaration(),
1294                                   method.getClassDeclaration());
1295                     }
1296 
1297                     // If our superclass has a package-private abstract
1298                     // method that we have no access to, then we add
1299                     // this method to our list of permanently abstract
1300                     // methods.  The idea is, since we cannot override
1301                     // the method, we can never make this class
1302                     // non-abstract.
1303                     if (method.isAbstract()) {
1304                         permanentlyAbstractMethods.add(method);
1305                     }
1306 
1307                     // `method' is inaccessible.  We do not inherit it.
1308                     continue;
1309                 }
1310 
1311                 if (override != null) {
1312                     // `method' and `override' have the same signature.
1313                     // We are required to check that `override' is a
1314                     // legal override of `method'
1315 
1316                     //System.out.println ("About to check override of " +
1317                     //              method);
1318 
1319                     override.checkOverride(env, method);
1320                 } else {
1321                     // In the absence of a definition in the class
1322                     // itself, we check to see if this definition
1323                     // can be successfully merged with any other
1324                     // inherited definitions.
1325 
1326                     // Have we added a member of the same signature
1327                     // to `allMethods' already?
1328                     MemberDefinition formerMethod =
1329                         allMethods.lookupSig(name, type);
1330 
1331                     // If the previous definition is nonexistent or
1332                     // ignorable, replace it.
1333                     if (formerMethod == null) {
1334                         //System.out.println("Added " + method + " to " +
1335                         //             this);
1336 
1337                         if (mirandaMethods != null &&
1338                             pClass.isInterface() && !isInterface()) {
1339                             // Whenever a class inherits a method
1340                             // from an interface, that method is
1341                             // one of our "miranda" methods.  Early
1342                             // VMs require that these methods be
1343                             // added as true members to the class
1344                             // to enable method lookup to work in the
1345                             // VM.
1346                             method =
1347                                 new sun.tools.javac.SourceMember(method,this,
1348                                                                  env);
1349                             mirandaMethods.add(method);
1350 
1351                             //System.out.println("Added " + method +
1352                             // " to " + this + " as a Miranda");
1353                         }
1354 
1355                         // There is no previous inherited definition.
1356                         // Add `method' to `allMethods'.
1357                         allMethods.add(method);
1358                     } else if (isInterface() &&
1359                                !formerMethod.isAbstract() &&
1360                                method.isAbstract()) {
1361                         // If we are in an interface and we have inherited
1362                         // both an abstract method and a non-abstract method
1363                         // then we know that the non-abstract method is
1364                         // a placeholder from Object put in for type checking
1365                         // and the abstract method was already checked to
1366                         // be proper by our superinterface.
1367                         allMethods.replace(method);
1368 
1369                     } else {
1370                         // Okay, `formerMethod' and `method' both have the
1371                         // same signature.  See if they are compatible.
1372 
1373                         //System.out.println ("About to check meet of " +
1374                         //              method);
1375 
1376                         if (!formerMethod.checkMeet(env,
1377                                            method,
1378                                            this.getClassDeclaration())) {
1379                                 // The methods are incompatible.  Skip to
1380                                 // next method.
1381                             continue;
1382                         }
1383 
1384                         if (formerMethod.couldOverride(env, method)) {
1385                                 // Do nothing.  The current definition
1386                                 // is specific enough.
1387 
1388                                 //System.out.println("trivial meet of " +
1389                                 //                 method);
1390                             continue;
1391                         }
1392 
1393                         if (method.couldOverride(env, formerMethod)) {
1394                                 // `method' is more specific than
1395                                 // `formerMethod'.  replace `formerMethod'.
1396 
1397                                 //System.out.println("new def of " + method);
1398                             if (mirandaMethods != null &&
1399                                 pClass.isInterface() && !isInterface()) {
1400                                 // Whenever a class inherits a method
1401                                 // from an interface, that method is
1402                                 // one of our "miranda" methods.  Early
1403                                 // VMs require that these methods be
1404                                 // added as true members to the class
1405                                 // to enable method lookup to work in the
1406                                 // VM.
1407                                 method =
1408                                     new sun.tools.javac.SourceMember(method,
1409                                                                      this,env);
1410 
1411                                 mirandaMethods.replace(method);
1412 
1413                                 //System.out.println("Added " + method +
1414                                 // " to " + this + " as a Miranda");
1415                             }
1416 
1417                             allMethods.replace(method);
1418 
1419                             continue;
1420                         }
1421 
1422                         // Neither method is more specific than the other.
1423                         // Oh well.  We need to construct a nontrivial
1424                         // meet of the two methods.
1425                         //
1426                         // This is not yet implemented, so we give
1427                         // a message with a helpful workaround.
1428                         env.error(this.where,
1429                                   "nontrivial.meet", method,
1430                                   formerMethod.getClassDefinition(),
1431                                   method.getClassDeclaration()
1432                                   );
1433                     }
1434                 }
1435             }
1436         } catch (ClassNotFound ee) {
1437             env.error(getWhere(), "class.not.found", ee.name, this);
1438         }
1439     }
1440 
1441     /**
1442      * <p>Collect all methods defined in this class or inherited from
1443      * any of our superclasses or interfaces.  Look for any
1444      * incompatible definitions.
1445      *
1446      * <p>This function is also responsible for collecting the
1447      * <em>Miranda</em> methods for a class.  For a definition of
1448      * Miranda methods, see the comment in addMirandaMethods()
1449      * below.
1450      */
1451     protected void collectInheritedMethods(Environment env) {
1452         // The methods defined in this class.
1453         MethodSet myMethods;
1454         MethodSet mirandaMethods;
1455 
1456         //System.out.println("Called collectInheritedMethods() for " +
1457         //                 this);
1458 
1459         if (allMethods != null) {
1460             if (allMethods.isFrozen()) {
1461                 // We have already done the collection.  No need to
1462                 // do it again.
1463                 return;
1464             } else {
1465                 // We have run into a circular need to collect our methods.
1466                 // This should not happen at this stage.
1467                 throw new CompilerError("collectInheritedMethods()");
1468             }
1469         }
1470 
1471         myMethods = new MethodSet();
1472         allMethods = new MethodSet();
1473 
1474         // For testing, do not generate miranda methods.
1475         if (env.version12()) {
1476             mirandaMethods = null;
1477         } else {
1478             mirandaMethods = new MethodSet();
1479         }
1480 
1481         // Any methods defined in the current class get added
1482         // to both the myMethods and the allMethods MethodSets.
1483 
1484         for (MemberDefinition member = getFirstMember();
1485              member != null;
1486              member = member.nextMember) {
1487 
1488             // We only collect methods.  Initializers are not relevant.
1489             if (member.isMethod() &&
1490                 !member.isInitializer()) {
1491 
1492                 //System.out.println("Declared in " + this + ", " + member);
1493 
1494                 ////////////////////////////////////////////////////////////
1495                 // PCJ 2003-07-30 modified the following code because with
1496                 // the covariant return type feature of the 1.5 compiler,
1497                 // there might be multiple methods with the same signature
1498                 // but different return types, and MethodSet doesn't
1499                 // support that.  We use a new utility method that attempts
1500                 // to ensure that the appropriate method winds up in the
1501                 // MethodSet.  See 4892308.
1502                 ////////////////////////////////////////////////////////////
1503                 // myMethods.add(member);
1504                 // allMethods.add(member);
1505                 ////////////////////////////////////////////////////////////
1506                 methodSetAdd(env, myMethods, member);
1507                 methodSetAdd(env, allMethods, member);
1508                 ////////////////////////////////////////////////////////////
1509             }
1510         }
1511 
1512         // We're ready to start adding inherited methods.  First add
1513         // the methods from our superclass.
1514 
1515         //System.out.println("About to start superclasses for " + this);
1516 
1517         ClassDeclaration scDecl = getSuperClass(env);
1518         if (scDecl != null) {
1519             collectOneClass(env, scDecl,
1520                             myMethods, allMethods, mirandaMethods);
1521 
1522             // Make sure that we add all unimplementable methods from our
1523             // superclass to our list of unimplementable methods.
1524             ClassDefinition sc = scDecl.getClassDefinition();
1525             Iterator<MemberDefinition> supIter = sc.getPermanentlyAbstractMethods();
1526             while (supIter.hasNext()) {
1527                 permanentlyAbstractMethods.add(supIter.next());
1528             }
1529         }
1530 
1531         // Now we inherit all of the methods from our interfaces.
1532 
1533         //System.out.println("About to start interfaces for " + this);
1534 
1535         for (int i = 0; i < interfaces.length; i++) {
1536             collectOneClass(env, interfaces[i],
1537                             myMethods, allMethods, mirandaMethods);
1538         }
1539         allMethods.freeze();
1540 
1541         // Now we have collected all of our methods from our superclasses
1542         // and interfaces into our `allMethods' member.  Good.  As a last
1543         // task, we add our collected miranda methods to this class.
1544         //
1545         // If we do not add the mirandas to the class explicitly, there
1546         // will be no code generated for them.
1547         if (mirandaMethods != null && mirandaMethods.size() > 0) {
1548             addMirandaMethods(env, mirandaMethods.iterator());
1549         }
1550     }
1551 
1552     ////////////////////////////////////////////////////////////
1553     // PCJ 2003-07-30 added this utility method to insulate
1554     // MethodSet additions from the covariant return type
1555     // feature of the 1.5 compiler.  When there are multiple
1556     // methods with the same signature and different return
1557     // types to be added, we try to ensure that the one with
1558     // the most specific return type winds up in the MethodSet.
1559     // This logic was not put into MethodSet itself because it
1560     // requires access to an Environment for type relationship
1561     // checking.  No error checking is performed here, but that
1562     // should be OK because this code is only still used by
1563     // rmic.  See 4892308.
1564     ////////////////////////////////////////////////////////////
1565     private static void methodSetAdd(Environment env,
1566                                      MethodSet methodSet,
1567                                      MemberDefinition newMethod)
1568     {
1569         MemberDefinition oldMethod = methodSet.lookupSig(newMethod.getName(),
1570                                                          newMethod.getType());
1571         if (oldMethod != null) {
1572             Type oldReturnType = oldMethod.getType().getReturnType();
1573             Type newReturnType = newMethod.getType().getReturnType();
1574             try {
1575                 if (env.isMoreSpecific(newReturnType, oldReturnType)) {
1576                     methodSet.replace(newMethod);
1577                 }
1578             } catch (ClassNotFound ignore) {
1579             }
1580         } else {
1581             methodSet.add(newMethod);
1582         }
1583     }
1584     ////////////////////////////////////////////////////////////
1585 
1586     /**
1587      * Get an Iterator of all methods which could be accessed in an
1588      * instance of this class.
1589      */
1590     public Iterator<MemberDefinition> getMethods(Environment env) {
1591         if (allMethods == null) {
1592             collectInheritedMethods(env);
1593         }
1594         return getMethods();
1595     }
1596 
1597     /**
1598      * Get an Iterator of all methods which could be accessed in an
1599      * instance of this class.  Throw a compiler error if we haven't
1600      * generated this information yet.
1601      */
1602     public Iterator<MemberDefinition> getMethods() {
1603         if (allMethods == null) {
1604             throw new CompilerError("getMethods: too early");
1605         }
1606         return allMethods.iterator();
1607     }
1608 
1609     // In early VM's there was a bug -- the VM didn't walk the interfaces
1610     // of a class looking for a method, they only walked the superclass
1611     // chain.  This meant that abstract methods defined only in interfaces
1612     // were not being found.  To fix this bug, a counter-bug was introduced
1613     // in the compiler -- the so-called Miranda methods.  If a class
1614     // does not provide a definition for an abstract method in one of
1615     // its interfaces then the compiler inserts one in the class artificially.
1616     // That way the VM didn't have to bother looking at the interfaces.
1617     //
1618     // This is a problem.  Miranda methods are not part of the specification.
1619     // But they continue to be inserted so that old VM's can run new code.
1620     // Someday, when the old VM's are gone, perhaps classes can be compiled
1621     // without Miranda methods.  Towards this end, the compiler has a
1622     // flag, -nomiranda, which can turn off the creation of these methods.
1623     // Eventually that behavior should become the default.
1624     //
1625     // Why are they called Miranda methods?  Well the sentence "If the
1626     // class is not able to provide a method, then one will be provided
1627     // by the compiler" is very similar to the sentence "If you cannot
1628     // afford an attorney, one will be provided by the court," -- one
1629     // of the so-called "Miranda" rights in the United States.
1630 
1631     /**
1632      * Add a list of methods to this class as miranda methods.  This
1633      * gets overridden with a meaningful implementation in SourceClass.
1634      * BinaryClass should not need to do anything -- it should already
1635      * have its miranda methods and, if it doesn't, then that doesn't
1636      * affect our compilation.
1637      */
1638     protected void addMirandaMethods(Environment env,
1639                                      Iterator<MemberDefinition> mirandas) {
1640         // do nothing.
1641     }
1642 
1643     //---------------------------------------------------------------
1644 
1645     public void inlineLocalClass(Environment env) {
1646     }
1647 
1648     /**
1649      * We create a stub for this.  Source classes do more work.
1650      * Some calls from 'SourceClass.checkSupers' execute this method.
1651      * @see sun.tools.javac.SourceClass#resolveTypeStructure
1652      */
1653 
1654     public void resolveTypeStructure(Environment env) {
1655     }
1656 
1657     /**
1658      * Look up an inner class name, from somewhere inside this class.
1659      * Since supers and outers are in scope, search them too.
1660      * <p>
1661      * If no inner class is found, env.resolveName() is then called,
1662      * to interpret the ambient package and import directives.
1663      * <p>
1664      * This routine operates on a "best-efforts" basis.  If
1665      * at some point a class is not found, the partially-resolved
1666      * identifier is returned.  Eventually, someone else has to
1667      * try to get the ClassDefinition and diagnose the ClassNotFound.
1668      * <p>
1669      * resolveName() looks at surrounding scopes, and hence
1670      * pulling in both inherited and uplevel types.  By contrast,
1671      * resolveInnerClass() is intended only for interpreting
1672      * explicitly qualified names, and so look only at inherited
1673      * types.  Also, resolveName() looks for package prefixes,
1674      * which appear similar to "very uplevel" outer classes.
1675      * <p>
1676      * A similar (but more complex) name-lookup process happens
1677      * when field and identifier expressions denoting qualified names
1678      * are type-checked.  The added complexity comes from the fact
1679      * that variables may occur in such names, and take precedence
1680      * over class and package names.
1681      * <p>
1682      * In the expression type-checker, resolveInnerClass() is paralleled
1683      * by code in FieldExpression.checkAmbigName(), which also calls
1684      * ClassDefinition.getInnerClass() to interpret names of the form
1685      * "OuterClass.Inner" (and also outerObject.Inner).  The checking
1686      * of an identifier expression that fails to be a variable is referred
1687      * directly to resolveName().
1688      */
1689     public Identifier resolveName(Environment env, Identifier name) {
1690         if (tracing) env.dtEvent("ClassDefinition.resolveName: " + name);
1691         // This logic is pretty much exactly parallel to that of
1692         // Environment.resolveName().
1693         if (name.isQualified()) {
1694             // Try to resolve the first identifier component,
1695             // because inner class names take precedence over
1696             // package prefixes.  (Cf. Environment.resolveName.)
1697             Identifier rhead = resolveName(env, name.getHead());
1698 
1699             if (rhead.hasAmbigPrefix()) {
1700                 // The first identifier component refers to an
1701                 // ambiguous class.  Limp on.  We throw away the
1702                 // rest of the classname as it is irrelevant.
1703                 // (part of solution for 4059855).
1704                 return rhead;
1705             }
1706 
1707             if (!env.classExists(rhead)) {
1708                 return env.resolvePackageQualifiedName(name);
1709             }
1710             try {
1711                 return env.getClassDefinition(rhead).
1712                     resolveInnerClass(env, name.getTail());
1713             } catch (ClassNotFound ee) {
1714                 // return partially-resolved name someone else can fail on
1715                 return Identifier.lookupInner(rhead, name.getTail());
1716             }
1717         }
1718 
1719         // This method used to fail to look for local classes, thus a
1720         // reference to a local class within, e.g., the type of a member
1721         // declaration, would fail to resolve if the immediately enclosing
1722         // context was an inner class.  The code added below is ugly, but
1723         // it works, and is lifted from existing code in 'Context.resolveName'
1724         // and 'Context.getClassCommon'. See the comments there about the design.
1725         // Fixes 4095716.
1726 
1727         int ls = -2;
1728         LocalMember lf = null;
1729         if (classContext != null) {
1730             lf = classContext.getLocalClass(name);
1731             if (lf != null) {
1732                 ls = lf.getScopeNumber();
1733             }
1734         }
1735 
1736         // Look for an unqualified name in enclosing scopes.
1737         for (ClassDefinition c = this; c != null; c = c.outerClass) {
1738             try {
1739                 MemberDefinition f = c.getInnerClass(env, name);
1740                 if (f != null &&
1741                     (lf == null || classContext.getScopeNumber(c) > ls)) {
1742                     // An uplevel member was found, and was nested more deeply than
1743                     // any enclosing local of the same name.
1744                     return f.getInnerClass().getName();
1745                 }
1746             } catch (ClassNotFound ee) {
1747                 // a missing superclass, or something catastrophic
1748             }
1749         }
1750 
1751         // No uplevel member found, so use the enclosing local if one was found.
1752         if (lf != null) {
1753            return lf.getInnerClass().getName();
1754         }
1755 
1756         // look in imports, etc.
1757         return env.resolveName(name);
1758     }
1759 
1760     /**
1761      * Interpret a qualified class name, which may have further subcomponents..
1762      * Follow inheritance links, as in:
1763      *  class C { class N { } }  class D extends C { }  ... new D.N() ...
1764      * Ignore outer scopes and packages.
1765      * @see resolveName
1766      */
1767     public Identifier resolveInnerClass(Environment env, Identifier nm) {
1768         if (nm.isInner())  throw new CompilerError("inner");
1769         if (nm.isQualified()) {
1770             Identifier rhead = resolveInnerClass(env, nm.getHead());
1771             try {
1772                 return env.getClassDefinition(rhead).
1773                     resolveInnerClass(env, nm.getTail());
1774             } catch (ClassNotFound ee) {
1775                 // return partially-resolved name someone else can fail on
1776                 return Identifier.lookupInner(rhead, nm.getTail());
1777             }
1778         } else {
1779             try {
1780                 MemberDefinition f = getInnerClass(env, nm);
1781                 if (f != null) {
1782                     return f.getInnerClass().getName();
1783                 }
1784             } catch (ClassNotFound ee) {
1785                 // a missing superclass, or something catastrophic
1786             }
1787             // Fake a good name for a diagnostic.
1788             return Identifier.lookupInner(this.getName(), nm);
1789         }
1790     }
1791 
1792     /**
1793      * While resolving import directives, the question has arisen:
1794      * does a given inner class exist?  If the top-level class exists,
1795      * we ask it about an inner class via this method.
1796      * This method looks only at the literal name of the class,
1797      * and does not attempt to follow inheritance links.
1798      * This is necessary, since at the time imports are being
1799      * processed, inheritance links have not been resolved yet.
1800      * (Thus, an import directive must always spell a class
1801      * name exactly.)
1802      */
1803     public boolean innerClassExists(Identifier nm) {
1804         for (MemberDefinition field = getFirstMatch(nm.getHead()) ; field != null ; field = field.getNextMatch()) {
1805             if (field.isInnerClass()) {
1806                 if (field.getInnerClass().isLocal()) {
1807                     continue;   // ignore this name; it is internally generated
1808                 }
1809                 return !nm.isQualified() ||
1810                     field.getInnerClass().innerClassExists(nm.getTail());
1811             }
1812         }
1813         return false;
1814     }
1815 
1816    /**
1817      * Find any method with a given name.
1818      */
1819     public MemberDefinition findAnyMethod(Environment env, Identifier nm) throws ClassNotFound {
1820         MemberDefinition f;
1821         for (f = getFirstMatch(nm) ; f != null ; f = f.getNextMatch()) {
1822             if (f.isMethod()) {
1823                 return f;
1824             }
1825         }
1826 
1827         // look in the super class
1828         ClassDeclaration sup = getSuperClass();
1829         if (sup == null)
1830             return null;
1831         return sup.getClassDefinition(env).findAnyMethod(env, nm);
1832     }
1833 
1834     /**
1835       * Given the fact that this class has no method "nm" matching "argTypes",
1836       * find out if the mismatch can be blamed on a particular actual argument
1837       * which disagrees with all of the overloadings.
1838       * If so, return the code (i<<2)+(castOK<<1)+ambig, where
1839       * "i" is the number of the offending argument, and
1840       * "castOK" is 1 if a cast could fix the problem.
1841       * The target type for the argument is returned in margTypeResult[0].
1842       * If not all methods agree on this type, "ambig" is 1.
1843       * If there is more than one method, the choice of target type is
1844       * arbitrary.<p>
1845       * Return -1 if every argument is acceptable to at least one method.
1846       * Return -2 if there are no methods of the required arity.
1847       * The value "start" gives the index of the first argument to begin
1848       * checking.
1849       */
1850     public int diagnoseMismatch(Environment env, Identifier nm, Type argTypes[],
1851                                 int start, Type margTypeResult[]) throws ClassNotFound {
1852         int haveMatch[] = new int[argTypes.length];
1853         Type margType[] = new Type[argTypes.length];
1854         if (!diagnoseMismatch(env, nm, argTypes, start, haveMatch, margType))
1855             return -2;
1856         for (int i = start; i < argTypes.length; i++) {
1857             if (haveMatch[i] < 4) {
1858                 margTypeResult[0] = margType[i];
1859                 return (i<<2) | haveMatch[i];
1860             }
1861         }
1862         return -1;
1863     }
1864 
1865     private boolean diagnoseMismatch(Environment env, Identifier nm, Type argTypes[], int start,
1866                                      int haveMatch[], Type margType[]) throws ClassNotFound {
1867         // look in the current class
1868         boolean haveOne = false;
1869         MemberDefinition f;
1870         for (f = getFirstMatch(nm) ; f != null ; f = f.getNextMatch()) {
1871             if (!f.isMethod()) {
1872                 continue;
1873             }
1874             Type fArgTypes[] = f.getType().getArgumentTypes();
1875             if (fArgTypes.length == argTypes.length) {
1876                 haveOne = true;
1877                 for (int i = start; i < argTypes.length; i++) {
1878                     Type at = argTypes[i];
1879                     Type ft = fArgTypes[i];
1880                     if (env.implicitCast(at, ft)) {
1881                         haveMatch[i] = 4;
1882                         continue;
1883                     } else if (haveMatch[i] <= 2 && env.explicitCast(at, ft)) {
1884                         if (haveMatch[i] < 2)  margType[i] = null;
1885                         haveMatch[i] = 2;
1886                     } else if (haveMatch[i] > 0) {
1887                         continue;
1888                     }
1889                     if (margType[i] == null)
1890                         margType[i] = ft;
1891                     else if (margType[i] != ft)
1892                         haveMatch[i] |= 1;
1893                 }
1894             }
1895         }
1896 
1897         // constructors are not inherited
1898         if (nm.equals(idInit)) {
1899             return haveOne;
1900         }
1901 
1902         // look in the super class
1903         ClassDeclaration sup = getSuperClass();
1904         if (sup != null) {
1905             if (sup.getClassDefinition(env).diagnoseMismatch(env, nm, argTypes, start,
1906                                                              haveMatch, margType))
1907                 haveOne = true;
1908         }
1909         return haveOne;
1910     }
1911 
1912     /**
1913      * Add a field (no checks)
1914      */
1915     public void addMember(MemberDefinition field) {
1916         //System.out.println("ADD = " + field);
1917         if (firstMember == null) {
1918             firstMember = lastMember = field;
1919         } else if (field.isSynthetic() && field.isFinal()
1920                                        && field.isVariable()) {
1921             // insert this at the front, because of initialization order
1922             field.nextMember = firstMember;
1923             firstMember = field;
1924             field.nextMatch = fieldHash.get(field.name);
1925         } else {
1926             lastMember.nextMember = field;
1927             lastMember = field;
1928             field.nextMatch = fieldHash.get(field.name);
1929         }
1930         fieldHash.put(field.name, field);
1931     }
1932 
1933     /**
1934      * Add a field (subclasses make checks)
1935      */
1936     public void addMember(Environment env, MemberDefinition field) {
1937         addMember(field);
1938         if (resolved) {
1939             // a late addition
1940             field.resolveTypeStructure(env);
1941         }
1942     }
1943 
1944     /**
1945      * Find or create an uplevel reference for the given target.
1946      */
1947     public UplevelReference getReference(LocalMember target) {
1948         for (UplevelReference r = references; r != null; r = r.getNext()) {
1949             if (r.getTarget() == target) {
1950                 return r;
1951             }
1952         }
1953         return addReference(target);
1954     }
1955 
1956     protected UplevelReference addReference(LocalMember target) {
1957         if (target.getClassDefinition() == this) {
1958             throw new CompilerError("addReference "+target);
1959         }
1960         referencesMustNotBeFrozen();
1961         UplevelReference r = new UplevelReference(this, target);
1962         references = r.insertInto(references);
1963         return r;
1964     }
1965 
1966     /**
1967      * Return the list of all uplevel references.
1968      */
1969     public UplevelReference getReferences() {
1970         return references;
1971     }
1972 
1973     /**
1974      * Return the same value as getReferences.
1975      * Also, mark the set of references frozen.
1976      * After that, it is an error to add new references.
1977      */
1978     public UplevelReference getReferencesFrozen() {
1979         referencesFrozen = true;
1980         return references;
1981     }
1982 
1983     /**
1984      * assertion check
1985      */
1986     public final void referencesMustNotBeFrozen() {
1987         if (referencesFrozen) {
1988             throw new CompilerError("referencesMustNotBeFrozen "+this);
1989         }
1990     }
1991 
1992     /**
1993      * Get helper method for class literal lookup.
1994      */
1995     public MemberDefinition getClassLiteralLookup(long fwhere) {
1996         throw new CompilerError("binary class");
1997     }
1998 
1999     /**
2000      * Add a dependency
2001      */
2002     public void addDependency(ClassDeclaration c) {
2003         throw new CompilerError("addDependency");
2004     }
2005 
2006     /**
2007      * Maintain a hash table of local and anonymous classes
2008      * whose internal names are prefixed by the current class.
2009      * The key is the simple internal name, less the prefix.
2010      */
2011 
2012     public ClassDefinition getLocalClass(String name) {
2013         if (localClasses == null) {
2014             return null;
2015         } else {
2016             return localClasses.get(name);
2017         }
2018     }
2019 
2020     public void addLocalClass(ClassDefinition c, String name) {
2021         if (localClasses == null) {
2022             localClasses = new Hashtable<>(LOCAL_CLASSES_SIZE);
2023         }
2024         localClasses.put(name, c);
2025     }
2026 
2027 
2028     /**
2029      * Print for debugging
2030      */
2031     public void print(PrintStream out) {
2032         if (isPublic()) {
2033             out.print("public ");
2034         }
2035         if (isInterface()) {
2036             out.print("interface ");
2037         } else {
2038             out.print("class ");
2039         }
2040         out.print(getName() + " ");
2041         if (getSuperClass() != null) {
2042             out.print("extends " + getSuperClass().getName() + " ");
2043         }
2044         if (interfaces.length > 0) {
2045             out.print("implements ");
2046             for (int i = 0 ; i < interfaces.length ; i++) {
2047                 if (i > 0) {
2048                     out.print(", ");
2049                 }
2050                 out.print(interfaces[i].getName());
2051                 out.print(" ");
2052             }
2053         }
2054         out.println("{");
2055 
2056         for (MemberDefinition f = getFirstMember() ; f != null ; f = f.getNextMember()) {
2057             out.print("    ");
2058             f.print(out);
2059         }
2060 
2061         out.println("}");
2062     }
2063 
2064     /**
2065      * Convert to String
2066      */
2067     public String toString() {
2068         return getClassDeclaration().toString();
2069     }
2070 
2071     /**
2072      * After the class has been written to disk, try to free up
2073      * some storage.
2074      */
2075     public void cleanup(Environment env) {
2076         if (env.dump()) {
2077             env.output("[cleanup " + getName() + "]");
2078         }
2079         for (MemberDefinition f = getFirstMember() ; f != null ; f = f.getNextMember()) {
2080             f.cleanup(env);
2081         }
2082         // keep "references" around, for the sake of local subclasses
2083         documentation = null;
2084     }
2085 }