Chromium Code Reviews| 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 '../elements/elements.dart'; | |
| 14 import '../tree/tree.dart'; | |
| 15 import '../universe/universe.dart'; | |
| 16 | |
| 17 /** | |
| 18 * Enum representing the different kinds of destinations which a property | |
| 19 * access or method or function invocation might refer to. | |
| 20 */ | |
| 21 enum AccessKind { | |
| 22 /** | |
|
karlklose
2015/02/25 12:39:38
Please use '///' to make the comments more compact
Johnni Winther
2015/03/04 11:59:39
Done.
| |
| 23 * The destination of the access is an instance method, property, or field | |
| 24 * of a class, and thus must be determined dynamically. | |
| 25 */ | |
| 26 DYNAMIC_PROPERTY, | |
| 27 | |
|
karlklose
2015/02/25 12:39:38
I think we should split LOCAL_FUNCTION, LOCAL_VARI
Johnni Winther
2015/03/04 11:59:39
Added a TODO.
| |
| 28 /** | |
| 29 * The destination of the access is a function that is defined locally within | |
| 30 * an enclosing function or method. | |
| 31 */ | |
| 32 LOCAL_FUNCTION, | |
| 33 | |
| 34 /** | |
| 35 * The destination of the access is a variable that is defined locally within | |
| 36 * an enclosing function or method. | |
| 37 */ | |
| 38 LOCAL_VARIABLE, | |
| 39 | |
| 40 /** | |
| 41 * The destination of the access is a variable that is defined as a parameter | |
| 42 * to an enclosing function or method. | |
| 43 */ | |
| 44 PARAMETER, | |
| 45 | |
| 46 /** | |
| 47 * The destination of the access is a field that is defined statically within | |
| 48 * a class, or a top level variable within a library. | |
| 49 */ | |
| 50 STATIC_FIELD, | |
| 51 | |
| 52 /** | |
| 53 * The destination of the access is a method that is defined statically | |
| 54 * within a class, or at top level within a library. | |
| 55 */ | |
| 56 STATIC_METHOD, | |
| 57 | |
| 58 /** | |
| 59 * The destination of the access is a property getter that is defined | |
| 60 * statically within a class, or at top level within a library. | |
| 61 */ | |
| 62 STATIC_GETTER, | |
| 63 | |
| 64 /** | |
| 65 * The destination of the access is a property setter that is defined | |
| 66 * statically within a class, or at top level within a library. | |
| 67 */ | |
| 68 STATIC_SETTER, | |
| 69 | |
| 70 /** | |
| 71 * The destination of the access is a field that is defined statically within | |
| 72 * a class, or a top level variable within a library. | |
| 73 */ | |
| 74 TOPLEVEL_FIELD, | |
| 75 | |
| 76 /** | |
| 77 * The destination of the access is a method that is defined statically | |
| 78 * within a class, or at top level within a library. | |
| 79 */ | |
| 80 TOPLEVEL_METHOD, | |
| 81 | |
| 82 /** | |
| 83 * The destination of the access is a property getter that is defined | |
| 84 * statically within a class, or at top level within a library. | |
| 85 */ | |
| 86 TOPLEVEL_GETTER, | |
| 87 | |
| 88 /** | |
| 89 * The destination of the access is a property setter that is defined | |
| 90 * statically within a class, or at top level within a library. | |
| 91 */ | |
| 92 TOPLEVEL_SETTER, | |
| 93 | |
| 94 /** | |
| 95 * The destination of the access is a toplevel class, or mixin application. | |
| 96 */ | |
| 97 CLASS_TYPE_LITERAL, | |
| 98 | |
| 99 /** | |
| 100 * The destination of the access is a function typedef. | |
| 101 */ | |
| 102 TYPEDEF_TYPE_LITERAL, | |
| 103 | |
| 104 /** | |
| 105 * The destination of the access is the built-in type "dynamic". | |
| 106 */ | |
| 107 DYNAMIC_TYPE_LITERAL, | |
| 108 | |
| 109 /** | |
| 110 * The destination of the access is a type parameter of the enclosing class. | |
| 111 */ | |
| 112 TYPE_PARAMETER_TYPE_LITERAL, | |
| 113 | |
| 114 /** | |
| 115 * The destination of the access is a (complex) expression. For instance the | |
| 116 * function expression `(){}` in the function expression invocation `(){}()`. | |
| 117 */ | |
| 118 EXPRESSION, | |
| 119 | |
| 120 /** | |
| 121 * The destination of the access is `this` of the enclosing class. | |
| 122 */ | |
| 123 THIS, | |
| 124 | |
| 125 /** | |
| 126 * The destination of the access is a property on the enclosing class. | |
| 127 */ | |
| 128 THIS_PROPERTY, | |
| 129 | |
| 130 /** | |
| 131 * The destination of the access is a field of the super class of the | |
| 132 * enclosing class. | |
| 133 */ | |
| 134 SUPER_FIELD, | |
| 135 | |
| 136 /** | |
| 137 * The destination of the access is a method of the super class of the | |
| 138 * enclosing class. | |
| 139 */ | |
| 140 SUPER_METHOD, | |
| 141 | |
| 142 /** | |
| 143 * The destination of the access is a getter of the super class of the | |
| 144 * enclosing class. | |
| 145 */ | |
| 146 SUPER_GETTER, | |
| 147 | |
| 148 /** | |
| 149 * The destination of the access is a setter of the super class of the | |
| 150 * enclosing class. | |
| 151 */ | |
| 152 SUPER_SETTER, | |
| 153 | |
| 154 /// Compound access where read and write access different elements. | |
| 155 /// See [CompoundAccessKind]. | |
| 156 COMPOUND, | |
| 157 } | |
| 158 | |
| 159 enum CompoundAccessKind { | |
| 160 /// Read from a static getter and write to static setter. | |
| 161 STATIC_GETTER_SETTER, | |
| 162 /// Read from a static method (closurize) and write to static setter. | |
| 163 STATIC_METHOD_SETTER, | |
| 164 | |
| 165 /// Read from a top level getter and write to a top level setter. | |
| 166 TOPLEVEL_GETTER_SETTER, | |
| 167 /// Read from a top level method (closurize) and write to top level setter. | |
| 168 TOPLEVEL_METHOD_SETTER, | |
| 169 | |
| 170 /// Read from one superclass field and write to another. | |
| 171 SUPER_FIELD_FIELD, | |
| 172 /// Read from a superclass field and write to a superclass setter. | |
| 173 SUPER_FIELD_SETTER, | |
| 174 /// Read from a superclass getter and write to a superclass setter. | |
| 175 SUPER_GETTER_SETTER, | |
| 176 /// Read from a superclass method (closurize) and write to a superclass | |
| 177 /// setter. | |
| 178 SUPER_METHOD_SETTER, | |
| 179 /// Read from a superclass getter and write to a superclass field. | |
| 180 SUPER_GETTER_FIELD, | |
| 181 } | |
| 182 | |
| 183 /** | |
| 184 * Data structure used to classify the semantics of a property access or method | |
| 185 * or function invocation. | |
| 186 */ | |
| 187 class AccessSemantics { | |
| 188 /** | |
| 189 * The kind of access. | |
| 190 */ | |
| 191 final AccessKind kind; | |
| 192 | |
| 193 /** | |
| 194 * The element being accessed, if statically known. This will be null if | |
| 195 * [kind] is DYNAMIC or if the element is undefined (e.g. an attempt to | |
| 196 * access a non-existent static method in a class). | |
| 197 */ | |
| 198 final Element element; | |
| 199 | |
| 200 /** | |
| 201 * The class containing the element being accessed, if this is a static | |
| 202 * reference to an element in a class. This will be null if [kind] is | |
| 203 * DYNAMIC, LOCAL_FUNCTION, LOCAL_VARIABLE, PARAMETER, TOPLEVEL_CLASS, or | |
| 204 * TYPE_PARAMETER, or if the element being accessed is defined at toplevel | |
| 205 * within a library. | |
| 206 * | |
| 207 * Note: it is possible for [classElement] to be non-null and for [element] | |
| 208 * to be null; for example this occurs if the element being accessed is a | |
| 209 * non-existent static method or field inside an existing class. | |
| 210 */ | |
| 211 final ClassElement classElement; | |
| 212 | |
| 213 // TODO(paulberry): would it also be useful to store the libraryElement? | |
| 214 | |
| 215 /** | |
| 216 * When [kind] is DYNAMIC, the expression whose runtime type determines the | |
| 217 * class in which [identifier] should be looked up. Null if the expression | |
|
karlklose
2015/02/25 12:39:38
'[Null]' or '`null`'?
Johnni Winther
2015/03/04 11:59:38
Done.
| |
| 218 * is implicit "this". | |
| 219 * | |
| 220 * When [kind] is not DYNAMIC, this field is always null. | |
| 221 */ | |
| 222 final /*Expression*/ target; | |
| 223 | |
| 224 AccessSemantics.dynamicProperty(this.target) | |
| 225 : kind = AccessKind.DYNAMIC_PROPERTY, | |
| 226 element = null, | |
| 227 classElement = null; | |
| 228 | |
| 229 AccessSemantics.localFunction(this.element) | |
| 230 : kind = AccessKind.LOCAL_FUNCTION, | |
| 231 classElement = null, | |
| 232 target = null; | |
| 233 | |
| 234 AccessSemantics.localVariable(this.element) | |
| 235 : kind = AccessKind.LOCAL_VARIABLE, | |
| 236 classElement = null, | |
| 237 target = null; | |
| 238 | |
| 239 AccessSemantics.parameter(this.element) | |
| 240 : kind = AccessKind.PARAMETER, | |
| 241 classElement = null, | |
| 242 target = null; | |
| 243 | |
| 244 AccessSemantics.staticField(this.element, this.classElement) | |
| 245 : kind = AccessKind.STATIC_FIELD, | |
| 246 target = null; | |
| 247 | |
| 248 AccessSemantics.staticMethod(this.element, this.classElement) | |
| 249 : kind = AccessKind.STATIC_METHOD, | |
| 250 target = null; | |
| 251 | |
| 252 AccessSemantics.staticGetter(this.element, this.classElement) | |
| 253 : kind = AccessKind.STATIC_GETTER, | |
| 254 target = null; | |
| 255 | |
| 256 AccessSemantics.staticSetter(this.element, this.classElement) | |
| 257 : kind = AccessKind.STATIC_SETTER, | |
| 258 target = null; | |
| 259 | |
| 260 AccessSemantics.topLevelField(this.element) | |
| 261 : kind = AccessKind.TOPLEVEL_FIELD, | |
| 262 target = null, | |
| 263 classElement = null; | |
| 264 | |
| 265 AccessSemantics.topLevelMethod(this.element) | |
| 266 : kind = AccessKind.TOPLEVEL_METHOD, | |
| 267 target = null, | |
| 268 classElement = null; | |
| 269 | |
| 270 AccessSemantics.topLevelGetter(this.element) | |
| 271 : kind = AccessKind.TOPLEVEL_GETTER, | |
| 272 target = null, | |
| 273 classElement = null; | |
| 274 | |
| 275 AccessSemantics.topLevelSetter(this.element) | |
| 276 : kind = AccessKind.TOPLEVEL_SETTER, | |
| 277 target = null, | |
| 278 classElement = null; | |
| 279 | |
| 280 AccessSemantics.classTypeLiteral(this.element) | |
| 281 : kind = AccessKind.CLASS_TYPE_LITERAL, | |
| 282 classElement = null, | |
| 283 target = null; | |
| 284 | |
| 285 AccessSemantics.typedefTypeLiteral(this.element) | |
| 286 : kind = AccessKind.TYPEDEF_TYPE_LITERAL, | |
| 287 classElement = null, | |
| 288 target = null; | |
| 289 | |
| 290 AccessSemantics.dynamicTypeLiteral() | |
| 291 : kind = AccessKind.DYNAMIC_TYPE_LITERAL, | |
| 292 element = null, | |
| 293 classElement = null, | |
| 294 target = null; | |
| 295 | |
| 296 AccessSemantics.typeParameterTypeLiteral(this.element) | |
| 297 : kind = AccessKind.TYPE_PARAMETER_TYPE_LITERAL, | |
| 298 classElement = null, | |
| 299 target = null; | |
| 300 | |
| 301 AccessSemantics.expression() | |
| 302 : kind = AccessKind.EXPRESSION, | |
| 303 element = null, | |
| 304 classElement = null, | |
| 305 target = null; | |
| 306 | |
| 307 AccessSemantics.thisAccess() | |
| 308 : kind = AccessKind.THIS, | |
| 309 element = null, | |
| 310 classElement = null, | |
| 311 target = null; | |
| 312 | |
| 313 AccessSemantics.thisProperty() | |
| 314 : kind = AccessKind.THIS_PROPERTY, | |
| 315 element = null, | |
| 316 classElement = null, | |
| 317 target = null; | |
| 318 | |
| 319 AccessSemantics.superField(this.element) | |
| 320 : kind = AccessKind.SUPER_FIELD, | |
| 321 classElement = null, | |
| 322 target = null; | |
| 323 | |
| 324 AccessSemantics.superMethod(this.element) | |
| 325 : kind = AccessKind.SUPER_METHOD, | |
| 326 classElement = null, | |
| 327 target = null; | |
| 328 | |
| 329 AccessSemantics.superGetter(this.element) | |
| 330 : kind = AccessKind.SUPER_GETTER, | |
| 331 classElement = null, | |
| 332 target = null; | |
| 333 | |
| 334 AccessSemantics.superSetter(this.element) | |
| 335 : kind = AccessKind.SUPER_SETTER, | |
| 336 classElement = null, | |
| 337 target = null; | |
| 338 | |
| 339 AccessSemantics._compound(this.element, this.classElement) | |
| 340 : this.kind = AccessKind.COMPOUND, | |
| 341 this.target = null; | |
| 342 | |
| 343 String toString() { | |
| 344 StringBuffer sb = new StringBuffer(); | |
| 345 sb.write('AccessSemantics['); | |
| 346 sb.write('kind=$kind,'); | |
| 347 if (element != null) { | |
| 348 sb.write('element='); | |
| 349 if (classElement != null) { | |
| 350 sb.write('${classElement.name}.'); | |
| 351 } | |
| 352 sb.write('${element}'); | |
| 353 } | |
| 354 sb.write(']'); | |
| 355 return sb.toString(); | |
| 356 } | |
| 357 } | |
| 358 | |
| 359 class CompoundAccessSemantics extends AccessSemantics { | |
| 360 final CompoundAccessKind compoundAccessKind; | |
| 361 final Element getter; | |
| 362 | |
| 363 CompoundAccessSemantics(this.compoundAccessKind, | |
| 364 this.getter, | |
| 365 Element setter, | |
| 366 {ClassElement classElement}) | |
| 367 : super._compound(setter, classElement); | |
| 368 | |
| 369 Element get setter => element; | |
| 370 } | |
| OLD | NEW |