OLD | NEW |
(Empty) | |
| 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 |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 library dart2js.universe.use; |
| 6 |
| 7 import '../closure.dart' show |
| 8 BoxFieldElement; |
| 9 import '../common.dart'; |
| 10 import '../elements/elements.dart'; |
| 11 import '../util/util.dart' show |
| 12 Hashing; |
| 13 |
| 14 import 'call_structure.dart' show |
| 15 CallStructure; |
| 16 |
| 17 enum StaticUseKind { |
| 18 GENERAL, |
| 19 STATIC_TEAR_OFF, |
| 20 SUPER_TEAR_OFF, |
| 21 FIELD_GET, |
| 22 FIELD_SET, |
| 23 } |
| 24 |
| 25 /// Statically known use of an [Element]. |
| 26 // TODO(johnniwinther): Create backend-specific implementations with better |
| 27 // invariants. |
| 28 class StaticUse { |
| 29 final Element element; |
| 30 final StaticUseKind kind; |
| 31 final int hashCode; |
| 32 |
| 33 StaticUse._(Element element, StaticUseKind kind) |
| 34 : this.element = element, |
| 35 this.kind = kind, |
| 36 this.hashCode = Hashing.objectHash(element, Hashing.objectHash(kind)) { |
| 37 assert(invariant(element, element.isDeclaration, |
| 38 message: "Static use element $element must be " |
| 39 "the declaration element.")); |
| 40 } |
| 41 |
| 42 /// Invocation of a static or top-level [element] with the given |
| 43 /// [callStructure]. |
| 44 factory StaticUse.staticInvoke(MethodElement element, |
| 45 CallStructure callStructure) { |
| 46 // TODO(johnniwinther): Use the [callStructure]. |
| 47 assert(invariant(element, element.isStatic || element.isTopLevel, |
| 48 message: "Static invoke element $element must be a top-level " |
| 49 "or static method.")); |
| 50 return new StaticUse._(element, StaticUseKind.GENERAL); |
| 51 } |
| 52 |
| 53 /// Closurization of a static or top-level function [element]. |
| 54 factory StaticUse.staticTearOff(MethodElement element) { |
| 55 assert(invariant(element, element.isStatic || element.isTopLevel, |
| 56 message: "Static tear-off element $element must be a top-level " |
| 57 "or static method.")); |
| 58 return new StaticUse._(element, StaticUseKind.STATIC_TEAR_OFF); |
| 59 } |
| 60 |
| 61 /// Read access of a static or top-level field or getter [element]. |
| 62 factory StaticUse.staticGet(MemberElement element) { |
| 63 assert(invariant(element, element.isStatic || element.isTopLevel, |
| 64 message: "Static get element $element must be a top-level " |
| 65 "or static method.")); |
| 66 assert(invariant(element, element.isField || element.isGetter, |
| 67 message: "Static get element $element must be a field or a getter.")); |
| 68 return new StaticUse._(element, StaticUseKind.GENERAL); |
| 69 } |
| 70 |
| 71 /// Write access of a static or top-level field or setter [element]. |
| 72 factory StaticUse.staticSet(MemberElement element) { |
| 73 assert(invariant(element, element.isStatic || element.isTopLevel, |
| 74 message: "Static set element $element must be a top-level " |
| 75 "or static method.")); |
| 76 assert(invariant(element, element.isField || element.isSetter, |
| 77 message: "Static set element $element must be a field or a setter.")); |
| 78 return new StaticUse._(element, StaticUseKind.GENERAL); |
| 79 } |
| 80 |
| 81 /// Invocation of the lazy initializer for a static or top-level field |
| 82 /// [element]. |
| 83 factory StaticUse.staticInit(FieldElement element) { |
| 84 assert(invariant(element, element.isStatic || element.isTopLevel, |
| 85 message: "Static init element $element must be a top-level " |
| 86 "or static method.")); |
| 87 assert(invariant(element, element.isField, |
| 88 message: "Static init element $element must be a field.")); |
| 89 return new StaticUse._(element, StaticUseKind.GENERAL); |
| 90 } |
| 91 |
| 92 /// Invocation of a super method [element] with the given [callStructure]. |
| 93 factory StaticUse.superInvoke(MethodElement element, |
| 94 CallStructure callStructure) { |
| 95 // TODO(johnniwinther): Use the [callStructure]. |
| 96 assert(invariant(element, element.isInstanceMember, |
| 97 message: "Super invoke element $element must be an instance method.")); |
| 98 return new StaticUse._(element, StaticUseKind.GENERAL); |
| 99 } |
| 100 |
| 101 /// Read access of a super field or getter [element]. |
| 102 factory StaticUse.superGet(MemberElement element) { |
| 103 assert(invariant(element, element.isInstanceMember, |
| 104 message: "Super get element $element must be an instance method.")); |
| 105 assert(invariant(element, element.isField || element.isGetter, |
| 106 message: "Super get element $element must be a field or a getter.")); |
| 107 return new StaticUse._(element, StaticUseKind.GENERAL); |
| 108 } |
| 109 |
| 110 /// Write access of a super field or setter [element]. |
| 111 factory StaticUse.superSet(Element element) { |
| 112 assert(invariant(element, element.isInstanceMember, |
| 113 message: "Super set element $element must be an instance method.")); |
| 114 assert(invariant(element, element.isField || element.isSetter, |
| 115 message: "Super set element $element must be a field or a setter.")); |
| 116 return new StaticUse._(element, StaticUseKind.GENERAL); |
| 117 } |
| 118 |
| 119 /// Closurization of a super method [element]. |
| 120 factory StaticUse.superTearOff(MethodElement element) { |
| 121 assert(invariant(element, element.isInstanceMember && element.isFunction, |
| 122 message: "Super invoke element $element must be an instance method.")); |
| 123 return new StaticUse._(element, StaticUseKind.SUPER_TEAR_OFF); |
| 124 } |
| 125 |
| 126 /// Invocation of a constructor [element] through a this or super |
| 127 /// constructor call with the given [callStructure]. |
| 128 factory StaticUse.superConstructorInvoke(Element element, |
| 129 CallStructure callStructure) { |
| 130 // TODO(johnniwinther): Use the [callStructure]. |
| 131 assert(invariant(element, |
| 132 element.isGenerativeConstructor, |
| 133 message: "Constructor invoke element $element must be a " |
| 134 "generative constructor.")); |
| 135 return new StaticUse._(element, StaticUseKind.GENERAL); |
| 136 } |
| 137 |
| 138 /// Invocation of a constructor (body) [element] through a this or super |
| 139 /// constructor call with the given [callStructure]. |
| 140 factory StaticUse.constructorBodyInvoke(ConstructorBodyElement element, |
| 141 CallStructure callStructure) { |
| 142 // TODO(johnniwinther): Use the [callStructure]. |
| 143 return new StaticUse._(element, StaticUseKind.GENERAL); |
| 144 } |
| 145 |
| 146 /// Constructor invocation of [element] with the given [callStructure]. |
| 147 factory StaticUse.constructorInvoke(ConstructorElement element, |
| 148 CallStructure callStructure) { |
| 149 // TODO(johnniwinther): Use the [callStructure]. |
| 150 return new StaticUse._(element, StaticUseKind.GENERAL); |
| 151 } |
| 152 |
| 153 /// Constructor redirection to [element]. |
| 154 factory StaticUse.constructorRedirect(ConstructorElement element) { |
| 155 return new StaticUse._(element, StaticUseKind.GENERAL); |
| 156 } |
| 157 |
| 158 /// Initialization of an instance field [element]. |
| 159 factory StaticUse.fieldInit(FieldElement element) { |
| 160 assert(invariant(element, element.isInstanceMember, |
| 161 message: "Field init element $element must be an instance field.")); |
| 162 return new StaticUse._(element, StaticUseKind.GENERAL); |
| 163 } |
| 164 |
| 165 /// Read access of an instance field or boxed field [element]. |
| 166 factory StaticUse.fieldGet(Element element) { |
| 167 assert(invariant(element, |
| 168 element.isInstanceMember || element is BoxFieldElement, |
| 169 message: "Field init element $element must be an instance " |
| 170 "or boxed field.")); |
| 171 return new StaticUse._(element, StaticUseKind.FIELD_GET); |
| 172 } |
| 173 |
| 174 /// Write access of an instance field or boxed field [element]. |
| 175 factory StaticUse.fieldSet(Element element) { |
| 176 assert(invariant(element, |
| 177 element.isInstanceMember || element is BoxFieldElement, |
| 178 message: "Field init element $element must be an instance " |
| 179 "or boxed field.")); |
| 180 return new StaticUse._(element, StaticUseKind.FIELD_SET); |
| 181 } |
| 182 |
| 183 /// Unknown use of [element]. |
| 184 @deprecated |
| 185 factory StaticUse.foreignUse(Element element) { |
| 186 return new StaticUse._(element, StaticUseKind.GENERAL); |
| 187 } |
| 188 |
| 189 bool operator ==(other) { |
| 190 if (identical(this, other)) return true; |
| 191 if (other is! StaticUse) return false; |
| 192 return element == other.element && |
| 193 kind == other.kind; |
| 194 } |
| 195 |
| 196 String toString() => 'StaticUse($element,$kind)'; |
| 197 } |
| 198 |
OLD | NEW |