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; |
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()) { |
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 |