56 import static com.sun.tools.javac.code.Flags.BLOCK; |
56 import static com.sun.tools.javac.code.Flags.BLOCK; |
57 import static com.sun.tools.javac.code.Kinds.*; |
57 import static com.sun.tools.javac.code.Kinds.*; |
58 import static com.sun.tools.javac.code.Kinds.ERRONEOUS; |
58 import static com.sun.tools.javac.code.Kinds.ERRONEOUS; |
59 import static com.sun.tools.javac.code.TypeTag.*; |
59 import static com.sun.tools.javac.code.TypeTag.*; |
60 import static com.sun.tools.javac.code.TypeTag.WILDCARD; |
60 import static com.sun.tools.javac.code.TypeTag.WILDCARD; |
61 import static com.sun.tools.javac.code.TypeTag.ARRAY; |
|
62 import static com.sun.tools.javac.tree.JCTree.Tag.*; |
61 import static com.sun.tools.javac.tree.JCTree.Tag.*; |
63 |
62 |
64 /** This is the main context-dependent analysis phase in GJC. It |
63 /** This is the main context-dependent analysis phase in GJC. It |
65 * encompasses name resolution, type checking and constant folding as |
64 * encompasses name resolution, type checking and constant folding as |
66 * subtasks. Some subtasks involve auxiliary classes. |
65 * subtasks. Some subtasks involve auxiliary classes. |
804 boolean interfaceExpected, |
803 boolean interfaceExpected, |
805 boolean checkExtensible) { |
804 boolean checkExtensible) { |
806 Type t = tree.type != null ? |
805 Type t = tree.type != null ? |
807 tree.type : |
806 tree.type : |
808 attribType(tree, env); |
807 attribType(tree, env); |
809 return checkBase(t, tree, env, classExpected, interfaceExpected, false, checkExtensible); |
808 return checkBase(t, tree, env, classExpected, interfaceExpected, checkExtensible); |
810 } |
809 } |
811 Type checkBase(Type t, |
810 Type checkBase(Type t, |
812 JCTree tree, |
811 JCTree tree, |
813 Env<AttrContext> env, |
812 Env<AttrContext> env, |
814 boolean classExpected, |
813 boolean classExpected, |
815 boolean interfacesOnlyExpected, |
814 boolean interfaceExpected, |
816 boolean interfacesOrArraysExpected, |
|
817 boolean checkExtensible) { |
815 boolean checkExtensible) { |
818 if (t.isErroneous()) |
816 if (t.isErroneous()) |
819 return t; |
817 return t; |
820 if (t.hasTag(TYPEVAR) && !classExpected && |
818 if (t.hasTag(TYPEVAR) && !classExpected && !interfaceExpected) { |
821 !interfacesOrArraysExpected && !interfacesOnlyExpected) { |
|
822 // check that type variable is already visible |
819 // check that type variable is already visible |
823 if (t.getUpperBound() == null) { |
820 if (t.getUpperBound() == null) { |
824 log.error(tree.pos(), "illegal.forward.ref"); |
821 log.error(tree.pos(), "illegal.forward.ref"); |
825 return types.createErrorType(t); |
822 return types.createErrorType(t); |
826 } |
823 } |
827 } else if (classExpected) { |
824 } else { |
828 t = chk.checkClassType(tree.pos(), t, checkExtensible|!allowGenerics); |
825 t = chk.checkClassType(tree.pos(), t, checkExtensible|!allowGenerics); |
829 } else { |
826 } |
830 t = chk.checkClassOrArrayType(tree.pos(), t, |
827 if (interfaceExpected && (t.tsym.flags() & INTERFACE) == 0) { |
831 checkExtensible|!allowGenerics); |
|
832 } |
|
833 if (interfacesOnlyExpected && !t.tsym.isInterface()) { |
|
834 log.error(tree.pos(), "intf.expected.here"); |
828 log.error(tree.pos(), "intf.expected.here"); |
835 // return errType is necessary since otherwise there might |
|
836 // be undetected cycles which cause attribution to loop |
|
837 return types.createErrorType(t); |
|
838 } else if (interfacesOrArraysExpected && |
|
839 !(t.tsym.isInterface() || t.getTag() == ARRAY)) { |
|
840 log.error(tree.pos(), "intf.or.array.expected.here"); |
|
841 // return errType is necessary since otherwise there might |
829 // return errType is necessary since otherwise there might |
842 // be undetected cycles which cause attribution to loop |
830 // be undetected cycles which cause attribution to loop |
843 return types.createErrorType(t); |
831 return types.createErrorType(t); |
844 } else if (checkExtensible && |
832 } else if (checkExtensible && |
845 classExpected && |
833 classExpected && |
846 t.tsym.isInterface()) { |
834 (t.tsym.flags() & INTERFACE) != 0) { |
847 log.error(tree.pos(), "no.intf.expected.here"); |
835 log.error(tree.pos(), "no.intf.expected.here"); |
848 return types.createErrorType(t); |
836 return types.createErrorType(t); |
849 } |
837 } |
850 if (checkExtensible && |
838 if (checkExtensible && |
851 ((t.tsym.flags() & FINAL) != 0)) { |
839 ((t.tsym.flags() & FINAL) != 0)) { |
853 "cant.inherit.from.final", t.tsym); |
841 "cant.inherit.from.final", t.tsym); |
854 } |
842 } |
855 chk.checkNonCyclic(tree.pos(), t); |
843 chk.checkNonCyclic(tree.pos(), t); |
856 return t; |
844 return t; |
857 } |
845 } |
858 //where |
|
859 private Object asTypeParam(Type t) { |
|
860 return (t.hasTag(TYPEVAR)) |
|
861 ? diags.fragment("type.parameter", t) |
|
862 : t; |
|
863 } |
|
864 |
846 |
865 Type attribIdentAsEnumType(Env<AttrContext> env, JCIdent id) { |
847 Type attribIdentAsEnumType(Env<AttrContext> env, JCIdent id) { |
866 Assert.check((env.enclClass.sym.flags() & ENUM) != 0); |
848 Assert.check((env.enclClass.sym.flags() & ENUM) != 0); |
867 id.type = env.info.scope.owner.type; |
849 id.type = env.info.scope.owner.type; |
868 id.sym = env.info.scope.owner; |
850 id.sym = env.info.scope.owner; |
3983 |
3965 |
3984 Type checkIntersection(JCTree tree, List<JCExpression> bounds) { |
3966 Type checkIntersection(JCTree tree, List<JCExpression> bounds) { |
3985 Set<Type> boundSet = new HashSet<Type>(); |
3967 Set<Type> boundSet = new HashSet<Type>(); |
3986 if (bounds.nonEmpty()) { |
3968 if (bounds.nonEmpty()) { |
3987 // accept class or interface or typevar as first bound. |
3969 // accept class or interface or typevar as first bound. |
3988 bounds.head.type = checkBase(bounds.head.type, bounds.head, env, false, false, false, false); |
3970 bounds.head.type = checkBase(bounds.head.type, bounds.head, env, false, false, false); |
3989 boundSet.add(types.erasure(bounds.head.type)); |
3971 boundSet.add(types.erasure(bounds.head.type)); |
3990 if (bounds.head.type.isErroneous()) { |
3972 if (bounds.head.type.isErroneous()) { |
3991 return bounds.head.type; |
3973 return bounds.head.type; |
3992 } |
3974 } |
3993 else if (bounds.head.type.hasTag(TYPEVAR)) { |
3975 else if (bounds.head.type.hasTag(TYPEVAR)) { |
3999 } |
3981 } |
4000 } else { |
3982 } else { |
4001 // if first bound was a class or interface, accept only interfaces |
3983 // if first bound was a class or interface, accept only interfaces |
4002 // as further bounds. |
3984 // as further bounds. |
4003 for (JCExpression bound : bounds.tail) { |
3985 for (JCExpression bound : bounds.tail) { |
4004 bound.type = checkBase(bound.type, bound, env, false, false, true, false); |
3986 bound.type = checkBase(bound.type, bound, env, false, true, false); |
4005 if (bound.type.isErroneous()) { |
3987 if (bound.type.isErroneous()) { |
4006 bounds = List.of(bound); |
3988 bounds = List.of(bound); |
4007 } |
3989 } |
4008 else if (bound.type.hasTag(CLASS)) { |
3990 else if (bound.type.hasTag(CLASS)) { |
4009 chk.checkNotRepeated(bound.pos(), types.erasure(bound.type), boundSet); |
3991 chk.checkNotRepeated(bound.pos(), types.erasure(bound.type), boundSet); |