1 /* 2 * Copyright (c) 1994, 2006, 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 public 45 class ClassDefinition implements Constants { 46 47 protected Object source; 48 protected long where; 49 protected int modifiers; 50 protected Identifier localName; // for local classes 51 protected ClassDeclaration declaration; 52 protected IdentifierToken superClassId; 53 protected IdentifierToken interfaceIds[]; 54 protected ClassDeclaration superClass; 55 protected ClassDeclaration interfaces[]; 56 protected ClassDefinition outerClass; 57 protected MemberDefinition outerMember; 58 protected MemberDefinition innerClassMember; // field for me in outerClass 59 protected MemberDefinition firstMember; 60 protected MemberDefinition lastMember; 61 protected boolean resolved; 62 protected String documentation; 63 protected boolean error; 64 protected boolean nestError; 65 protected UplevelReference references; 66 protected boolean referencesFrozen; 67 private Hashtable fieldHash = new Hashtable(31); 68 private int abstr; 69 70 // Table of local and anonymous classes whose internal names are constructed 71 // using the current class as a prefix. This is part of a fix for 72 // bugid 4054523 and 4030421. See also 'Environment.getClassDefinition' 73 // and 'BatchEnvironment.makeClassDefinition'. Allocated on demand. 74 private Hashtable localClasses = null; 75 private final int LOCAL_CLASSES_SIZE = 31; 76 77 // The immediately surrounding context in which the class appears. 78 // Set at the beginning of checking, upon entry to 'SourceClass.checkInternal'. 79 // Null for classes that are not local or inside a local class. 80 // At present, this field exists only for the benefit of 'resolveName' as part 81 // of the fix for 4095716. 82 protected Context classContext; 83 84 // The saved class context is now also used in 'SourceClass.getAccessMember'. 85 // Provide read-only access via this method. Part of fix for 4098093. getClassContext()86 public Context getClassContext() { 87 return classContext; 88 } 89 90 91 /** 92 * Constructor 93 */ ClassDefinition(Object source, long where, ClassDeclaration declaration, int modifiers, IdentifierToken superClass, IdentifierToken interfaces[])94 protected ClassDefinition(Object source, long where, ClassDeclaration declaration, 95 int modifiers, IdentifierToken superClass, IdentifierToken interfaces[]) { 96 this.source = source; 97 this.where = where; 98 this.declaration = declaration; 99 this.modifiers = modifiers; 100 this.superClassId = superClass; 101 this.interfaceIds = interfaces; 102 } 103 104 /** 105 * Get the source of the class 106 */ getSource()107 public final Object getSource() { 108 return source; 109 } 110 111 /** 112 * Check if there were any errors in this class. 113 */ getError()114 public final boolean getError() { 115 return error; 116 } 117 118 /** 119 * Mark this class to be erroneous. 120 */ setError()121 public final void setError() { 122 this.error = true; 123 setNestError(); 124 } 125 126 /** 127 * Check if there were any errors in our class nest. 128 */ getNestError()129 public final boolean getNestError() { 130 // Check to see if our error value is set, or if any of our 131 // outer classes' error values are set. This will work in 132 // conjunction with setError(), which sets the error value 133 // of its outer class, to yield true is any of our nest 134 // siblings has an error. This addresses bug 4111488: either 135 // code should be generated for all classes in a nest, or 136 // none of them. 137 return nestError || ((outerClass != null) ? outerClass.getNestError() : false); 138 } 139 140 /** 141 * Mark this class, and all siblings in its class nest, to be 142 * erroneous. 143 */ setNestError()144 public final void setNestError() { 145 this.nestError = true; 146 if (outerClass != null) { 147 // If we have an outer class, set it to be erroneous as well. 148 // This will work in conjunction with getError(), which checks 149 // the error value of its outer class, to set the whole class 150 // nest to be erroneous. This address bug 4111488: either 151 // code should be generated for all classes in a nest, or 152 // none of them. 153 outerClass.setNestError(); 154 } 155 } 156 157 /** 158 * Get the position in the input 159 */ getWhere()160 public final long getWhere() { 161 return where; 162 } 163 164 /** 165 * Get the class declaration 166 */ getClassDeclaration()167 public final ClassDeclaration getClassDeclaration() { 168 return declaration; 169 } 170 171 /** 172 * Get the class' modifiers 173 */ getModifiers()174 public final int getModifiers() { 175 return modifiers; 176 } subModifiers(int mod)177 public final void subModifiers(int mod) { 178 modifiers &= ~mod; 179 } addModifiers(int mod)180 public final void addModifiers(int mod) { 181 modifiers |= mod; 182 } 183 184 // *** DEBUG *** 185 protected boolean supersCheckStarted = !(this instanceof sun.tools.javac.SourceClass); 186 187 /** 188 * Get the class' super class 189 */ getSuperClass()190 public final ClassDeclaration getSuperClass() { 191 /*--- 192 if (superClass == null && superClassId != null) 193 throw new CompilerError("getSuperClass "+superClassId); 194 // There are obscure cases where null is the right answer, 195 // in order to enable some error reporting later on. 196 // For example: class T extends T.N { class N { } } 197 ---*/ 198 199 // *** DEBUG *** 200 // This method should not be called if the superclass has not been resolved. 201 if (!supersCheckStarted) throw new CompilerError("unresolved super"); 202 203 return superClass; 204 } 205 206 /** 207 * Get the super class, and resolve names now if necessary. 208 * 209 * It is only possible to resolve names at this point if we are 210 * a source class. The provision of this method at this level 211 * in the class hierarchy is dubious, but see 'getInnerClass' below. 212 * All other calls to 'getSuperClass(env)' appear in 'SourceClass'. 213 * NOTE: An older definition of this method has been moved to 214 * 'SourceClass', where it overrides this one. 215 * 216 * @see #resolveTypeStructure 217 */ 218 getSuperClass(Environment env)219 public ClassDeclaration getSuperClass(Environment env) { 220 return getSuperClass(); 221 } 222 223 /** 224 * Get the class' interfaces 225 */ getInterfaces()226 public final ClassDeclaration getInterfaces()[] { 227 if (interfaces == null) throw new CompilerError("getInterfaces"); 228 return interfaces; 229 } 230 231 /** 232 * Get the class' enclosing class (or null if not inner) 233 */ getOuterClass()234 public final ClassDefinition getOuterClass() { 235 return outerClass; 236 } 237 238 /** 239 * Set the class' enclosing class. Must be done at most once. 240 */ setOuterClass(ClassDefinition outerClass)241 protected final void setOuterClass(ClassDefinition outerClass) { 242 if (this.outerClass != null) throw new CompilerError("setOuterClass"); 243 this.outerClass = outerClass; 244 } 245 246 /** 247 * Set the class' enclosing current instance pointer. 248 * Must be done at most once. 249 */ setOuterMember(MemberDefinition outerMember)250 protected final void setOuterMember(MemberDefinition outerMember) { 251 252 if (isStatic() || !isInnerClass()) throw new CompilerError("setOuterField"); 253 if (this.outerMember != null) throw new CompilerError("setOuterField"); 254 this.outerMember = outerMember; 255 } 256 257 /** 258 * Tell if the class is inner. 259 * This predicate also returns true for top-level nested types. 260 * To test for a true inner class as seen by the programmer, 261 * use <tt>!isTopLevel()</tt>. 262 */ isInnerClass()263 public final boolean isInnerClass() { 264 return outerClass != null; 265 } 266 267 /** 268 * Tell if the class is a member of another class. 269 * This is false for package members and for block-local classes. 270 */ isMember()271 public final boolean isMember() { 272 return outerClass != null && !isLocal(); 273 } 274 275 /** 276 * Tell if the class is "top-level", which is either a package member, 277 * or a static member of another top-level class. 278 */ isTopLevel()279 public final boolean isTopLevel() { 280 return outerClass == null || isStatic() || isInterface(); 281 } 282 283 /** 284 * Tell if the class is local or inside a local class, 285 * which means it cannot be mentioned outside of its file. 286 */ 287 288 // The comment above is true only because M_LOCAL is set 289 // whenever M_ANONYMOUS is. I think it is risky to assume that 290 // isAnonymous(x) => isLocal(x). 291 isInsideLocal()292 public final boolean isInsideLocal() { 293 return isLocal() || 294 (outerClass != null && outerClass.isInsideLocal()); 295 } 296 297 /** 298 * Tell if the class is local or or anonymous class, or inside 299 * such a class, which means it cannot be mentioned outside of 300 * its file. 301 */ isInsideLocalOrAnonymous()302 public final boolean isInsideLocalOrAnonymous() { 303 return isLocal() || isAnonymous () || 304 (outerClass != null && outerClass.isInsideLocalOrAnonymous()); 305 } 306 307 /** 308 * Return a simple identifier for this class (idNull if anonymous). 309 */ getLocalName()310 public Identifier getLocalName() { 311 if (localName != null) { 312 return localName; 313 } 314 // This is also the name of the innerClassMember, if any: 315 return getName().getFlatName().getName(); 316 } 317 318 /** 319 * Set the local name of a class. Must be a local class. 320 */ setLocalName(Identifier name)321 public void setLocalName(Identifier name) { 322 if (isLocal()) { 323 localName = name; 324 } 325 } 326 327 /** 328 * If inner, get the field for this class in the enclosing class 329 */ getInnerClassMember()330 public final MemberDefinition getInnerClassMember() { 331 if (outerClass == null) 332 return null; 333 if (innerClassMember == null) { 334 // We must find the field in the outer class. 335 Identifier nm = getName().getFlatName().getName(); 336 for (MemberDefinition field = outerClass.getFirstMatch(nm); 337 field != null; field = field.getNextMatch()) { 338 if (field.isInnerClass()) { 339 innerClassMember = field; 340 break; 341 } 342 } 343 if (innerClassMember == null) 344 throw new CompilerError("getInnerClassField"); 345 } 346 return innerClassMember; 347 } 348 349 /** 350 * If inner, return an innermost uplevel self pointer, if any exists. 351 * Otherwise, return null. 352 */ findOuterMember()353 public final MemberDefinition findOuterMember() { 354 return outerMember; 355 } 356 357 /** 358 * See if this is a (nested) static class. 359 */ isStatic()360 public final boolean isStatic() { 361 return (modifiers & ACC_STATIC) != 0; 362 } 363 364 /** 365 * Get the class' top-level enclosing class 366 */ getTopClass()367 public final ClassDefinition getTopClass() { 368 ClassDefinition p, q; 369 for (p = this; (q = p.outerClass) != null; p = q) 370 ; 371 return p; 372 } 373 374 /** 375 * Get the class' first field or first match 376 */ getFirstMember()377 public final MemberDefinition getFirstMember() { 378 return firstMember; 379 } getFirstMatch(Identifier name)380 public final MemberDefinition getFirstMatch(Identifier name) { 381 return (MemberDefinition)fieldHash.get(name); 382 } 383 384 /** 385 * Get the class' name 386 */ getName()387 public final Identifier getName() { 388 return declaration.getName(); 389 } 390 391 /** 392 * Get the class' type 393 */ getType()394 public final Type getType() { 395 return declaration.getType(); 396 } 397 398 /** 399 * Get the class' documentation 400 */ getDocumentation()401 public String getDocumentation() { 402 return documentation; 403 } 404 405 /** 406 * Return true if the given documentation string contains a deprecation 407 * paragraph. This is true if the string contains the tag @deprecated 408 * is the first word in a line. 409 */ containsDeprecated(String documentation)410 public static boolean containsDeprecated(String documentation) { 411 if (documentation == null) { 412 return false; 413 } 414 doScan: 415 for (int scan = 0; 416 (scan = documentation.indexOf(paraDeprecated, scan)) >= 0; 417 scan += paraDeprecated.length()) { 418 // make sure there is only whitespace between this word 419 // and the beginning of the line 420 for (int beg = scan-1; beg >= 0; beg--) { 421 char ch = documentation.charAt(beg); 422 if (ch == '\n' || ch == '\r') { 423 break; // OK 424 } 425 if (!Character.isSpace(ch)) { 426 continue doScan; 427 } 428 } 429 // make sure the char after the word is space or end of line 430 int end = scan+paraDeprecated.length(); 431 if (end < documentation.length()) { 432 char ch = documentation.charAt(end); 433 if (!(ch == '\n' || ch == '\r') && !Character.isSpace(ch)) { 434 continue doScan; 435 } 436 } 437 return true; 438 } 439 return false; 440 } 441 inSamePackage(ClassDeclaration c)442 public final boolean inSamePackage(ClassDeclaration c) { 443 // find out if the class stored in c is defined in the same 444 // package as the current class. 445 return inSamePackage(c.getName().getQualifier()); 446 } 447 inSamePackage(ClassDefinition c)448 public final boolean inSamePackage(ClassDefinition c) { 449 // find out if the class stored in c is defined in the same 450 // package as the current class. 451 return inSamePackage(c.getName().getQualifier()); 452 } 453 inSamePackage(Identifier packageName)454 public final boolean inSamePackage(Identifier packageName) { 455 return (getName().getQualifier().equals(packageName)); 456 } 457 458 /** 459 * Checks 460 */ isInterface()461 public final boolean isInterface() { 462 return (getModifiers() & M_INTERFACE) != 0; 463 } isClass()464 public final boolean isClass() { 465 return (getModifiers() & M_INTERFACE) == 0; 466 } isPublic()467 public final boolean isPublic() { 468 return (getModifiers() & M_PUBLIC) != 0; 469 } isPrivate()470 public final boolean isPrivate() { 471 return (getModifiers() & M_PRIVATE) != 0; 472 } isProtected()473 public final boolean isProtected() { 474 return (getModifiers() & M_PROTECTED) != 0; 475 } isPackagePrivate()476 public final boolean isPackagePrivate() { 477 return (modifiers & (M_PUBLIC | M_PRIVATE | M_PROTECTED)) == 0; 478 } isFinal()479 public final boolean isFinal() { 480 return (getModifiers() & M_FINAL) != 0; 481 } isAbstract()482 public final boolean isAbstract() { 483 return (getModifiers() & M_ABSTRACT) != 0; 484 } isSynthetic()485 public final boolean isSynthetic() { 486 return (getModifiers() & M_SYNTHETIC) != 0; 487 } isDeprecated()488 public final boolean isDeprecated() { 489 return (getModifiers() & M_DEPRECATED) != 0; 490 } isAnonymous()491 public final boolean isAnonymous() { 492 return (getModifiers() & M_ANONYMOUS) != 0; 493 } isLocal()494 public final boolean isLocal() { 495 return (getModifiers() & M_LOCAL) != 0; 496 } hasConstructor()497 public final boolean hasConstructor() { 498 return getFirstMatch(idInit) != null; 499 } 500 501 502 /** 503 * Check to see if a class must be abstract. This method replaces 504 * isAbstract(env) 505 */ mustBeAbstract(Environment env)506 public final boolean mustBeAbstract(Environment env) { 507 // If it is declared abstract, return true. 508 // (Fix for 4110534.) 509 if (isAbstract()) { 510 return true; 511 } 512 513 // Check to see if the class should have been declared to be 514 // abstract. 515 516 // We make sure that the inherited method collection has been 517 // performed. 518 collectInheritedMethods(env); 519 520 // We check for any abstract methods inherited or declared 521 // by this class. 522 Iterator methods = getMethods(); 523 while (methods.hasNext()) { 524 MemberDefinition method = (MemberDefinition) methods.next(); 525 526 if (method.isAbstract()) { 527 return true; 528 } 529 } 530 531 // We check for hidden "permanently abstract" methods in 532 // our superclasses. 533 return getPermanentlyAbstractMethods().hasNext(); 534 } 535 536 /** 537 * Check if this is a super class of another class 538 */ superClassOf(Environment env, ClassDeclaration otherClass)539 public boolean superClassOf(Environment env, ClassDeclaration otherClass) 540 throws ClassNotFound { 541 while (otherClass != null) { 542 if (getClassDeclaration().equals(otherClass)) { 543 return true; 544 } 545 otherClass = otherClass.getClassDefinition(env).getSuperClass(); 546 } 547 return false; 548 } 549 550 /** 551 * Check if this is an enclosing class of another class 552 */ enclosingClassOf(ClassDefinition otherClass)553 public boolean enclosingClassOf(ClassDefinition otherClass) { 554 while ((otherClass = otherClass.getOuterClass()) != null) { 555 if (this == otherClass) { 556 return true; 557 } 558 } 559 return false; 560 } 561 562 /** 563 * Check if this is a sub class of another class 564 */ subClassOf(Environment env, ClassDeclaration otherClass)565 public boolean subClassOf(Environment env, ClassDeclaration otherClass) throws ClassNotFound { 566 ClassDeclaration c = getClassDeclaration(); 567 while (c != null) { 568 if (c.equals(otherClass)) { 569 return true; 570 } 571 c = c.getClassDefinition(env).getSuperClass(); 572 } 573 return false; 574 } 575 576 /** 577 * Check if this class is implemented by another class 578 */ implementedBy(Environment env, ClassDeclaration c)579 public boolean implementedBy(Environment env, ClassDeclaration c) throws ClassNotFound { 580 for (; c != null ; c = c.getClassDefinition(env).getSuperClass()) { 581 if (getClassDeclaration().equals(c)) { 582 return true; 583 } 584 ClassDeclaration intf[] = c.getClassDefinition(env).getInterfaces(); 585 for (int i = 0 ; i < intf.length ; i++) { 586 if (implementedBy(env, intf[i])) { 587 return true; 588 } 589 } 590 } 591 return false; 592 } 593 594 /** 595 * Check to see if a class which implements interface `this' could 596 * possibly implement the interface `intDef'. Note that the only 597 * way that this can fail is if `this' and `intDef' have methods 598 * which are of the same signature and different return types. This 599 * method is used by Environment.explicitCast() to determine if a 600 * cast between two interfaces is legal. 601 * 602 * This method should only be called on a class after it has been 603 * basicCheck()'ed. 604 */ couldImplement(ClassDefinition intDef)605 public boolean couldImplement(ClassDefinition intDef) { 606 // Check to see if we could have done the necessary checks. 607 if (!doInheritanceChecks) { 608 throw new CompilerError("couldImplement: no checks"); 609 } 610 611 // This method should only be called for interfaces. 612 if (!isInterface() || !intDef.isInterface()) { 613 throw new CompilerError("couldImplement: not interface"); 614 } 615 616 // Make sure we are not called before we have collected our 617 // inheritance information. 618 if (allMethods == null) { 619 throw new CompilerError("couldImplement: called early"); 620 } 621 622 // Get the other classes' methods. getMethods() in 623 // general can return methods which are not visible to the 624 // current package. We need to make sure that these do not 625 // prevent this class from being implemented. 626 Iterator otherMethods = intDef.getMethods(); 627 628 while (otherMethods.hasNext()) { 629 // Get one of the methods from intDef... 630 MemberDefinition method = 631 (MemberDefinition) 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 */ extendsCanAccess(Environment env, ClassDeclaration c)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 */ canAccess(Environment env, ClassDeclaration c)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 canAccess(Environment env, MemberDefinition f)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 */ permitInlinedAccess(Environment env, ClassDeclaration c)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 */ permitInlinedAccess(Environment env, MemberDefinition f)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 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 */ protectedAccess(Environment env, MemberDefinition f, Type accessorType)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 */ getAccessMember(Environment env, Context ctx, MemberDefinition field, boolean isSuper)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 */ getUpdateMember(Environment env, Context ctx, MemberDefinition field, boolean isSuper)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 */ getVariable(Environment env, Identifier nm, ClassDefinition source)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 */ getVariable0(Environment env, Identifier nm, ClassDefinition source, boolean showPrivate, boolean showPackage)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 */ reportDeprecated(Environment env)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 */ noteUsedBy(ClassDefinition ref, long where, Environment env)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 */ getInnerClass(Environment env, Identifier nm)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 */ matchMethod(Environment env, ClassDefinition accessor, Identifier methodName, Type[] argumentTypes, boolean isAnonConstCall, Identifier accessPackage)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 candidateList = null; 1000 1001 // Get all the methods inherited by this class which 1002 // have the name `methodName'. 1003 Iterator methods = allMethods.lookupName(methodName); 1004 1005 while (methods.hasNext()) { 1006 MemberDefinition method = (MemberDefinition)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 candidates = candidateList.iterator(); 1061 while (candidates.hasNext()) { 1062 MemberDefinition method = (MemberDefinition)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 */ matchMethod(Environment env, ClassDefinition accessor, Identifier methodName, Type[] argumentTypes)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 */ matchMethod(Environment env, ClassDefinition accessor, Identifier methodName)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 */ matchAnonConstructor(Environment env, Identifier accessPackage, Type argumentTypes[])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 */ findMethod(Environment env, Identifier nm, Type t)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. basicCheck(Environment env)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 */ check(Environment env)1163 public void check(Environment env) throws ClassNotFound { 1164 } 1165 checkLocalClass(Environment env, Context ctx, Vset vset, ClassDefinition sup, Expression args[], Type argTypes[] )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 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 */ getPermanentlyAbstractMethods()1195 protected Iterator 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 */ turnOffInheritanceChecks()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 */ collectOneClass(Environment env, ClassDeclaration parent, MethodSet myMethods, MethodSet allMethods, MethodSet mirandaMethods)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 methods = pClass.getMethods(env); 1243 while (methods.hasNext()) { 1244 MemberDefinition method = 1245 (MemberDefinition) 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 */ collectInheritedMethods(Environment env)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 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 //////////////////////////////////////////////////////////// methodSetAdd(Environment env, MethodSet methodSet, MemberDefinition newMethod)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 */ getMethods(Environment env)1590 public Iterator 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 */ getMethods()1602 public Iterator 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 */ addMirandaMethods(Environment env, Iterator mirandas)1638 protected void addMirandaMethods(Environment env, 1639 Iterator mirandas) { 1640 // do nothing. 1641 } 1642 1643 //--------------------------------------------------------------- 1644 inlineLocalClass(Environment env)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 resolveTypeStructure(Environment env)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 */ resolveName(Environment env, Identifier name)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 */ resolveInnerClass(Environment env, Identifier nm)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 */ innerClassExists(Identifier nm)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 */ findAnyMethod(Environment env, Identifier nm)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 */ diagnoseMismatch(Environment env, Identifier nm, Type argTypes[], int start, Type margTypeResult[])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 diagnoseMismatch(Environment env, Identifier nm, Type argTypes[], int start, int haveMatch[], Type margType[])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 */ addMember(MemberDefinition field)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 = (MemberDefinition)fieldHash.get(field.name); 1925 } else { 1926 lastMember.nextMember = field; 1927 lastMember = field; 1928 field.nextMatch = (MemberDefinition)fieldHash.get(field.name); 1929 } 1930 fieldHash.put(field.name, field); 1931 } 1932 1933 /** 1934 * Add a field (subclasses make checks) 1935 */ addMember(Environment env, MemberDefinition field)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 */ getReference(LocalMember target)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 addReference(LocalMember target)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 */ getReferences()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 */ getReferencesFrozen()1978 public UplevelReference getReferencesFrozen() { 1979 referencesFrozen = true; 1980 return references; 1981 } 1982 1983 /** 1984 * assertion check 1985 */ referencesMustNotBeFrozen()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 */ getClassLiteralLookup(long fwhere)1995 public MemberDefinition getClassLiteralLookup(long fwhere) { 1996 throw new CompilerError("binary class"); 1997 } 1998 1999 /** 2000 * Add a dependency 2001 */ addDependency(ClassDeclaration c)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 getLocalClass(String name)2012 public ClassDefinition getLocalClass(String name) { 2013 if (localClasses == null) { 2014 return null; 2015 } else { 2016 return (ClassDefinition)localClasses.get(name); 2017 } 2018 } 2019 addLocalClass(ClassDefinition c, String name)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 */ print(PrintStream out)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 */ toString()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 */ cleanup(Environment env)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 } 2086