| OLD | NEW |
| (Empty) | |
| 1 // Copyright (c) 2015, 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 // TODO(johnniwinther): Temporarily copied from analyzer2dart. Merge when |
| 6 // we shared code with the analyzer and this semantic visitor is complete. |
| 7 |
| 8 /** |
| 9 * Code for classifying the semantics of identifiers appearing in a Dart file. |
| 10 */ |
| 11 library dart2js.access_semantics; |
| 12 |
| 13 import '../constants/expressions.dart'; |
| 14 import '../elements/elements.dart'; |
| 15 |
| 16 /// Enum representing the different kinds of destinations which a property |
| 17 /// access or method or function invocation might refer to. |
| 18 enum AccessKind { |
| 19 /// The destination of the access is an instance method, property, or field |
| 20 /// of a class, and thus must be determined dynamically. |
| 21 DYNAMIC_PROPERTY, |
| 22 |
| 23 // TODO(johnniwinther): Split these cases into captured and non-captured |
| 24 // local access. |
| 25 /// The destination of the access is a function that is defined locally within |
| 26 /// an enclosing function or method. |
| 27 LOCAL_FUNCTION, |
| 28 |
| 29 /// The destination of the access is a variable that is defined locally within |
| 30 /// an enclosing function or method. |
| 31 LOCAL_VARIABLE, |
| 32 |
| 33 /// The destination of the access is a variable that is defined as a parameter |
| 34 /// to an enclosing function or method. |
| 35 PARAMETER, |
| 36 |
| 37 /// The destination of the access is a field that is defined statically within |
| 38 /// a class. |
| 39 STATIC_FIELD, |
| 40 |
| 41 /// The destination of the access is a method that is defined statically |
| 42 /// within a class. |
| 43 STATIC_METHOD, |
| 44 |
| 45 /// The destination of the access is a property getter that is defined |
| 46 /// statically within a class. |
| 47 STATIC_GETTER, |
| 48 |
| 49 /// The destination of the access is a property setter that is defined |
| 50 /// statically within a class. |
| 51 STATIC_SETTER, |
| 52 |
| 53 /// The destination of the access is a top level variable defined within a |
| 54 /// library. |
| 55 TOPLEVEL_FIELD, |
| 56 |
| 57 /// The destination of the access is a top level method defined within a |
| 58 /// library. |
| 59 TOPLEVEL_METHOD, |
| 60 |
| 61 /// The destination of the access is a top level property getter defined |
| 62 /// within a library. |
| 63 TOPLEVEL_GETTER, |
| 64 |
| 65 /// The destination of the access is a top level property setter defined |
| 66 /// within a library. |
| 67 TOPLEVEL_SETTER, |
| 68 |
| 69 /// The destination of the access is a toplevel class, or named mixin |
| 70 /// application. |
| 71 CLASS_TYPE_LITERAL, |
| 72 |
| 73 /// The destination of the access is a function typedef. |
| 74 TYPEDEF_TYPE_LITERAL, |
| 75 |
| 76 /// The destination of the access is the built-in type "dynamic". |
| 77 DYNAMIC_TYPE_LITERAL, |
| 78 |
| 79 /// The destination of the access is a type parameter of the enclosing class. |
| 80 TYPE_PARAMETER_TYPE_LITERAL, |
| 81 |
| 82 /// The destination of the access is a (complex) expression. For instance the |
| 83 /// function expression `(){}` in the function expression invocation `(){}()`. |
| 84 EXPRESSION, |
| 85 |
| 86 /// The destination of the access is `this` of the enclosing class. |
| 87 THIS, |
| 88 |
| 89 /// The destination of the access is an instance method, property, or field |
| 90 /// of the enclosing class. |
| 91 THIS_PROPERTY, |
| 92 |
| 93 /// The destination of the access is a field of the super class of the |
| 94 /// enclosing class. |
| 95 SUPER_FIELD, |
| 96 |
| 97 /// The destination of the access is a method of the super class of the |
| 98 /// enclosing class. |
| 99 SUPER_METHOD, |
| 100 |
| 101 /// The destination of the access is a getter of the super class of the |
| 102 /// enclosing class. |
| 103 SUPER_GETTER, |
| 104 |
| 105 /// The destination of the access is a setter of the super class of the |
| 106 /// enclosing class. |
| 107 SUPER_SETTER, |
| 108 |
| 109 /// Compound access where read and write access different elements. |
| 110 /// See [CompoundAccessKind]. |
| 111 COMPOUND, |
| 112 |
| 113 /// The destination of the access is a compile-time constant. |
| 114 CONSTANT, |
| 115 |
| 116 /// The destination of the access is unresolved in a static context. |
| 117 UNRESOLVED, |
| 118 } |
| 119 |
| 120 enum CompoundAccessKind { |
| 121 /// Read from a static getter and write to static setter. |
| 122 STATIC_GETTER_SETTER, |
| 123 /// Read from a static method (closurize) and write to static setter. |
| 124 STATIC_METHOD_SETTER, |
| 125 |
| 126 /// Read from a top level getter and write to a top level setter. |
| 127 TOPLEVEL_GETTER_SETTER, |
| 128 /// Read from a top level method (closurize) and write to top level setter. |
| 129 TOPLEVEL_METHOD_SETTER, |
| 130 |
| 131 /// Read from one superclass field and write to another. |
| 132 SUPER_FIELD_FIELD, |
| 133 /// Read from a superclass field and write to a superclass setter. |
| 134 SUPER_FIELD_SETTER, |
| 135 /// Read from a superclass getter and write to a superclass setter. |
| 136 SUPER_GETTER_SETTER, |
| 137 /// Read from a superclass method (closurize) and write to a superclass |
| 138 /// setter. |
| 139 SUPER_METHOD_SETTER, |
| 140 /// Read from a superclass getter and write to a superclass field. |
| 141 SUPER_GETTER_FIELD, |
| 142 } |
| 143 |
| 144 /** |
| 145 * Data structure used to classify the semantics of a property access or method |
| 146 * or function invocation. |
| 147 */ |
| 148 class AccessSemantics { |
| 149 /** |
| 150 * The kind of access. |
| 151 */ |
| 152 final AccessKind kind; |
| 153 |
| 154 /** |
| 155 * The element being accessed, if statically known. This will be null if |
| 156 * [kind] is DYNAMIC or if the element is undefined (e.g. an attempt to |
| 157 * access a non-existent static method in a class). |
| 158 */ |
| 159 Element get element => null; |
| 160 |
| 161 /** |
| 162 * The class containing the element being accessed, if this is a static |
| 163 * reference to an element in a class. This will be null if [kind] is |
| 164 * DYNAMIC, LOCAL_FUNCTION, LOCAL_VARIABLE, PARAMETER, TOPLEVEL_CLASS, or |
| 165 * TYPE_PARAMETER, or if the element being accessed is defined at toplevel |
| 166 * within a library. |
| 167 * |
| 168 * Note: it is possible for [classElement] to be non-null and for [element] |
| 169 * to be null; for example this occurs if the element being accessed is a |
| 170 * non-existent static method or field inside an existing class. |
| 171 */ |
| 172 ClassElement get classElement => null; |
| 173 |
| 174 // TODO(paulberry): would it also be useful to store the libraryElement? |
| 175 |
| 176 // TODO(johnniwinther): Do we need this? |
| 177 /** |
| 178 * When [kind] is DYNAMIC_PROPERTY, the expression whose runtime type |
| 179 * determines the class in which [identifier] should be looked up. |
| 180 * |
| 181 * When [kind] is not DYNAMIC_PROPERTY, this field is always null. |
| 182 */ |
| 183 /*Expression*/ get target => null; |
| 184 |
| 185 ConstantExpression get constant => null; |
| 186 |
| 187 AccessSemantics.expression() |
| 188 : kind = AccessKind.EXPRESSION; |
| 189 |
| 190 AccessSemantics.thisAccess() |
| 191 : kind = AccessKind.THIS; |
| 192 |
| 193 AccessSemantics.thisProperty() |
| 194 : kind = AccessKind.THIS_PROPERTY; |
| 195 |
| 196 AccessSemantics._(this.kind); |
| 197 |
| 198 String toString() { |
| 199 StringBuffer sb = new StringBuffer(); |
| 200 sb.write('AccessSemantics['); |
| 201 sb.write('kind=$kind,'); |
| 202 if (element != null) { |
| 203 sb.write('element='); |
| 204 if (classElement != null) { |
| 205 sb.write('${classElement.name}.'); |
| 206 } |
| 207 sb.write('${element}'); |
| 208 } |
| 209 sb.write(']'); |
| 210 return sb.toString(); |
| 211 } |
| 212 } |
| 213 |
| 214 |
| 215 class DynamicAccess extends AccessSemantics { |
| 216 final target; |
| 217 |
| 218 DynamicAccess.dynamicProperty(this.target) |
| 219 : super._(AccessKind.DYNAMIC_PROPERTY); |
| 220 } |
| 221 |
| 222 class ConstantAccess extends AccessSemantics { |
| 223 final ConstantExpression constant; |
| 224 |
| 225 ConstantAccess(AccessKind kind, this.constant) |
| 226 : super._(kind); |
| 227 |
| 228 ConstantAccess.classTypeLiteral(this.constant) |
| 229 : super._(AccessKind.CLASS_TYPE_LITERAL); |
| 230 |
| 231 ConstantAccess.typedefTypeLiteral(this.constant) |
| 232 : super._(AccessKind.TYPEDEF_TYPE_LITERAL); |
| 233 |
| 234 ConstantAccess.dynamicTypeLiteral(this.constant) |
| 235 : super._(AccessKind.DYNAMIC_TYPE_LITERAL); |
| 236 } |
| 237 |
| 238 class StaticAccess extends AccessSemantics { |
| 239 final Element element; |
| 240 |
| 241 ClassElement get classElement => element.enclosingClass; |
| 242 |
| 243 StaticAccess._(AccessKind kind, this.element) |
| 244 : super._(kind); |
| 245 |
| 246 StaticAccess.superSetter(MethodElement this.element) |
| 247 : super._(AccessKind.SUPER_SETTER); |
| 248 |
| 249 StaticAccess.superField(FieldElement this.element) |
| 250 : super._(AccessKind.SUPER_FIELD); |
| 251 |
| 252 StaticAccess.superMethod(MethodElement this.element) |
| 253 : super._(AccessKind.SUPER_METHOD); |
| 254 |
| 255 StaticAccess.superGetter(MethodElement this.element) |
| 256 : super._(AccessKind.SUPER_GETTER); |
| 257 |
| 258 StaticAccess.typeParameterTypeLiteral(TypeVariableElement this.element) |
| 259 : super._(AccessKind.TYPE_PARAMETER_TYPE_LITERAL); |
| 260 |
| 261 StaticAccess.localFunction(LocalFunctionElement this.element) |
| 262 : super._(AccessKind.LOCAL_FUNCTION); |
| 263 |
| 264 StaticAccess.localVariable(LocalVariableElement this.element) |
| 265 : super._(AccessKind.LOCAL_VARIABLE); |
| 266 |
| 267 StaticAccess.parameter(ParameterElement this.element) |
| 268 : super._(AccessKind.PARAMETER); |
| 269 |
| 270 StaticAccess.staticField(FieldElement this.element) |
| 271 : super._(AccessKind.STATIC_FIELD); |
| 272 |
| 273 StaticAccess.staticMethod(MethodElement this.element) |
| 274 : super._(AccessKind.STATIC_METHOD); |
| 275 |
| 276 StaticAccess.staticGetter(MethodElement this.element) |
| 277 : super._(AccessKind.STATIC_GETTER); |
| 278 |
| 279 StaticAccess.staticSetter(MethodElement this.element) |
| 280 : super._(AccessKind.STATIC_SETTER); |
| 281 |
| 282 StaticAccess.topLevelField(FieldElement this.element) |
| 283 : super._(AccessKind.TOPLEVEL_FIELD); |
| 284 |
| 285 StaticAccess.topLevelMethod(MethodElement this.element) |
| 286 : super._(AccessKind.TOPLEVEL_METHOD); |
| 287 |
| 288 StaticAccess.topLevelGetter(MethodElement this.element) |
| 289 : super._(AccessKind.TOPLEVEL_GETTER); |
| 290 |
| 291 StaticAccess.topLevelSetter(MethodElement this.element) |
| 292 : super._(AccessKind.TOPLEVEL_SETTER); |
| 293 |
| 294 StaticAccess.unresolved(this.element) |
| 295 : super._(AccessKind.UNRESOLVED); |
| 296 } |
| 297 |
| 298 class CompoundAccessSemantics extends AccessSemantics { |
| 299 final CompoundAccessKind compoundAccessKind; |
| 300 final Element getter; |
| 301 final Element setter; |
| 302 |
| 303 CompoundAccessSemantics(this.compoundAccessKind, |
| 304 this.getter, |
| 305 this.setter) |
| 306 : super._(AccessKind.COMPOUND); |
| 307 |
| 308 Element get element => setter; |
| 309 } |
| OLD | NEW |