790 boolean interfaceExpected, |
790 boolean interfaceExpected, |
791 boolean checkExtensible) { |
791 boolean checkExtensible) { |
792 Type t = tree.type != null ? |
792 Type t = tree.type != null ? |
793 tree.type : |
793 tree.type : |
794 attribType(tree, env); |
794 attribType(tree, env); |
795 return checkBase(t, tree, env, classExpected, interfaceExpected, checkExtensible); |
795 return checkBase(t, tree, env, classExpected, interfaceExpected, false, checkExtensible); |
796 } |
796 } |
797 Type checkBase(Type t, |
797 Type checkBase(Type t, |
798 JCTree tree, |
798 JCTree tree, |
799 Env<AttrContext> env, |
799 Env<AttrContext> env, |
800 boolean classExpected, |
800 boolean classExpected, |
801 boolean interfaceOrArrayExpected, |
801 boolean interfacesOnlyExpected, |
|
802 boolean interfacesOrArraysExpected, |
802 boolean checkExtensible) { |
803 boolean checkExtensible) { |
803 if (t.isErroneous()) |
804 if (t.isErroneous()) |
804 return t; |
805 return t; |
805 if (t.hasTag(TYPEVAR) && !classExpected && !interfaceOrArrayExpected) { |
806 if (t.hasTag(TYPEVAR) && !classExpected && |
|
807 !interfacesOrArraysExpected && !interfacesOnlyExpected) { |
806 // check that type variable is already visible |
808 // check that type variable is already visible |
807 if (t.getUpperBound() == null) { |
809 if (t.getUpperBound() == null) { |
808 log.error(tree.pos(), "illegal.forward.ref"); |
810 log.error(tree.pos(), "illegal.forward.ref"); |
809 return types.createErrorType(t); |
811 return types.createErrorType(t); |
810 } |
812 } |
812 t = chk.checkClassType(tree.pos(), t, checkExtensible|!allowGenerics); |
814 t = chk.checkClassType(tree.pos(), t, checkExtensible|!allowGenerics); |
813 } else { |
815 } else { |
814 t = chk.checkClassOrArrayType(tree.pos(), t, |
816 t = chk.checkClassOrArrayType(tree.pos(), t, |
815 checkExtensible|!allowGenerics); |
817 checkExtensible|!allowGenerics); |
816 } |
818 } |
817 if (interfaceOrArrayExpected && |
819 if (interfacesOnlyExpected && !t.tsym.isInterface()) { |
|
820 log.error(tree.pos(), "intf.expected.here"); |
|
821 // return errType is necessary since otherwise there might |
|
822 // be undetected cycles which cause attribution to loop |
|
823 return types.createErrorType(t); |
|
824 } else if (interfacesOrArraysExpected && |
818 !(t.tsym.isInterface() || t.getTag() == ARRAY)) { |
825 !(t.tsym.isInterface() || t.getTag() == ARRAY)) { |
819 log.error(tree.pos(), "intf.expected.here"); |
826 log.error(tree.pos(), "intf.or.array.expected.here"); |
820 // return errType is necessary since otherwise there might |
827 // return errType is necessary since otherwise there might |
821 // be undetected cycles which cause attribution to loop |
828 // be undetected cycles which cause attribution to loop |
822 return types.createErrorType(t); |
829 return types.createErrorType(t); |
823 } else if (checkExtensible && |
830 } else if (checkExtensible && |
824 classExpected && |
831 classExpected && |
3986 |
3993 |
3987 Type checkIntersection(JCTree tree, List<JCExpression> bounds) { |
3994 Type checkIntersection(JCTree tree, List<JCExpression> bounds) { |
3988 Set<Type> boundSet = new HashSet<Type>(); |
3995 Set<Type> boundSet = new HashSet<Type>(); |
3989 if (bounds.nonEmpty()) { |
3996 if (bounds.nonEmpty()) { |
3990 // accept class or interface or typevar as first bound. |
3997 // accept class or interface or typevar as first bound. |
3991 bounds.head.type = checkBase(bounds.head.type, bounds.head, env, false, false, false); |
3998 bounds.head.type = checkBase(bounds.head.type, bounds.head, env, false, false, false, false); |
3992 boundSet.add(types.erasure(bounds.head.type)); |
3999 boundSet.add(types.erasure(bounds.head.type)); |
3993 if (bounds.head.type.isErroneous()) { |
4000 if (bounds.head.type.isErroneous()) { |
3994 return bounds.head.type; |
4001 return bounds.head.type; |
3995 } |
4002 } |
3996 else if (bounds.head.type.hasTag(TYPEVAR)) { |
4003 else if (bounds.head.type.hasTag(TYPEVAR)) { |
4002 } |
4009 } |
4003 } else { |
4010 } else { |
4004 // if first bound was a class or interface, accept only interfaces |
4011 // if first bound was a class or interface, accept only interfaces |
4005 // as further bounds. |
4012 // as further bounds. |
4006 for (JCExpression bound : bounds.tail) { |
4013 for (JCExpression bound : bounds.tail) { |
4007 bound.type = checkBase(bound.type, bound, env, false, true, false); |
4014 bound.type = checkBase(bound.type, bound, env, false, false, true, false); |
4008 if (bound.type.isErroneous()) { |
4015 if (bound.type.isErroneous()) { |
4009 bounds = List.of(bound); |
4016 bounds = List.of(bound); |
4010 } |
4017 } |
4011 else if (bound.type.hasTag(CLASS)) { |
4018 else if (bound.type.hasTag(CLASS)) { |
4012 chk.checkNotRepeated(bound.pos(), types.erasure(bound.type), boundSet); |
4019 chk.checkNotRepeated(bound.pos(), types.erasure(bound.type), boundSet); |