72 * <dd>If the first argument to an operation is a type, it should be named t.</dd>
73 * <dt>s</dt>
74 * <dd>Similarly, if the second argument to an operation is a type, it should be named s.</dd>
75 * <dt>ts</dt>
76 * <dd>If an operations takes a list of types, the first should be named ts.</dd>
77 * <dt>ss</dt>
78 * <dd>A second list of types should be named ss.</dd>
79 * </dl>
80 *
81 * <p><b>This is NOT part of any supported API.
82 * If you write code that depends on this, you do so at your own risk.
83 * This code and its internal interfaces are subject to change or
84 * deletion without notice.</b>
85 */
86 public class Types {
87 protected static final Context.Key<Types> typesKey = new Context.Key<>();
88
89 final Symtab syms;
90 final JavacMessages messages;
91 final Names names;
92 final boolean allowObjectToPrimitiveCast;
93 final boolean allowDefaultMethods;
94 final boolean mapCapturesToBounds;
95 final Check chk;
96 final Enter enter;
97 JCDiagnostic.Factory diags;
98 List<Warner> warnStack = List.nil();
99 final Name capturedName;
100
101 public final Warner noWarnings;
102
103 // <editor-fold defaultstate="collapsed" desc="Instantiating">
104 public static Types instance(Context context) {
105 Types instance = context.get(typesKey);
106 if (instance == null)
107 instance = new Types(context);
108 return instance;
109 }
110
111 protected Types(Context context) {
112 context.put(typesKey, this);
113 syms = Symtab.instance(context);
114 names = Names.instance(context);
115 Source source = Source.instance(context);
116 allowObjectToPrimitiveCast = Feature.OBJECT_TO_PRIMITIVE_CAST.allowedInSource(source);
117 allowDefaultMethods = Feature.DEFAULT_METHODS.allowedInSource(source);
118 mapCapturesToBounds = Feature.MAP_CAPTURES_TO_BOUNDS.allowedInSource(source);
119 chk = Check.instance(context);
120 enter = Enter.instance(context);
121 capturedName = names.fromString("<captured wildcard>");
122 messages = JavacMessages.instance(context);
123 diags = JCDiagnostic.Factory.instance(context);
124 noWarnings = new Warner(null);
125 }
126 // </editor-fold>
127
128 // <editor-fold defaultstate="collapsed" desc="bounds">
129 /**
130 * Get a wildcard's upper bound, returning non-wildcards unchanged.
131 * @param t a type argument, either a wildcard or a type
132 */
133 public Type wildUpperBound(Type t) {
134 if (t.hasTag(WILDCARD)) {
135 WildcardType w = (WildcardType) t;
136 if (w.isSuperBound())
1622 return ts.isEmpty() && ss.isEmpty();
1623 }
1624 // </editor-fold>
1625
1626 // <editor-fold defaultstate="collapsed" desc="isCastable">
1627 public boolean isCastable(Type t, Type s) {
1628 return isCastable(t, s, noWarnings);
1629 }
1630
1631 /**
1632 * Is t is castable to s?<br>
1633 * s is assumed to be an erased type.<br>
1634 * (not defined for Method and ForAll types).
1635 */
1636 public boolean isCastable(Type t, Type s, Warner warn) {
1637 if (t == s)
1638 return true;
1639 if (t.isPrimitive() != s.isPrimitive()) {
1640 t = skipTypeVars(t, false);
1641 return (isConvertible(t, s, warn)
1642 || (allowObjectToPrimitiveCast &&
1643 s.isPrimitive() &&
1644 isSubtype(boxedClass(s).type, t)));
1645 }
1646 if (warn != warnStack.head) {
1647 try {
1648 warnStack = warnStack.prepend(warn);
1649 checkUnsafeVarargsConversion(t, s, warn);
1650 return isCastable.visit(t,s);
1651 } finally {
1652 warnStack = warnStack.tail;
1653 }
1654 } else {
1655 return isCastable.visit(t,s);
1656 }
1657 }
1658 // where
1659 private TypeRelation isCastable = new TypeRelation() {
1660
1661 public Boolean visitType(Type t, Type s) {
1662 if (s.hasTag(ERROR) || t.hasTag(NONE))
1663 return true;
|
72 * <dd>If the first argument to an operation is a type, it should be named t.</dd>
73 * <dt>s</dt>
74 * <dd>Similarly, if the second argument to an operation is a type, it should be named s.</dd>
75 * <dt>ts</dt>
76 * <dd>If an operations takes a list of types, the first should be named ts.</dd>
77 * <dt>ss</dt>
78 * <dd>A second list of types should be named ss.</dd>
79 * </dl>
80 *
81 * <p><b>This is NOT part of any supported API.
82 * If you write code that depends on this, you do so at your own risk.
83 * This code and its internal interfaces are subject to change or
84 * deletion without notice.</b>
85 */
86 public class Types {
87 protected static final Context.Key<Types> typesKey = new Context.Key<>();
88
89 final Symtab syms;
90 final JavacMessages messages;
91 final Names names;
92 final boolean allowDefaultMethods;
93 final boolean mapCapturesToBounds;
94 final Check chk;
95 final Enter enter;
96 JCDiagnostic.Factory diags;
97 List<Warner> warnStack = List.nil();
98 final Name capturedName;
99
100 public final Warner noWarnings;
101
102 // <editor-fold defaultstate="collapsed" desc="Instantiating">
103 public static Types instance(Context context) {
104 Types instance = context.get(typesKey);
105 if (instance == null)
106 instance = new Types(context);
107 return instance;
108 }
109
110 protected Types(Context context) {
111 context.put(typesKey, this);
112 syms = Symtab.instance(context);
113 names = Names.instance(context);
114 Source source = Source.instance(context);
115 allowDefaultMethods = Feature.DEFAULT_METHODS.allowedInSource(source);
116 mapCapturesToBounds = Feature.MAP_CAPTURES_TO_BOUNDS.allowedInSource(source);
117 chk = Check.instance(context);
118 enter = Enter.instance(context);
119 capturedName = names.fromString("<captured wildcard>");
120 messages = JavacMessages.instance(context);
121 diags = JCDiagnostic.Factory.instance(context);
122 noWarnings = new Warner(null);
123 }
124 // </editor-fold>
125
126 // <editor-fold defaultstate="collapsed" desc="bounds">
127 /**
128 * Get a wildcard's upper bound, returning non-wildcards unchanged.
129 * @param t a type argument, either a wildcard or a type
130 */
131 public Type wildUpperBound(Type t) {
132 if (t.hasTag(WILDCARD)) {
133 WildcardType w = (WildcardType) t;
134 if (w.isSuperBound())
1620 return ts.isEmpty() && ss.isEmpty();
1621 }
1622 // </editor-fold>
1623
1624 // <editor-fold defaultstate="collapsed" desc="isCastable">
1625 public boolean isCastable(Type t, Type s) {
1626 return isCastable(t, s, noWarnings);
1627 }
1628
1629 /**
1630 * Is t is castable to s?<br>
1631 * s is assumed to be an erased type.<br>
1632 * (not defined for Method and ForAll types).
1633 */
1634 public boolean isCastable(Type t, Type s, Warner warn) {
1635 if (t == s)
1636 return true;
1637 if (t.isPrimitive() != s.isPrimitive()) {
1638 t = skipTypeVars(t, false);
1639 return (isConvertible(t, s, warn)
1640 || (s.isPrimitive() &&
1641 isSubtype(boxedClass(s).type, t)));
1642 }
1643 if (warn != warnStack.head) {
1644 try {
1645 warnStack = warnStack.prepend(warn);
1646 checkUnsafeVarargsConversion(t, s, warn);
1647 return isCastable.visit(t,s);
1648 } finally {
1649 warnStack = warnStack.tail;
1650 }
1651 } else {
1652 return isCastable.visit(t,s);
1653 }
1654 }
1655 // where
1656 private TypeRelation isCastable = new TypeRelation() {
1657
1658 public Boolean visitType(Type t, Type s) {
1659 if (s.hasTag(ERROR) || t.hasTag(NONE))
1660 return true;
|