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. getClassContext()87 public Context getClassContext() { 88 return classContext; 89 } 90 91 92 /** 93 * Constructor 94 */ ClassDefinition(Object source, long where, ClassDeclaration declaration, int modifiers, IdentifierToken superClass, IdentifierToken interfaces[])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 */ getSource()108 public final Object getSource() { 109 return source; 110 } 111 112 /** 113 * Check if there were any errors in this class. 114 */ getError()115 public final boolean getError() { 116 return error; 117 } 118 119 /** 120 * Mark this class to be erroneous. 121 */ setError()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 */ getNestError()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 */ setNestError()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 */ getWhere()161 public final long getWhere() { 162 return where; 163 } 164 165 /** 166 * Get the class declaration 167 */ getClassDeclaration()168 public final ClassDeclaration getClassDeclaration() { 169 return declaration; 170 } 171 172 /** 173 * Get the class' modifiers 174 */ getModifiers()175 public final int getModifiers() { 176 return modifiers; 177 } subModifiers(int mod)178 public final void subModifiers(int mod) { 179 modifiers &= ~mod; 180 } addModifiers(int mod)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 */ getSuperClass()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 getSuperClass(Environment env)220 public ClassDeclaration getSuperClass(Environment env) { 221 return getSuperClass(); 222 } 223 224 /** 225 * Get the class' interfaces 226 */ getInterfaces()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 */ getOuterClass()235 public final ClassDefinition getOuterClass() { 236 return outerClass; 237 } 238 239 /** 240 * Set the class' enclosing class. Must be done at most once. 241 */ setOuterClass(ClassDefinition outerClass)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 */ setOuterMember(MemberDefinition outerMember)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 {@code !isTopLevel()}. 263 */ isInnerClass()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 */ isMember()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 */ isTopLevel()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 isInsideLocal()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 */ isInsideLocalOrAnonymous()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 */ getLocalName()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 */ setLocalName(Identifier name)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 */ getInnerClassMember()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 */ findOuterMember()354 public final MemberDefinition findOuterMember() { 355 return outerMember; 356 } 357 358 /** 359 * See if this is a (nested) static class. 360 */ isStatic()361 public final boolean isStatic() { 362 return (modifiers & ACC_STATIC) != 0; 363 } 364 365 /** 366 * Get the class' top-level enclosing class 367 */ getTopClass()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 */ getFirstMember()378 public final MemberDefinition getFirstMember() { 379 return firstMember; 380 } getFirstMatch(Identifier name)381 public final MemberDefinition getFirstMatch(Identifier name) { 382 return fieldHash.get(name); 383 } 384 385 /** 386 * Get the class' name 387 */ getName()388 public final Identifier getName() { 389 return declaration.getName(); 390 } 391 392 /** 393 * Get the class' type 394 */ getType()395 public final Type getType() { 396 return declaration.getType(); 397 } 398 399 /** 400 * Get the class' documentation 401 */ getDocumentation()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 */ containsDeprecated(String documentation)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 inSamePackage(ClassDeclaration c)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 inSamePackage(ClassDefinition c)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 inSamePackage(Identifier packageName)455 public final boolean inSamePackage(Identifier packageName) { 456 return (getName().getQualifier().equals(packageName)); 457 } 458 459 /** 460 * Checks 461 */ isInterface()462 public final boolean isInterface() { 463 return (getModifiers() & M_INTERFACE) != 0; 464 } isClass()465 public final boolean isClass() { 466 return (getModifiers() & M_INTERFACE) == 0; 467 } isPublic()468 public final boolean isPublic() { 469 return (getModifiers() & M_PUBLIC) != 0; 470 } isPrivate()471 public final boolean isPrivate() { 472 return (getModifiers() & M_PRIVATE) != 0; 473 } isProtected()474 public final boolean isProtected() { 475 return (getModifiers() & M_PROTECTED) != 0; 476 } isPackagePrivate()477 public final boolean isPackagePrivate() { 478 return (modifiers & (M_PUBLIC | M_PRIVATE | M_PROTECTED)) == 0; 479 } isFinal()480 public final boolean isFinal() { 481 return (getModifiers() & M_FINAL) != 0; 482 } isAbstract()483 public final boolean isAbstract() { 484 return (getModifiers() & M_ABSTRACT) != 0; 485 } isSynthetic()486 public final boolean isSynthetic() { 487 return (getModifiers() & M_SYNTHETIC) != 0; 488 } isDeprecated()489 public final boolean isDeprecated() { 490 return (getModifiers() & M_DEPRECATED) != 0; 491 } isAnonymous()492 public final boolean isAnonymous() { 493 return (getModifiers() & M_ANONYMOUS) != 0; 494 } isLocal()495 public final boolean isLocal() { 496 return (getModifiers() & M_LOCAL) != 0; 497 } hasConstructor()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 */ mustBeAbstract(Environment env)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 */ superClassOf(Environment env, ClassDeclaration otherClass)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 */ enclosingClassOf(ClassDefinition otherClass)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 */ subClassOf(Environment env, ClassDeclaration otherClass)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 */ implementedBy(Environment env, ClassDeclaration c)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 */ couldImplement(ClassDefinition intDef)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 */ 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 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 {@code ref}. 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<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 */ 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<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 */ getPermanentlyAbstractMethods()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 */ 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<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 */ 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<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 //////////////////////////////////////////////////////////// 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<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 */ getMethods()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 */ addMirandaMethods(Environment env, Iterator<MemberDefinition> mirandas)1638 protected void addMirandaMethods(Environment env, 1639 Iterator<MemberDefinition> 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 = 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 */ 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 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