equal
deleted
inserted
replaced
71 * If you write code that depends on this, you do so at your own risk. |
71 * If you write code that depends on this, you do so at your own risk. |
72 * This code and its internal interfaces are subject to change or |
72 * This code and its internal interfaces are subject to change or |
73 * deletion without notice.</b> |
73 * deletion without notice.</b> |
74 */ |
74 */ |
75 public class Attr extends JCTree.Visitor { |
75 public class Attr extends JCTree.Visitor { |
76 protected static final Context.Key<Attr> attrKey = |
76 protected static final Context.Key<Attr> attrKey = new Context.Key<>(); |
77 new Context.Key<Attr>(); |
|
78 |
77 |
79 final Names names; |
78 final Names names; |
80 final Log log; |
79 final Log log; |
81 final Symtab syms; |
80 final Symtab syms; |
82 final Resolve rs; |
81 final Resolve rs; |
666 } |
665 } |
667 |
666 |
668 /** Attribute a list of expressions, returning a list of types. |
667 /** Attribute a list of expressions, returning a list of types. |
669 */ |
668 */ |
670 List<Type> attribExprs(List<JCExpression> trees, Env<AttrContext> env, Type pt) { |
669 List<Type> attribExprs(List<JCExpression> trees, Env<AttrContext> env, Type pt) { |
671 ListBuffer<Type> ts = new ListBuffer<Type>(); |
670 ListBuffer<Type> ts = new ListBuffer<>(); |
672 for (List<JCExpression> l = trees; l.nonEmpty(); l = l.tail) |
671 for (List<JCExpression> l = trees; l.nonEmpty(); l = l.tail) |
673 ts.append(attribExpr(l.head, env, pt)); |
672 ts.append(attribExpr(l.head, env, pt)); |
674 return ts.toList(); |
673 return ts.toList(); |
675 } |
674 } |
676 |
675 |
700 |
699 |
701 /** Attribute a type argument list, returning a list of types. |
700 /** Attribute a type argument list, returning a list of types. |
702 * Caller is responsible for calling checkRefTypes. |
701 * Caller is responsible for calling checkRefTypes. |
703 */ |
702 */ |
704 List<Type> attribAnyTypes(List<JCExpression> trees, Env<AttrContext> env) { |
703 List<Type> attribAnyTypes(List<JCExpression> trees, Env<AttrContext> env) { |
705 ListBuffer<Type> argtypes = new ListBuffer<Type>(); |
704 ListBuffer<Type> argtypes = new ListBuffer<>(); |
706 for (List<JCExpression> l = trees; l.nonEmpty(); l = l.tail) |
705 for (List<JCExpression> l = trees; l.nonEmpty(); l = l.tail) |
707 argtypes.append(attribType(l.head, env)); |
706 argtypes.append(attribType(l.head, env)); |
708 return argtypes.toList(); |
707 return argtypes.toList(); |
709 } |
708 } |
710 |
709 |
1236 if (!enumSwitch && !stringSwitch) |
1235 if (!enumSwitch && !stringSwitch) |
1237 seltype = chk.checkType(tree.selector.pos(), seltype, syms.intType); |
1236 seltype = chk.checkType(tree.selector.pos(), seltype, syms.intType); |
1238 |
1237 |
1239 // Attribute all cases and |
1238 // Attribute all cases and |
1240 // check that there are no duplicate case labels or default clauses. |
1239 // check that there are no duplicate case labels or default clauses. |
1241 Set<Object> labels = new HashSet<Object>(); // The set of case labels. |
1240 Set<Object> labels = new HashSet<>(); // The set of case labels. |
1242 boolean hasDefault = false; // Is there a default label? |
1241 boolean hasDefault = false; // Is there a default label? |
1243 for (List<JCCase> l = tree.cases; l.nonEmpty(); l = l.tail) { |
1242 for (List<JCCase> l = tree.cases; l.nonEmpty(); l = l.tail) { |
1244 JCCase c = l.head; |
1243 JCCase c = l.head; |
1245 Env<AttrContext> caseEnv = |
1244 Env<AttrContext> caseEnv = |
1246 switchEnv.dup(c, env.info.dup(switchEnv.info.scope.dup())); |
1245 switchEnv.dup(c, env.info.dup(switchEnv.info.scope.dup())); |
3813 } catch (Resolve.InapplicableMethodException ex) { |
3812 } catch (Resolve.InapplicableMethodException ex) { |
3814 final JCDiagnostic diag = ex.getDiagnostic(); |
3813 final JCDiagnostic diag = ex.getDiagnostic(); |
3815 Resolve.InapplicableSymbolError errSym = rs.new InapplicableSymbolError(null) { |
3814 Resolve.InapplicableSymbolError errSym = rs.new InapplicableSymbolError(null) { |
3816 @Override |
3815 @Override |
3817 protected Pair<Symbol, JCDiagnostic> errCandidate() { |
3816 protected Pair<Symbol, JCDiagnostic> errCandidate() { |
3818 return new Pair<Symbol, JCDiagnostic>(sym, diag); |
3817 return new Pair<>(sym, diag); |
3819 } |
3818 } |
3820 }; |
3819 }; |
3821 List<Type> argtypes2 = Type.map(argtypes, |
3820 List<Type> argtypes2 = Type.map(argtypes, |
3822 rs.new ResolveDeferredRecoveryMap(AttrMode.CHECK, sym, env.info.pendingResolutionPhase)); |
3821 rs.new ResolveDeferredRecoveryMap(AttrMode.CHECK, sym, env.info.pendingResolutionPhase)); |
3823 JCDiagnostic errDiag = errSym.getDiagnostic(JCDiagnostic.DiagnosticType.ERROR, |
3822 JCDiagnostic errDiag = errSym.getDiagnostic(JCDiagnostic.DiagnosticType.ERROR, |
3966 typeVar.bound = checkIntersection(tree, tree.bounds); |
3965 typeVar.bound = checkIntersection(tree, tree.bounds); |
3967 } |
3966 } |
3968 } |
3967 } |
3969 |
3968 |
3970 Type checkIntersection(JCTree tree, List<JCExpression> bounds) { |
3969 Type checkIntersection(JCTree tree, List<JCExpression> bounds) { |
3971 Set<Type> boundSet = new HashSet<Type>(); |
3970 Set<Type> boundSet = new HashSet<>(); |
3972 if (bounds.nonEmpty()) { |
3971 if (bounds.nonEmpty()) { |
3973 // accept class or interface or typevar as first bound. |
3972 // accept class or interface or typevar as first bound. |
3974 bounds.head.type = checkBase(bounds.head.type, bounds.head, env, false, false, false); |
3973 bounds.head.type = checkBase(bounds.head.type, bounds.head, env, false, false, false); |
3975 boundSet.add(types.erasure(bounds.head.type)); |
3974 boundSet.add(types.erasure(bounds.head.type)); |
3976 if (bounds.head.type.isErroneous()) { |
3975 if (bounds.head.type.isErroneous()) { |
4571 if (enclTy == null || |
4570 if (enclTy == null || |
4572 enclTy.hasTag(NONE)) { |
4571 enclTy.hasTag(NONE)) { |
4573 if (at.getAnnotations().size() == 1) { |
4572 if (at.getAnnotations().size() == 1) { |
4574 log.error(at.underlyingType.pos(), "cant.type.annotate.scoping.1", at.getAnnotations().head.attribute); |
4573 log.error(at.underlyingType.pos(), "cant.type.annotate.scoping.1", at.getAnnotations().head.attribute); |
4575 } else { |
4574 } else { |
4576 ListBuffer<Attribute.Compound> comps = new ListBuffer<Attribute.Compound>(); |
4575 ListBuffer<Attribute.Compound> comps = new ListBuffer<>(); |
4577 for (JCAnnotation an : at.getAnnotations()) { |
4576 for (JCAnnotation an : at.getAnnotations()) { |
4578 comps.add(an.attribute); |
4577 comps.add(an.attribute); |
4579 } |
4578 } |
4580 log.error(at.underlyingType.pos(), "cant.type.annotate.scoping", comps.toList()); |
4579 log.error(at.underlyingType.pos(), "cant.type.annotate.scoping", comps.toList()); |
4581 } |
4580 } |
4632 typeAnnotations.annotationType(ai.attribute, sym) == TypeAnnotations.AnnotationType.DECLARATION) { |
4631 typeAnnotations.annotationType(ai.attribute, sym) == TypeAnnotations.AnnotationType.DECLARATION) { |
4633 log.error(ai.pos(), "annotation.type.not.applicable"); |
4632 log.error(ai.pos(), "annotation.type.not.applicable"); |
4634 } |
4633 } |
4635 } |
4634 } |
4636 } |
4635 } |
4637 }; |
4636 } |
4638 |
4637 |
4639 // <editor-fold desc="post-attribution visitor"> |
4638 // <editor-fold desc="post-attribution visitor"> |
4640 |
4639 |
4641 /** |
4640 /** |
4642 * Handle missing types/symbols in an AST. This routine is useful when |
4641 * Handle missing types/symbols in an AST. This routine is useful when |