src/share/classes/com/sun/tools/javac/comp/Attr.java

changeset 1521
71f35e4b93a5
parent 1513
cf84b07a82db
child 1550
1df20330f6bd
child 1570
f91144b7da75
equal deleted inserted replaced
1520:5c956be64b9e 1521:71f35e4b93a5
24 */ 24 */
25 25
26 package com.sun.tools.javac.comp; 26 package com.sun.tools.javac.comp;
27 27
28 import java.util.*; 28 import java.util.*;
29 import java.util.Set;
30 29
31 import javax.lang.model.element.ElementKind; 30 import javax.lang.model.element.ElementKind;
31 import javax.lang.model.type.TypeKind;
32 import javax.tools.JavaFileObject; 32 import javax.tools.JavaFileObject;
33 33
34 import com.sun.source.tree.IdentifierTree; 34 import com.sun.source.tree.IdentifierTree;
35 import com.sun.source.tree.MemberReferenceTree.ReferenceMode; 35 import com.sun.source.tree.MemberReferenceTree.ReferenceMode;
36 import com.sun.source.tree.MemberSelectTree; 36 import com.sun.source.tree.MemberSelectTree;
43 import com.sun.tools.javac.comp.Check.CheckContext; 43 import com.sun.tools.javac.comp.Check.CheckContext;
44 import com.sun.tools.javac.comp.DeferredAttr.AttrMode; 44 import com.sun.tools.javac.comp.DeferredAttr.AttrMode;
45 import com.sun.tools.javac.comp.Infer.InferenceContext; 45 import com.sun.tools.javac.comp.Infer.InferenceContext;
46 import com.sun.tools.javac.comp.Infer.InferenceContext.FreeTypeListener; 46 import com.sun.tools.javac.comp.Infer.InferenceContext.FreeTypeListener;
47 import com.sun.tools.javac.jvm.*; 47 import com.sun.tools.javac.jvm.*;
48 import com.sun.tools.javac.jvm.Target;
49 import com.sun.tools.javac.tree.*; 48 import com.sun.tools.javac.tree.*;
50 import com.sun.tools.javac.tree.JCTree.*; 49 import com.sun.tools.javac.tree.JCTree.*;
51 import com.sun.tools.javac.tree.JCTree.JCPolyExpression.*; 50 import com.sun.tools.javac.tree.JCTree.JCPolyExpression.*;
52 import com.sun.tools.javac.util.*; 51 import com.sun.tools.javac.util.*;
53 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; 52 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
878 MethodSymbol prevMethod = chk.setMethod(m); 877 MethodSymbol prevMethod = chk.setMethod(m);
879 try { 878 try {
880 deferredLintHandler.flush(tree.pos()); 879 deferredLintHandler.flush(tree.pos());
881 chk.checkDeprecatedAnnotation(tree.pos(), m); 880 chk.checkDeprecatedAnnotation(tree.pos(), m);
882 881
882
883 // Create a new environment with local scope 883 // Create a new environment with local scope
884 // for attributing the method. 884 // for attributing the method.
885 Env<AttrContext> localEnv = memberEnter.methodEnv(tree, env); 885 Env<AttrContext> localEnv = memberEnter.methodEnv(tree, env);
886 localEnv.info.lint = lint; 886 localEnv.info.lint = lint;
887 887
920 // Check that type parameters are well-formed. 920 // Check that type parameters are well-formed.
921 chk.validate(tree.typarams, localEnv); 921 chk.validate(tree.typarams, localEnv);
922 922
923 // Check that result type is well-formed. 923 // Check that result type is well-formed.
924 chk.validate(tree.restype, localEnv); 924 chk.validate(tree.restype, localEnv);
925
926 // Check that receiver type is well-formed.
927 if (tree.recvparam != null) {
928 // Use a new environment to check the receiver parameter.
929 // Otherwise I get "might not have been initialized" errors.
930 // Is there a better way?
931 Env<AttrContext> newEnv = memberEnter.methodEnv(tree, env);
932 attribType(tree.recvparam, newEnv);
933 chk.validate(tree.recvparam, newEnv);
934 if (!(tree.recvparam.type == m.owner.type || types.isSameType(tree.recvparam.type, m.owner.type))) {
935 // The == covers the common non-generic case, but for generic classes we need isSameType;
936 // note that equals didn't work.
937 log.error(tree.recvparam.pos(), "incorrect.receiver.type");
938 }
939 }
925 940
926 // annotation method checks 941 // annotation method checks
927 if ((owner.flags() & ANNOTATION) != 0) { 942 if ((owner.flags() & ANNOTATION) != 0) {
928 // annotation method cannot have throws clause 943 // annotation method cannot have throws clause
929 if (tree.thrown.nonEmpty()) { 944 if (tree.thrown.nonEmpty()) {
994 "call.to.super.not.allowed.in.enum.ctor", 1009 "call.to.super.not.allowed.in.enum.ctor",
995 env.enclClass.sym); 1010 env.enclClass.sym);
996 } 1011 }
997 } 1012 }
998 1013
1014 // Attribute all type annotations in the body
1015 memberEnter.typeAnnotate(tree.body, localEnv, m);
1016 annotate.flush();
1017
999 // Attribute method body. 1018 // Attribute method body.
1000 attribStat(tree.body, localEnv); 1019 attribStat(tree.body, localEnv);
1001 } 1020 }
1021
1002 localEnv.info.scope.leave(); 1022 localEnv.info.scope.leave();
1003 result = tree.type = m.type; 1023 result = tree.type = m.type;
1004 chk.validateAnnotations(tree.mods.annotations, m); 1024 chk.validateAnnotations(tree.mods.annotations, m);
1005 } 1025 }
1006 finally { 1026 finally {
1015 if (tree.sym != null) { 1035 if (tree.sym != null) {
1016 // parameters have already been entered 1036 // parameters have already been entered
1017 env.info.scope.enter(tree.sym); 1037 env.info.scope.enter(tree.sym);
1018 } else { 1038 } else {
1019 memberEnter.memberEnter(tree, env); 1039 memberEnter.memberEnter(tree, env);
1040 annotate.flush();
1041 }
1042 } else {
1043 if (tree.init != null) {
1044 // Field initializer expression need to be entered.
1045 memberEnter.typeAnnotate(tree.init, env, tree.sym);
1020 annotate.flush(); 1046 annotate.flush();
1021 } 1047 }
1022 } 1048 }
1023 1049
1024 VarSymbol v = tree.sym; 1050 VarSymbol v = tree.sym;
1074 env.dup(tree, env.info.dup(env.info.scope.dupUnshared())); 1100 env.dup(tree, env.info.dup(env.info.scope.dupUnshared()));
1075 localEnv.info.scope.owner = 1101 localEnv.info.scope.owner =
1076 new MethodSymbol(tree.flags | BLOCK, names.empty, null, 1102 new MethodSymbol(tree.flags | BLOCK, names.empty, null,
1077 env.info.scope.owner); 1103 env.info.scope.owner);
1078 if ((tree.flags & STATIC) != 0) localEnv.info.staticLevel++; 1104 if ((tree.flags & STATIC) != 0) localEnv.info.staticLevel++;
1105
1106 // Attribute all type annotations in the block
1107 memberEnter.typeAnnotate(tree, localEnv, localEnv.info.scope.owner);
1108 annotate.flush();
1109
1079 attribStats(tree.stats, localEnv); 1110 attribStats(tree.stats, localEnv);
1080 } else { 1111 } else {
1081 // Create a new local environment with a local scope. 1112 // Create a new local environment with a local scope.
1082 Env<AttrContext> localEnv = 1113 Env<AttrContext> localEnv =
1083 env.dup(tree, env.info.dup(env.info.scope.dup())); 1114 env.dup(tree, env.info.dup(env.info.scope.dup()));
1845 JCClassDecl cdef = tree.def; 1876 JCClassDecl cdef = tree.def;
1846 1877
1847 // If enclosing class is given, attribute it, and 1878 // If enclosing class is given, attribute it, and
1848 // complete class name to be fully qualified 1879 // complete class name to be fully qualified
1849 JCExpression clazz = tree.clazz; // Class field following new 1880 JCExpression clazz = tree.clazz; // Class field following new
1850 JCExpression clazzid = // Identifier in class field 1881 JCExpression clazzid; // Identifier in class field
1851 (clazz.hasTag(TYPEAPPLY)) 1882 JCAnnotatedType annoclazzid; // Annotated type enclosing clazzid
1852 ? ((JCTypeApply) clazz).clazz 1883 annoclazzid = null;
1853 : clazz; 1884
1885 if (clazz.hasTag(TYPEAPPLY)) {
1886 clazzid = ((JCTypeApply) clazz).clazz;
1887 if (clazzid.hasTag(ANNOTATED_TYPE)) {
1888 annoclazzid = (JCAnnotatedType) clazzid;
1889 clazzid = annoclazzid.underlyingType;
1890 }
1891 } else {
1892 if (clazz.hasTag(ANNOTATED_TYPE)) {
1893 annoclazzid = (JCAnnotatedType) clazz;
1894 clazzid = annoclazzid.underlyingType;
1895 } else {
1896 clazzid = clazz;
1897 }
1898 }
1854 1899
1855 JCExpression clazzid1 = clazzid; // The same in fully qualified form 1900 JCExpression clazzid1 = clazzid; // The same in fully qualified form
1856 1901
1857 if (tree.encl != null) { 1902 if (tree.encl != null) {
1858 // We are seeing a qualified new, of the form 1903 // We are seeing a qualified new, of the form
1863 // resolve it with standard techniques later. I.e., if 1908 // resolve it with standard techniques later. I.e., if
1864 // <expr> has type T, then <expr>.new C <...> (...) 1909 // <expr> has type T, then <expr>.new C <...> (...)
1865 // yields a clazz T.C. 1910 // yields a clazz T.C.
1866 Type encltype = chk.checkRefType(tree.encl.pos(), 1911 Type encltype = chk.checkRefType(tree.encl.pos(),
1867 attribExpr(tree.encl, env)); 1912 attribExpr(tree.encl, env));
1913 // TODO 308: in <expr>.new C, do we also want to add the type annotations
1914 // from expr to the combined type, or not? Yes, do this.
1868 clazzid1 = make.at(clazz.pos).Select(make.Type(encltype), 1915 clazzid1 = make.at(clazz.pos).Select(make.Type(encltype),
1869 ((JCIdent) clazzid).name); 1916 ((JCIdent) clazzid).name);
1870 if (clazz.hasTag(TYPEAPPLY)) 1917
1871 clazz = make.at(tree.pos). 1918 if (clazz.hasTag(ANNOTATED_TYPE)) {
1919 JCAnnotatedType annoType = (JCAnnotatedType) clazz;
1920 List<JCAnnotation> annos = annoType.annotations;
1921
1922 if (annoType.underlyingType.hasTag(TYPEAPPLY)) {
1923 clazzid1 = make.at(tree.pos).
1924 TypeApply(clazzid1,
1925 ((JCTypeApply) clazz).arguments);
1926 }
1927
1928 clazzid1 = make.at(tree.pos).
1929 AnnotatedType(annos, clazzid1);
1930 } else if (clazz.hasTag(TYPEAPPLY)) {
1931 clazzid1 = make.at(tree.pos).
1872 TypeApply(clazzid1, 1932 TypeApply(clazzid1,
1873 ((JCTypeApply) clazz).arguments); 1933 ((JCTypeApply) clazz).arguments);
1874 else 1934 }
1875 clazz = clazzid1; 1935
1936 clazz = clazzid1;
1876 } 1937 }
1877 1938
1878 // Attribute clazz expression and store 1939 // Attribute clazz expression and store
1879 // symbol + type back into the attributed tree. 1940 // symbol + type back into the attributed tree.
1880 Type clazztype = TreeInfo.isEnumInit(env.tree) ? 1941 Type clazztype = TreeInfo.isEnumInit(env.tree) ?
1887 // We have to work in this case to store 1948 // We have to work in this case to store
1888 // symbol + type back into the attributed tree. 1949 // symbol + type back into the attributed tree.
1889 tree.clazz.type = clazztype; 1950 tree.clazz.type = clazztype;
1890 TreeInfo.setSymbol(clazzid, TreeInfo.symbol(clazzid1)); 1951 TreeInfo.setSymbol(clazzid, TreeInfo.symbol(clazzid1));
1891 clazzid.type = ((JCIdent) clazzid).sym.type; 1952 clazzid.type = ((JCIdent) clazzid).sym.type;
1953 if (annoclazzid != null) {
1954 annoclazzid.type = clazzid.type;
1955 }
1892 if (!clazztype.isErroneous()) { 1956 if (!clazztype.isErroneous()) {
1893 if (cdef != null && clazztype.tsym.isInterface()) { 1957 if (cdef != null && clazztype.tsym.isInterface()) {
1894 log.error(tree.encl.pos(), "anon.class.impl.intf.no.qual.for.new"); 1958 log.error(tree.encl.pos(), "anon.class.impl.intf.no.qual.for.new");
1895 } else if (clazztype.tsym.isStatic()) { 1959 } else if (clazztype.tsym.isStatic()) {
1896 log.error(tree.encl.pos(), "qualified.new.of.static.class", clazztype.tsym); 1960 log.error(tree.encl.pos(), "qualified.new.of.static.class", clazztype.tsym);
3253 // 3317 //
3254 // Then the type of the last expression above is 3318 // Then the type of the last expression above is
3255 // Tree<Point>.Visitor. 3319 // Tree<Point>.Visitor.
3256 else if (ownOuter.hasTag(CLASS) && site != ownOuter) { 3320 else if (ownOuter.hasTag(CLASS) && site != ownOuter) {
3257 Type normOuter = site; 3321 Type normOuter = site;
3258 if (normOuter.hasTag(CLASS)) 3322 if (normOuter.hasTag(CLASS)) {
3259 normOuter = types.asEnclosingSuper(site, ownOuter.tsym); 3323 normOuter = types.asEnclosingSuper(site, ownOuter.tsym);
3324 if (site.getKind() == TypeKind.ANNOTATED) {
3325 // Propagate any type annotations.
3326 // TODO: should asEnclosingSuper do this?
3327 // Note that the type annotations in site will be updated
3328 // by annotateType. Therefore, modify site instead
3329 // of creating a new AnnotatedType.
3330 ((AnnotatedType)site).underlyingType = normOuter;
3331 normOuter = site;
3332 }
3333 }
3260 if (normOuter == null) // perhaps from an import 3334 if (normOuter == null) // perhaps from an import
3261 normOuter = types.erasure(ownOuter); 3335 normOuter = types.erasure(ownOuter);
3262 if (normOuter != ownOuter) 3336 if (normOuter != ownOuter)
3263 owntype = new ClassType( 3337 owntype = new ClassType(
3264 normOuter, List.<Type>nil(), owntype.tsym); 3338 normOuter, List.<Type>nil(), owntype.tsym);
3642 public void visitTypeIntersection(JCTypeIntersection tree) { 3716 public void visitTypeIntersection(JCTypeIntersection tree) {
3643 attribTypes(tree.bounds, env); 3717 attribTypes(tree.bounds, env);
3644 tree.type = result = checkIntersection(tree, tree.bounds); 3718 tree.type = result = checkIntersection(tree, tree.bounds);
3645 } 3719 }
3646 3720
3647 public void visitTypeParameter(JCTypeParameter tree) { 3721 public void visitTypeParameter(JCTypeParameter tree) {
3648 TypeVar typeVar = (TypeVar)tree.type; 3722 TypeVar typeVar = (TypeVar) tree.type;
3723
3724 if (tree.annotations != null && tree.annotations.nonEmpty()) {
3725 AnnotatedType antype = new AnnotatedType(typeVar);
3726 annotateType(antype, tree.annotations);
3727 tree.type = antype;
3728 }
3729
3649 if (!typeVar.bound.isErroneous()) { 3730 if (!typeVar.bound.isErroneous()) {
3650 //fixup type-parameter bound computed in 'attribTypeVariables' 3731 //fixup type-parameter bound computed in 'attribTypeVariables'
3651 typeVar.bound = checkIntersection(tree, tree.bounds); 3732 typeVar.bound = checkIntersection(tree, tree.bounds);
3652 } 3733 }
3653 } 3734 }
3737 } 3818 }
3738 3819
3739 public void visitAnnotation(JCAnnotation tree) { 3820 public void visitAnnotation(JCAnnotation tree) {
3740 log.error(tree.pos(), "annotation.not.valid.for.type", pt()); 3821 log.error(tree.pos(), "annotation.not.valid.for.type", pt());
3741 result = tree.type = syms.errType; 3822 result = tree.type = syms.errType;
3823 }
3824
3825 public void visitAnnotatedType(JCAnnotatedType tree) {
3826 Type underlyingType = attribType(tree.getUnderlyingType(), env);
3827 this.attribAnnotationTypes(tree.annotations, env);
3828 AnnotatedType antype = new AnnotatedType(underlyingType);
3829 annotateType(antype, tree.annotations);
3830 result = tree.type = antype;
3831 }
3832
3833 /**
3834 * Apply the annotations to the particular type.
3835 */
3836 public void annotateType(final AnnotatedType type, final List<JCAnnotation> annotations) {
3837 if (annotations.isEmpty())
3838 return;
3839 annotate.typeAnnotation(new Annotate.Annotator() {
3840 @Override
3841 public String toString() {
3842 return "annotate " + annotations + " onto " + type;
3843 }
3844 @Override
3845 public void enterAnnotation() {
3846 List<Attribute.TypeCompound> compounds = fromAnnotations(annotations);
3847 type.typeAnnotations = compounds;
3848 }
3849 });
3850 }
3851
3852 private static List<Attribute.TypeCompound> fromAnnotations(List<JCAnnotation> annotations) {
3853 if (annotations.isEmpty())
3854 return List.nil();
3855
3856 ListBuffer<Attribute.TypeCompound> buf = ListBuffer.lb();
3857 for (JCAnnotation anno : annotations) {
3858 buf.append((Attribute.TypeCompound) anno.attribute);
3859 }
3860 return buf.toList();
3742 } 3861 }
3743 3862
3744 public void visitErroneous(JCErroneous tree) { 3863 public void visitErroneous(JCErroneous tree) {
3745 if (tree.errs != null) 3864 if (tree.errs != null)
3746 for (JCTree err : tree.errs) 3865 for (JCTree err : tree.errs)
3970 isSerializable(c) && 4089 isSerializable(c) &&
3971 (c.flags() & Flags.ENUM) == 0 && 4090 (c.flags() & Flags.ENUM) == 0 &&
3972 (c.flags() & ABSTRACT) == 0) { 4091 (c.flags() & ABSTRACT) == 0) {
3973 checkSerialVersionUID(tree, c); 4092 checkSerialVersionUID(tree, c);
3974 } 4093 }
4094
4095 // Correctly organize the postions of the type annotations
4096 TypeAnnotations.organizeTypeAnnotationsBodies(this.syms, this.names, this.log, tree);
4097
4098 // Check type annotations applicability rules
4099 validateTypeAnnotations(tree);
3975 } 4100 }
3976 // where 4101 // where
3977 /** get a diagnostic position for an attribute of Type t, or null if attribute missing */ 4102 /** get a diagnostic position for an attribute of Type t, or null if attribute missing */
3978 private DiagnosticPosition getDiagnosticPosition(JCClassDecl tree, Type t) { 4103 private DiagnosticPosition getDiagnosticPosition(JCClassDecl tree, Type t) {
3979 for(List<JCAnnotation> al = tree.mods.annotations; !al.isEmpty(); al = al.tail) { 4104 for(List<JCAnnotation> al = tree.mods.annotations; !al.isEmpty(); al = al.tail) {
4027 4152
4028 private Type capture(Type type) { 4153 private Type capture(Type type) {
4029 return types.capture(type); 4154 return types.capture(type);
4030 } 4155 }
4031 4156
4157 private void validateTypeAnnotations(JCTree tree) {
4158 tree.accept(typeAnnotationsValidator);
4159 }
4160 //where
4161 private final JCTree.Visitor typeAnnotationsValidator =
4162 new TreeScanner() {
4163 public void visitAnnotation(JCAnnotation tree) {
4164 if (tree.hasTag(TYPE_ANNOTATION)) {
4165 // TODO: It seems to WMD as if the annotation in
4166 // parameters, in particular also the recvparam, are never
4167 // of type JCTypeAnnotation and therefore never checked!
4168 // Luckily this check doesn't really do anything that isn't
4169 // also done elsewhere.
4170 chk.validateTypeAnnotation(tree, false);
4171 }
4172 super.visitAnnotation(tree);
4173 }
4174 public void visitTypeParameter(JCTypeParameter tree) {
4175 chk.validateTypeAnnotations(tree.annotations, true);
4176 scan(tree.bounds);
4177 // Don't call super.
4178 // This is needed because above we call validateTypeAnnotation with
4179 // false, which would forbid annotations on type parameters.
4180 // super.visitTypeParameter(tree);
4181 }
4182 public void visitMethodDef(JCMethodDecl tree) {
4183 // Static methods cannot have receiver type annotations.
4184 // In test case FailOver15.java, the nested method getString has
4185 // a null sym, because an unknown class is instantiated.
4186 // I would say it's safe to skip.
4187 if (tree.sym != null && (tree.sym.flags() & Flags.STATIC) != 0) {
4188 if (tree.recvparam != null) {
4189 // TODO: better error message. Is the pos good?
4190 log.error(tree.recvparam.pos(), "annotation.type.not.applicable");
4191 }
4192 }
4193 if (tree.restype != null && tree.restype.type != null) {
4194 validateAnnotatedType(tree.restype, tree.restype.type);
4195 }
4196 super.visitMethodDef(tree);
4197 }
4198 public void visitVarDef(final JCVariableDecl tree) {
4199 if (tree.sym != null && tree.sym.type != null)
4200 validateAnnotatedType(tree, tree.sym.type);
4201 super.visitVarDef(tree);
4202 }
4203 public void visitTypeCast(JCTypeCast tree) {
4204 if (tree.clazz != null && tree.clazz.type != null)
4205 validateAnnotatedType(tree.clazz, tree.clazz.type);
4206 super.visitTypeCast(tree);
4207 }
4208 public void visitTypeTest(JCInstanceOf tree) {
4209 if (tree.clazz != null && tree.clazz.type != null)
4210 validateAnnotatedType(tree.clazz, tree.clazz.type);
4211 super.visitTypeTest(tree);
4212 }
4213 // TODO: what else do we need?
4214 // public void visitNewClass(JCNewClass tree) {
4215 // public void visitNewArray(JCNewArray tree) {
4216
4217 /* I would want to model this after
4218 * com.sun.tools.javac.comp.Check.Validator.visitSelectInternal(JCFieldAccess)
4219 * and override visitSelect and visitTypeApply.
4220 * However, we only set the annotated type in the top-level type
4221 * of the symbol.
4222 * Therefore, we need to override each individual location where a type
4223 * can occur.
4224 */
4225 private void validateAnnotatedType(final JCTree errtree, final Type type) {
4226 if (type.getEnclosingType() != null &&
4227 type != type.getEnclosingType()) {
4228 validateEnclosingAnnotatedType(errtree, type.getEnclosingType());
4229 }
4230 for (Type targ : type.getTypeArguments()) {
4231 validateAnnotatedType(errtree, targ);
4232 }
4233 }
4234 private void validateEnclosingAnnotatedType(final JCTree errtree, final Type type) {
4235 validateAnnotatedType(errtree, type);
4236 if (type.tsym != null &&
4237 type.tsym.isStatic() &&
4238 type.getAnnotations().nonEmpty()) {
4239 // Enclosing static classes cannot have type annotations.
4240 log.error(errtree.pos(), "cant.annotate.static.class");
4241 }
4242 }
4243 };
4244
4032 // <editor-fold desc="post-attribution visitor"> 4245 // <editor-fold desc="post-attribution visitor">
4033 4246
4034 /** 4247 /**
4035 * Handle missing types/symbols in an AST. This routine is useful when 4248 * Handle missing types/symbols in an AST. This routine is useful when
4036 * the compiler has encountered some errors (which might have ended up 4249 * the compiler has encountered some errors (which might have ended up

mercurial