src/share/classes/com/sun/tools/javac/code/Symbol.java

changeset 1
9a66ca7c79fa
child 12
7366066839bb
equal deleted inserted replaced
-1:000000000000 1:9a66ca7c79fa
1 /*
2 * Copyright 1999-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
26 package com.sun.tools.javac.code;
27
28 import java.util.ArrayList;
29 import java.util.Collections;
30 import java.util.Set;
31 import java.util.concurrent.Callable;
32 import javax.lang.model.element.*;
33 import javax.lang.model.type.ReferenceType;
34 import javax.lang.model.type.TypeMirror;
35 import javax.tools.JavaFileObject;
36
37 import com.sun.tools.javac.util.*;
38 import com.sun.tools.javac.util.Name;
39 import com.sun.tools.javac.code.Type.*;
40 import com.sun.tools.javac.comp.Attr;
41 import com.sun.tools.javac.comp.AttrContext;
42 import com.sun.tools.javac.comp.Env;
43 import com.sun.tools.javac.jvm.*;
44 import com.sun.tools.javac.model.*;
45 import com.sun.tools.javac.tree.JCTree;
46
47 import static com.sun.tools.javac.code.Flags.*;
48 import static com.sun.tools.javac.code.Kinds.*;
49 import static com.sun.tools.javac.code.TypeTags.*;
50
51 /** Root class for Java symbols. It contains subclasses
52 * for specific sorts of symbols, such as variables, methods and operators,
53 * types, packages. Each subclass is represented as a static inner class
54 * inside Symbol.
55 *
56 * <p><b>This is NOT part of any API supported by Sun Microsystems. If
57 * you write code that depends on this, you do so at your own risk.
58 * This code and its internal interfaces are subject to change or
59 * deletion without notice.</b>
60 */
61 public abstract class Symbol implements Element {
62 // public Throwable debug = new Throwable();
63
64 /** The kind of this symbol.
65 * @see Kinds
66 */
67 public int kind;
68
69 /** The flags of this symbol.
70 */
71 public long flags_field;
72
73 /** An accessor method for the flags of this symbol.
74 * Flags of class symbols should be accessed through the accessor
75 * method to make sure that the class symbol is loaded.
76 */
77 public long flags() { return flags_field; }
78
79 /** The attributes of this symbol.
80 */
81 public List<Attribute.Compound> attributes_field;
82
83 /** An accessor method for the attributes of this symbol.
84 * Attributes of class symbols should be accessed through the accessor
85 * method to make sure that the class symbol is loaded.
86 */
87 public List<Attribute.Compound> getAnnotationMirrors() {
88 assert attributes_field != null;
89 return attributes_field;
90 }
91
92 /** Fetch a particular annotation from a symbol. */
93 public Attribute.Compound attribute(Symbol anno) {
94 for (Attribute.Compound a : getAnnotationMirrors())
95 if (a.type.tsym == anno) return a;
96 return null;
97 }
98
99 /** The name of this symbol in Utf8 representation.
100 */
101 public Name name;
102
103 /** The type of this symbol.
104 */
105 public Type type;
106
107 /** The owner of this symbol.
108 */
109 public Symbol owner;
110
111 /** The completer of this symbol.
112 */
113 public Completer completer;
114
115 /** A cache for the type erasure of this symbol.
116 */
117 public Type erasure_field;
118
119 /** Construct a symbol with given kind, flags, name, type and owner.
120 */
121 public Symbol(int kind, long flags, Name name, Type type, Symbol owner) {
122 this.kind = kind;
123 this.flags_field = flags;
124 this.type = type;
125 this.owner = owner;
126 this.completer = null;
127 this.erasure_field = null;
128 this.attributes_field = List.nil();
129 this.name = name;
130 }
131
132 /** Clone this symbol with new owner.
133 * Legal only for fields and methods.
134 */
135 public Symbol clone(Symbol newOwner) {
136 throw new AssertionError();
137 }
138
139 /** The Java source which this symbol represents.
140 * A description of this symbol; overrides Object.
141 */
142 public String toString() {
143 return name.toString();
144 }
145
146 /** A Java source description of the location of this symbol; used for
147 * error reporting. Use of this method may result in the loss of the
148 * symbol's description.
149 */
150 public String location() {
151 if (owner.name == null || (owner.name.len == 0 && owner.kind != PCK)) {
152 return "";
153 }
154 return owner.toString();
155 }
156
157 public String location(Type site, Types types) {
158 if (owner.name == null || owner.name.len == 0) {
159 return location();
160 }
161 if (owner.type.tag == CLASS) {
162 Type ownertype = types.asOuterSuper(site, owner);
163 if (ownertype != null) return ownertype.toString();
164 }
165 return owner.toString();
166 }
167
168 /** The symbol's erased type.
169 */
170 public Type erasure(Types types) {
171 if (erasure_field == null)
172 erasure_field = types.erasure(type);
173 return erasure_field;
174 }
175
176 /** The external type of a symbol. This is the symbol's erased type
177 * except for constructors of inner classes which get the enclosing
178 * instance class added as first argument.
179 */
180 public Type externalType(Types types) {
181 Type t = erasure(types);
182 if (name == name.table.init && owner.hasOuterInstance()) {
183 Type outerThisType = types.erasure(owner.type.getEnclosingType());
184 return new MethodType(t.getParameterTypes().prepend(outerThisType),
185 t.getReturnType(),
186 t.getThrownTypes(),
187 t.tsym);
188 } else {
189 return t;
190 }
191 }
192
193 public boolean isStatic() {
194 return
195 (flags() & STATIC) != 0 ||
196 (owner.flags() & INTERFACE) != 0 && kind != MTH;
197 }
198
199 public boolean isInterface() {
200 return (flags() & INTERFACE) != 0;
201 }
202
203 /** Is this symbol declared (directly or indirectly) local
204 * to a method or variable initializer?
205 * Also includes fields of inner classes which are in
206 * turn local to a method or variable initializer.
207 */
208 public boolean isLocal() {
209 return
210 (owner.kind & (VAR | MTH)) != 0 ||
211 (owner.kind == TYP && owner.isLocal());
212 }
213
214 /** Is this symbol a constructor?
215 */
216 public boolean isConstructor() {
217 return name == name.table.init;
218 }
219
220 /** The fully qualified name of this symbol.
221 * This is the same as the symbol's name except for class symbols,
222 * which are handled separately.
223 */
224 public Name getQualifiedName() {
225 return name;
226 }
227
228 /** The fully qualified name of this symbol after converting to flat
229 * representation. This is the same as the symbol's name except for
230 * class symbols, which are handled separately.
231 */
232 public Name flatName() {
233 return getQualifiedName();
234 }
235
236 /** If this is a class or package, its members, otherwise null.
237 */
238 public Scope members() {
239 return null;
240 }
241
242 /** A class is an inner class if it it has an enclosing instance class.
243 */
244 public boolean isInner() {
245 return type.getEnclosingType().tag == CLASS;
246 }
247
248 /** An inner class has an outer instance if it is not an interface
249 * it has an enclosing instance class which might be referenced from the class.
250 * Nested classes can see instance members of their enclosing class.
251 * Their constructors carry an additional this$n parameter, inserted
252 * implicitly by the compiler.
253 *
254 * @see #isInner
255 */
256 public boolean hasOuterInstance() {
257 return
258 type.getEnclosingType().tag == CLASS && (flags() & (INTERFACE | NOOUTERTHIS)) == 0;
259 }
260
261 /** The closest enclosing class of this symbol's declaration.
262 */
263 public ClassSymbol enclClass() {
264 Symbol c = this;
265 while (c != null &&
266 ((c.kind & TYP) == 0 || c.type.tag != CLASS)) {
267 c = c.owner;
268 }
269 return (ClassSymbol)c;
270 }
271
272 /** The outermost class which indirectly owns this symbol.
273 */
274 public ClassSymbol outermostClass() {
275 Symbol sym = this;
276 Symbol prev = null;
277 while (sym.kind != PCK) {
278 prev = sym;
279 sym = sym.owner;
280 }
281 return (ClassSymbol) prev;
282 }
283
284 /** The package which indirectly owns this symbol.
285 */
286 public PackageSymbol packge() {
287 Symbol sym = this;
288 while (sym.kind != PCK) {
289 sym = sym.owner;
290 }
291 return (PackageSymbol) sym;
292 }
293
294 /** Is this symbol a subclass of `base'? Only defined for ClassSymbols.
295 */
296 public boolean isSubClass(Symbol base, Types types) {
297 throw new AssertionError("isSubClass " + this);
298 }
299
300 /** Fully check membership: hierarchy, protection, and hiding.
301 * Does not exclude methods not inherited due to overriding.
302 */
303 public boolean isMemberOf(TypeSymbol clazz, Types types) {
304 return
305 owner == clazz ||
306 clazz.isSubClass(owner, types) &&
307 isInheritedIn(clazz, types) &&
308 !hiddenIn((ClassSymbol)clazz, types);
309 }
310
311 /** Is this symbol the same as or enclosed by the given class? */
312 public boolean isEnclosedBy(ClassSymbol clazz) {
313 for (Symbol sym = this; sym.kind != PCK; sym = sym.owner)
314 if (sym == clazz) return true;
315 return false;
316 }
317
318 /** Check for hiding. Note that this doesn't handle multiple
319 * (interface) inheritance. */
320 private boolean hiddenIn(ClassSymbol clazz, Types types) {
321 if (kind == MTH && (flags() & STATIC) == 0) return false;
322 while (true) {
323 if (owner == clazz) return false;
324 Scope.Entry e = clazz.members().lookup(name);
325 while (e.scope != null) {
326 if (e.sym == this) return false;
327 if (e.sym.kind == kind &&
328 (kind != MTH ||
329 (e.sym.flags() & STATIC) != 0 &&
330 types.isSubSignature(e.sym.type, type)))
331 return true;
332 e = e.next();
333 }
334 Type superType = types.supertype(clazz.type);
335 if (superType.tag != TypeTags.CLASS) return false;
336 clazz = (ClassSymbol)superType.tsym;
337 }
338 }
339
340 /** Is this symbol inherited into a given class?
341 * PRE: If symbol's owner is a interface,
342 * it is already assumed that the interface is a superinterface
343 * of given class.
344 * @param clazz The class for which we want to establish membership.
345 * This must be a subclass of the member's owner.
346 */
347 public boolean isInheritedIn(Symbol clazz, Types types) {
348 switch ((int)(flags_field & Flags.AccessFlags)) {
349 default: // error recovery
350 case PUBLIC:
351 return true;
352 case PRIVATE:
353 return this.owner == clazz;
354 case PROTECTED:
355 // we model interfaces as extending Object
356 return (clazz.flags() & INTERFACE) == 0;
357 case 0:
358 PackageSymbol thisPackage = this.packge();
359 for (Symbol sup = clazz;
360 sup != null && sup != this.owner;
361 sup = types.supertype(sup.type).tsym) {
362 if (sup.type.isErroneous())
363 return true; // error recovery
364 if ((sup.flags() & COMPOUND) != 0)
365 continue;
366 if (sup.packge() != thisPackage)
367 return false;
368 }
369 return (clazz.flags() & INTERFACE) == 0;
370 }
371 }
372
373 /** The (variable or method) symbol seen as a member of given
374 * class type`site' (this might change the symbol's type).
375 * This is used exclusively for producing diagnostics.
376 */
377 public Symbol asMemberOf(Type site, Types types) {
378 throw new AssertionError();
379 }
380
381 /** Does this method symbol override `other' symbol, when both are seen as
382 * members of class `origin'? It is assumed that _other is a member
383 * of origin.
384 *
385 * It is assumed that both symbols have the same name. The static
386 * modifier is ignored for this test.
387 *
388 * See JLS 8.4.6.1 (without transitivity) and 8.4.6.4
389 */
390 public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult) {
391 return false;
392 }
393
394 /** Complete the elaboration of this symbol's definition.
395 */
396 public void complete() throws CompletionFailure {
397 if (completer != null) {
398 Completer c = completer;
399 completer = null;
400 c.complete(this);
401 }
402 }
403
404 /** True if the symbol represents an entity that exists.
405 */
406 public boolean exists() {
407 return true;
408 }
409
410 public Type asType() {
411 return type;
412 }
413
414 public Symbol getEnclosingElement() {
415 return owner;
416 }
417
418 public ElementKind getKind() {
419 return ElementKind.OTHER; // most unkind
420 }
421
422 public Set<Modifier> getModifiers() {
423 return Flags.asModifierSet(flags());
424 }
425
426 public Name getSimpleName() {
427 return name;
428 }
429
430 /**
431 * @deprecated this method should never be used by javac internally.
432 */
433 @Deprecated
434 public <A extends java.lang.annotation.Annotation> A getAnnotation(Class<A> annoType) {
435 return JavacElements.getAnnotation(this, annoType);
436 }
437
438 // TODO: getEnclosedElements should return a javac List, fix in FilteredMemberList
439 public java.util.List<Symbol> getEnclosedElements() {
440 return List.nil();
441 }
442
443 public List<TypeSymbol> getTypeParameters() {
444 ListBuffer<TypeSymbol> l = ListBuffer.lb();
445 for (Type t : type.getTypeArguments()) {
446 l.append(t.tsym);
447 }
448 return l.toList();
449 }
450
451 public static class DelegatedSymbol extends Symbol {
452 protected Symbol other;
453 public DelegatedSymbol(Symbol other) {
454 super(other.kind, other.flags_field, other.name, other.type, other.owner);
455 this.other = other;
456 }
457 public String toString() { return other.toString(); }
458 public String location() { return other.location(); }
459 public String location(Type site, Types types) { return other.location(site, types); }
460 public Type erasure(Types types) { return other.erasure(types); }
461 public Type externalType(Types types) { return other.externalType(types); }
462 public boolean isLocal() { return other.isLocal(); }
463 public boolean isConstructor() { return other.isConstructor(); }
464 public Name getQualifiedName() { return other.getQualifiedName(); }
465 public Name flatName() { return other.flatName(); }
466 public Scope members() { return other.members(); }
467 public boolean isInner() { return other.isInner(); }
468 public boolean hasOuterInstance() { return other.hasOuterInstance(); }
469 public ClassSymbol enclClass() { return other.enclClass(); }
470 public ClassSymbol outermostClass() { return other.outermostClass(); }
471 public PackageSymbol packge() { return other.packge(); }
472 public boolean isSubClass(Symbol base, Types types) { return other.isSubClass(base, types); }
473 public boolean isMemberOf(TypeSymbol clazz, Types types) { return other.isMemberOf(clazz, types); }
474 public boolean isEnclosedBy(ClassSymbol clazz) { return other.isEnclosedBy(clazz); }
475 public boolean isInheritedIn(Symbol clazz, Types types) { return other.isInheritedIn(clazz, types); }
476 public Symbol asMemberOf(Type site, Types types) { return other.asMemberOf(site, types); }
477 public void complete() throws CompletionFailure { other.complete(); }
478
479 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
480 return other.accept(v, p);
481 }
482 }
483
484 /** A class for type symbols. Type variables are represented by instances
485 * of this class, classes and packages by instances of subclasses.
486 */
487 public static class TypeSymbol
488 extends Symbol implements TypeParameterElement {
489 // Implements TypeParameterElement because type parameters don't
490 // have their own TypeSymbol subclass.
491 // TODO: type parameters should have their own TypeSymbol subclass
492
493 public TypeSymbol(long flags, Name name, Type type, Symbol owner) {
494 super(TYP, flags, name, type, owner);
495 }
496
497 /** form a fully qualified name from a name and an owner
498 */
499 static public Name formFullName(Name name, Symbol owner) {
500 if (owner == null) return name;
501 if (((owner.kind != ERR)) &&
502 ((owner.kind & (VAR | MTH)) != 0
503 || (owner.kind == TYP && owner.type.tag == TYPEVAR)
504 )) return name;
505 Name prefix = owner.getQualifiedName();
506 if (prefix == null || prefix == prefix.table.empty)
507 return name;
508 else return prefix.append('.', name);
509 }
510
511 /** form a fully qualified name from a name and an owner, after
512 * converting to flat representation
513 */
514 static public Name formFlatName(Name name, Symbol owner) {
515 if (owner == null ||
516 (owner.kind & (VAR | MTH)) != 0
517 || (owner.kind == TYP && owner.type.tag == TYPEVAR)
518 ) return name;
519 char sep = owner.kind == TYP ? '$' : '.';
520 Name prefix = owner.flatName();
521 if (prefix == null || prefix == prefix.table.empty)
522 return name;
523 else return prefix.append(sep, name);
524 }
525
526 /**
527 * A total ordering between type symbols that refines the
528 * class inheritance graph.
529 *
530 * Typevariables always precede other kinds of symbols.
531 */
532 public final boolean precedes(TypeSymbol that, Types types) {
533 if (this == that)
534 return false;
535 if (this.type.tag == that.type.tag) {
536 if (this.type.tag == CLASS) {
537 return
538 types.rank(that.type) < types.rank(this.type) ||
539 types.rank(that.type) == types.rank(this.type) &&
540 that.getQualifiedName().compareTo(this.getQualifiedName()) < 0;
541 } else if (this.type.tag == TYPEVAR) {
542 return types.isSubtype(this.type, that.type);
543 }
544 }
545 return this.type.tag == TYPEVAR;
546 }
547
548 // For type params; overridden in subclasses.
549 public ElementKind getKind() {
550 return ElementKind.TYPE_PARAMETER;
551 }
552
553 public java.util.List<Symbol> getEnclosedElements() {
554 List<Symbol> list = List.nil();
555 for (Scope.Entry e = members().elems; e != null; e = e.sibling) {
556 if (e.sym != null && (e.sym.flags() & SYNTHETIC) == 0 && e.sym.owner == this)
557 list = list.prepend(e.sym);
558 }
559 return list;
560 }
561
562 // For type params.
563 // Perhaps not needed if getEnclosingElement can be spec'ed
564 // to do the same thing.
565 // TODO: getGenericElement() might not be needed
566 public Symbol getGenericElement() {
567 return owner;
568 }
569
570 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
571 assert type.tag == TYPEVAR; // else override will be invoked
572 return v.visitTypeParameter(this, p);
573 }
574
575 public List<Type> getBounds() {
576 TypeVar t = (TypeVar)type;
577 Type bound = t.getUpperBound();
578 if (!bound.isCompound())
579 return List.of(bound);
580 ClassType ct = (ClassType)bound;
581 if (!ct.tsym.erasure_field.isInterface()) {
582 return ct.interfaces_field.prepend(ct.supertype_field);
583 } else {
584 // No superclass was given in bounds.
585 // In this case, supertype is Object, erasure is first interface.
586 return ct.interfaces_field;
587 }
588 }
589 }
590
591 /** A class for package symbols
592 */
593 public static class PackageSymbol extends TypeSymbol
594 implements PackageElement {
595
596 public Scope members_field;
597 public Name fullname;
598 public ClassSymbol package_info; // see bug 6443073
599
600 public PackageSymbol(Name name, Type type, Symbol owner) {
601 super(0, name, type, owner);
602 this.kind = PCK;
603 this.members_field = null;
604 this.fullname = formFullName(name, owner);
605 }
606
607 public PackageSymbol(Name name, Symbol owner) {
608 this(name, null, owner);
609 this.type = new PackageType(this);
610 }
611
612 public String toString() {
613 return fullname.toString();
614 }
615
616 public Name getQualifiedName() {
617 return fullname;
618 }
619
620 public boolean isUnnamed() {
621 return name.isEmpty() && owner != null;
622 }
623
624 public Scope members() {
625 if (completer != null) complete();
626 return members_field;
627 }
628
629 public long flags() {
630 if (completer != null) complete();
631 return flags_field;
632 }
633
634 public List<Attribute.Compound> getAnnotationMirrors() {
635 if (completer != null) complete();
636 assert attributes_field != null;
637 return attributes_field;
638 }
639
640 /** A package "exists" if a type or package that exists has
641 * been seen within it.
642 */
643 public boolean exists() {
644 return (flags_field & EXISTS) != 0;
645 }
646
647 public ElementKind getKind() {
648 return ElementKind.PACKAGE;
649 }
650
651 public Symbol getEnclosingElement() {
652 return null;
653 }
654
655 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
656 return v.visitPackage(this, p);
657 }
658 }
659
660 /** A class for class symbols
661 */
662 public static class ClassSymbol extends TypeSymbol implements TypeElement {
663
664 /** a scope for all class members; variables, methods and inner classes
665 * type parameters are not part of this scope
666 */
667 public Scope members_field;
668
669 /** the fully qualified name of the class, i.e. pck.outer.inner.
670 * null for anonymous classes
671 */
672 public Name fullname;
673
674 /** the fully qualified name of the class after converting to flat
675 * representation, i.e. pck.outer$inner,
676 * set externally for local and anonymous classes
677 */
678 public Name flatname;
679
680 /** the sourcefile where the class came from
681 */
682 public JavaFileObject sourcefile;
683
684 /** the classfile from where to load this class
685 * this will have extension .class or .java
686 */
687 public JavaFileObject classfile;
688
689 /** the constant pool of the class
690 */
691 public Pool pool;
692
693 public ClassSymbol(long flags, Name name, Type type, Symbol owner) {
694 super(flags, name, type, owner);
695 this.members_field = null;
696 this.fullname = formFullName(name, owner);
697 this.flatname = formFlatName(name, owner);
698 this.sourcefile = null;
699 this.classfile = null;
700 this.pool = null;
701 }
702
703 public ClassSymbol(long flags, Name name, Symbol owner) {
704 this(
705 flags,
706 name,
707 new ClassType(Type.noType, null, null),
708 owner);
709 this.type.tsym = this;
710 }
711
712 /** The Java source which this symbol represents.
713 */
714 public String toString() {
715 return className();
716 }
717
718 public long flags() {
719 if (completer != null) complete();
720 return flags_field;
721 }
722
723 public Scope members() {
724 if (completer != null) complete();
725 return members_field;
726 }
727
728 public List<Attribute.Compound> getAnnotationMirrors() {
729 if (completer != null) complete();
730 assert attributes_field != null;
731 return attributes_field;
732 }
733
734 public Type erasure(Types types) {
735 if (erasure_field == null)
736 erasure_field = new ClassType(types.erasure(type.getEnclosingType()),
737 List.<Type>nil(), this);
738 return erasure_field;
739 }
740
741 public String className() {
742 if (name.len == 0)
743 return
744 Log.getLocalizedString("anonymous.class", flatname);
745 else
746 return fullname.toString();
747 }
748
749 public Name getQualifiedName() {
750 return fullname;
751 }
752
753 public Name flatName() {
754 return flatname;
755 }
756
757 public boolean isSubClass(Symbol base, Types types) {
758 if (this == base) {
759 return true;
760 } else if ((base.flags() & INTERFACE) != 0) {
761 for (Type t = type; t.tag == CLASS; t = types.supertype(t))
762 for (List<Type> is = types.interfaces(t);
763 is.nonEmpty();
764 is = is.tail)
765 if (is.head.tsym.isSubClass(base, types)) return true;
766 } else {
767 for (Type t = type; t.tag == CLASS; t = types.supertype(t))
768 if (t.tsym == base) return true;
769 }
770 return false;
771 }
772
773 /** Complete the elaboration of this symbol's definition.
774 */
775 public void complete() throws CompletionFailure {
776 try {
777 super.complete();
778 } catch (CompletionFailure ex) {
779 // quiet error recovery
780 flags_field |= (PUBLIC|STATIC);
781 this.type = new ErrorType(this);
782 throw ex;
783 }
784 }
785
786 public List<Type> getInterfaces() {
787 complete();
788 if (type instanceof ClassType) {
789 ClassType t = (ClassType)type;
790 if (t.interfaces_field == null) // FIXME: shouldn't be null
791 t.interfaces_field = List.nil();
792 return t.interfaces_field;
793 } else {
794 return List.nil();
795 }
796 }
797
798 public Type getSuperclass() {
799 complete();
800 if (type instanceof ClassType) {
801 ClassType t = (ClassType)type;
802 if (t.supertype_field == null) // FIXME: shouldn't be null
803 t.supertype_field = Type.noType;
804 // An interface has no superclass; its supertype is Object.
805 return t.isInterface()
806 ? Type.noType
807 : t.supertype_field;
808 } else {
809 return Type.noType;
810 }
811 }
812
813 public ElementKind getKind() {
814 long flags = flags();
815 if ((flags & ANNOTATION) != 0)
816 return ElementKind.ANNOTATION_TYPE;
817 else if ((flags & INTERFACE) != 0)
818 return ElementKind.INTERFACE;
819 else if ((flags & ENUM) != 0)
820 return ElementKind.ENUM;
821 else
822 return ElementKind.CLASS;
823 }
824
825 public NestingKind getNestingKind() {
826 complete();
827 if (owner.kind == PCK)
828 return NestingKind.TOP_LEVEL;
829 else if (name.isEmpty())
830 return NestingKind.ANONYMOUS;
831 else if (owner.kind == MTH)
832 return NestingKind.LOCAL;
833 else
834 return NestingKind.MEMBER;
835 }
836
837 /**
838 * @deprecated this method should never be used by javac internally.
839 */
840 @Override @Deprecated
841 public <A extends java.lang.annotation.Annotation> A getAnnotation(Class<A> annoType) {
842 return JavacElements.getAnnotation(this, annoType);
843 }
844
845 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
846 return v.visitType(this, p);
847 }
848 }
849
850
851 /** A class for variable symbols
852 */
853 public static class VarSymbol extends Symbol implements VariableElement {
854
855 /** The variable's declaration position.
856 */
857 public int pos = Position.NOPOS;
858
859 /** The variable's address. Used for different purposes during
860 * flow analysis, translation and code generation.
861 * Flow analysis:
862 * If this is a blank final or local variable, its sequence number.
863 * Translation:
864 * If this is a private field, its access number.
865 * Code generation:
866 * If this is a local variable, its logical slot number.
867 */
868 public int adr = -1;
869
870 /** Construct a variable symbol, given its flags, name, type and owner.
871 */
872 public VarSymbol(long flags, Name name, Type type, Symbol owner) {
873 super(VAR, flags, name, type, owner);
874 }
875
876 /** Clone this symbol with new owner.
877 */
878 public VarSymbol clone(Symbol newOwner) {
879 VarSymbol v = new VarSymbol(flags_field, name, type, newOwner);
880 v.pos = pos;
881 v.adr = adr;
882 v.data = data;
883 // System.out.println("clone " + v + " in " + newOwner);//DEBUG
884 return v;
885 }
886
887 public String toString() {
888 return name.toString();
889 }
890
891 public Symbol asMemberOf(Type site, Types types) {
892 return new VarSymbol(flags_field, name, types.memberType(site, this), owner);
893 }
894
895 public ElementKind getKind() {
896 long flags = flags();
897 if ((flags & PARAMETER) != 0) {
898 if (isExceptionParameter())
899 return ElementKind.EXCEPTION_PARAMETER;
900 else
901 return ElementKind.PARAMETER;
902 } else if ((flags & ENUM) != 0) {
903 return ElementKind.ENUM_CONSTANT;
904 } else if (owner.kind == TYP || owner.kind == ERR) {
905 return ElementKind.FIELD;
906 } else {
907 return ElementKind.LOCAL_VARIABLE;
908 }
909 }
910
911 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
912 return v.visitVariable(this, p);
913 }
914
915 public Object getConstantValue() { // Mirror API
916 return Constants.decode(getConstValue(), type);
917 }
918
919 public void setLazyConstValue(final Env<AttrContext> env,
920 final Log log,
921 final Attr attr,
922 final JCTree.JCExpression initializer)
923 {
924 setData(new Callable<Object>() {
925 public Object call() {
926 JavaFileObject source = log.useSource(env.toplevel.sourcefile);
927 try {
928 // In order to catch self-references, we set
929 // the variable's declaration position to
930 // maximal possible value, effectively marking
931 // the variable as undefined.
932 int pos = VarSymbol.this.pos;
933 VarSymbol.this.pos = Position.MAXPOS;
934 Type itype = attr.attribExpr(initializer, env, type);
935 VarSymbol.this.pos = pos;
936 if (itype.constValue() != null)
937 return attr.coerce(itype, type).constValue();
938 else
939 return null;
940 } finally {
941 log.useSource(source);
942 }
943 }
944 });
945 }
946
947 /**
948 * The variable's constant value, if this is a constant.
949 * Before the constant value is evaluated, it points to an
950 * initalizer environment. If this is not a constant, it can
951 * be used for other stuff.
952 */
953 private Object data;
954
955 public boolean isExceptionParameter() {
956 return data == ElementKind.EXCEPTION_PARAMETER;
957 }
958
959 public Object getConstValue() {
960 // TODO: Consider if getConstValue and getConstantValue can be collapsed
961 if (data == ElementKind.EXCEPTION_PARAMETER) {
962 return null;
963 } else if (data instanceof Callable<?>) {
964 // In this case, this is final a variable, with an as
965 // yet unevaluated initializer.
966 Callable<?> eval = (Callable<?>)data;
967 data = null; // to make sure we don't evaluate this twice.
968 try {
969 data = eval.call();
970 } catch (Exception ex) {
971 throw new AssertionError(ex);
972 }
973 }
974 return data;
975 }
976
977 public void setData(Object data) {
978 assert !(data instanceof Env<?>) : this;
979 this.data = data;
980 }
981 }
982
983 /** A class for method symbols.
984 */
985 public static class MethodSymbol extends Symbol implements ExecutableElement {
986
987 /** The code of the method. */
988 public Code code = null;
989
990 /** The parameters of the method. */
991 public List<VarSymbol> params = null;
992
993 /** The names of the parameters */
994 public List<Name> savedParameterNames;
995
996 /** For an attribute field accessor, its default value if any.
997 * The value is null if none appeared in the method
998 * declaration.
999 */
1000 public Attribute defaultValue = null;
1001
1002 /** Construct a method symbol, given its flags, name, type and owner.
1003 */
1004 public MethodSymbol(long flags, Name name, Type type, Symbol owner) {
1005 super(MTH, flags, name, type, owner);
1006 assert owner.type.tag != TYPEVAR : owner + "." + name;
1007 }
1008
1009 /** Clone this symbol with new owner.
1010 */
1011 public MethodSymbol clone(Symbol newOwner) {
1012 MethodSymbol m = new MethodSymbol(flags_field, name, type, newOwner);
1013 m.code = code;
1014 return m;
1015 }
1016
1017 /** The Java source which this symbol represents.
1018 */
1019 public String toString() {
1020 if ((flags() & BLOCK) != 0) {
1021 return owner.name.toString();
1022 } else {
1023 String s = (name == name.table.init)
1024 ? owner.name.toString()
1025 : name.toString();
1026 if (type != null) {
1027 if (type.tag == FORALL)
1028 s = "<" + ((ForAll)type).getTypeArguments() + ">" + s;
1029 s += "(" + type.argtypes((flags() & VARARGS) != 0) + ")";
1030 }
1031 return s;
1032 }
1033 }
1034
1035 /** find a symbol that this (proxy method) symbol implements.
1036 * @param c The class whose members are searched for
1037 * implementations
1038 */
1039 public Symbol implemented(TypeSymbol c, Types types) {
1040 Symbol impl = null;
1041 for (List<Type> is = types.interfaces(c.type);
1042 impl == null && is.nonEmpty();
1043 is = is.tail) {
1044 TypeSymbol i = is.head.tsym;
1045 for (Scope.Entry e = i.members().lookup(name);
1046 impl == null && e.scope != null;
1047 e = e.next()) {
1048 if (this.overrides(e.sym, (TypeSymbol)owner, types, true) &&
1049 // FIXME: I suspect the following requires a
1050 // subst() for a parametric return type.
1051 types.isSameType(type.getReturnType(),
1052 types.memberType(owner.type, e.sym).getReturnType())) {
1053 impl = e.sym;
1054 }
1055 if (impl == null)
1056 impl = implemented(i, types);
1057 }
1058 }
1059 return impl;
1060 }
1061
1062 /** Will the erasure of this method be considered by the VM to
1063 * override the erasure of the other when seen from class `origin'?
1064 */
1065 public boolean binaryOverrides(Symbol _other, TypeSymbol origin, Types types) {
1066 if (isConstructor() || _other.kind != MTH) return false;
1067
1068 if (this == _other) return true;
1069 MethodSymbol other = (MethodSymbol)_other;
1070
1071 // check for a direct implementation
1072 if (other.isOverridableIn((TypeSymbol)owner) &&
1073 types.asSuper(owner.type, other.owner) != null &&
1074 types.isSameType(erasure(types), other.erasure(types)))
1075 return true;
1076
1077 // check for an inherited implementation
1078 return
1079 (flags() & ABSTRACT) == 0 &&
1080 other.isOverridableIn(origin) &&
1081 this.isMemberOf(origin, types) &&
1082 types.isSameType(erasure(types), other.erasure(types));
1083 }
1084
1085 /** The implementation of this (abstract) symbol in class origin,
1086 * from the VM's point of view, null if method does not have an
1087 * implementation in class.
1088 * @param origin The class of which the implementation is a member.
1089 */
1090 public MethodSymbol binaryImplementation(ClassSymbol origin, Types types) {
1091 for (TypeSymbol c = origin; c != null; c = types.supertype(c.type).tsym) {
1092 for (Scope.Entry e = c.members().lookup(name);
1093 e.scope != null;
1094 e = e.next()) {
1095 if (e.sym.kind == MTH &&
1096 ((MethodSymbol)e.sym).binaryOverrides(this, origin, types))
1097 return (MethodSymbol)e.sym;
1098 }
1099 }
1100 return null;
1101 }
1102
1103 /** Does this symbol override `other' symbol, when both are seen as
1104 * members of class `origin'? It is assumed that _other is a member
1105 * of origin.
1106 *
1107 * It is assumed that both symbols have the same name. The static
1108 * modifier is ignored for this test.
1109 *
1110 * See JLS 8.4.6.1 (without transitivity) and 8.4.6.4
1111 */
1112 public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult) {
1113 if (isConstructor() || _other.kind != MTH) return false;
1114
1115 if (this == _other) return true;
1116 MethodSymbol other = (MethodSymbol)_other;
1117
1118 // check for a direct implementation
1119 if (other.isOverridableIn((TypeSymbol)owner) &&
1120 types.asSuper(owner.type, other.owner) != null) {
1121 Type mt = types.memberType(owner.type, this);
1122 Type ot = types.memberType(owner.type, other);
1123 if (types.isSubSignature(mt, ot)) {
1124 if (!checkResult)
1125 return true;
1126 if (types.returnTypeSubstitutable(mt, ot))
1127 return true;
1128 }
1129 }
1130
1131 // check for an inherited implementation
1132 if ((flags() & ABSTRACT) != 0 ||
1133 (other.flags() & ABSTRACT) == 0 ||
1134 !other.isOverridableIn(origin) ||
1135 !this.isMemberOf(origin, types))
1136 return false;
1137
1138 // assert types.asSuper(origin.type, other.owner) != null;
1139 Type mt = types.memberType(origin.type, this);
1140 Type ot = types.memberType(origin.type, other);
1141 return
1142 types.isSubSignature(mt, ot) &&
1143 (!checkResult || types.resultSubtype(mt, ot, Warner.noWarnings));
1144 }
1145
1146 private boolean isOverridableIn(TypeSymbol origin) {
1147 // JLS3 8.4.6.1
1148 switch ((int)(flags_field & Flags.AccessFlags)) {
1149 case Flags.PRIVATE:
1150 return false;
1151 case Flags.PUBLIC:
1152 return true;
1153 case Flags.PROTECTED:
1154 return (origin.flags() & INTERFACE) == 0;
1155 case 0:
1156 // for package private: can only override in the same
1157 // package
1158 return
1159 this.packge() == origin.packge() &&
1160 (origin.flags() & INTERFACE) == 0;
1161 default:
1162 return false;
1163 }
1164 }
1165
1166 /** The implementation of this (abstract) symbol in class origin;
1167 * null if none exists. Synthetic methods are not considered
1168 * as possible implementations.
1169 */
1170 public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult) {
1171 for (Type t = origin.type; t.tag == CLASS; t = types.supertype(t)) {
1172 TypeSymbol c = t.tsym;
1173 for (Scope.Entry e = c.members().lookup(name);
1174 e.scope != null;
1175 e = e.next()) {
1176 if (e.sym.kind == MTH) {
1177 MethodSymbol m = (MethodSymbol) e.sym;
1178 if (m.overrides(this, origin, types, checkResult) &&
1179 (m.flags() & SYNTHETIC) == 0)
1180 return m;
1181 }
1182 }
1183 }
1184 // if origin is derived from a raw type, we might have missed
1185 // an implementation because we do not know enough about instantiations.
1186 // in this case continue with the supertype as origin.
1187 if (types.isDerivedRaw(origin.type))
1188 return implementation(types.supertype(origin.type).tsym, types, checkResult);
1189 else
1190 return null;
1191 }
1192
1193 public List<VarSymbol> params() {
1194 owner.complete();
1195 if (params == null) {
1196 List<Name> names = savedParameterNames;
1197 savedParameterNames = null;
1198 if (names == null) {
1199 names = List.nil();
1200 int i = 0;
1201 for (Type t : type.getParameterTypes())
1202 names = names.prepend(name.table.fromString("arg" + i++));
1203 names = names.reverse();
1204 }
1205 ListBuffer<VarSymbol> buf = new ListBuffer<VarSymbol>();
1206 for (Type t : type.getParameterTypes()) {
1207 buf.append(new VarSymbol(PARAMETER, names.head, t, this));
1208 names = names.tail;
1209 }
1210 params = buf.toList();
1211 }
1212 return params;
1213 }
1214
1215 public Symbol asMemberOf(Type site, Types types) {
1216 return new MethodSymbol(flags_field, name, types.memberType(site, this), owner);
1217 }
1218
1219 public ElementKind getKind() {
1220 if (name == name.table.init)
1221 return ElementKind.CONSTRUCTOR;
1222 else if (name == name.table.clinit)
1223 return ElementKind.STATIC_INIT;
1224 else
1225 return ElementKind.METHOD;
1226 }
1227
1228 public Attribute getDefaultValue() {
1229 return defaultValue;
1230 }
1231
1232 public List<VarSymbol> getParameters() {
1233 return params();
1234 }
1235
1236 public boolean isVarArgs() {
1237 return (flags() & VARARGS) != 0;
1238 }
1239
1240 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
1241 return v.visitExecutable(this, p);
1242 }
1243
1244 public Type getReturnType() {
1245 return asType().getReturnType();
1246 }
1247
1248 public List<Type> getThrownTypes() {
1249 return asType().getThrownTypes();
1250 }
1251 }
1252
1253 /** A class for predefined operators.
1254 */
1255 public static class OperatorSymbol extends MethodSymbol {
1256
1257 public int opcode;
1258
1259 public OperatorSymbol(Name name, Type type, int opcode, Symbol owner) {
1260 super(PUBLIC | STATIC, name, type, owner);
1261 this.opcode = opcode;
1262 }
1263 }
1264
1265 /** Symbol completer interface.
1266 */
1267 public static interface Completer {
1268 void complete(Symbol sym) throws CompletionFailure;
1269 }
1270
1271 public static class CompletionFailure extends RuntimeException {
1272 private static final long serialVersionUID = 0;
1273 public Symbol sym;
1274
1275 /** A localized string describing the failure.
1276 */
1277 public String errmsg;
1278
1279 public CompletionFailure(Symbol sym, String errmsg) {
1280 this.sym = sym;
1281 this.errmsg = errmsg;
1282 // this.printStackTrace();//DEBUG
1283 }
1284
1285 public String getMessage() {
1286 return errmsg;
1287 }
1288
1289 @Override
1290 public CompletionFailure initCause(Throwable cause) {
1291 super.initCause(cause);
1292 return this;
1293 }
1294
1295 }
1296 }

mercurial