OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 library kernel.transformations.insert_covariance_checks; | 4 library kernel.transformations.insert_covariance_checks; |
5 | 5 |
6 import '../class_hierarchy.dart'; | 6 import '../class_hierarchy.dart'; |
7 import '../clone.dart'; | 7 import '../clone.dart'; |
8 import '../core_types.dart'; | 8 import '../core_types.dart'; |
9 import '../kernel.dart'; | 9 import '../kernel.dart'; |
10 import '../log.dart'; | 10 import '../log.dart'; |
11 import '../type_algebra.dart'; | 11 import '../type_algebra.dart'; |
12 import '../type_environment.dart'; | 12 import '../type_environment.dart'; |
13 | 13 |
14 // TODO: Should helper be removed? | |
15 DartType substituteBounds(DartType type, Map<TypeParameter, DartType> upper, | 14 DartType substituteBounds(DartType type, Map<TypeParameter, DartType> upper, |
16 Map<TypeParameter, DartType> lower) { | 15 Map<TypeParameter, DartType> lower) { |
17 return Substitution | 16 return Substitution |
18 .fromUpperAndLowerBounds(upper, lower) | 17 .fromUpperAndLowerBounds(upper, lower) |
19 .substituteType(type); | 18 .substituteType(type); |
20 } | 19 } |
21 | 20 |
22 /// Inserts checked entry points for methods in order to enforce type safety | 21 /// Inserts checked entry points for methods in order to enforce type safety |
23 /// in face on covariant subtyping. | 22 /// in face on covariant subtyping. |
24 /// | 23 /// |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
110 // | 109 // |
111 // The "substitution" maps translate type parameters to their exact type, | 110 // The "substitution" maps translate type parameters to their exact type, |
112 // while the "upper bound" maps translate type parameters to their erased | 111 // while the "upper bound" maps translate type parameters to their erased |
113 // upper bounds. | 112 // upper bounds. |
114 Map<TypeParameter, DartType> ownSubstitution; | 113 Map<TypeParameter, DartType> ownSubstitution; |
115 Map<TypeParameter, DartType> ownUpperBounds; | 114 Map<TypeParameter, DartType> ownUpperBounds; |
116 Map<TypeParameter, DartType> superSubstitution; | 115 Map<TypeParameter, DartType> superSubstitution; |
117 Map<TypeParameter, DartType> superUpperBounds; | 116 Map<TypeParameter, DartType> superUpperBounds; |
118 | 117 |
119 /// Members for which a checked entry point must be created in this current | 118 /// Members for which a checked entry point must be created in this current |
120 /// class. | 119 /// class, indexed by name. |
121 Set<Member> membersNeedingCheckedEntryPoint = new Set<Member>(); | 120 Map<Name, Member> membersNeedingCheckedEntryPoint = <Name, Member>{}; |
122 | 121 |
123 _ClassTransformer(this.host, InsertCovarianceChecks global) | 122 _ClassTransformer(this.host, InsertCovarianceChecks global) |
124 : hierarchy = global.hierarchy, | 123 : hierarchy = global.hierarchy, |
125 types = global.types, | 124 types = global.types, |
126 this.global = global; | 125 this.global = global; |
127 | 126 |
128 /// Mark [parameter] unsafe, with [type] as a potential argument type. | 127 /// Mark [parameter] unsafe, with [type] as a potential argument type. |
129 void addUnsafeParameter( | 128 void addUnsafeParameter( |
130 VariableDeclaration parameter, DartType type, Member member) { | 129 VariableDeclaration parameter, DartType type, Member member) { |
131 unsafeParameterTypes.putIfAbsent(parameter, () => <DartType>[]).add(type); | 130 unsafeParameterTypes.putIfAbsent(parameter, () => <DartType>[]).add(type); |
(...skipping 19 matching lines...) Expand all Loading... |
151 bool hasCheckedEntryPoint(Member member, {bool setter: false}) { | 150 bool hasCheckedEntryPoint(Member member, {bool setter: false}) { |
152 if (!setter && member is Field) { | 151 if (!setter && member is Field) { |
153 return false; // Field getters never have checked entry points. | 152 return false; // Field getters never have checked entry points. |
154 } | 153 } |
155 return global.membersWithCheckedEntryPoint.contains(member); | 154 return global.membersWithCheckedEntryPoint.contains(member); |
156 } | 155 } |
157 | 156 |
158 /// Ensures that a checked entry point for [member] will be emitted in the | 157 /// Ensures that a checked entry point for [member] will be emitted in the |
159 /// current class. | 158 /// current class. |
160 void requireLocalCheckedEntryPoint(Member member) { | 159 void requireLocalCheckedEntryPoint(Member member) { |
161 if (membersNeedingCheckedEntryPoint.add(member)) { | 160 membersNeedingCheckedEntryPoint[member.name] = member; |
162 global.membersWithCheckedEntryPoint.add(member); | 161 global.membersWithCheckedEntryPoint.add(member); |
163 } | |
164 } | 162 } |
165 | 163 |
166 void transformClass() { | 164 void transformClass() { |
167 if (host.isMixinApplication) { | 165 if (host.isMixinApplication) { |
168 // TODO(asgerf): We need a way to support mixin applications with unsafe | 166 // TODO(asgerf): We need a way to support mixin applications with unsafe |
169 // overrides. This version assumes mixins have been resolved by cloning. | 167 // overrides. This version assumes mixins have been resolved by cloning. |
170 // We could generate a subclass of the mixin application containing the | 168 // We could generate a subclass of the mixin application containing the |
171 // checked entry points. | 169 // checked entry points. |
172 throw 'Mixin applications must be resolved before inserting covariance ' | 170 throw 'Mixin applications must be resolved before inserting covariance ' |
173 'checks'; | 171 'checks'; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
218 if (superMember is Procedure) { | 216 if (superMember is Procedure) { |
219 checkProcedureOverride(ownMember, superMember); | 217 checkProcedureOverride(ownMember, superMember); |
220 } else if (superMember is Field && isSetter) { | 218 } else if (superMember is Field && isSetter) { |
221 checkSetterFieldOverride(ownMember, superMember); | 219 checkSetterFieldOverride(ownMember, superMember); |
222 } | 220 } |
223 } else if (isSetter) { | 221 } else if (isSetter) { |
224 checkFieldOverride(ownMember, superMember); | 222 checkFieldOverride(ownMember, superMember); |
225 } | 223 } |
226 }); | 224 }); |
227 | 225 |
228 for (Member member in membersNeedingCheckedEntryPoint) { | 226 for (Member member in membersNeedingCheckedEntryPoint.values) { |
229 ownSubstitution = getSubstitutionMap( | 227 ownSubstitution = getSubstitutionMap( |
230 hierarchy.getClassAsInstanceOf(host, member.enclosingClass)); | 228 hierarchy.getClassAsInstanceOf(host, member.enclosingClass)); |
231 ownSubstitution = ensureMutable(ownSubstitution); | 229 ownSubstitution = ensureMutable(ownSubstitution); |
232 generateCheckedEntryPoint(member); | 230 generateCheckedEntryPoint(member); |
233 } | 231 } |
234 } | 232 } |
235 | 233 |
236 /// Compute an upper bound of the types in [inputTypes]. | 234 /// Compute an upper bound of the types in [inputTypes]. |
237 /// | 235 /// |
238 /// We use this to compute a trustworthy type for a parameter, given a list | 236 /// We use this to compute a trustworthy type for a parameter, given a list |
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
515 @override | 513 @override |
516 visitPropertySet(PropertySet node) { | 514 visitPropertySet(PropertySet node) { |
517 var target = getChecked(node.receiver, node.interfaceTarget); | 515 var target = getChecked(node.receiver, node.interfaceTarget); |
518 if (target != null) { | 516 if (target != null) { |
519 node.interfaceTarget = target; | 517 node.interfaceTarget = target; |
520 node.name = target.name; | 518 node.name = target.name; |
521 } | 519 } |
522 node.visitChildren(this); | 520 node.visitChildren(this); |
523 } | 521 } |
524 } | 522 } |
OLD | NEW |