blob: 714b25126a8c4101e3ad73490ab07599a59099f3 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1994-2006 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package sun.tools.java;
27
28import java.util.*;
29import java.io.OutputStream;
30import java.io.PrintStream;
31import sun.tools.tree.Context;
32import sun.tools.tree.Vset;
33import sun.tools.tree.Expression;
34import sun.tools.tree.LocalMember;
35import 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 */
44public
45class 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.
86 public Context getClassContext() {
87 return classContext;
88 }
89
90
91 /**
92 * Constructor
93 */
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 */
107 public final Object getSource() {
108 return source;
109 }
110
111 /**
112 * Check if there were any errors in this class.
113 */
114 public final boolean getError() {
115 return error;
116 }
117
118 /**
119 * Mark this class to be erroneous.
120 */
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 */
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 */
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 */
160 public final long getWhere() {
161 return where;
162 }
163
164 /**
165 * Get the class declaration
166 */
167 public final ClassDeclaration getClassDeclaration() {
168 return declaration;
169 }
170
171 /**
172 * Get the class' modifiers
173 */
174 public final int getModifiers() {
175 return modifiers;
176 }
177 public final void subModifiers(int mod) {
178 modifiers &= ~mod;
179 }
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 */
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
219 public ClassDeclaration getSuperClass(Environment env) {
220 return getSuperClass();
221 }
222
223 /**
224 * Get the class' interfaces
225 */
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 */
234 public final ClassDefinition getOuterClass() {
235 return outerClass;
236 }
237
238 /**
239 * Set the class' enclosing class. Must be done at most once.
240 */
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 */
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 */
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 */
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 */
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
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 */
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 */
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 */
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 */
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 */
353 public final MemberDefinition findOuterMember() {
354 return outerMember;
355 }
356
357 /**
358 * See if this is a (nested) static class.
359 */
360 public final boolean isStatic() {
361 return (modifiers & ACC_STATIC) != 0;
362 }
363
364 /**
365 * Get the class' top-level enclosing class
366 */
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 */
377 public final MemberDefinition getFirstMember() {
378 return firstMember;
379 }
380 public final MemberDefinition getFirstMatch(Identifier name) {
381 return (MemberDefinition)fieldHash.get(name);
382 }
383
384 /**
385 * Get the class' name
386 */
387 public final Identifier getName() {
388 return declaration.getName();
389 }
390
391 /**
392 * Get the class' type
393 */
394 public final Type getType() {
395 return declaration.getType();
396 }
397
398 /**
399 * Get the class' documentation
400 */
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 */
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
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
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
454 public final boolean inSamePackage(Identifier packageName) {
455 return (getName().getQualifier().equals(packageName));
456 }
457
458 /**
459 * Checks
460 */
461 public final boolean isInterface() {
462 return (getModifiers() & M_INTERFACE) != 0;
463 }
464 public final boolean isClass() {
465 return (getModifiers() & M_INTERFACE) == 0;
466 }
467 public final boolean isPublic() {
468 return (getModifiers() & M_PUBLIC) != 0;
469 }
470 public final boolean isPrivate() {
471 return (getModifiers() & M_PRIVATE) != 0;
472 }
473 public final boolean isProtected() {
474 return (getModifiers() & M_PROTECTED) != 0;
475 }
476 public final boolean isPackagePrivate() {
477 return (modifiers & (M_PUBLIC | M_PRIVATE | M_PROTECTED)) == 0;
478 }
479 public final boolean isFinal() {
480 return (getModifiers() & M_FINAL) != 0;
481 }
482 public final boolean isAbstract() {
483 return (getModifiers() & M_ABSTRACT) != 0;
484 }
485 public final boolean isSynthetic() {
486 return (getModifiers() & M_SYNTHETIC) != 0;
487 }
488 public final boolean isDeprecated() {
489 return (getModifiers() & M_DEPRECATED) != 0;
490 }
491 public final boolean isAnonymous() {
492 return (getModifiers() & M_ANONYMOUS) != 0;
493 }
494 public final boolean isLocal() {
495 return (getModifiers() & M_LOCAL) != 0;
496 }
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 */
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 */
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 */
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 */
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 */
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 */
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 */
657 public boolean extendsCanAccess(Environment env, ClassDeclaration c) throws ClassNotFound {
658
659 // Names in the 'extends' or 'implements' clause of an inner class
660 // are checked as if they appeared in the body of the surrounding class.
661 if (outerClass != null) {
662 return outerClass.canAccess(env, c);
663 }
664
665 // We are a package member.
666
667 ClassDefinition cdef = c.getClassDefinition(env);
668
669 if (cdef.isLocal()) {
670 // No locals should be in scope in the 'extends' or
671 // 'implements' clause of a package member.
672 throw new CompilerError("top local");
673 }
674
675 if (cdef.isInnerClass()) {
676 MemberDefinition f = cdef.getInnerClassMember();
677
678 // Access to public member is always allowed.
679 if (f.isPublic()) {
680 return true;
681 }
682
683 // Private access is ok only from the same class nest. This can
684 // happen only if the class represented by 'this' encloses the inner
685 // class represented by 'f'.
686 if (f.isPrivate()) {
687 return getClassDeclaration().equals(f.getTopClass().getClassDeclaration());
688 }
689
690 // Protected or default access -- allow access if in same package.
691 return getName().getQualifier().equals(f.getClassDeclaration().getName().getQualifier());
692 }
693
694 // Access to public member is always allowed.
695 if (cdef.isPublic()) {
696 return true;
697 }
698
699 // Default access -- allow access if in same package.
700 return getName().getQualifier().equals(c.getName().getQualifier());
701 }
702
703 /**
704 * Check if another class can be accessed from within the body of this class.
705 */
706 public boolean canAccess(Environment env, ClassDeclaration c) throws ClassNotFound {
707 ClassDefinition cdef = c.getClassDefinition(env);
708
709 if (cdef.isLocal()) {
710 // if it's in scope, it's accessible
711 return true;
712 }
713
714 if (cdef.isInnerClass()) {
715 return canAccess(env, cdef.getInnerClassMember());
716 }
717
718 // Public access is always ok
719 if (cdef.isPublic()) {
720 return true;
721 }
722
723 // It must be in the same package
724 return getName().getQualifier().equals(c.getName().getQualifier());
725 }
726
727 /**
728 * Check if a field can be accessed from a class
729 */
730
731 public boolean canAccess(Environment env, MemberDefinition f)
732 throws ClassNotFound {
733
734 // Public access is always ok
735 if (f.isPublic()) {
736 return true;
737 }
738 // Protected access is ok from a subclass
739 if (f.isProtected() && subClassOf(env, f.getClassDeclaration())) {
740 return true;
741 }
742 // Private access is ok only from the same class nest
743 if (f.isPrivate()) {
744 return getTopClass().getClassDeclaration()
745 .equals(f.getTopClass().getClassDeclaration());
746 }
747 // It must be in the same package
748 return getName().getQualifier().equals(f.getClassDeclaration().getName().getQualifier());
749 }
750
751 /**
752 * Check if a class is entitled to inline access to a class from
753 * another class.
754 */
755 public boolean permitInlinedAccess(Environment env, ClassDeclaration c)
756 throws ClassNotFound {
757
758 return (env.opt() && c.equals(declaration)) ||
759 (env.opt_interclass() && canAccess(env, c));
760 }
761
762 /**
763 * Check if a class is entitled to inline access to a method from
764 * another class.
765 */
766 public boolean permitInlinedAccess(Environment env, MemberDefinition f)
767 throws ClassNotFound {
768 return (env.opt()
769 && (f.clazz.getClassDeclaration().equals(declaration))) ||
770 (env.opt_interclass() && canAccess(env, f));
771 }
772
773 /**
774 * We know the the field is marked protected (and not public) and that
775 * the field is visible (as per canAccess). Can we access the field as
776 * <accessor>.<field>, where <accessor> has the type <accessorType>?
777 *
778 * Protected fields can only be accessed when the accessorType is a
779 * subclass of the current class
780 */
781 public boolean protectedAccess(Environment env, MemberDefinition f,
782 Type accessorType)
783 throws ClassNotFound
784 {
785
786 return
787 // static protected fields are accessible
788 f.isStatic()
789 || // allow array.clone()
790 (accessorType.isType(TC_ARRAY) && (f.getName() == idClone)
791 && (f.getType().getArgumentTypes().length == 0))
792 || // <accessorType> is a subtype of the current class
793 (accessorType.isType(TC_CLASS)
794 && env.getClassDefinition(accessorType.getClassName())
795 .subClassOf(env, getClassDeclaration()))
796 || // we are accessing the field from a friendly class (same package)
797 (getName().getQualifier()
798 .equals(f.getClassDeclaration().getName().getQualifier()));
799 }
800
801
802 /**
803 * Find or create an access method for a private member,
804 * or return null if this is not possible.
805 */
806 public MemberDefinition getAccessMember(Environment env, Context ctx,
807 MemberDefinition field, boolean isSuper) {
808 throw new CompilerError("binary getAccessMember");
809 }
810
811 /**
812 * Find or create an update method for a private member,
813 * or return null if this is not possible.
814 */
815 public MemberDefinition getUpdateMember(Environment env, Context ctx,
816 MemberDefinition field, boolean isSuper) {
817 throw new CompilerError("binary getUpdateMember");
818 }
819
820 /**
821 * Get a field from this class. Report ambiguous fields.
822 * If no accessible field is found, this method may return an
823 * inaccessible field to allow a useful error message.
824 *
825 * getVariable now takes the source class `source' as an argument.
826 * This allows getVariable to check whether a field is inaccessible
827 * before it signals that a field is ambiguous. The compiler used to
828 * signal an ambiguity even when one of the fields involved was not
829 * accessible. (bug 4053724)
830 */
831 public MemberDefinition getVariable(Environment env,
832 Identifier nm,
833 ClassDefinition source)
834 throws AmbiguousMember, ClassNotFound {
835
836 return getVariable0(env, nm, source, true, true);
837 }
838
839 /*
840 * private fields are never inherited. package-private fields are
841 * not inherited across package boundaries. To capture this, we
842 * take two booleans as parameters: showPrivate indicates whether
843 * we have passed a class boundary, and showPackage indicates whether
844 * we have crossed a package boundary.
845 */
846 private MemberDefinition getVariable0(Environment env,
847 Identifier nm,
848 ClassDefinition source,
849 boolean showPrivate,
850 boolean showPackage)
851 throws AmbiguousMember, ClassNotFound {
852
853 // Check to see if this field is defined in the current class
854 for (MemberDefinition member = getFirstMatch(nm);
855 member != null;
856 member = member.getNextMatch()) {
857 if (member.isVariable()) {
858 if ((showPrivate || !member.isPrivate()) &&
859 (showPackage || !member.isPackagePrivate())) {
860 // It is defined in this class.
861 return member;
862 } else {
863 // Even though this definition is not inherited,
864 // it hides all definitions in supertypes.
865 return null;
866 }
867 }
868 }
869
870 // Find the field in our superclass.
871 ClassDeclaration sup = getSuperClass();
872 MemberDefinition field = null;
873 if (sup != null) {
874 field =
875 sup.getClassDefinition(env)
876 .getVariable0(env, nm, source,
877 false,
878 showPackage && inSamePackage(sup));
879 }
880
881 // Find the field in our superinterfaces.
882 for (int i = 0 ; i < interfaces.length ; i++) {
883 // Try to look up the field in an interface. Since interfaces
884 // only have public fields, the values of the two boolean
885 // arguments are not important.
886 MemberDefinition field2 =
887 interfaces[i].getClassDefinition(env)
888 .getVariable0(env, nm, source, true, true);
889
890 if (field2 != null) {
891 // If we have two different, accessible fields, then
892 // we've found an ambiguity.
893 if (field != null &&
894 source.canAccess(env, field) &&
895 field2 != field) {
896
897 throw new AmbiguousMember(field2, field);
898 }
899 field = field2;
900 }
901 }
902 return field;
903 }
904
905 /**
906 * Tells whether to report a deprecation error for this class.
907 */
908 public boolean reportDeprecated(Environment env) {
909 return (isDeprecated()
910 || (outerClass != null && outerClass.reportDeprecated(env)));
911 }
912
913 /**
914 * Note that this class is being used somehow by <tt>ref</tt>.
915 * Report deprecation errors, etc.
916 */
917 public void noteUsedBy(ClassDefinition ref, long where, Environment env) {
918 // (Have this deal with canAccess() checks, too?)
919 if (reportDeprecated(env)) {
920 env.error(where, "warn.class.is.deprecated", this);
921 }
922 }
923
924 /**
925 * Get an inner class.
926 * Look in supers but not outers.
927 * (This is used directly to resolve expressions like "site.K", and
928 * inside a loop to resolve lone names like "K" or the "K" in "K.L".)
929 *
930 * Called from 'Context' and 'FieldExpression' as well as this class.
931 *
932 * @see FieldExpression.checkCommon
933 * @see resolveName
934 */
935 public MemberDefinition getInnerClass(Environment env, Identifier nm)
936 throws ClassNotFound {
937 // Note: AmbiguousClass will not be thrown unless and until
938 // inner classes can be defined inside interfaces.
939
940 // Check if it is defined in the current class
941 for (MemberDefinition field = getFirstMatch(nm);
942 field != null ; field = field.getNextMatch()) {
943 if (field.isInnerClass()) {
944 if (field.getInnerClass().isLocal()) {
945 continue; // ignore this name; it is internally generated
946 }
947 return field;
948 }
949 }
950
951 // Get it from the super class
952 // It is likely that 'getSuperClass()' could be made to work here
953 // but we would have to assure somehow that 'resolveTypeStructure'
954 // has been called on the current class nest. Since we can get
955 // here from 'resolveName', which is called from 'resolveSupers',
956 // it is possible that the first attempt to resolve the superclass
957 // will originate here, instead of in the call to 'getSuperClass'
958 // in 'checkSupers'. See 'resolveTypeStructure', in which a call
959 // to 'resolveSupers' precedes the call to 'checkSupers'. Why is
960 // name resolution done twice, first in 'resolveName'?
961 // NOTE: 'SourceMember.resolveTypeStructure' may initiate type
962 // structure resolution for an inner class. Normally, this
963 // occurs during the resolution of the outer class, but fields
964 // added after the resolution of their containing class will
965 // be resolved late -- see 'addMember(env,field)' below.
966 // This should only happen for synthetic members, which should
967 // never be an inner class.
968 ClassDeclaration sup = getSuperClass(env);
969 if (sup != null)
970 return sup.getClassDefinition(env).getInnerClass(env, nm);
971
972 return null;
973 }
974
975 /**
976 * Lookup a method. This code implements the method lookup
977 * mechanism specified in JLS 15.11.2.
978 *
979 * This mechanism cannot be used to lookup synthetic methods.
980 */
981 private MemberDefinition matchMethod(Environment env,
982 ClassDefinition accessor,
983 Identifier methodName,
984 Type[] argumentTypes,
985 boolean isAnonConstCall,
986 Identifier accessPackage)
987 throws AmbiguousMember, ClassNotFound {
988
989 if (allMethods == null || !allMethods.isFrozen()) {
990 // This may be too restrictive.
991 throw new CompilerError("matchMethod called early");
992 // collectInheritedMethods(env);
993 }
994
995 // A tentative maximally specific method.
996 MemberDefinition tentative = null;
997
998 // A list of other methods which may be maximally specific too.
999 List 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 */
1078 public MemberDefinition matchMethod(Environment env,
1079 ClassDefinition accessor,
1080 Identifier methodName,
1081 Type[] argumentTypes)
1082 throws AmbiguousMember, ClassNotFound {
1083
1084 return matchMethod(env, accessor, methodName,
1085 argumentTypes, false, null);
1086 }
1087
1088 /**
1089 * Lookup a method. This code implements the method lookup
1090 * mechanism specified in JLS 15.11.2.
1091 *
1092 * This mechanism cannot be used to lookup synthetic methods.
1093 */
1094 public MemberDefinition matchMethod(Environment env,
1095 ClassDefinition accessor,
1096 Identifier methodName)
1097 throws AmbiguousMember, ClassNotFound {
1098
1099 return matchMethod(env, accessor, methodName,
1100 Type.noArgs, false, null);
1101 }
1102
1103 /**
1104 * A version of matchMethod to be used only for constructors
1105 * when we cannot pass in a sourceClass argument. We just assert
1106 * our package name.
1107 *
1108 * This is used only for anonymous classes, where we have to look up
1109 * a (potentially) protected constructor with no valid sourceClass
1110 * parameter available.
1111 */
1112 public MemberDefinition matchAnonConstructor(Environment env,
1113 Identifier accessPackage,
1114 Type argumentTypes[])
1115 throws AmbiguousMember, ClassNotFound {
1116
1117 return matchMethod(env, null, idInit, argumentTypes,
1118 true, accessPackage);
1119 }
1120
1121 /**
1122 * Find a method, ie: exact match in this class or any of the super
1123 * classes.
1124 *
1125 * Only called by javadoc. For now I am holding off rewriting this
1126 * code to rely on collectInheritedMethods(), as that code has
1127 * not gotten along with javadoc in the past.
1128 */
1129 public MemberDefinition findMethod(Environment env, Identifier nm, Type t)
1130 throws ClassNotFound {
1131 // look in the current class
1132 MemberDefinition f;
1133 for (f = getFirstMatch(nm) ; f != null ; f = f.getNextMatch()) {
1134 // Note that non-method types return false for equalArguments().
1135 if (f.getType().equalArguments(t)) {
1136 return f;
1137 }
1138 }
1139
1140 // constructors are not inherited
1141 if (nm.equals(idInit)) {
1142 return null;
1143 }
1144
1145 // look in the super class
1146 ClassDeclaration sup = getSuperClass();
1147 if (sup == null)
1148 return null;
1149
1150 return sup.getClassDefinition(env).findMethod(env, nm, t);
1151 }
1152
1153 // We create a stub for this. Source classes do more work.
1154 protected void basicCheck(Environment env) throws ClassNotFound {
1155 // Do the outer class first.
1156 if (outerClass != null)
1157 outerClass.basicCheck(env);
1158 }
1159
1160 /**
1161 * Check this class.
1162 */
1163 public void check(Environment env) throws ClassNotFound {
1164 }
1165
1166 public Vset checkLocalClass(Environment env, Context ctx,
1167 Vset vset, ClassDefinition sup,
1168 Expression args[], Type argTypes[]
1169 ) throws ClassNotFound {
1170 throw new CompilerError("checkLocalClass");
1171 }
1172
1173 //---------------------------------------------------------------
1174 // The non-synthetic methods defined in this class or in any
1175 // of its parents (class or interface). This member is used
1176 // to cache work done in collectInheritedMethods for use by
1177 // getMethods() and matchMethod(). It should be accessed by
1178 // no other method without forethought.
1179 MethodSet allMethods = null;
1180
1181 // One of our superclasses may contain an abstract method which
1182 // we are unable to ever implement. This happens when there is
1183 // a package-private abstract method in our parent and we are in
1184 // a different package than our parent. In these cases, we
1185 // keep a list of the "permanently abstract" or "unimplementable"
1186 // methods so that we can correctly detect that this class is
1187 // indeed abstract and so that we can give somewhat comprehensible
1188 // error messages.
1189 private List permanentlyAbstractMethods = new ArrayList();
1190
1191 /**
1192 * This method returns an Iterator of all abstract methods
1193 * in our superclasses which we are unable to implement.
1194 */
1195 protected Iterator getPermanentlyAbstractMethods() {
1196 // This method can only be called after collectInheritedMethods.
1197 if (allMethods == null) {
1198 throw new CompilerError("isPermanentlyAbstract() called early");
1199 }
1200
1201 return permanentlyAbstractMethods.iterator();
1202 }
1203
1204 /**
1205 * A flag used by turnOffInheritanceChecks() to indicate if
1206 * inheritance checks are on or off.
1207 */
1208 protected static boolean doInheritanceChecks = true;
1209
1210 /**
1211 * This is a workaround to allow javadoc to turn off certain
1212 * inheritance/override checks which interfere with javadoc
1213 * badly. In the future it might be good to eliminate the
1214 * shared sources of javadoc and javac to avoid the need for this
1215 * sort of workaround.
1216 */
1217 public static void turnOffInheritanceChecks() {
1218 doInheritanceChecks = false;
1219 }
1220
1221 /**
1222 * Add all of the methods declared in or above `parent' to
1223 * `allMethods', the set of methods in the current class.
1224 * `myMethods' is the set of all methods declared in this
1225 * class, and `mirandaMethods' is a repository for Miranda methods.
1226 * If mirandaMethods is null, no mirandaMethods will be
1227 * generated.
1228 *
1229 * For a definition of Miranda methods, see the comment above the
1230 * method addMirandaMethods() which occurs later in this file.
1231 */
1232 private void collectOneClass(Environment env,
1233 ClassDeclaration parent,
1234 MethodSet myMethods,
1235 MethodSet allMethods,
1236 MethodSet mirandaMethods) {
1237
1238 // System.out.println("Inheriting methods from " + parent);
1239
1240 try {
1241 ClassDefinition pClass = parent.getClassDefinition(env);
1242 Iterator 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 */
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 ////////////////////////////////////////////////////////////
1565 private static void methodSetAdd(Environment env,
1566 MethodSet methodSet,
1567 MemberDefinition newMethod)
1568 {
1569 MemberDefinition oldMethod = methodSet.lookupSig(newMethod.getName(),
1570 newMethod.getType());
1571 if (oldMethod != null) {
1572 Type oldReturnType = oldMethod.getType().getReturnType();
1573 Type newReturnType = newMethod.getType().getReturnType();
1574 try {
1575 if (env.isMoreSpecific(newReturnType, oldReturnType)) {
1576 methodSet.replace(newMethod);
1577 }
1578 } catch (ClassNotFound ignore) {
1579 }
1580 } else {
1581 methodSet.add(newMethod);
1582 }
1583 }
1584 ////////////////////////////////////////////////////////////
1585
1586 /**
1587 * Get an Iterator of all methods which could be accessed in an
1588 * instance of this class.
1589 */
1590 public Iterator getMethods(Environment env) {
1591 if (allMethods == null) {
1592 collectInheritedMethods(env);
1593 }
1594 return getMethods();
1595 }
1596
1597 /**
1598 * Get an Iterator of all methods which could be accessed in an
1599 * instance of this class. Throw a compiler error if we haven't
1600 * generated this information yet.
1601 */
1602 public Iterator getMethods() {
1603 if (allMethods == null) {
1604 throw new CompilerError("getMethods: too early");
1605 }
1606 return allMethods.iterator();
1607 }
1608
1609 // In early VM's there was a bug -- the VM didn't walk the interfaces
1610 // of a class looking for a method, they only walked the superclass
1611 // chain. This meant that abstract methods defined only in interfaces
1612 // were not being found. To fix this bug, a counter-bug was introduced
1613 // in the compiler -- the so-called Miranda methods. If a class
1614 // does not provide a definition for an abstract method in one of
1615 // its interfaces then the compiler inserts one in the class artificially.
1616 // That way the VM didn't have to bother looking at the interfaces.
1617 //
1618 // This is a problem. Miranda methods are not part of the specification.
1619 // But they continue to be inserted so that old VM's can run new code.
1620 // Someday, when the old VM's are gone, perhaps classes can be compiled
1621 // without Miranda methods. Towards this end, the compiler has a
1622 // flag, -nomiranda, which can turn off the creation of these methods.
1623 // Eventually that behavior should become the default.
1624 //
1625 // Why are they called Miranda methods? Well the sentence "If the
1626 // class is not able to provide a method, then one will be provided
1627 // by the compiler" is very similar to the sentence "If you cannot
1628 // afford an attorney, one will be provided by the court," -- one
1629 // of the so-called "Miranda" rights in the United States.
1630
1631 /**
1632 * Add a list of methods to this class as miranda methods. This
1633 * gets overridden with a meaningful implementation in SourceClass.
1634 * BinaryClass should not need to do anything -- it should already
1635 * have its miranda methods and, if it doesn't, then that doesn't
1636 * affect our compilation.
1637 */
1638 protected void addMirandaMethods(Environment env,
1639 Iterator mirandas) {
1640 // do nothing.
1641 }
1642
1643 //---------------------------------------------------------------
1644
1645 public void inlineLocalClass(Environment env) {
1646 }
1647
1648 /**
1649 * We create a stub for this. Source classes do more work.
1650 * Some calls from 'SourceClass.checkSupers' execute this method.
1651 * @see sun.tools.javac.SourceClass#resolveTypeStructure
1652 */
1653
1654 public void resolveTypeStructure(Environment env) {
1655 }
1656
1657 /**
1658 * Look up an inner class name, from somewhere inside this class.
1659 * Since supers and outers are in scope, search them too.
1660 * <p>
1661 * If no inner class is found, env.resolveName() is then called,
1662 * to interpret the ambient package and import directives.
1663 * <p>
1664 * This routine operates on a "best-efforts" basis. If
1665 * at some point a class is not found, the partially-resolved
1666 * identifier is returned. Eventually, someone else has to
1667 * try to get the ClassDefinition and diagnose the ClassNotFound.
1668 * <p>
1669 * resolveName() looks at surrounding scopes, and hence
1670 * pulling in both inherited and uplevel types. By contrast,
1671 * resolveInnerClass() is intended only for interpreting
1672 * explicitly qualified names, and so look only at inherited
1673 * types. Also, resolveName() looks for package prefixes,
1674 * which appear similar to "very uplevel" outer classes.
1675 * <p>
1676 * A similar (but more complex) name-lookup process happens
1677 * when field and identifier expressions denoting qualified names
1678 * are type-checked. The added complexity comes from the fact
1679 * that variables may occur in such names, and take precedence
1680 * over class and package names.
1681 * <p>
1682 * In the expression type-checker, resolveInnerClass() is paralleled
1683 * by code in FieldExpression.checkAmbigName(), which also calls
1684 * ClassDefinition.getInnerClass() to interpret names of the form
1685 * "OuterClass.Inner" (and also outerObject.Inner). The checking
1686 * of an identifier expression that fails to be a variable is referred
1687 * directly to resolveName().
1688 */
1689 public Identifier resolveName(Environment env, Identifier name) {
1690 if (tracing) env.dtEvent("ClassDefinition.resolveName: " + name);
1691 // This logic is pretty much exactly parallel to that of
1692 // Environment.resolveName().
1693 if (name.isQualified()) {
1694 // Try to resolve the first identifier component,
1695 // because inner class names take precedence over
1696 // package prefixes. (Cf. Environment.resolveName.)
1697 Identifier rhead = resolveName(env, name.getHead());
1698
1699 if (rhead.hasAmbigPrefix()) {
1700 // The first identifier component refers to an
1701 // ambiguous class. Limp on. We throw away the
1702 // rest of the classname as it is irrelevant.
1703 // (part of solution for 4059855).
1704 return rhead;
1705 }
1706
1707 if (!env.classExists(rhead)) {
1708 return env.resolvePackageQualifiedName(name);
1709 }
1710 try {
1711 return env.getClassDefinition(rhead).
1712 resolveInnerClass(env, name.getTail());
1713 } catch (ClassNotFound ee) {
1714 // return partially-resolved name someone else can fail on
1715 return Identifier.lookupInner(rhead, name.getTail());
1716 }
1717 }
1718
1719 // This method used to fail to look for local classes, thus a
1720 // reference to a local class within, e.g., the type of a member
1721 // declaration, would fail to resolve if the immediately enclosing
1722 // context was an inner class. The code added below is ugly, but
1723 // it works, and is lifted from existing code in 'Context.resolveName'
1724 // and 'Context.getClassCommon'. See the comments there about the design.
1725 // Fixes 4095716.
1726
1727 int ls = -2;
1728 LocalMember lf = null;
1729 if (classContext != null) {
1730 lf = classContext.getLocalClass(name);
1731 if (lf != null) {
1732 ls = lf.getScopeNumber();
1733 }
1734 }
1735
1736 // Look for an unqualified name in enclosing scopes.
1737 for (ClassDefinition c = this; c != null; c = c.outerClass) {
1738 try {
1739 MemberDefinition f = c.getInnerClass(env, name);
1740 if (f != null &&
1741 (lf == null || classContext.getScopeNumber(c) > ls)) {
1742 // An uplevel member was found, and was nested more deeply than
1743 // any enclosing local of the same name.
1744 return f.getInnerClass().getName();
1745 }
1746 } catch (ClassNotFound ee) {
1747 // a missing superclass, or something catastrophic
1748 }
1749 }
1750
1751 // No uplevel member found, so use the enclosing local if one was found.
1752 if (lf != null) {
1753 return lf.getInnerClass().getName();
1754 }
1755
1756 // look in imports, etc.
1757 return env.resolveName(name);
1758 }
1759
1760 /**
1761 * Interpret a qualified class name, which may have further subcomponents..
1762 * Follow inheritance links, as in:
1763 * class C { class N { } } class D extends C { } ... new D.N() ...
1764 * Ignore outer scopes and packages.
1765 * @see resolveName
1766 */
1767 public Identifier resolveInnerClass(Environment env, Identifier nm) {
1768 if (nm.isInner()) throw new CompilerError("inner");
1769 if (nm.isQualified()) {
1770 Identifier rhead = resolveInnerClass(env, nm.getHead());
1771 try {
1772 return env.getClassDefinition(rhead).
1773 resolveInnerClass(env, nm.getTail());
1774 } catch (ClassNotFound ee) {
1775 // return partially-resolved name someone else can fail on
1776 return Identifier.lookupInner(rhead, nm.getTail());
1777 }
1778 } else {
1779 try {
1780 MemberDefinition f = getInnerClass(env, nm);
1781 if (f != null) {
1782 return f.getInnerClass().getName();
1783 }
1784 } catch (ClassNotFound ee) {
1785 // a missing superclass, or something catastrophic
1786 }
1787 // Fake a good name for a diagnostic.
1788 return Identifier.lookupInner(this.getName(), nm);
1789 }
1790 }
1791
1792 /**
1793 * While resolving import directives, the question has arisen:
1794 * does a given inner class exist? If the top-level class exists,
1795 * we ask it about an inner class via this method.
1796 * This method looks only at the literal name of the class,
1797 * and does not attempt to follow inheritance links.
1798 * This is necessary, since at the time imports are being
1799 * processed, inheritance links have not been resolved yet.
1800 * (Thus, an import directive must always spell a class
1801 * name exactly.)
1802 */
1803 public boolean innerClassExists(Identifier nm) {
1804 for (MemberDefinition field = getFirstMatch(nm.getHead()) ; field != null ; field = field.getNextMatch()) {
1805 if (field.isInnerClass()) {
1806 if (field.getInnerClass().isLocal()) {
1807 continue; // ignore this name; it is internally generated
1808 }
1809 return !nm.isQualified() ||
1810 field.getInnerClass().innerClassExists(nm.getTail());
1811 }
1812 }
1813 return false;
1814 }
1815
1816 /**
1817 * Find any method with a given name.
1818 */
1819 public MemberDefinition findAnyMethod(Environment env, Identifier nm) throws ClassNotFound {
1820 MemberDefinition f;
1821 for (f = getFirstMatch(nm) ; f != null ; f = f.getNextMatch()) {
1822 if (f.isMethod()) {
1823 return f;
1824 }
1825 }
1826
1827 // look in the super class
1828 ClassDeclaration sup = getSuperClass();
1829 if (sup == null)
1830 return null;
1831 return sup.getClassDefinition(env).findAnyMethod(env, nm);
1832 }
1833
1834 /**
1835 * Given the fact that this class has no method "nm" matching "argTypes",
1836 * find out if the mismatch can be blamed on a particular actual argument
1837 * which disagrees with all of the overloadings.
1838 * If so, return the code (i<<2)+(castOK<<1)+ambig, where
1839 * "i" is the number of the offending argument, and
1840 * "castOK" is 1 if a cast could fix the problem.
1841 * The target type for the argument is returned in margTypeResult[0].
1842 * If not all methods agree on this type, "ambig" is 1.
1843 * If there is more than one method, the choice of target type is
1844 * arbitrary.<p>
1845 * Return -1 if every argument is acceptable to at least one method.
1846 * Return -2 if there are no methods of the required arity.
1847 * The value "start" gives the index of the first argument to begin
1848 * checking.
1849 */
1850 public int diagnoseMismatch(Environment env, Identifier nm, Type argTypes[],
1851 int start, Type margTypeResult[]) throws ClassNotFound {
1852 int haveMatch[] = new int[argTypes.length];
1853 Type margType[] = new Type[argTypes.length];
1854 if (!diagnoseMismatch(env, nm, argTypes, start, haveMatch, margType))
1855 return -2;
1856 for (int i = start; i < argTypes.length; i++) {
1857 if (haveMatch[i] < 4) {
1858 margTypeResult[0] = margType[i];
1859 return (i<<2) | haveMatch[i];
1860 }
1861 }
1862 return -1;
1863 }
1864
1865 private boolean diagnoseMismatch(Environment env, Identifier nm, Type argTypes[], int start,
1866 int haveMatch[], Type margType[]) throws ClassNotFound {
1867 // look in the current class
1868 boolean haveOne = false;
1869 MemberDefinition f;
1870 for (f = getFirstMatch(nm) ; f != null ; f = f.getNextMatch()) {
1871 if (!f.isMethod()) {
1872 continue;
1873 }
1874 Type fArgTypes[] = f.getType().getArgumentTypes();
1875 if (fArgTypes.length == argTypes.length) {
1876 haveOne = true;
1877 for (int i = start; i < argTypes.length; i++) {
1878 Type at = argTypes[i];
1879 Type ft = fArgTypes[i];
1880 if (env.implicitCast(at, ft)) {
1881 haveMatch[i] = 4;
1882 continue;
1883 } else if (haveMatch[i] <= 2 && env.explicitCast(at, ft)) {
1884 if (haveMatch[i] < 2) margType[i] = null;
1885 haveMatch[i] = 2;
1886 } else if (haveMatch[i] > 0) {
1887 continue;
1888 }
1889 if (margType[i] == null)
1890 margType[i] = ft;
1891 else if (margType[i] != ft)
1892 haveMatch[i] |= 1;
1893 }
1894 }
1895 }
1896
1897 // constructors are not inherited
1898 if (nm.equals(idInit)) {
1899 return haveOne;
1900 }
1901
1902 // look in the super class
1903 ClassDeclaration sup = getSuperClass();
1904 if (sup != null) {
1905 if (sup.getClassDefinition(env).diagnoseMismatch(env, nm, argTypes, start,
1906 haveMatch, margType))
1907 haveOne = true;
1908 }
1909 return haveOne;
1910 }
1911
1912 /**
1913 * Add a field (no checks)
1914 */
1915 public void addMember(MemberDefinition field) {
1916 //System.out.println("ADD = " + field);
1917 if (firstMember == null) {
1918 firstMember = lastMember = field;
1919 } else if (field.isSynthetic() && field.isFinal()
1920 && field.isVariable()) {
1921 // insert this at the front, because of initialization order
1922 field.nextMember = firstMember;
1923 firstMember = field;
1924 field.nextMatch = (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 */
1936 public void addMember(Environment env, MemberDefinition field) {
1937 addMember(field);
1938 if (resolved) {
1939 // a late addition
1940 field.resolveTypeStructure(env);
1941 }
1942 }
1943
1944 /**
1945 * Find or create an uplevel reference for the given target.
1946 */
1947 public UplevelReference getReference(LocalMember target) {
1948 for (UplevelReference r = references; r != null; r = r.getNext()) {
1949 if (r.getTarget() == target) {
1950 return r;
1951 }
1952 }
1953 return addReference(target);
1954 }
1955
1956 protected UplevelReference addReference(LocalMember target) {
1957 if (target.getClassDefinition() == this) {
1958 throw new CompilerError("addReference "+target);
1959 }
1960 referencesMustNotBeFrozen();
1961 UplevelReference r = new UplevelReference(this, target);
1962 references = r.insertInto(references);
1963 return r;
1964 }
1965
1966 /**
1967 * Return the list of all uplevel references.
1968 */
1969 public UplevelReference getReferences() {
1970 return references;
1971 }
1972
1973 /**
1974 * Return the same value as getReferences.
1975 * Also, mark the set of references frozen.
1976 * After that, it is an error to add new references.
1977 */
1978 public UplevelReference getReferencesFrozen() {
1979 referencesFrozen = true;
1980 return references;
1981 }
1982
1983 /**
1984 * assertion check
1985 */
1986 public final void referencesMustNotBeFrozen() {
1987 if (referencesFrozen) {
1988 throw new CompilerError("referencesMustNotBeFrozen "+this);
1989 }
1990 }
1991
1992 /**
1993 * Get helper method for class literal lookup.
1994 */
1995 public MemberDefinition getClassLiteralLookup(long fwhere) {
1996 throw new CompilerError("binary class");
1997 }
1998
1999 /**
2000 * Add a dependency
2001 */
2002 public void addDependency(ClassDeclaration c) {
2003 throw new CompilerError("addDependency");
2004 }
2005
2006 /**
2007 * Maintain a hash table of local and anonymous classes
2008 * whose internal names are prefixed by the current class.
2009 * The key is the simple internal name, less the prefix.
2010 */
2011
2012 public ClassDefinition getLocalClass(String name) {
2013 if (localClasses == null) {
2014 return null;
2015 } else {
2016 return (ClassDefinition)localClasses.get(name);
2017 }
2018 }
2019
2020 public void addLocalClass(ClassDefinition c, String name) {
2021 if (localClasses == null) {
2022 localClasses = new Hashtable(LOCAL_CLASSES_SIZE);
2023 }
2024 localClasses.put(name, c);
2025 }
2026
2027
2028 /**
2029 * Print for debugging
2030 */
2031 public void print(PrintStream out) {
2032 if (isPublic()) {
2033 out.print("public ");
2034 }
2035 if (isInterface()) {
2036 out.print("interface ");
2037 } else {
2038 out.print("class ");
2039 }
2040 out.print(getName() + " ");
2041 if (getSuperClass() != null) {
2042 out.print("extends " + getSuperClass().getName() + " ");
2043 }
2044 if (interfaces.length > 0) {
2045 out.print("implements ");
2046 for (int i = 0 ; i < interfaces.length ; i++) {
2047 if (i > 0) {
2048 out.print(", ");
2049 }
2050 out.print(interfaces[i].getName());
2051 out.print(" ");
2052 }
2053 }
2054 out.println("{");
2055
2056 for (MemberDefinition f = getFirstMember() ; f != null ; f = f.getNextMember()) {
2057 out.print(" ");
2058 f.print(out);
2059 }
2060
2061 out.println("}");
2062 }
2063
2064 /**
2065 * Convert to String
2066 */
2067 public String toString() {
2068 return getClassDeclaration().toString();
2069 }
2070
2071 /**
2072 * After the class has been written to disk, try to free up
2073 * some storage.
2074 */
2075 public void cleanup(Environment env) {
2076 if (env.dump()) {
2077 env.output("[cleanup " + getName() + "]");
2078 }
2079 for (MemberDefinition f = getFirstMember() ; f != null ; f = f.getNextMember()) {
2080 f.cleanup(env);
2081 }
2082 // keep "references" around, for the sake of local subclasses
2083 documentation = null;
2084 }
2085}