| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 | 4 |
| 5 /// This library defined `uses`. A `use` is a single impact of the world, for | 5 /// This library defined `uses`. A `use` is a single impact of the world, for |
| 6 /// instance an invocation of a top level function or a call to the `foo()` | 6 /// instance an invocation of a top level function or a call to the `foo()` |
| 7 /// method on an unknown class. | 7 /// method on an unknown class. |
| 8 library dart2js.universe.use; | 8 library dart2js.universe.use; |
| 9 | 9 |
| 10 import '../closure.dart' show | 10 import '../closure.dart' show BoxFieldElement; |
| 11 BoxFieldElement; | |
| 12 import '../common.dart'; | 11 import '../common.dart'; |
| 13 import '../dart_types.dart'; | 12 import '../dart_types.dart'; |
| 14 import '../elements/elements.dart'; | 13 import '../elements/elements.dart'; |
| 15 import '../world.dart' show | 14 import '../world.dart' show ClassWorld; |
| 16 ClassWorld; | 15 import '../util/util.dart' show Hashing; |
| 17 import '../util/util.dart' show | |
| 18 Hashing; | |
| 19 | 16 |
| 20 import 'call_structure.dart' show | 17 import 'call_structure.dart' show CallStructure; |
| 21 CallStructure; | 18 import 'selector.dart' show Selector; |
| 22 import 'selector.dart' show | 19 import 'universe.dart' show ReceiverConstraint; |
| 23 Selector; | |
| 24 import 'universe.dart' show | |
| 25 ReceiverConstraint; | |
| 26 | 20 |
| 27 | 21 enum DynamicUseKind { INVOKE, GET, SET, } |
| 28 enum DynamicUseKind { | |
| 29 INVOKE, | |
| 30 GET, | |
| 31 SET, | |
| 32 } | |
| 33 | 22 |
| 34 /// The use of a dynamic property. [selector] defined the name and kind of the | 23 /// The use of a dynamic property. [selector] defined the name and kind of the |
| 35 /// property and [mask] defines the known constraint for the object on which | 24 /// property and [mask] defines the known constraint for the object on which |
| 36 /// the property is accessed. | 25 /// the property is accessed. |
| 37 class DynamicUse { | 26 class DynamicUse { |
| 38 final Selector selector; | 27 final Selector selector; |
| 39 final ReceiverConstraint mask; | 28 final ReceiverConstraint mask; |
| 40 | 29 |
| 41 DynamicUse(this.selector, this.mask); | 30 DynamicUse(this.selector, this.mask); |
| 42 | 31 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 final Element element; | 72 final Element element; |
| 84 final StaticUseKind kind; | 73 final StaticUseKind kind; |
| 85 final int hashCode; | 74 final int hashCode; |
| 86 | 75 |
| 87 StaticUse.internal(Element element, StaticUseKind kind) | 76 StaticUse.internal(Element element, StaticUseKind kind) |
| 88 : this.element = element, | 77 : this.element = element, |
| 89 this.kind = kind, | 78 this.kind = kind, |
| 90 this.hashCode = Hashing.objectHash(element, Hashing.objectHash(kind)) { | 79 this.hashCode = Hashing.objectHash(element, Hashing.objectHash(kind)) { |
| 91 assert(invariant(element, element.isDeclaration, | 80 assert(invariant(element, element.isDeclaration, |
| 92 message: "Static use element $element must be " | 81 message: "Static use element $element must be " |
| 93 "the declaration element.")); | 82 "the declaration element.")); |
| 94 } | 83 } |
| 95 | 84 |
| 96 /// Invocation of a static or top-level [element] with the given | 85 /// Invocation of a static or top-level [element] with the given |
| 97 /// [callStructure]. | 86 /// [callStructure]. |
| 98 factory StaticUse.staticInvoke(MethodElement element, | 87 factory StaticUse.staticInvoke( |
| 99 CallStructure callStructure) { | 88 MethodElement element, CallStructure callStructure) { |
| 100 // TODO(johnniwinther): Use the [callStructure]. | 89 // TODO(johnniwinther): Use the [callStructure]. |
| 101 assert(invariant(element, element.isStatic || element.isTopLevel, | 90 assert(invariant(element, element.isStatic || element.isTopLevel, |
| 102 message: "Static invoke element $element must be a top-level " | 91 message: "Static invoke element $element must be a top-level " |
| 103 "or static method.")); | 92 "or static method.")); |
| 104 return new StaticUse.internal(element, StaticUseKind.GENERAL); | 93 return new StaticUse.internal(element, StaticUseKind.GENERAL); |
| 105 } | 94 } |
| 106 | 95 |
| 107 /// Closurization of a static or top-level function [element]. | 96 /// Closurization of a static or top-level function [element]. |
| 108 factory StaticUse.staticTearOff(MethodElement element) { | 97 factory StaticUse.staticTearOff(MethodElement element) { |
| 109 assert(invariant(element, element.isStatic || element.isTopLevel, | 98 assert(invariant(element, element.isStatic || element.isTopLevel, |
| 110 message: "Static tear-off element $element must be a top-level " | 99 message: "Static tear-off element $element must be a top-level " |
| 111 "or static method.")); | 100 "or static method.")); |
| 112 return new StaticUse.internal(element, StaticUseKind.STATIC_TEAR_OFF); | 101 return new StaticUse.internal(element, StaticUseKind.STATIC_TEAR_OFF); |
| 113 } | 102 } |
| 114 | 103 |
| 115 /// Read access of a static or top-level field or getter [element]. | 104 /// Read access of a static or top-level field or getter [element]. |
| 116 factory StaticUse.staticGet(MemberElement element) { | 105 factory StaticUse.staticGet(MemberElement element) { |
| 117 assert(invariant(element, element.isStatic || element.isTopLevel, | 106 assert(invariant(element, element.isStatic || element.isTopLevel, |
| 118 message: "Static get element $element must be a top-level " | 107 message: "Static get element $element must be a top-level " |
| 119 "or static method.")); | 108 "or static method.")); |
| 120 assert(invariant(element, element.isField || element.isGetter, | 109 assert(invariant(element, element.isField || element.isGetter, |
| 121 message: "Static get element $element must be a field or a getter.")); | 110 message: "Static get element $element must be a field or a getter.")); |
| 122 return new StaticUse.internal(element, StaticUseKind.GENERAL); | 111 return new StaticUse.internal(element, StaticUseKind.GENERAL); |
| 123 } | 112 } |
| 124 | 113 |
| 125 /// Write access of a static or top-level field or setter [element]. | 114 /// Write access of a static or top-level field or setter [element]. |
| 126 factory StaticUse.staticSet(MemberElement element) { | 115 factory StaticUse.staticSet(MemberElement element) { |
| 127 assert(invariant(element, element.isStatic || element.isTopLevel, | 116 assert(invariant(element, element.isStatic || element.isTopLevel, |
| 128 message: "Static set element $element must be a top-level " | 117 message: "Static set element $element must be a top-level " |
| 129 "or static method.")); | 118 "or static method.")); |
| 130 assert(invariant(element, element.isField || element.isSetter, | 119 assert(invariant(element, element.isField || element.isSetter, |
| 131 message: "Static set element $element must be a field or a setter.")); | 120 message: "Static set element $element must be a field or a setter.")); |
| 132 return new StaticUse.internal(element, StaticUseKind.GENERAL); | 121 return new StaticUse.internal(element, StaticUseKind.GENERAL); |
| 133 } | 122 } |
| 134 | 123 |
| 135 /// Invocation of the lazy initializer for a static or top-level field | 124 /// Invocation of the lazy initializer for a static or top-level field |
| 136 /// [element]. | 125 /// [element]. |
| 137 factory StaticUse.staticInit(FieldElement element) { | 126 factory StaticUse.staticInit(FieldElement element) { |
| 138 assert(invariant(element, element.isStatic || element.isTopLevel, | 127 assert(invariant(element, element.isStatic || element.isTopLevel, |
| 139 message: "Static init element $element must be a top-level " | 128 message: "Static init element $element must be a top-level " |
| 140 "or static method.")); | 129 "or static method.")); |
| 141 assert(invariant(element, element.isField, | 130 assert(invariant(element, element.isField, |
| 142 message: "Static init element $element must be a field.")); | 131 message: "Static init element $element must be a field.")); |
| 143 return new StaticUse.internal(element, StaticUseKind.GENERAL); | 132 return new StaticUse.internal(element, StaticUseKind.GENERAL); |
| 144 } | 133 } |
| 145 | 134 |
| 146 /// Invocation of a super method [element] with the given [callStructure]. | 135 /// Invocation of a super method [element] with the given [callStructure]. |
| 147 factory StaticUse.superInvoke(MethodElement element, | 136 factory StaticUse.superInvoke( |
| 148 CallStructure callStructure) { | 137 MethodElement element, CallStructure callStructure) { |
| 149 // TODO(johnniwinther): Use the [callStructure]. | 138 // TODO(johnniwinther): Use the [callStructure]. |
| 150 assert(invariant(element, element.isInstanceMember, | 139 assert(invariant(element, element.isInstanceMember, |
| 151 message: "Super invoke element $element must be an instance method.")); | 140 message: "Super invoke element $element must be an instance method.")); |
| 152 return new StaticUse.internal(element, StaticUseKind.GENERAL); | 141 return new StaticUse.internal(element, StaticUseKind.GENERAL); |
| 153 } | 142 } |
| 154 | 143 |
| 155 /// Read access of a super field or getter [element]. | 144 /// Read access of a super field or getter [element]. |
| 156 factory StaticUse.superGet(MemberElement element) { | 145 factory StaticUse.superGet(MemberElement element) { |
| 157 assert(invariant(element, element.isInstanceMember, | 146 assert(invariant(element, element.isInstanceMember, |
| 158 message: "Super get element $element must be an instance method.")); | 147 message: "Super get element $element must be an instance method.")); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 181 | 170 |
| 182 /// Closurization of a super method [element]. | 171 /// Closurization of a super method [element]. |
| 183 factory StaticUse.superTearOff(MethodElement element) { | 172 factory StaticUse.superTearOff(MethodElement element) { |
| 184 assert(invariant(element, element.isInstanceMember && element.isFunction, | 173 assert(invariant(element, element.isInstanceMember && element.isFunction, |
| 185 message: "Super invoke element $element must be an instance method.")); | 174 message: "Super invoke element $element must be an instance method.")); |
| 186 return new StaticUse.internal(element, StaticUseKind.SUPER_TEAR_OFF); | 175 return new StaticUse.internal(element, StaticUseKind.SUPER_TEAR_OFF); |
| 187 } | 176 } |
| 188 | 177 |
| 189 /// Invocation of a constructor [element] through a this or super | 178 /// Invocation of a constructor [element] through a this or super |
| 190 /// constructor call with the given [callStructure]. | 179 /// constructor call with the given [callStructure]. |
| 191 factory StaticUse.superConstructorInvoke(Element element, | 180 factory StaticUse.superConstructorInvoke( |
| 192 CallStructure callStructure) { | 181 Element element, CallStructure callStructure) { |
| 193 // TODO(johnniwinther): Use the [callStructure]. | 182 // TODO(johnniwinther): Use the [callStructure]. |
| 194 assert(invariant(element, | 183 assert(invariant(element, element.isGenerativeConstructor, |
| 195 element.isGenerativeConstructor, | |
| 196 message: "Constructor invoke element $element must be a " | 184 message: "Constructor invoke element $element must be a " |
| 197 "generative constructor.")); | 185 "generative constructor.")); |
| 198 return new StaticUse.internal(element, StaticUseKind.GENERAL); | 186 return new StaticUse.internal(element, StaticUseKind.GENERAL); |
| 199 } | 187 } |
| 200 | 188 |
| 201 /// Invocation of a constructor (body) [element] through a this or super | 189 /// Invocation of a constructor (body) [element] through a this or super |
| 202 /// constructor call with the given [callStructure]. | 190 /// constructor call with the given [callStructure]. |
| 203 factory StaticUse.constructorBodyInvoke(ConstructorBodyElement element, | 191 factory StaticUse.constructorBodyInvoke( |
| 204 CallStructure callStructure) { | 192 ConstructorBodyElement element, CallStructure callStructure) { |
| 205 // TODO(johnniwinther): Use the [callStructure]. | 193 // TODO(johnniwinther): Use the [callStructure]. |
| 206 return new StaticUse.internal(element, StaticUseKind.GENERAL); | 194 return new StaticUse.internal(element, StaticUseKind.GENERAL); |
| 207 } | 195 } |
| 208 | 196 |
| 209 /// Constructor invocation of [element] with the given [callStructure]. | 197 /// Constructor invocation of [element] with the given [callStructure]. |
| 210 factory StaticUse.constructorInvoke(ConstructorElement element, | 198 factory StaticUse.constructorInvoke( |
| 211 CallStructure callStructure) { | 199 ConstructorElement element, CallStructure callStructure) { |
| 212 // TODO(johnniwinther): Use the [callStructure]. | 200 // TODO(johnniwinther): Use the [callStructure]. |
| 213 return new StaticUse.internal(element, StaticUseKind.GENERAL); | 201 return new StaticUse.internal(element, StaticUseKind.GENERAL); |
| 214 } | 202 } |
| 215 | 203 |
| 216 /// Constructor redirection to [element]. | 204 /// Constructor redirection to [element]. |
| 217 factory StaticUse.constructorRedirect(ConstructorElement element) { | 205 factory StaticUse.constructorRedirect(ConstructorElement element) { |
| 218 return new StaticUse.internal(element, StaticUseKind.GENERAL); | 206 return new StaticUse.internal(element, StaticUseKind.GENERAL); |
| 219 } | 207 } |
| 220 | 208 |
| 221 /// Initialization of an instance field [element]. | 209 /// Initialization of an instance field [element]. |
| 222 factory StaticUse.fieldInit(FieldElement element) { | 210 factory StaticUse.fieldInit(FieldElement element) { |
| 223 assert(invariant(element, element.isInstanceMember, | 211 assert(invariant(element, element.isInstanceMember, |
| 224 message: "Field init element $element must be an instance field.")); | 212 message: "Field init element $element must be an instance field.")); |
| 225 return new StaticUse.internal(element, StaticUseKind.GENERAL); | 213 return new StaticUse.internal(element, StaticUseKind.GENERAL); |
| 226 } | 214 } |
| 227 | 215 |
| 228 /// Read access of an instance field or boxed field [element]. | 216 /// Read access of an instance field or boxed field [element]. |
| 229 factory StaticUse.fieldGet(Element element) { | 217 factory StaticUse.fieldGet(Element element) { |
| 230 assert(invariant(element, | 218 assert(invariant( |
| 231 element.isInstanceMember || element is BoxFieldElement, | 219 element, element.isInstanceMember || element is BoxFieldElement, |
| 232 message: "Field init element $element must be an instance " | 220 message: "Field init element $element must be an instance " |
| 233 "or boxed field.")); | 221 "or boxed field.")); |
| 234 return new StaticUse.internal(element, StaticUseKind.FIELD_GET); | 222 return new StaticUse.internal(element, StaticUseKind.FIELD_GET); |
| 235 } | 223 } |
| 236 | 224 |
| 237 /// Write access of an instance field or boxed field [element]. | 225 /// Write access of an instance field or boxed field [element]. |
| 238 factory StaticUse.fieldSet(Element element) { | 226 factory StaticUse.fieldSet(Element element) { |
| 239 assert(invariant(element, | 227 assert(invariant( |
| 240 element.isInstanceMember || element is BoxFieldElement, | 228 element, element.isInstanceMember || element is BoxFieldElement, |
| 241 message: "Field init element $element must be an instance " | 229 message: "Field init element $element must be an instance " |
| 242 "or boxed field.")); | 230 "or boxed field.")); |
| 243 return new StaticUse.internal(element, StaticUseKind.FIELD_SET); | 231 return new StaticUse.internal(element, StaticUseKind.FIELD_SET); |
| 244 } | 232 } |
| 245 | 233 |
| 246 /// Read of a local function [element]. | 234 /// Read of a local function [element]. |
| 247 factory StaticUse.closure(LocalFunctionElement element) { | 235 factory StaticUse.closure(LocalFunctionElement element) { |
| 248 return new StaticUse.internal(element, StaticUseKind.CLOSURE); | 236 return new StaticUse.internal(element, StaticUseKind.CLOSURE); |
| 249 } | 237 } |
| 250 | 238 |
| 251 /// Unknown use of [element]. | 239 /// Unknown use of [element]. |
| 252 @deprecated | 240 @deprecated |
| 253 factory StaticUse.foreignUse(Element element) { | 241 factory StaticUse.foreignUse(Element element) { |
| 254 return new StaticUse.internal(element, StaticUseKind.GENERAL); | 242 return new StaticUse.internal(element, StaticUseKind.GENERAL); |
| 255 } | 243 } |
| 256 | 244 |
| 257 bool operator ==(other) { | 245 bool operator ==(other) { |
| 258 if (identical(this, other)) return true; | 246 if (identical(this, other)) return true; |
| 259 if (other is! StaticUse) return false; | 247 if (other is! StaticUse) return false; |
| 260 return element == other.element && | 248 return element == other.element && kind == other.kind; |
| 261 kind == other.kind; | |
| 262 } | 249 } |
| 263 | 250 |
| 264 String toString() => 'StaticUse($element,$kind)'; | 251 String toString() => 'StaticUse($element,$kind)'; |
| 265 } | 252 } |
| 266 | 253 |
| 267 enum TypeUseKind { | 254 enum TypeUseKind { |
| 268 IS_CHECK, | 255 IS_CHECK, |
| 269 AS_CAST, | 256 AS_CAST, |
| 270 CHECKED_MODE_CHECK, | 257 CHECKED_MODE_CHECK, |
| 271 CATCH_TYPE, | 258 CATCH_TYPE, |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 310 } | 297 } |
| 311 | 298 |
| 312 /// [type] used in an instantiation, like `new T();`. | 299 /// [type] used in an instantiation, like `new T();`. |
| 313 factory TypeUse.instantiation(InterfaceType type) { | 300 factory TypeUse.instantiation(InterfaceType type) { |
| 314 return new TypeUse.internal(type, TypeUseKind.INSTANTIATION); | 301 return new TypeUse.internal(type, TypeUseKind.INSTANTIATION); |
| 315 } | 302 } |
| 316 | 303 |
| 317 bool operator ==(other) { | 304 bool operator ==(other) { |
| 318 if (identical(this, other)) return true; | 305 if (identical(this, other)) return true; |
| 319 if (other is! TypeUse) return false; | 306 if (other is! TypeUse) return false; |
| 320 return type == other.type && | 307 return type == other.type && kind == other.kind; |
| 321 kind == other.kind; | |
| 322 } | 308 } |
| 323 | 309 |
| 324 String toString() => 'TypeUse($type,$kind)'; | 310 String toString() => 'TypeUse($type,$kind)'; |
| 325 } | 311 } |
| OLD | NEW |