904 * class B<A extends C> { ... } |
904 * class B<A extends C> { ... } |
905 * class C extends B<C> { ... } |
905 * class C extends B<C> { ... } |
906 * |
906 * |
907 * and we can't make sure that the bound is already attributed because |
907 * and we can't make sure that the bound is already attributed because |
908 * of possible cycles. |
908 * of possible cycles. |
909 */ |
909 * |
910 private Validator validator = new Validator(); |
910 * Visitor method: Validate a type expression, if it is not null, catching |
911 |
|
912 /** Visitor method: Validate a type expression, if it is not null, catching |
|
913 * and reporting any completion failures. |
911 * and reporting any completion failures. |
914 */ |
912 */ |
915 void validate(JCTree tree, Env<AttrContext> env) { |
913 void validate(JCTree tree, Env<AttrContext> env) { |
916 try { |
914 validate(tree, env, true); |
917 if (tree != null) { |
915 } |
918 validator.env = env; |
916 void validate(JCTree tree, Env<AttrContext> env, boolean checkRaw) { |
919 tree.accept(validator); |
917 new Validator(env).validateTree(tree, checkRaw, true); |
920 checkRaw(tree, env); |
|
921 } |
|
922 } catch (CompletionFailure ex) { |
|
923 completionError(tree.pos(), ex); |
|
924 } |
|
925 } |
|
926 //where |
|
927 void checkRaw(JCTree tree, Env<AttrContext> env) { |
|
928 if (lint.isEnabled(Lint.LintCategory.RAW) && |
|
929 tree.type.tag == CLASS && |
|
930 !TreeInfo.isDiamond(tree) && |
|
931 !env.enclClass.name.isEmpty() && //anonymous or intersection |
|
932 tree.type.isRaw()) { |
|
933 log.warning(Lint.LintCategory.RAW, |
|
934 tree.pos(), "raw.class.use", tree.type, tree.type.tsym.type); |
|
935 } |
|
936 } |
918 } |
937 |
919 |
938 /** Visitor method: Validate a list of type expressions. |
920 /** Visitor method: Validate a list of type expressions. |
939 */ |
921 */ |
940 void validate(List<? extends JCTree> trees, Env<AttrContext> env) { |
922 void validate(List<? extends JCTree> trees, Env<AttrContext> env) { |
944 |
926 |
945 /** A visitor class for type validation. |
927 /** A visitor class for type validation. |
946 */ |
928 */ |
947 class Validator extends JCTree.Visitor { |
929 class Validator extends JCTree.Visitor { |
948 |
930 |
|
931 boolean isOuter; |
|
932 Env<AttrContext> env; |
|
933 |
|
934 Validator(Env<AttrContext> env) { |
|
935 this.env = env; |
|
936 } |
|
937 |
949 @Override |
938 @Override |
950 public void visitTypeArray(JCArrayTypeTree tree) { |
939 public void visitTypeArray(JCArrayTypeTree tree) { |
951 validate(tree.elemtype, env); |
940 tree.elemtype.accept(this); |
952 } |
941 } |
953 |
942 |
954 @Override |
943 @Override |
955 public void visitTypeApply(JCTypeApply tree) { |
944 public void visitTypeApply(JCTypeApply tree) { |
956 if (tree.type.tag == CLASS) { |
945 if (tree.type.tag == CLASS) { |
958 List<Type> actuals = tree.type.allparams(); |
947 List<Type> actuals = tree.type.allparams(); |
959 List<JCExpression> args = tree.arguments; |
948 List<JCExpression> args = tree.arguments; |
960 List<Type> forms = tree.type.tsym.type.getTypeArguments(); |
949 List<Type> forms = tree.type.tsym.type.getTypeArguments(); |
961 ListBuffer<Type> tvars_buf = new ListBuffer<Type>(); |
950 ListBuffer<Type> tvars_buf = new ListBuffer<Type>(); |
962 |
951 |
|
952 boolean is_java_lang_Class = tree.type.tsym.flatName() == names.java_lang_Class; |
|
953 |
963 // For matching pairs of actual argument types `a' and |
954 // For matching pairs of actual argument types `a' and |
964 // formal type parameters with declared bound `b' ... |
955 // formal type parameters with declared bound `b' ... |
965 while (args.nonEmpty() && forms.nonEmpty()) { |
956 while (args.nonEmpty() && forms.nonEmpty()) { |
966 validate(args.head, env); |
957 validateTree(args.head, |
|
958 !(isOuter && is_java_lang_Class), |
|
959 false); |
967 |
960 |
968 // exact type arguments needs to know their |
961 // exact type arguments needs to know their |
969 // bounds (for upper and lower bound |
962 // bounds (for upper and lower bound |
970 // calculations). So we create new TypeVars with |
963 // calculations). So we create new TypeVars with |
971 // bounds substed with actuals. |
964 // bounds substed with actuals. |
1013 } |
1006 } |
1014 } |
1007 } |
1015 |
1008 |
1016 @Override |
1009 @Override |
1017 public void visitTypeParameter(JCTypeParameter tree) { |
1010 public void visitTypeParameter(JCTypeParameter tree) { |
1018 validate(tree.bounds, env); |
1011 validateTrees(tree.bounds, true, isOuter); |
1019 checkClassBounds(tree.pos(), tree.type); |
1012 checkClassBounds(tree.pos(), tree.type); |
1020 } |
1013 } |
1021 |
1014 |
1022 @Override |
1015 @Override |
1023 public void visitWildcard(JCWildcard tree) { |
1016 public void visitWildcard(JCWildcard tree) { |
1024 if (tree.inner != null) |
1017 if (tree.inner != null) |
1025 validate(tree.inner, env); |
1018 validateTree(tree.inner, true, isOuter); |
1026 } |
1019 } |
1027 |
1020 |
1028 @Override |
1021 @Override |
1029 public void visitSelect(JCFieldAccess tree) { |
1022 public void visitSelect(JCFieldAccess tree) { |
1030 if (tree.type.tag == CLASS) { |
1023 if (tree.type.tag == CLASS) { |
1058 */ |
1051 */ |
1059 @Override |
1052 @Override |
1060 public void visitTree(JCTree tree) { |
1053 public void visitTree(JCTree tree) { |
1061 } |
1054 } |
1062 |
1055 |
1063 Env<AttrContext> env; |
1056 public void validateTree(JCTree tree, boolean checkRaw, boolean isOuter) { |
|
1057 try { |
|
1058 if (tree != null) { |
|
1059 this.isOuter = isOuter; |
|
1060 tree.accept(this); |
|
1061 if (checkRaw) |
|
1062 checkRaw(tree, env); |
|
1063 } |
|
1064 } catch (CompletionFailure ex) { |
|
1065 completionError(tree.pos(), ex); |
|
1066 } |
|
1067 } |
|
1068 |
|
1069 public void validateTrees(List<? extends JCTree> trees, boolean checkRaw, boolean isOuter) { |
|
1070 for (List<? extends JCTree> l = trees; l.nonEmpty(); l = l.tail) |
|
1071 validateTree(l.head, checkRaw, isOuter); |
|
1072 } |
|
1073 |
|
1074 void checkRaw(JCTree tree, Env<AttrContext> env) { |
|
1075 if (lint.isEnabled(Lint.LintCategory.RAW) && |
|
1076 tree.type.tag == CLASS && |
|
1077 !TreeInfo.isDiamond(tree) && |
|
1078 !env.enclClass.name.isEmpty() && //anonymous or intersection |
|
1079 tree.type.isRaw()) { |
|
1080 log.warning(Lint.LintCategory.RAW, |
|
1081 tree.pos(), "raw.class.use", tree.type, tree.type.tsym.type); |
|
1082 } |
|
1083 } |
1064 } |
1084 } |
1065 |
1085 |
1066 /* ************************************************************************* |
1086 /* ************************************************************************* |
1067 * Exception checking |
1087 * Exception checking |
1068 **************************************************************************/ |
1088 **************************************************************************/ |