Chromium Code Reviews| 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 | 4 |
| 5 /// ----------------------------------------------------------------------- | 5 /// ----------------------------------------------------------------------- |
| 6 /// ERROR HANDLING | 6 /// ERROR HANDLING |
| 7 /// ----------------------------------------------------------------------- | 7 /// ----------------------------------------------------------------------- |
| 8 /// | 8 /// |
| 9 /// As a rule of thumb, errors that can be detected statically are handled by | 9 /// As a rule of thumb, errors that can be detected statically are handled by |
| 10 /// the frontend, typically by translating the erroneous code into a 'throw' or | 10 /// the frontend, typically by translating the erroneous code into a 'throw' or |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 49 /// has to update parent pointers manually. | 49 /// has to update parent pointers manually. |
| 50 /// | 50 /// |
| 51 library kernel.ast; | 51 library kernel.ast; |
| 52 | 52 |
| 53 import 'visitor.dart'; | 53 import 'visitor.dart'; |
| 54 export 'visitor.dart'; | 54 export 'visitor.dart'; |
| 55 | 55 |
| 56 import 'type_propagation/type_propagation.dart'; | 56 import 'type_propagation/type_propagation.dart'; |
| 57 export 'type_propagation/type_propagation.dart'; | 57 export 'type_propagation/type_propagation.dart'; |
| 58 | 58 |
| 59 import 'canonical_name.dart' show CanonicalName; | |
| 60 export 'canonical_name.dart' show CanonicalName; | |
| 61 | |
| 59 import 'transformations/flags.dart'; | 62 import 'transformations/flags.dart'; |
| 60 import 'text/ast_to_text.dart'; | 63 import 'text/ast_to_text.dart'; |
| 61 import 'type_algebra.dart'; | 64 import 'type_algebra.dart'; |
| 62 import 'type_environment.dart'; | 65 import 'type_environment.dart'; |
| 63 | 66 |
| 64 /// Any type of node in the IR. | 67 /// Any type of node in the IR. |
| 65 abstract class Node { | 68 abstract class Node { |
| 66 const Node(); | 69 const Node(); |
| 67 | 70 |
| 68 accept(Visitor v); | 71 accept(Visitor v); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 145 Location get location { | 148 Location get location { |
| 146 if (fileOffset == noOffset) return parent?.location; | 149 if (fileOffset == noOffset) return parent?.location; |
| 147 return _getLocationInEnclosingFile(fileOffset); | 150 return _getLocationInEnclosingFile(fileOffset); |
| 148 } | 151 } |
| 149 | 152 |
| 150 Location _getLocationInEnclosingFile(int offset) { | 153 Location _getLocationInEnclosingFile(int offset) { |
| 151 return parent?._getLocationInEnclosingFile(offset); | 154 return parent?._getLocationInEnclosingFile(offset); |
| 152 } | 155 } |
| 153 } | 156 } |
| 154 | 157 |
| 158 /// An AST node that can be referenced by other nodes. | |
| 159 /// | |
| 160 /// There is a single [box] belonging to this node, providing a level of | |
| 161 /// indirection that is needed during serialization. | |
| 162 abstract class LinkedNode extends TreeNode { | |
|
Kevin Millikin (Google)
2017/02/22 09:09:30
Suggestion: LinkedNode ==> NamedNode, LinkedNodeBo
asgerf
2017/02/22 10:06:54
Done.
| |
| 163 final LinkedNodeBox box; | |
| 164 | |
| 165 LinkedNode(LinkedNodeBox box) | |
| 166 : this.box = box ?? new LinkedNodeBox() { | |
| 167 this.box.node = this; | |
| 168 } | |
| 169 | |
| 170 CanonicalName get canonicalName => box?.canonicalName; | |
| 171 } | |
| 172 | |
| 173 /// Indirection between a reference and its definition. | |
| 174 class LinkedNodeBox { | |
| 175 CanonicalName canonicalName; | |
| 176 LinkedNode node; | |
| 177 | |
| 178 Library get asLibrary { | |
| 179 if (node == null) throw 'The box is empty. A library was expected'; | |
| 180 return node as Library; | |
| 181 } | |
| 182 | |
| 183 Class get asClass { | |
| 184 if (node == null) throw 'The box is empty. A class was expected'; | |
| 185 return node as Class; | |
| 186 } | |
| 187 | |
| 188 Member get asMember { | |
| 189 if (node == null) throw 'The box is empty. A member was expected'; | |
| 190 return node as Member; | |
| 191 } | |
| 192 | |
| 193 Field get asField { | |
| 194 if (node == null) throw 'The box is empty. A field was expected'; | |
| 195 return node as Field; | |
| 196 } | |
| 197 | |
| 198 Constructor get asConstructor { | |
| 199 if (node == null) throw 'The box is empty. A constructor was expected'; | |
| 200 return node as Constructor; | |
| 201 } | |
| 202 | |
| 203 Procedure get asProcedure { | |
| 204 if (node == null) throw 'The box is empty. A procedure was expected'; | |
| 205 return node as Procedure; | |
| 206 } | |
| 207 } | |
| 208 | |
| 155 // ------------------------------------------------------------------------ | 209 // ------------------------------------------------------------------------ |
| 156 // LIBRARIES and CLASSES | 210 // LIBRARIES and CLASSES |
| 157 // ------------------------------------------------------------------------ | 211 // ------------------------------------------------------------------------ |
| 158 | 212 |
| 159 class Library extends TreeNode implements Comparable<Library> { | 213 class Library extends LinkedNode implements Comparable<Library> { |
| 160 /// An import path to this library. | 214 /// An import path to this library. |
| 161 /// | 215 /// |
| 162 /// The [Uri] should have the `dart`, `package`, `app`, or `file` scheme. | 216 /// The [Uri] should have the `dart`, `package`, `app`, or `file` scheme. |
| 163 /// | 217 /// |
| 164 /// If the URI has the `app` scheme, it is relative to the application root. | 218 /// If the URI has the `app` scheme, it is relative to the application root. |
| 165 Uri importUri; | 219 Uri importUri; |
| 166 | 220 |
| 167 /// The uri of the source file this library was loaded from. | 221 /// The uri of the source file this library was loaded from. |
| 168 String fileUri; | 222 String fileUri; |
| 169 | 223 |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 184 final List<Procedure> procedures; | 238 final List<Procedure> procedures; |
| 185 final List<Field> fields; | 239 final List<Field> fields; |
| 186 | 240 |
| 187 Library(this.importUri, | 241 Library(this.importUri, |
| 188 {this.name, | 242 {this.name, |
| 189 this.isExternal: false, | 243 this.isExternal: false, |
| 190 List<DeferredImport> imports, | 244 List<DeferredImport> imports, |
| 191 List<Class> classes, | 245 List<Class> classes, |
| 192 List<Procedure> procedures, | 246 List<Procedure> procedures, |
| 193 List<Field> fields, | 247 List<Field> fields, |
| 194 this.fileUri}) | 248 this.fileUri, |
| 249 LinkedNodeBox box}) | |
| 195 : this.deferredImports = imports ?? <DeferredImport>[], | 250 : this.deferredImports = imports ?? <DeferredImport>[], |
| 196 this.classes = classes ?? <Class>[], | 251 this.classes = classes ?? <Class>[], |
| 197 this.procedures = procedures ?? <Procedure>[], | 252 this.procedures = procedures ?? <Procedure>[], |
| 198 this.fields = fields ?? <Field>[] { | 253 this.fields = fields ?? <Field>[], |
| 254 super(box) { | |
| 199 setParents(this.classes, this); | 255 setParents(this.classes, this); |
| 200 setParents(this.procedures, this); | 256 setParents(this.procedures, this); |
| 201 setParents(this.fields, this); | 257 setParents(this.fields, this); |
| 202 } | 258 } |
| 203 | 259 |
| 204 /// Returns the top-level fields and procedures defined in this library. | 260 /// Returns the top-level fields and procedures defined in this library. |
| 205 /// | 261 /// |
| 206 /// This getter is for convenience, not efficiency. Consider manually | 262 /// This getter is for convenience, not efficiency. Consider manually |
| 207 /// iterating the members to speed up code in production. | 263 /// iterating the members to speed up code in production. |
| 208 Iterable<Member> get members => | 264 Iterable<Member> get members => |
| 209 <Iterable<Member>>[fields, procedures].expand((x) => x); | 265 <Iterable<Member>>[fields, procedures].expand((x) => x); |
| 210 | 266 |
| 211 void addMember(Member member) { | 267 void addMember(Member member) { |
| 212 member.parent = this; | 268 member.parent = this; |
| 213 if (member is Procedure) { | 269 if (member is Procedure) { |
| 214 procedures.add(member); | 270 procedures.add(member); |
| 215 } else if (member is Field) { | 271 } else if (member is Field) { |
| 216 fields.add(member); | 272 fields.add(member); |
| 217 } else { | 273 } else { |
| 218 throw new ArgumentError(member); | 274 throw new ArgumentError(member); |
| 219 } | 275 } |
| 220 } | 276 } |
| 221 | 277 |
| 222 void addClass(Class class_) { | 278 void addClass(Class class_) { |
| 223 class_.parent = this; | 279 class_.parent = this; |
| 224 classes.add(class_); | 280 classes.add(class_); |
| 225 } | 281 } |
| 226 | 282 |
| 283 void computeCanonicalNames() { | |
| 284 assert(canonicalName != null); | |
| 285 for (var field in fields) { | |
| 286 canonicalName.getChildFromMember(field).bindTo(field.box); | |
| 287 } | |
| 288 for (var member in procedures) { | |
| 289 canonicalName.getChildFromMember(member).bindTo(member.box); | |
| 290 } | |
| 291 for (var class_ in classes) { | |
| 292 canonicalName.getChild(class_.name).bindTo(class_.box); | |
| 293 class_.computeCanonicalNames(); | |
| 294 } | |
| 295 } | |
| 296 | |
| 227 accept(TreeVisitor v) => v.visitLibrary(this); | 297 accept(TreeVisitor v) => v.visitLibrary(this); |
| 228 | 298 |
| 229 visitChildren(Visitor v) { | 299 visitChildren(Visitor v) { |
| 230 visitList(classes, v); | 300 visitList(classes, v); |
| 231 visitList(procedures, v); | 301 visitList(procedures, v); |
| 232 visitList(fields, v); | 302 visitList(fields, v); |
| 233 } | 303 } |
| 234 | 304 |
| 235 transformChildren(Transformer v) { | 305 transformChildren(Transformer v) { |
| 236 transformList(classes, v, this); | 306 transformList(classes, v, this); |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 247 /// the names across all [toString] calls. | 317 /// the names across all [toString] calls. |
| 248 String toString() => debugLibraryName(this); | 318 String toString() => debugLibraryName(this); |
| 249 | 319 |
| 250 Location _getLocationInEnclosingFile(int offset) { | 320 Location _getLocationInEnclosingFile(int offset) { |
| 251 return enclosingProgram.getLocation(fileUri, offset); | 321 return enclosingProgram.getLocation(fileUri, offset); |
| 252 } | 322 } |
| 253 } | 323 } |
| 254 | 324 |
| 255 /// An import of form: `import <url> deferred as <name>;`. | 325 /// An import of form: `import <url> deferred as <name>;`. |
| 256 class DeferredImport extends TreeNode { | 326 class DeferredImport extends TreeNode { |
| 257 Library importedLibrary; | 327 LinkedNodeBox importedLibraryBox; |
| 258 String name; | 328 String name; |
| 259 | 329 |
| 260 DeferredImport(this.importedLibrary, this.name); | 330 DeferredImport(Library importedLibrary, String name) |
| 331 : this.byBox(importedLibrary.box, name); | |
| 332 | |
| 333 DeferredImport.byBox(this.importedLibraryBox, this.name); | |
| 261 | 334 |
| 262 Library get enclosingLibrary => parent; | 335 Library get enclosingLibrary => parent; |
| 336 Library get importedLibrary => importedLibraryBox.node; | |
| 263 | 337 |
| 264 accept(TreeVisitor v) => v.visitDeferredImport(this); | 338 accept(TreeVisitor v) => v.visitDeferredImport(this); |
| 265 | 339 |
| 266 visitChildren(Visitor v) {} | 340 visitChildren(Visitor v) {} |
| 267 | 341 |
| 268 transformChildren(Transformer v) {} | 342 transformChildren(Transformer v) {} |
| 269 } | 343 } |
| 270 | 344 |
| 271 /// The degree to which the contents of a class have been loaded into memory. | 345 /// The degree to which the contents of a class have been loaded into memory. |
| 272 /// | 346 /// |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 314 /// not necessarily at [Body] level. | 388 /// not necessarily at [Body] level. |
| 315 Body, | 389 Body, |
| 316 } | 390 } |
| 317 | 391 |
| 318 /// Declaration of a regular class or a mixin application. | 392 /// Declaration of a regular class or a mixin application. |
| 319 /// | 393 /// |
| 320 /// Mixin applications may not contain fields or procedures, as they implicitly | 394 /// Mixin applications may not contain fields or procedures, as they implicitly |
| 321 /// use those from its mixed-in type. However, the IR does not enforce this | 395 /// use those from its mixed-in type. However, the IR does not enforce this |
| 322 /// rule directly, as doing so can obstruct transformations. It is possible to | 396 /// rule directly, as doing so can obstruct transformations. It is possible to |
| 323 /// transform a mixin application to become a regular class, and vice versa. | 397 /// transform a mixin application to become a regular class, and vice versa. |
| 324 class Class extends TreeNode { | 398 class Class extends LinkedNode { |
| 325 /// The degree to which the contents of the class have been loaded. | 399 /// The degree to which the contents of the class have been loaded. |
| 326 ClassLevel level = ClassLevel.Body; | 400 ClassLevel level = ClassLevel.Body; |
| 327 | 401 |
| 328 /// List of metadata annotations on the class. | 402 /// List of metadata annotations on the class. |
| 329 /// | 403 /// |
| 330 /// This defaults to an immutable empty list. Use [addAnnotation] to add | 404 /// This defaults to an immutable empty list. Use [addAnnotation] to add |
| 331 /// annotations if needed. | 405 /// annotations if needed. |
| 332 List<Expression> annotations = const <Expression>[]; | 406 List<Expression> annotations = const <Expression>[]; |
| 333 | 407 |
| 334 /// Name of the class. | 408 /// Name of the class. |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 371 Class( | 445 Class( |
| 372 {this.name, | 446 {this.name, |
| 373 this.isAbstract: false, | 447 this.isAbstract: false, |
| 374 this.supertype, | 448 this.supertype, |
| 375 this.mixedInType, | 449 this.mixedInType, |
| 376 List<TypeParameter> typeParameters, | 450 List<TypeParameter> typeParameters, |
| 377 List<Supertype> implementedTypes, | 451 List<Supertype> implementedTypes, |
| 378 List<Constructor> constructors, | 452 List<Constructor> constructors, |
| 379 List<Procedure> procedures, | 453 List<Procedure> procedures, |
| 380 List<Field> fields, | 454 List<Field> fields, |
| 381 this.fileUri}) | 455 this.fileUri, |
| 456 LinkedNodeBox box}) | |
| 382 : this.typeParameters = typeParameters ?? <TypeParameter>[], | 457 : this.typeParameters = typeParameters ?? <TypeParameter>[], |
| 383 this.implementedTypes = implementedTypes ?? <Supertype>[], | 458 this.implementedTypes = implementedTypes ?? <Supertype>[], |
| 384 this.fields = fields ?? <Field>[], | 459 this.fields = fields ?? <Field>[], |
| 385 this.constructors = constructors ?? <Constructor>[], | 460 this.constructors = constructors ?? <Constructor>[], |
| 386 this.procedures = procedures ?? <Procedure>[] { | 461 this.procedures = procedures ?? <Procedure>[], |
| 462 super(box) { | |
| 387 setParents(this.typeParameters, this); | 463 setParents(this.typeParameters, this); |
| 388 setParents(this.constructors, this); | 464 setParents(this.constructors, this); |
| 389 setParents(this.procedures, this); | 465 setParents(this.procedures, this); |
| 390 setParents(this.fields, this); | 466 setParents(this.fields, this); |
| 391 } | 467 } |
| 392 | 468 |
| 469 void computeCanonicalNames() { | |
| 470 assert(canonicalName != null); | |
| 471 for (var member in fields) { | |
| 472 canonicalName.getChildFromMember(member).bindTo(member.box); | |
| 473 } | |
| 474 for (var member in procedures) { | |
| 475 canonicalName.getChildFromMember(member).bindTo(member.box); | |
| 476 } | |
| 477 for (var member in constructors) { | |
| 478 canonicalName.getChildFromMember(member).bindTo(member.box); | |
| 479 } | |
| 480 } | |
| 481 | |
| 393 /// The immediate super class, or `null` if this is the root class. | 482 /// The immediate super class, or `null` if this is the root class. |
| 394 Class get superclass => supertype?.classNode; | 483 Class get superclass => supertype?.classNode; |
| 395 | 484 |
| 396 /// The mixed-in class if this is a mixin application, otherwise `null`. | 485 /// The mixed-in class if this is a mixin application, otherwise `null`. |
| 397 /// | 486 /// |
| 398 /// Note that this may itself be a mixin application. Use [mixin] to get the | 487 /// Note that this may itself be a mixin application. Use [mixin] to get the |
| 399 /// class that has the fields and procedures. | 488 /// class that has the fields and procedures. |
| 400 Class get mixedInClass => mixedInType?.classNode; | 489 Class get mixedInClass => mixedInType?.classNode; |
| 401 | 490 |
| 402 /// The class that declares the field and procedures of this class. | 491 /// The class that declares the field and procedures of this class. |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 515 | 604 |
| 516 Location _getLocationInEnclosingFile(int offset) { | 605 Location _getLocationInEnclosingFile(int offset) { |
| 517 return enclosingProgram.getLocation(fileUri, offset); | 606 return enclosingProgram.getLocation(fileUri, offset); |
| 518 } | 607 } |
| 519 } | 608 } |
| 520 | 609 |
| 521 // ------------------------------------------------------------------------ | 610 // ------------------------------------------------------------------------ |
| 522 // MEMBERS | 611 // MEMBERS |
| 523 // ------------------------------------------------------------------------ | 612 // ------------------------------------------------------------------------ |
| 524 | 613 |
| 525 /// A indirect reference to a member, which can be updated to point at another | 614 abstract class Member extends LinkedNode { |
| 526 /// member at a later time. | |
| 527 class _MemberAccessor { | |
| 528 Member target; | |
| 529 _MemberAccessor(this.target); | |
| 530 } | |
| 531 | |
| 532 abstract class Member extends TreeNode { | |
| 533 /// End offset in the source file it comes from. Valid values are from 0 and | 615 /// End offset in the source file it comes from. Valid values are from 0 and |
| 534 /// up, or -1 ([TreeNode.noOffset]) if the file end offset is not available | 616 /// up, or -1 ([TreeNode.noOffset]) if the file end offset is not available |
| 535 /// (this is the default if none is specifically set). | 617 /// (this is the default if none is specifically set). |
| 536 int fileEndOffset = TreeNode.noOffset; | 618 int fileEndOffset = TreeNode.noOffset; |
| 537 | 619 |
| 538 /// List of metadata annotations on the member. | 620 /// List of metadata annotations on the member. |
| 539 /// | 621 /// |
| 540 /// This defaults to an immutable empty list. Use [addAnnotation] to add | 622 /// This defaults to an immutable empty list. Use [addAnnotation] to add |
| 541 /// annotations if needed. | 623 /// annotations if needed. |
| 542 List<Expression> annotations = const <Expression>[]; | 624 List<Expression> annotations = const <Expression>[]; |
| 543 Name name; | 625 Name name; |
| 544 | 626 |
| 545 /// Flags summarizing the kinds of AST nodes contained in this member, for | 627 /// Flags summarizing the kinds of AST nodes contained in this member, for |
| 546 /// speeding up transformations that only affect certain types of nodes. | 628 /// speeding up transformations that only affect certain types of nodes. |
| 547 /// | 629 /// |
| 548 /// See [TransformerFlag] for the meaning of each bit. | 630 /// See [TransformerFlag] for the meaning of each bit. |
| 549 /// | 631 /// |
| 550 /// These should not be used for any purpose other than skipping certain | 632 /// These should not be used for any purpose other than skipping certain |
| 551 /// members if it can be determined that no work is needed in there. | 633 /// members if it can be determined that no work is needed in there. |
| 552 /// | 634 /// |
| 553 /// It is valid for these flags to be false positives in rare cases, so | 635 /// It is valid for these flags to be false positives in rare cases, so |
| 554 /// transformers must tolerate the case where a flag is spuriously set. | 636 /// transformers must tolerate the case where a flag is spuriously set. |
| 555 /// | 637 /// |
| 556 /// This value is not serialized; it is populated by the frontend and the | 638 /// This value is not serialized; it is populated by the frontend and the |
| 557 /// deserializer. | 639 /// deserializer. |
| 558 // | 640 // |
| 559 // TODO(asgerf): It might be worthwhile to put this on classes as well. | 641 // TODO(asgerf): It might be worthwhile to put this on classes as well. |
| 560 int transformerFlags = 0; | 642 int transformerFlags = 0; |
| 561 | 643 |
| 562 Member(this.name); | 644 Member(this.name, LinkedNodeBox box) : super(box); |
| 563 | 645 |
| 564 Class get enclosingClass => parent is Class ? parent : null; | 646 Class get enclosingClass => parent is Class ? parent : null; |
| 565 Library get enclosingLibrary => parent is Class ? parent.parent : parent; | 647 Library get enclosingLibrary => parent is Class ? parent.parent : parent; |
| 566 | 648 |
| 567 accept(MemberVisitor v); | 649 accept(MemberVisitor v); |
| 568 acceptReference(MemberReferenceVisitor v); | 650 acceptReference(MemberReferenceVisitor v); |
| 569 | 651 |
| 570 /// If true, the member is part of an external library, that is, it is defined | 652 /// If true, the member is part of an external library, that is, it is defined |
| 571 /// in another build unit. Such members have no body or initializer present | 653 /// in another build unit. Such members have no body or initializer present |
| 572 /// in the IR. | 654 /// in the IR. |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 610 annotations.add(node); | 692 annotations.add(node); |
| 611 node.parent = this; | 693 node.parent = this; |
| 612 } | 694 } |
| 613 | 695 |
| 614 DartType get getterType; | 696 DartType get getterType; |
| 615 DartType get setterType; | 697 DartType get setterType; |
| 616 | 698 |
| 617 bool get containsSuperCalls { | 699 bool get containsSuperCalls { |
| 618 return transformerFlags & TransformerFlag.superCalls != 0; | 700 return transformerFlags & TransformerFlag.superCalls != 0; |
| 619 } | 701 } |
| 620 | |
| 621 _MemberAccessor get _getterInterface; | |
| 622 _MemberAccessor get _setterInterface; | |
| 623 } | 702 } |
| 624 | 703 |
| 625 /// A field declaration. | 704 /// A field declaration. |
| 626 /// | 705 /// |
| 627 /// The implied getter and setter for the field are not represented explicitly, | 706 /// The implied getter and setter for the field are not represented explicitly, |
| 628 /// but can be made explicit if needed. | 707 /// but can be made explicit if needed. |
| 629 class Field extends Member { | 708 class Field extends Member { |
| 630 _MemberAccessor _getterInterface, _setterInterface; | |
| 631 | |
| 632 DartType type; // Not null. Defaults to DynamicType. | 709 DartType type; // Not null. Defaults to DynamicType. |
| 633 InferredValue inferredValue; // May be null. | 710 InferredValue inferredValue; // May be null. |
| 634 int flags = 0; | 711 int flags = 0; |
| 635 Expression initializer; // May be null. | 712 Expression initializer; // May be null. |
| 636 | 713 |
| 637 /// The uri of the source file this field was loaded from. | 714 /// The uri of the source file this field was loaded from. |
| 638 String fileUri; | 715 String fileUri; |
| 639 | 716 |
| 640 Field(Name name, | 717 Field(Name name, |
| 641 {this.type: const DynamicType(), | 718 {this.type: const DynamicType(), |
| 642 this.inferredValue, | 719 this.inferredValue, |
| 643 this.initializer, | 720 this.initializer, |
| 644 bool isFinal: false, | 721 bool isFinal: false, |
| 645 bool isConst: false, | 722 bool isConst: false, |
| 646 bool isStatic: false, | 723 bool isStatic: false, |
| 647 bool hasImplicitGetter, | 724 bool hasImplicitGetter, |
| 648 bool hasImplicitSetter, | 725 bool hasImplicitSetter, |
| 649 int transformerFlags: 0, | 726 int transformerFlags: 0, |
| 650 this.fileUri}) | 727 this.fileUri, |
| 651 : super(name) { | 728 LinkedNodeBox box}) |
| 652 _getterInterface = new _MemberAccessor(this); | 729 : super(name, box) { |
| 653 _setterInterface = new _MemberAccessor(this); | |
| 654 assert(type != null); | 730 assert(type != null); |
| 655 initializer?.parent = this; | 731 initializer?.parent = this; |
| 656 this.isFinal = isFinal; | 732 this.isFinal = isFinal; |
| 657 this.isConst = isConst; | 733 this.isConst = isConst; |
| 658 this.isStatic = isStatic; | 734 this.isStatic = isStatic; |
| 659 this.hasImplicitGetter = hasImplicitGetter ?? !isStatic; | 735 this.hasImplicitGetter = hasImplicitGetter ?? !isStatic; |
| 660 this.hasImplicitSetter = hasImplicitSetter ?? (!isStatic && !isFinal); | 736 this.hasImplicitSetter = hasImplicitSetter ?? (!isStatic && !isFinal); |
| 661 this.transformerFlags = transformerFlags; | 737 this.transformerFlags = transformerFlags; |
| 662 } | 738 } |
| 663 | 739 |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 743 transformList(annotations, v, this); | 819 transformList(annotations, v, this); |
| 744 if (initializer != null) { | 820 if (initializer != null) { |
| 745 initializer = initializer.accept(v); | 821 initializer = initializer.accept(v); |
| 746 initializer?.parent = this; | 822 initializer?.parent = this; |
| 747 } | 823 } |
| 748 } | 824 } |
| 749 | 825 |
| 750 DartType get getterType => type; | 826 DartType get getterType => type; |
| 751 DartType get setterType => isMutable ? type : const BottomType(); | 827 DartType get setterType => isMutable ? type : const BottomType(); |
| 752 | 828 |
| 753 /// Makes all [PropertyGet]s that have this field as its interface target | |
| 754 /// use [getter] as its interface target instead. | |
| 755 /// | |
| 756 /// That can be used to introduce an explicit getter for a field instead of | |
| 757 /// its implicit getter. | |
| 758 /// | |
| 759 /// This method only updates the stored interface target -- the caller must | |
| 760 /// ensure that [getter] actually becomes the target for dispatches that | |
| 761 /// would previously hit the implicit field getter. | |
| 762 /// | |
| 763 /// [DirectPropertyGet]s are not affected, and will continue to access the | |
| 764 /// field directly. [PropertyGet] nodes created after the call will not be | |
| 765 /// affected until the method is called again. | |
| 766 /// | |
| 767 /// Existing [ClassHierarchy] instances are not affected by this call. | |
| 768 void replaceGetterInterfaceWith(Procedure getter) { | |
| 769 _getterInterface.target = getter; | |
| 770 _getterInterface = new _MemberAccessor(this); | |
| 771 } | |
| 772 | |
| 773 /// Makes all [PropertySet]s that have this field as its interface target | |
| 774 /// use [setter] as its interface target instead. | |
| 775 /// | |
| 776 /// That can be used to introduce an explicit setter for a field instead of | |
| 777 /// its implicit setter. | |
| 778 /// | |
| 779 /// This method only updates the stored interface target -- the caller must | |
| 780 /// ensure that [setter] actually becomes the target for dispatches that | |
| 781 /// would previously hit the implicit field setter. | |
| 782 /// | |
| 783 /// [DirectPropertySet] and [FieldInitializer]s are not affected, and will | |
| 784 /// continue to access the field directly. [PropertySet] nodes created after | |
| 785 /// the call will not be affected until the method is called again. | |
| 786 /// | |
| 787 /// Existing [ClassHierarchy] instances are not affected by this call. | |
| 788 void replaceSetterInterfaceWith(Procedure setter) { | |
| 789 _setterInterface.target = setter; | |
| 790 _setterInterface = new _MemberAccessor(this); | |
| 791 } | |
| 792 | |
| 793 Location _getLocationInEnclosingFile(int offset) { | 829 Location _getLocationInEnclosingFile(int offset) { |
| 794 return enclosingProgram.getLocation(fileUri, offset); | 830 return enclosingProgram.getLocation(fileUri, offset); |
| 795 } | 831 } |
| 796 } | 832 } |
| 797 | 833 |
| 798 /// A generative constructor, possibly redirecting. | 834 /// A generative constructor, possibly redirecting. |
| 799 /// | 835 /// |
| 800 /// Note that factory constructors are treated as [Procedure]s. | 836 /// Note that factory constructors are treated as [Procedure]s. |
| 801 /// | 837 /// |
| 802 /// Constructors do not take type parameters. Type arguments from a constructor | 838 /// Constructors do not take type parameters. Type arguments from a constructor |
| 803 /// invocation should be matched with the type parameters declared in the class. | 839 /// invocation should be matched with the type parameters declared in the class. |
| 804 /// | 840 /// |
| 805 /// For unnamed constructors, the name is an empty string (in a [Name]). | 841 /// For unnamed constructors, the name is an empty string (in a [Name]). |
| 806 class Constructor extends Member { | 842 class Constructor extends Member { |
| 807 int flags = 0; | 843 int flags = 0; |
| 808 FunctionNode function; | 844 FunctionNode function; |
| 809 List<Initializer> initializers; | 845 List<Initializer> initializers; |
| 810 | 846 |
| 811 Constructor(this.function, | 847 Constructor(this.function, |
| 812 {Name name, | 848 {Name name, |
| 813 bool isConst: false, | 849 bool isConst: false, |
| 814 bool isExternal: false, | 850 bool isExternal: false, |
| 815 List<Initializer> initializers, | 851 List<Initializer> initializers, |
| 816 int transformerFlags: 0}) | 852 int transformerFlags: 0, |
| 853 LinkedNodeBox box}) | |
| 817 : this.initializers = initializers ?? <Initializer>[], | 854 : this.initializers = initializers ?? <Initializer>[], |
| 818 super(name) { | 855 super(name, box) { |
| 819 function?.parent = this; | 856 function?.parent = this; |
| 820 setParents(this.initializers, this); | 857 setParents(this.initializers, this); |
| 821 this.isConst = isConst; | 858 this.isConst = isConst; |
| 822 this.isExternal = isExternal; | 859 this.isExternal = isExternal; |
| 823 this.transformerFlags = transformerFlags; | 860 this.transformerFlags = transformerFlags; |
| 824 } | 861 } |
| 825 | 862 |
| 826 static const int FlagConst = 1 << 0; // Must match serialized bit positions. | 863 static const int FlagConst = 1 << 0; // Must match serialized bit positions. |
| 827 static const int FlagExternal = 1 << 1; | 864 static const int FlagExternal = 1 << 1; |
| 828 | 865 |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 857 transformList(annotations, v, this); | 894 transformList(annotations, v, this); |
| 858 if (function != null) { | 895 if (function != null) { |
| 859 function = function.accept(v); | 896 function = function.accept(v); |
| 860 function?.parent = this; | 897 function?.parent = this; |
| 861 } | 898 } |
| 862 transformList(initializers, v, this); | 899 transformList(initializers, v, this); |
| 863 } | 900 } |
| 864 | 901 |
| 865 DartType get getterType => const BottomType(); | 902 DartType get getterType => const BottomType(); |
| 866 DartType get setterType => const BottomType(); | 903 DartType get setterType => const BottomType(); |
| 867 | |
| 868 _MemberAccessor get _getterInterface { | |
| 869 throw 'Constructors cannot be used as getters'; | |
| 870 } | |
| 871 | |
| 872 _MemberAccessor get _setterInterface { | |
| 873 throw 'Constructors cannot be used as setters'; | |
| 874 } | |
| 875 } | 904 } |
| 876 | 905 |
| 877 /// A method, getter, setter, index-getter, index-setter, operator overloader, | 906 /// A method, getter, setter, index-getter, index-setter, operator overloader, |
| 878 /// or factory. | 907 /// or factory. |
| 879 /// | 908 /// |
| 880 /// Procedures can have the static, abstract, and/or external modifier, although | 909 /// Procedures can have the static, abstract, and/or external modifier, although |
| 881 /// only the static and external modifiers may be used together. | 910 /// only the static and external modifiers may be used together. |
| 882 /// | 911 /// |
| 883 /// For non-static procedures the name is required for dynamic dispatch. | 912 /// For non-static procedures the name is required for dynamic dispatch. |
| 884 /// For external procedures the name is required for identifying the external | 913 /// For external procedures the name is required for identifying the external |
| 885 /// implementation. | 914 /// implementation. |
| 886 /// | 915 /// |
| 887 /// For methods, getters, and setters the name is just as it was declared. | 916 /// For methods, getters, and setters the name is just as it was declared. |
| 888 /// For setters this does not include a trailing `=`. | 917 /// For setters this does not include a trailing `=`. |
| 889 /// For index-getters/setters, this is `[]` and `[]=`. | 918 /// For index-getters/setters, this is `[]` and `[]=`. |
| 890 /// For operators, this is the token for the operator, e.g. `+` or `==`, | 919 /// For operators, this is the token for the operator, e.g. `+` or `==`, |
| 891 /// except for the unary minus operator, whose name is `unary-`. | 920 /// except for the unary minus operator, whose name is `unary-`. |
| 892 class Procedure extends Member { | 921 class Procedure extends Member { |
| 893 _MemberAccessor _reference; | |
| 894 ProcedureKind kind; | 922 ProcedureKind kind; |
| 895 int flags = 0; | 923 int flags = 0; |
| 896 FunctionNode function; // Body is null if and only if abstract or external. | 924 FunctionNode function; // Body is null if and only if abstract or external. |
| 897 | 925 |
| 898 /// The uri of the source file this procedure was loaded from. | 926 /// The uri of the source file this procedure was loaded from. |
| 899 String fileUri; | 927 String fileUri; |
| 900 | 928 |
| 901 Procedure(Name name, this.kind, this.function, | 929 Procedure(Name name, this.kind, this.function, |
| 902 {bool isAbstract: false, | 930 {bool isAbstract: false, |
| 903 bool isStatic: false, | 931 bool isStatic: false, |
| 904 bool isExternal: false, | 932 bool isExternal: false, |
| 905 bool isConst: false, | 933 bool isConst: false, |
| 906 int transformerFlags: 0, | 934 int transformerFlags: 0, |
| 907 this.fileUri}) | 935 this.fileUri, |
| 908 : super(name) { | 936 LinkedNodeBox box}) |
| 909 _reference = new _MemberAccessor(this); | 937 : super(name, box) { |
| 910 function?.parent = this; | 938 function?.parent = this; |
| 911 this.isAbstract = isAbstract; | 939 this.isAbstract = isAbstract; |
| 912 this.isStatic = isStatic; | 940 this.isStatic = isStatic; |
| 913 this.isExternal = isExternal; | 941 this.isExternal = isExternal; |
| 914 this.isConst = isConst; | 942 this.isConst = isConst; |
| 915 this.transformerFlags = transformerFlags; | 943 this.transformerFlags = transformerFlags; |
| 916 } | 944 } |
| 917 | 945 |
| 918 static const int FlagStatic = 1 << 0; // Must match serialized bit positions. | 946 static const int FlagStatic = 1 << 0; // Must match serialized bit positions. |
| 919 static const int FlagAbstract = 1 << 1; | 947 static const int FlagAbstract = 1 << 1; |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 972 DartType get getterType { | 1000 DartType get getterType { |
| 973 return isGetter ? function.returnType : function.functionType; | 1001 return isGetter ? function.returnType : function.functionType; |
| 974 } | 1002 } |
| 975 | 1003 |
| 976 DartType get setterType { | 1004 DartType get setterType { |
| 977 return isSetter | 1005 return isSetter |
| 978 ? function.positionalParameters[0].type | 1006 ? function.positionalParameters[0].type |
| 979 : const BottomType(); | 1007 : const BottomType(); |
| 980 } | 1008 } |
| 981 | 1009 |
| 982 _MemberAccessor get _getterInterface => _reference; | |
| 983 _MemberAccessor get _setterInterface => _reference; | |
| 984 | |
| 985 Location _getLocationInEnclosingFile(int offset) { | 1010 Location _getLocationInEnclosingFile(int offset) { |
| 986 return enclosingProgram.getLocation(fileUri, offset); | 1011 return enclosingProgram.getLocation(fileUri, offset); |
| 987 } | 1012 } |
| 988 } | 1013 } |
| 989 | 1014 |
| 990 enum ProcedureKind { | 1015 enum ProcedureKind { |
| 991 Method, | 1016 Method, |
| 992 Getter, | 1017 Getter, |
| 993 Setter, | 1018 Setter, |
| 994 Operator, | 1019 Operator, |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 1020 /// A field assignment `field = value` occurring in the initializer list of | 1045 /// A field assignment `field = value` occurring in the initializer list of |
| 1021 /// a constructor. | 1046 /// a constructor. |
| 1022 /// | 1047 /// |
| 1023 /// This node has nothing to do with declaration-site field initializers; those | 1048 /// This node has nothing to do with declaration-site field initializers; those |
| 1024 /// are [Expression]s stored in [Field.initializer]. | 1049 /// are [Expression]s stored in [Field.initializer]. |
| 1025 // | 1050 // |
| 1026 // TODO: The frontend should check that all final fields are initialized | 1051 // TODO: The frontend should check that all final fields are initialized |
| 1027 // exactly once, and that no fields are assigned twice in the initializer list. | 1052 // exactly once, and that no fields are assigned twice in the initializer list. |
| 1028 class FieldInitializer extends Initializer { | 1053 class FieldInitializer extends Initializer { |
| 1029 /// Reference to the field being initialized. Not null. | 1054 /// Reference to the field being initialized. Not null. |
| 1030 Field field; | 1055 LinkedNodeBox fieldBox; |
| 1031 Expression value; | 1056 Expression value; |
| 1032 | 1057 |
| 1033 FieldInitializer(this.field, this.value) { | 1058 FieldInitializer(Field field, Expression value) |
| 1059 : this.byBox(field?.box, value); | |
| 1060 | |
| 1061 FieldInitializer.byBox(this.fieldBox, this.value) { | |
| 1034 value?.parent = this; | 1062 value?.parent = this; |
| 1035 } | 1063 } |
| 1036 | 1064 |
| 1065 Field get field => fieldBox?.node; | |
| 1066 | |
| 1067 void set field(Field field) { | |
| 1068 fieldBox = field?.box; | |
| 1069 } | |
| 1070 | |
| 1037 accept(InitializerVisitor v) => v.visitFieldInitializer(this); | 1071 accept(InitializerVisitor v) => v.visitFieldInitializer(this); |
| 1038 | 1072 |
| 1039 visitChildren(Visitor v) { | 1073 visitChildren(Visitor v) { |
| 1040 field?.acceptReference(v); | 1074 field?.acceptReference(v); |
| 1041 value?.accept(v); | 1075 value?.accept(v); |
| 1042 } | 1076 } |
| 1043 | 1077 |
| 1044 transformChildren(Transformer v) { | 1078 transformChildren(Transformer v) { |
| 1045 if (value != null) { | 1079 if (value != null) { |
| 1046 value = value.accept(v); | 1080 value = value.accept(v); |
| 1047 value?.parent = this; | 1081 value?.parent = this; |
| 1048 } | 1082 } |
| 1049 } | 1083 } |
| 1050 } | 1084 } |
| 1051 | 1085 |
| 1052 /// A super call `super(x,y)` occurring in the initializer list of a | 1086 /// A super call `super(x,y)` occurring in the initializer list of a |
| 1053 /// constructor. | 1087 /// constructor. |
| 1054 /// | 1088 /// |
| 1055 /// There are no type arguments on this call. | 1089 /// There are no type arguments on this call. |
| 1056 // | 1090 // |
| 1057 // TODO: The frontend should check that there is no more than one super call. | 1091 // TODO: The frontend should check that there is no more than one super call. |
| 1058 // | 1092 // |
| 1059 // DESIGN TODO: Consider if the frontend should insert type arguments derived | 1093 // DESIGN TODO: Consider if the frontend should insert type arguments derived |
| 1060 // from the extends clause. | 1094 // from the extends clause. |
| 1061 class SuperInitializer extends Initializer { | 1095 class SuperInitializer extends Initializer { |
| 1062 /// Reference to the constructor being invoked in the super class. Not null. | 1096 /// Reference to the constructor being invoked in the super class. Not null. |
| 1063 Constructor target; | 1097 LinkedNodeBox targetBox; |
| 1064 Arguments arguments; | 1098 Arguments arguments; |
| 1065 | 1099 |
| 1066 SuperInitializer(this.target, this.arguments) { | 1100 SuperInitializer(Constructor target, Arguments arguments) |
| 1101 : this.byBox(getBoxOfMember(target), arguments); | |
| 1102 | |
| 1103 SuperInitializer.byBox(this.targetBox, this.arguments) { | |
| 1067 arguments?.parent = this; | 1104 arguments?.parent = this; |
| 1068 } | 1105 } |
| 1069 | 1106 |
| 1107 Constructor get target => targetBox?.asConstructor; | |
| 1108 | |
| 1109 void set target(Constructor target) { | |
| 1110 targetBox = getBoxOfMember(target); | |
| 1111 } | |
| 1112 | |
| 1070 accept(InitializerVisitor v) => v.visitSuperInitializer(this); | 1113 accept(InitializerVisitor v) => v.visitSuperInitializer(this); |
| 1071 | 1114 |
| 1072 visitChildren(Visitor v) { | 1115 visitChildren(Visitor v) { |
| 1073 target?.acceptReference(v); | 1116 target?.acceptReference(v); |
| 1074 arguments?.accept(v); | 1117 arguments?.accept(v); |
| 1075 } | 1118 } |
| 1076 | 1119 |
| 1077 transformChildren(Transformer v) { | 1120 transformChildren(Transformer v) { |
| 1078 if (arguments != null) { | 1121 if (arguments != null) { |
| 1079 arguments = arguments.accept(v); | 1122 arguments = arguments.accept(v); |
| 1080 arguments?.parent = this; | 1123 arguments?.parent = this; |
| 1081 } | 1124 } |
| 1082 } | 1125 } |
| 1083 } | 1126 } |
| 1084 | 1127 |
| 1085 /// A redirecting call `this(x,y)` occurring in the initializer list of | 1128 /// A redirecting call `this(x,y)` occurring in the initializer list of |
| 1086 /// a constructor. | 1129 /// a constructor. |
| 1087 // | 1130 // |
| 1088 // TODO: The frontend should check that this is the only initializer and if the | 1131 // TODO: The frontend should check that this is the only initializer and if the |
| 1089 // constructor has a body or if there is a cycle in the initializer calls. | 1132 // constructor has a body or if there is a cycle in the initializer calls. |
| 1090 class RedirectingInitializer extends Initializer { | 1133 class RedirectingInitializer extends Initializer { |
| 1091 /// Reference to the constructor being invoked in the same class. Not null. | 1134 /// Reference to the constructor being invoked in the same class. Not null. |
| 1092 Constructor target; | 1135 LinkedNodeBox targetBox; |
| 1093 Arguments arguments; | 1136 Arguments arguments; |
| 1094 | 1137 |
| 1095 RedirectingInitializer(this.target, this.arguments) { | 1138 RedirectingInitializer(Constructor target, Arguments arguments) |
| 1139 : this.byBox(getBoxOfMember(target), arguments); | |
| 1140 | |
| 1141 RedirectingInitializer.byBox(this.targetBox, this.arguments) { | |
| 1096 arguments?.parent = this; | 1142 arguments?.parent = this; |
| 1097 } | 1143 } |
| 1098 | 1144 |
| 1145 Constructor get target => targetBox?.asConstructor; | |
| 1146 | |
| 1147 void set target(Constructor target) { | |
| 1148 targetBox = getBoxOfMember(target); | |
| 1149 } | |
| 1150 | |
| 1099 accept(InitializerVisitor v) => v.visitRedirectingInitializer(this); | 1151 accept(InitializerVisitor v) => v.visitRedirectingInitializer(this); |
| 1100 | 1152 |
| 1101 visitChildren(Visitor v) { | 1153 visitChildren(Visitor v) { |
| 1102 target?.acceptReference(v); | 1154 target?.acceptReference(v); |
| 1103 arguments?.accept(v); | 1155 arguments?.accept(v); |
| 1104 } | 1156 } |
| 1105 | 1157 |
| 1106 transformChildren(Transformer v) { | 1158 transformChildren(Transformer v) { |
| 1107 if (arguments != null) { | 1159 if (arguments != null) { |
| 1108 arguments = arguments.accept(v); | 1160 arguments = arguments.accept(v); |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1381 } | 1433 } |
| 1382 } | 1434 } |
| 1383 | 1435 |
| 1384 /// Expression of form `x.field`. | 1436 /// Expression of form `x.field`. |
| 1385 /// | 1437 /// |
| 1386 /// This may invoke a getter, read a field, or tear off a method. | 1438 /// This may invoke a getter, read a field, or tear off a method. |
| 1387 class PropertyGet extends Expression { | 1439 class PropertyGet extends Expression { |
| 1388 Expression receiver; | 1440 Expression receiver; |
| 1389 Name name; | 1441 Name name; |
| 1390 | 1442 |
| 1391 _MemberAccessor _interfaceTargetReference; | 1443 LinkedNodeBox interfaceTargetBox; |
| 1392 | 1444 |
| 1393 PropertyGet(this.receiver, this.name, [Member interfaceTarget]) { | 1445 PropertyGet(Expression receiver, Name name, [Member interfaceTarget]) |
| 1446 : this.byBox(receiver, name, getBoxOfMember(interfaceTarget)); | |
| 1447 | |
| 1448 PropertyGet.byBox(this.receiver, this.name, this.interfaceTargetBox) { | |
| 1394 receiver?.parent = this; | 1449 receiver?.parent = this; |
| 1395 this.interfaceTarget = interfaceTarget; | |
| 1396 } | 1450 } |
| 1397 | 1451 |
| 1398 Member get interfaceTarget => _interfaceTargetReference?.target; | 1452 Member get interfaceTarget => interfaceTargetBox?.asMember; |
| 1399 | 1453 |
| 1400 void set interfaceTarget(Member newTarget) { | 1454 void set interfaceTarget(Member member) { |
| 1401 _interfaceTargetReference = newTarget?._getterInterface; | 1455 interfaceTargetBox = getBoxOfMember(member); |
| 1402 } | 1456 } |
| 1403 | 1457 |
| 1404 DartType getStaticType(TypeEnvironment types) { | 1458 DartType getStaticType(TypeEnvironment types) { |
| 1405 var interfaceTarget = this.interfaceTarget; | 1459 var interfaceTarget = this.interfaceTarget; |
| 1406 if (interfaceTarget != null) { | 1460 if (interfaceTarget != null) { |
| 1407 Class superclass = interfaceTarget.enclosingClass; | 1461 Class superclass = interfaceTarget.enclosingClass; |
| 1408 var receiverType = receiver.getStaticTypeAsInstanceOf(superclass, types); | 1462 var receiverType = receiver.getStaticTypeAsInstanceOf(superclass, types); |
| 1409 return Substitution | 1463 return Substitution |
| 1410 .fromInterfaceType(receiverType) | 1464 .fromInterfaceType(receiverType) |
| 1411 .substituteType(interfaceTarget.getterType); | 1465 .substituteType(interfaceTarget.getterType); |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 1438 /// Expression of form `x.field = value`. | 1492 /// Expression of form `x.field = value`. |
| 1439 /// | 1493 /// |
| 1440 /// This may invoke a setter or assign a field. | 1494 /// This may invoke a setter or assign a field. |
| 1441 /// | 1495 /// |
| 1442 /// Evaluates to the value of [value]. | 1496 /// Evaluates to the value of [value]. |
| 1443 class PropertySet extends Expression { | 1497 class PropertySet extends Expression { |
| 1444 Expression receiver; | 1498 Expression receiver; |
| 1445 Name name; | 1499 Name name; |
| 1446 Expression value; | 1500 Expression value; |
| 1447 | 1501 |
| 1448 _MemberAccessor _interfaceTargetReference; | 1502 LinkedNodeBox interfaceTargetBox; |
| 1449 | 1503 |
| 1450 PropertySet(this.receiver, this.name, this.value, [Member interfaceTarget]) { | 1504 PropertySet(Expression receiver, Name name, Expression value, |
| 1505 [Member interfaceTarget]) | |
| 1506 : this.byBox( | |
| 1507 receiver, name, value, getBoxOfMember(interfaceTarget)); | |
| 1508 | |
| 1509 PropertySet.byBox( | |
| 1510 this.receiver, this.name, this.value, this.interfaceTargetBox) { | |
| 1451 receiver?.parent = this; | 1511 receiver?.parent = this; |
| 1452 value?.parent = this; | 1512 value?.parent = this; |
| 1453 this.interfaceTarget = interfaceTarget; | |
| 1454 } | 1513 } |
| 1455 | 1514 |
| 1456 Member get interfaceTarget => _interfaceTargetReference?.target; | 1515 Member get interfaceTarget => interfaceTargetBox?.asMember; |
| 1457 | 1516 |
| 1458 void set interfaceTarget(Member newTarget) { | 1517 void set interfaceTarget(Member member) { |
| 1459 _interfaceTargetReference = newTarget?._setterInterface; | 1518 interfaceTargetBox = getBoxOfMember(member); |
| 1460 } | 1519 } |
| 1461 | 1520 |
| 1462 DartType getStaticType(TypeEnvironment types) => value.getStaticType(types); | 1521 DartType getStaticType(TypeEnvironment types) => value.getStaticType(types); |
| 1463 | 1522 |
| 1464 accept(ExpressionVisitor v) => v.visitPropertySet(this); | 1523 accept(ExpressionVisitor v) => v.visitPropertySet(this); |
| 1465 | 1524 |
| 1466 visitChildren(Visitor v) { | 1525 visitChildren(Visitor v) { |
| 1467 receiver?.accept(v); | 1526 receiver?.accept(v); |
| 1468 name?.accept(v); | 1527 name?.accept(v); |
| 1469 value?.accept(v); | 1528 value?.accept(v); |
| 1470 } | 1529 } |
| 1471 | 1530 |
| 1472 transformChildren(Transformer v) { | 1531 transformChildren(Transformer v) { |
| 1473 if (receiver != null) { | 1532 if (receiver != null) { |
| 1474 receiver = receiver.accept(v); | 1533 receiver = receiver.accept(v); |
| 1475 receiver?.parent = this; | 1534 receiver?.parent = this; |
| 1476 } | 1535 } |
| 1477 if (value != null) { | 1536 if (value != null) { |
| 1478 value = value.accept(v); | 1537 value = value.accept(v); |
| 1479 value?.parent = this; | 1538 value?.parent = this; |
| 1480 } | 1539 } |
| 1481 } | 1540 } |
| 1482 } | 1541 } |
| 1483 | 1542 |
| 1484 /// Directly read a field, call a getter, or tear off a method. | 1543 /// Directly read a field, call a getter, or tear off a method. |
| 1485 class DirectPropertyGet extends Expression { | 1544 class DirectPropertyGet extends Expression { |
| 1486 Expression receiver; | 1545 Expression receiver; |
| 1487 Member target; | 1546 LinkedNodeBox targetBox; |
| 1488 | 1547 |
| 1489 DirectPropertyGet(this.receiver, this.target) { | 1548 DirectPropertyGet(Expression receiver, Member target) |
| 1549 : this.byBox(receiver, getBoxOfMember(target)); | |
| 1550 | |
| 1551 DirectPropertyGet.byBox(this.receiver, this.targetBox) { | |
| 1490 receiver?.parent = this; | 1552 receiver?.parent = this; |
| 1491 } | 1553 } |
| 1492 | 1554 |
| 1555 Member get target => targetBox?.asMember; | |
| 1556 | |
| 1557 void set target(Member target) { | |
| 1558 targetBox = getBoxOfMember(target); | |
| 1559 } | |
| 1560 | |
| 1493 visitChildren(Visitor v) { | 1561 visitChildren(Visitor v) { |
| 1494 receiver?.accept(v); | 1562 receiver?.accept(v); |
| 1495 target?.acceptReference(v); | 1563 target?.acceptReference(v); |
| 1496 } | 1564 } |
| 1497 | 1565 |
| 1498 transformChildren(Transformer v) { | 1566 transformChildren(Transformer v) { |
| 1499 if (receiver != null) { | 1567 if (receiver != null) { |
| 1500 receiver = receiver.accept(v); | 1568 receiver = receiver.accept(v); |
| 1501 receiver?.parent = this; | 1569 receiver?.parent = this; |
| 1502 } | 1570 } |
| 1503 } | 1571 } |
| 1504 | 1572 |
| 1505 accept(ExpressionVisitor v) => v.visitDirectPropertyGet(this); | 1573 accept(ExpressionVisitor v) => v.visitDirectPropertyGet(this); |
| 1506 | 1574 |
| 1507 DartType getStaticType(TypeEnvironment types) { | 1575 DartType getStaticType(TypeEnvironment types) { |
| 1508 Class superclass = target.enclosingClass; | 1576 Class superclass = target.enclosingClass; |
| 1509 var receiverType = receiver.getStaticTypeAsInstanceOf(superclass, types); | 1577 var receiverType = receiver.getStaticTypeAsInstanceOf(superclass, types); |
| 1510 return Substitution | 1578 return Substitution |
| 1511 .fromInterfaceType(receiverType) | 1579 .fromInterfaceType(receiverType) |
| 1512 .substituteType(target.getterType); | 1580 .substituteType(target.getterType); |
| 1513 } | 1581 } |
| 1514 } | 1582 } |
| 1515 | 1583 |
| 1516 /// Directly assign a field, or call a setter. | 1584 /// Directly assign a field, or call a setter. |
| 1517 /// | 1585 /// |
| 1518 /// Evaluates to the value of [value]. | 1586 /// Evaluates to the value of [value]. |
| 1519 class DirectPropertySet extends Expression { | 1587 class DirectPropertySet extends Expression { |
| 1520 Expression receiver; | 1588 Expression receiver; |
| 1521 Member target; | 1589 LinkedNodeBox targetBox; |
| 1522 Expression value; | 1590 Expression value; |
| 1523 | 1591 |
| 1524 DirectPropertySet(this.receiver, this.target, this.value) { | 1592 DirectPropertySet(Expression receiver, Member target, Expression value) |
| 1593 : this.byBox(receiver, getBoxOfMember(target), value); | |
| 1594 | |
| 1595 DirectPropertySet.byBox(this.receiver, this.targetBox, this.value) { | |
| 1525 receiver?.parent = this; | 1596 receiver?.parent = this; |
| 1526 value?.parent = this; | 1597 value?.parent = this; |
| 1527 } | 1598 } |
| 1528 | 1599 |
| 1600 Member get target => targetBox?.asMember; | |
| 1601 | |
| 1602 void set target(Member target) { | |
| 1603 targetBox = getBoxOfMember(target); | |
| 1604 } | |
| 1605 | |
| 1529 visitChildren(Visitor v) { | 1606 visitChildren(Visitor v) { |
| 1530 receiver?.accept(v); | 1607 receiver?.accept(v); |
| 1531 target?.acceptReference(v); | 1608 target?.acceptReference(v); |
| 1532 value?.accept(v); | 1609 value?.accept(v); |
| 1533 } | 1610 } |
| 1534 | 1611 |
| 1535 transformChildren(Transformer v) { | 1612 transformChildren(Transformer v) { |
| 1536 if (receiver != null) { | 1613 if (receiver != null) { |
| 1537 receiver = receiver.accept(v); | 1614 receiver = receiver.accept(v); |
| 1538 receiver?.parent = this; | 1615 receiver?.parent = this; |
| 1539 } | 1616 } |
| 1540 if (value != null) { | 1617 if (value != null) { |
| 1541 value = value.accept(v); | 1618 value = value.accept(v); |
| 1542 value?.parent = this; | 1619 value?.parent = this; |
| 1543 } | 1620 } |
| 1544 } | 1621 } |
| 1545 | 1622 |
| 1546 accept(ExpressionVisitor v) => v.visitDirectPropertySet(this); | 1623 accept(ExpressionVisitor v) => v.visitDirectPropertySet(this); |
| 1547 | 1624 |
| 1548 DartType getStaticType(TypeEnvironment types) => value.getStaticType(types); | 1625 DartType getStaticType(TypeEnvironment types) => value.getStaticType(types); |
| 1549 } | 1626 } |
| 1550 | 1627 |
| 1551 /// Directly call an instance method, bypassing ordinary dispatch. | 1628 /// Directly call an instance method, bypassing ordinary dispatch. |
| 1552 class DirectMethodInvocation extends InvocationExpression { | 1629 class DirectMethodInvocation extends InvocationExpression { |
| 1553 Expression receiver; | 1630 Expression receiver; |
| 1554 Procedure target; | 1631 LinkedNodeBox targetBox; |
| 1555 Arguments arguments; | 1632 Arguments arguments; |
| 1556 | 1633 |
| 1557 DirectMethodInvocation(this.receiver, this.target, this.arguments) { | 1634 DirectMethodInvocation( |
| 1635 Expression receiver, Procedure target, Arguments arguments) | |
| 1636 : this.byBox(receiver, getBoxOfMember(target), arguments); | |
| 1637 | |
| 1638 DirectMethodInvocation.byBox( | |
| 1639 this.receiver, this.targetBox, this.arguments) { | |
| 1558 receiver?.parent = this; | 1640 receiver?.parent = this; |
| 1559 arguments?.parent = this; | 1641 arguments?.parent = this; |
| 1560 } | 1642 } |
| 1561 | 1643 |
| 1644 Procedure get target => targetBox?.asProcedure; | |
| 1645 | |
| 1646 void set target(Procedure target) { | |
| 1647 targetBox = getBoxOfMember(target); | |
| 1648 } | |
| 1649 | |
| 1562 Name get name => target?.name; | 1650 Name get name => target?.name; |
| 1563 | 1651 |
| 1564 visitChildren(Visitor v) { | 1652 visitChildren(Visitor v) { |
| 1565 receiver?.accept(v); | 1653 receiver?.accept(v); |
| 1566 target?.acceptReference(v); | 1654 target?.acceptReference(v); |
| 1567 arguments?.accept(v); | 1655 arguments?.accept(v); |
| 1568 } | 1656 } |
| 1569 | 1657 |
| 1570 transformChildren(Transformer v) { | 1658 transformChildren(Transformer v) { |
| 1571 if (receiver != null) { | 1659 if (receiver != null) { |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 1594 .fromPairs(target.function.typeParameters, arguments.types) | 1682 .fromPairs(target.function.typeParameters, arguments.types) |
| 1595 .substituteType(returnType); | 1683 .substituteType(returnType); |
| 1596 } | 1684 } |
| 1597 } | 1685 } |
| 1598 | 1686 |
| 1599 /// Expression of form `super.field`. | 1687 /// Expression of form `super.field`. |
| 1600 /// | 1688 /// |
| 1601 /// This may invoke a getter, read a field, or tear off a method. | 1689 /// This may invoke a getter, read a field, or tear off a method. |
| 1602 class SuperPropertyGet extends Expression { | 1690 class SuperPropertyGet extends Expression { |
| 1603 Name name; | 1691 Name name; |
| 1604 _MemberAccessor _interfaceTargetReference; | 1692 LinkedNodeBox interfaceTargetBox; |
| 1605 | 1693 |
| 1606 SuperPropertyGet(this.name, [Member interfaceTarget]) { | 1694 SuperPropertyGet(Name name, [Member interfaceTarget]) |
| 1607 _interfaceTargetReference = interfaceTarget?._getterInterface; | 1695 : this.byBox(name, getBoxOfMember(interfaceTarget)); |
| 1608 } | |
| 1609 | 1696 |
| 1610 Member get interfaceTarget => _interfaceTargetReference?.target; | 1697 SuperPropertyGet.byBox(this.name, this.interfaceTargetBox); |
| 1611 | 1698 |
| 1612 void set interfaceTarget(Member newTarget) { | 1699 Member get interfaceTarget => interfaceTargetBox?.asMember; |
| 1613 _interfaceTargetReference = newTarget?._getterInterface; | 1700 |
| 1701 void set interfaceTarget(Member member) { | |
| 1702 interfaceTargetBox = getBoxOfMember(member); | |
| 1614 } | 1703 } |
| 1615 | 1704 |
| 1616 DartType getStaticType(TypeEnvironment types) { | 1705 DartType getStaticType(TypeEnvironment types) { |
| 1617 Class declaringClass = interfaceTarget.enclosingClass; | 1706 Class declaringClass = interfaceTarget.enclosingClass; |
| 1618 if (declaringClass.typeParameters.isEmpty) { | 1707 if (declaringClass.typeParameters.isEmpty) { |
| 1619 return interfaceTarget.getterType; | 1708 return interfaceTarget.getterType; |
| 1620 } | 1709 } |
| 1621 var receiver = | 1710 var receiver = |
| 1622 types.hierarchy.getTypeAsInstanceOf(types.thisType, declaringClass); | 1711 types.hierarchy.getTypeAsInstanceOf(types.thisType, declaringClass); |
| 1623 return Substitution | 1712 return Substitution |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 1635 } | 1724 } |
| 1636 | 1725 |
| 1637 /// Expression of form `super.field = value`. | 1726 /// Expression of form `super.field = value`. |
| 1638 /// | 1727 /// |
| 1639 /// This may invoke a setter or assign a field. | 1728 /// This may invoke a setter or assign a field. |
| 1640 /// | 1729 /// |
| 1641 /// Evaluates to the value of [value]. | 1730 /// Evaluates to the value of [value]. |
| 1642 class SuperPropertySet extends Expression { | 1731 class SuperPropertySet extends Expression { |
| 1643 Name name; | 1732 Name name; |
| 1644 Expression value; | 1733 Expression value; |
| 1645 _MemberAccessor _interfaceTargetReference; | 1734 LinkedNodeBox interfaceTargetBox; |
| 1646 | 1735 |
| 1647 SuperPropertySet(this.name, this.value, [Member interfaceTarget]) { | 1736 SuperPropertySet(Name name, Expression value, Member interfaceTarget) |
| 1737 : this.byBox(name, value, getBoxOfMember(interfaceTarget)); | |
| 1738 | |
| 1739 SuperPropertySet.byBox(this.name, this.value, this.interfaceTargetBox) { | |
| 1648 value?.parent = this; | 1740 value?.parent = this; |
| 1649 _interfaceTargetReference = interfaceTarget?._setterInterface; | |
| 1650 } | 1741 } |
| 1651 | 1742 |
| 1652 Member get interfaceTarget => _interfaceTargetReference?.target; | 1743 Member get interfaceTarget => interfaceTargetBox?.asMember; |
| 1653 | 1744 |
| 1654 void set interfaceTarget(Member newTarget) { | 1745 void set interfaceTarget(Member member) { |
| 1655 _interfaceTargetReference = newTarget?._setterInterface; | 1746 interfaceTargetBox = getBoxOfMember(member); |
| 1656 } | 1747 } |
| 1657 | 1748 |
| 1658 DartType getStaticType(TypeEnvironment types) => value.getStaticType(types); | 1749 DartType getStaticType(TypeEnvironment types) => value.getStaticType(types); |
| 1659 | 1750 |
| 1660 accept(ExpressionVisitor v) => v.visitSuperPropertySet(this); | 1751 accept(ExpressionVisitor v) => v.visitSuperPropertySet(this); |
| 1661 | 1752 |
| 1662 visitChildren(Visitor v) { | 1753 visitChildren(Visitor v) { |
| 1663 name?.accept(v); | 1754 name?.accept(v); |
| 1664 value?.accept(v); | 1755 value?.accept(v); |
| 1665 } | 1756 } |
| 1666 | 1757 |
| 1667 transformChildren(Transformer v) { | 1758 transformChildren(Transformer v) { |
| 1668 if (value != null) { | 1759 if (value != null) { |
| 1669 value = value.accept(v); | 1760 value = value.accept(v); |
| 1670 value?.parent = this; | 1761 value?.parent = this; |
| 1671 } | 1762 } |
| 1672 } | 1763 } |
| 1673 } | 1764 } |
| 1674 | 1765 |
| 1675 /// Read a static field, call a static getter, or tear off a static method. | 1766 /// Read a static field, call a static getter, or tear off a static method. |
| 1676 class StaticGet extends Expression { | 1767 class StaticGet extends Expression { |
| 1677 /// A static field, getter, or method (for tear-off). | 1768 /// A static field, getter, or method (for tear-off). |
| 1678 Member target; | 1769 LinkedNodeBox targetBox; |
| 1679 | 1770 |
| 1680 StaticGet(this.target); | 1771 StaticGet(Member target) : this.byBox(getBoxOfMember(target)); |
| 1772 | |
| 1773 StaticGet.byBox(this.targetBox); | |
| 1774 | |
| 1775 Member get target => targetBox?.asMember; | |
| 1776 | |
| 1777 void set target(Member target) { | |
| 1778 targetBox = getBoxOfMember(target); | |
| 1779 } | |
| 1681 | 1780 |
| 1682 DartType getStaticType(TypeEnvironment types) => target.getterType; | 1781 DartType getStaticType(TypeEnvironment types) => target.getterType; |
| 1683 | 1782 |
| 1684 accept(ExpressionVisitor v) => v.visitStaticGet(this); | 1783 accept(ExpressionVisitor v) => v.visitStaticGet(this); |
| 1685 | 1784 |
| 1686 visitChildren(Visitor v) { | 1785 visitChildren(Visitor v) { |
| 1687 target?.acceptReference(v); | 1786 target?.acceptReference(v); |
| 1688 } | 1787 } |
| 1689 | 1788 |
| 1690 transformChildren(Transformer v) {} | 1789 transformChildren(Transformer v) {} |
| 1691 } | 1790 } |
| 1692 | 1791 |
| 1693 /// Assign a static field or call a static setter. | 1792 /// Assign a static field or call a static setter. |
| 1694 /// | 1793 /// |
| 1695 /// Evaluates to the value of [value]. | 1794 /// Evaluates to the value of [value]. |
| 1696 class StaticSet extends Expression { | 1795 class StaticSet extends Expression { |
| 1697 /// A mutable static field or a static setter. | 1796 /// A mutable static field or a static setter. |
| 1698 Member target; | 1797 LinkedNodeBox targetBox; |
| 1699 Expression value; | 1798 Expression value; |
| 1700 | 1799 |
| 1701 StaticSet(this.target, this.value) { | 1800 StaticSet(Member target, Expression value) |
| 1801 : this.byBox(getBoxOfMember(target), value); | |
| 1802 | |
| 1803 StaticSet.byBox(this.targetBox, this.value) { | |
| 1702 value?.parent = this; | 1804 value?.parent = this; |
| 1703 } | 1805 } |
| 1704 | 1806 |
| 1807 Member get target => targetBox?.asMember; | |
| 1808 | |
| 1809 void set target(Member target) { | |
| 1810 targetBox = getBoxOfMember(target); | |
| 1811 } | |
| 1812 | |
| 1705 DartType getStaticType(TypeEnvironment types) => value.getStaticType(types); | 1813 DartType getStaticType(TypeEnvironment types) => value.getStaticType(types); |
| 1706 | 1814 |
| 1707 accept(ExpressionVisitor v) => v.visitStaticSet(this); | 1815 accept(ExpressionVisitor v) => v.visitStaticSet(this); |
| 1708 | 1816 |
| 1709 visitChildren(Visitor v) { | 1817 visitChildren(Visitor v) { |
| 1710 target?.acceptReference(v); | 1818 target?.acceptReference(v); |
| 1711 value?.accept(v); | 1819 value?.accept(v); |
| 1712 } | 1820 } |
| 1713 | 1821 |
| 1714 transformChildren(Transformer v) { | 1822 transformChildren(Transformer v) { |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1788 /// May be `null` if the target is a synthetic static member without a name. | 1896 /// May be `null` if the target is a synthetic static member without a name. |
| 1789 Name get name; | 1897 Name get name; |
| 1790 } | 1898 } |
| 1791 | 1899 |
| 1792 /// Expression of form `x.foo(y)`. | 1900 /// Expression of form `x.foo(y)`. |
| 1793 class MethodInvocation extends InvocationExpression { | 1901 class MethodInvocation extends InvocationExpression { |
| 1794 Expression receiver; | 1902 Expression receiver; |
| 1795 Name name; | 1903 Name name; |
| 1796 Arguments arguments; | 1904 Arguments arguments; |
| 1797 | 1905 |
| 1798 Procedure interfaceTarget; | 1906 LinkedNodeBox interfaceTargetBox; |
| 1799 | 1907 |
| 1800 MethodInvocation(this.receiver, this.name, this.arguments, | 1908 MethodInvocation(Expression receiver, Name name, Arguments arguments, |
| 1801 [this.interfaceTarget]) { | 1909 [Procedure interfaceTarget]) |
| 1910 : this.byBox(receiver, name, arguments, | |
| 1911 getBoxOfMember(interfaceTarget)); | |
| 1912 | |
| 1913 MethodInvocation.byBox( | |
| 1914 this.receiver, this.name, this.arguments, this.interfaceTargetBox) { | |
| 1802 receiver?.parent = this; | 1915 receiver?.parent = this; |
| 1803 arguments?.parent = this; | 1916 arguments?.parent = this; |
| 1804 } | 1917 } |
| 1805 | 1918 |
| 1919 Procedure get interfaceTarget => interfaceTargetBox?.asProcedure; | |
| 1920 | |
| 1921 void set interfaceTarget(Member target) { | |
| 1922 interfaceTargetBox = getBoxOfMember(target); | |
| 1923 } | |
| 1924 | |
| 1806 DartType getStaticType(TypeEnvironment types) { | 1925 DartType getStaticType(TypeEnvironment types) { |
| 1807 if (interfaceTarget != null) { | 1926 if (interfaceTarget != null) { |
| 1808 if (types.isOverloadedArithmeticOperator(interfaceTarget)) { | 1927 if (types.isOverloadedArithmeticOperator(interfaceTarget)) { |
| 1809 return types.getTypeOfOverloadedArithmetic( | 1928 return types.getTypeOfOverloadedArithmetic( |
| 1810 receiver.getStaticType(types), | 1929 receiver.getStaticType(types), |
| 1811 arguments.positional[0].getStaticType(types)); | 1930 arguments.positional[0].getStaticType(types)); |
| 1812 } | 1931 } |
| 1813 Class superclass = interfaceTarget.enclosingClass; | 1932 Class superclass = interfaceTarget.enclosingClass; |
| 1814 var receiverType = receiver.getStaticTypeAsInstanceOf(superclass, types); | 1933 var receiverType = receiver.getStaticTypeAsInstanceOf(superclass, types); |
| 1815 var returnType = Substitution | 1934 var returnType = Substitution |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1857 } | 1976 } |
| 1858 } | 1977 } |
| 1859 | 1978 |
| 1860 /// Expression of form `super.foo(x)`. | 1979 /// Expression of form `super.foo(x)`. |
| 1861 /// | 1980 /// |
| 1862 /// The provided arguments might not match the parameters of the target. | 1981 /// The provided arguments might not match the parameters of the target. |
| 1863 class SuperMethodInvocation extends InvocationExpression { | 1982 class SuperMethodInvocation extends InvocationExpression { |
| 1864 Name name; | 1983 Name name; |
| 1865 Arguments arguments; | 1984 Arguments arguments; |
| 1866 | 1985 |
| 1867 Procedure interfaceTarget; | 1986 LinkedNodeBox interfaceTargetBox; |
| 1868 | 1987 |
| 1869 SuperMethodInvocation(this.name, this.arguments, this.interfaceTarget) { | 1988 SuperMethodInvocation(Name name, Arguments arguments, |
| 1989 [Procedure interfaceTarget]) | |
| 1990 : this.byBox(name, arguments, getBoxOfMember(interfaceTarget)); | |
| 1991 | |
| 1992 SuperMethodInvocation.byBox( | |
| 1993 this.name, this.arguments, this.interfaceTargetBox) { | |
| 1870 arguments?.parent = this; | 1994 arguments?.parent = this; |
| 1871 } | 1995 } |
| 1872 | 1996 |
| 1997 Procedure get interfaceTarget => interfaceTargetBox?.asProcedure; | |
| 1998 | |
| 1999 void set interfaceTarget(Procedure target) { | |
| 2000 interfaceTargetBox = getBoxOfMember(target); | |
| 2001 } | |
| 2002 | |
| 1873 DartType getStaticType(TypeEnvironment types) { | 2003 DartType getStaticType(TypeEnvironment types) { |
| 1874 if (interfaceTarget == null) return const DynamicType(); | 2004 if (interfaceTarget == null) return const DynamicType(); |
| 1875 Class superclass = interfaceTarget.enclosingClass; | 2005 Class superclass = interfaceTarget.enclosingClass; |
| 1876 var receiverType = | 2006 var receiverType = |
| 1877 types.hierarchy.getTypeAsInstanceOf(types.thisType, superclass); | 2007 types.hierarchy.getTypeAsInstanceOf(types.thisType, superclass); |
| 1878 var returnType = Substitution | 2008 var returnType = Substitution |
| 1879 .fromInterfaceType(receiverType) | 2009 .fromInterfaceType(receiverType) |
| 1880 .substituteType(interfaceTarget.function.returnType); | 2010 .substituteType(interfaceTarget.function.returnType); |
| 1881 return Substitution | 2011 return Substitution |
| 1882 .fromPairs(interfaceTarget.function.typeParameters, arguments.types) | 2012 .fromPairs(interfaceTarget.function.typeParameters, arguments.types) |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 1896 arguments?.parent = this; | 2026 arguments?.parent = this; |
| 1897 } | 2027 } |
| 1898 } | 2028 } |
| 1899 } | 2029 } |
| 1900 | 2030 |
| 1901 /// Expression of form `foo(x)`, or `const foo(x)` if the target is an | 2031 /// Expression of form `foo(x)`, or `const foo(x)` if the target is an |
| 1902 /// external constant factory. | 2032 /// external constant factory. |
| 1903 /// | 2033 /// |
| 1904 /// The provided arguments might not match the parameters of the target. | 2034 /// The provided arguments might not match the parameters of the target. |
| 1905 class StaticInvocation extends InvocationExpression { | 2035 class StaticInvocation extends InvocationExpression { |
| 1906 Procedure target; | 2036 LinkedNodeBox targetBox; |
| 1907 Arguments arguments; | 2037 Arguments arguments; |
| 1908 | 2038 |
| 1909 /// True if this is a constant call to an external constant factory. | 2039 /// True if this is a constant call to an external constant factory. |
| 1910 bool isConst; | 2040 bool isConst; |
| 1911 | 2041 |
| 1912 Name get name => target?.name; | 2042 Name get name => target?.name; |
| 1913 | 2043 |
| 1914 StaticInvocation(this.target, this.arguments, {this.isConst: false}) { | 2044 StaticInvocation(Procedure target, Arguments arguments, {bool isConst: false}) |
| 2045 : this.byBox(getBoxOfMember(target), arguments, | |
| 2046 isConst: isConst); | |
| 2047 | |
| 2048 StaticInvocation.byBox(this.targetBox, this.arguments, | |
| 2049 {this.isConst: false}) { | |
| 1915 arguments?.parent = this; | 2050 arguments?.parent = this; |
| 1916 } | 2051 } |
| 1917 | 2052 |
| 2053 Procedure get target => targetBox?.asProcedure; | |
| 2054 | |
| 2055 void set target(Procedure target) { | |
| 2056 targetBox = getBoxOfMember(target); | |
| 2057 } | |
| 2058 | |
| 1918 DartType getStaticType(TypeEnvironment types) { | 2059 DartType getStaticType(TypeEnvironment types) { |
| 1919 return Substitution | 2060 return Substitution |
| 1920 .fromPairs(target.function.typeParameters, arguments.types) | 2061 .fromPairs(target.function.typeParameters, arguments.types) |
| 1921 .substituteType(target.function.returnType); | 2062 .substituteType(target.function.returnType); |
| 1922 } | 2063 } |
| 1923 | 2064 |
| 1924 accept(ExpressionVisitor v) => v.visitStaticInvocation(this); | 2065 accept(ExpressionVisitor v) => v.visitStaticInvocation(this); |
| 1925 | 2066 |
| 1926 visitChildren(Visitor v) { | 2067 visitChildren(Visitor v) { |
| 1927 target?.acceptReference(v); | 2068 target?.acceptReference(v); |
| 1928 arguments?.accept(v); | 2069 arguments?.accept(v); |
| 1929 } | 2070 } |
| 1930 | 2071 |
| 1931 transformChildren(Transformer v) { | 2072 transformChildren(Transformer v) { |
| 1932 if (arguments != null) { | 2073 if (arguments != null) { |
| 1933 arguments = arguments.accept(v); | 2074 arguments = arguments.accept(v); |
| 1934 arguments?.parent = this; | 2075 arguments?.parent = this; |
| 1935 } | 2076 } |
| 1936 } | 2077 } |
| 1937 } | 2078 } |
| 1938 | 2079 |
| 1939 /// Expression of form `new Foo(x)` or `const Foo(x)`. | 2080 /// Expression of form `new Foo(x)` or `const Foo(x)`. |
| 1940 /// | 2081 /// |
| 1941 /// The provided arguments might not match the parameters of the target. | 2082 /// The provided arguments might not match the parameters of the target. |
| 1942 // | 2083 // |
| 1943 // DESIGN TODO: Should we pass type arguments in a separate field | 2084 // DESIGN TODO: Should we pass type arguments in a separate field |
| 1944 // `classTypeArguments`? They are quite different from type arguments to | 2085 // `classTypeArguments`? They are quite different from type arguments to |
| 1945 // generic functions. | 2086 // generic functions. |
| 1946 class ConstructorInvocation extends InvocationExpression { | 2087 class ConstructorInvocation extends InvocationExpression { |
| 1947 Constructor target; | 2088 LinkedNodeBox targetBox; |
| 1948 Arguments arguments; | 2089 Arguments arguments; |
| 1949 bool isConst; | 2090 bool isConst; |
| 1950 | 2091 |
| 1951 Name get name => target?.name; | 2092 Name get name => target?.name; |
| 1952 | 2093 |
| 1953 ConstructorInvocation(this.target, this.arguments, {this.isConst: false}) { | 2094 ConstructorInvocation(Constructor target, Arguments arguments, |
| 2095 {bool isConst: false}) | |
| 2096 : this.byBox(getBoxOfMember(target), arguments, | |
| 2097 isConst: isConst); | |
| 2098 | |
| 2099 ConstructorInvocation.byBox(this.targetBox, this.arguments, | |
| 2100 {this.isConst: false}) { | |
| 1954 arguments?.parent = this; | 2101 arguments?.parent = this; |
| 1955 } | 2102 } |
| 1956 | 2103 |
| 2104 Constructor get target => targetBox?.asConstructor; | |
| 2105 | |
| 2106 void set target(Constructor target) { | |
| 2107 targetBox = getBoxOfMember(target); | |
| 2108 } | |
| 2109 | |
| 1957 DartType getStaticType(TypeEnvironment types) { | 2110 DartType getStaticType(TypeEnvironment types) { |
| 1958 return arguments.types.isEmpty | 2111 return arguments.types.isEmpty |
| 1959 ? target.enclosingClass.rawType | 2112 ? target.enclosingClass.rawType |
| 1960 : new InterfaceType(target.enclosingClass, arguments.types); | 2113 : new InterfaceType(target.enclosingClass, arguments.types); |
| 1961 } | 2114 } |
| 1962 | 2115 |
| 1963 accept(ExpressionVisitor v) => v.visitConstructorInvocation(this); | 2116 accept(ExpressionVisitor v) => v.visitConstructorInvocation(this); |
| 1964 | 2117 |
| 1965 visitChildren(Visitor v) { | 2118 visitChildren(Visitor v) { |
| 1966 target?.acceptReference(v); | 2119 target?.acceptReference(v); |
| (...skipping 1226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3193 /// statically resolved references are represented in nameless form. | 3346 /// statically resolved references are represented in nameless form. |
| 3194 /// | 3347 /// |
| 3195 /// [Name]s are immutable and compare based on structural equality, and they | 3348 /// [Name]s are immutable and compare based on structural equality, and they |
| 3196 /// are not AST nodes. | 3349 /// are not AST nodes. |
| 3197 /// | 3350 /// |
| 3198 /// The [toString] method returns a human-readable string that includes the | 3351 /// The [toString] method returns a human-readable string that includes the |
| 3199 /// library name for private names; uniqueness is not guaranteed. | 3352 /// library name for private names; uniqueness is not guaranteed. |
| 3200 abstract class Name implements Node { | 3353 abstract class Name implements Node { |
| 3201 final int hashCode; | 3354 final int hashCode; |
| 3202 final String name; | 3355 final String name; |
| 3356 LinkedNodeBox get libraryName; | |
| 3203 Library get library; | 3357 Library get library; |
| 3204 bool get isPrivate; | 3358 bool get isPrivate; |
| 3205 | 3359 |
| 3206 Name._internal(this.hashCode, this.name); | 3360 Name._internal(this.hashCode, this.name); |
| 3207 | 3361 |
| 3208 factory Name(String name, [Library library]) { | 3362 factory Name(String name, [Library library]) => |
| 3363 new Name.byReference(name, library?.box); | |
| 3364 | |
| 3365 factory Name.byReference(String name, LinkedNodeBox libraryName) { | |
| 3209 /// Use separate subclasses for the public and private case to save memory | 3366 /// Use separate subclasses for the public and private case to save memory |
| 3210 /// for public names. | 3367 /// for public names. |
| 3211 if (name.startsWith('_')) { | 3368 if (name.startsWith('_')) { |
| 3212 assert(library != null); | 3369 assert(libraryName != null); |
| 3213 return new _PrivateName(name, library); | 3370 return new _PrivateName(name, libraryName); |
| 3214 } else { | 3371 } else { |
| 3215 return new _PublicName(name); | 3372 return new _PublicName(name); |
| 3216 } | 3373 } |
| 3217 } | 3374 } |
| 3218 | 3375 |
| 3219 bool operator ==(other) { | 3376 bool operator ==(other) { |
| 3220 return other is Name && name == other.name && library == other.library; | 3377 return other is Name && name == other.name && library == other.library; |
| 3221 } | 3378 } |
| 3222 | 3379 |
| 3223 accept(Visitor v) => v.visitName(this); | 3380 accept(Visitor v) => v.visitName(this); |
| 3224 | 3381 |
| 3225 visitChildren(Visitor v) { | 3382 visitChildren(Visitor v) { |
| 3226 // DESIGN TODO: Should we visit the library as a library reference? | 3383 // DESIGN TODO: Should we visit the library as a library reference? |
| 3227 } | 3384 } |
| 3228 } | 3385 } |
| 3229 | 3386 |
| 3230 class _PrivateName extends Name { | 3387 class _PrivateName extends Name { |
| 3231 final Library library; | 3388 final LinkedNodeBox libraryName; |
| 3232 bool get isPrivate => true; | 3389 bool get isPrivate => true; |
| 3233 | 3390 |
| 3234 _PrivateName(String name, Library library) | 3391 _PrivateName(String name, LinkedNodeBox libraryName) |
| 3235 : this.library = library, | 3392 : this.libraryName = libraryName, |
| 3236 super._internal(_computeHashCode(name, library), name); | 3393 super._internal(_computeHashCode(name, libraryName), name); |
| 3237 | 3394 |
| 3238 String toString() => library != null ? '$library::$name' : name; | 3395 String toString() => library != null ? '$library::$name' : name; |
| 3239 | 3396 |
| 3240 static int _computeHashCode(String name, Library library) { | 3397 Library get library => libraryName.asLibrary; |
| 3241 return 131 * name.hashCode + 17 * library.hashCode; | 3398 |
| 3399 static int _computeHashCode(String name, LinkedNodeBox libraryName) { | |
| 3400 return 131 * name.hashCode + 17 * libraryName.hashCode; | |
| 3242 } | 3401 } |
| 3243 } | 3402 } |
| 3244 | 3403 |
| 3245 class _PublicName extends Name { | 3404 class _PublicName extends Name { |
| 3405 LinkedNodeBox get libraryName => null; | |
| 3246 Library get library => null; | 3406 Library get library => null; |
| 3247 bool get isPrivate => false; | 3407 bool get isPrivate => false; |
| 3248 | 3408 |
| 3249 _PublicName(String name) : super._internal(name.hashCode, name); | 3409 _PublicName(String name) : super._internal(name.hashCode, name); |
| 3250 | 3410 |
| 3251 String toString() => name; | 3411 String toString() => name; |
| 3252 } | 3412 } |
| 3253 | 3413 |
| 3254 // ------------------------------------------------------------------------ | 3414 // ------------------------------------------------------------------------ |
| 3255 // TYPES | 3415 // TYPES |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3315 | 3475 |
| 3316 const BottomType(); | 3476 const BottomType(); |
| 3317 | 3477 |
| 3318 accept(DartTypeVisitor v) => v.visitBottomType(this); | 3478 accept(DartTypeVisitor v) => v.visitBottomType(this); |
| 3319 visitChildren(Visitor v) {} | 3479 visitChildren(Visitor v) {} |
| 3320 | 3480 |
| 3321 bool operator ==(Object other) => other is BottomType; | 3481 bool operator ==(Object other) => other is BottomType; |
| 3322 } | 3482 } |
| 3323 | 3483 |
| 3324 class InterfaceType extends DartType { | 3484 class InterfaceType extends DartType { |
| 3325 final Class classNode; | 3485 final LinkedNodeBox className; |
| 3326 final List<DartType> typeArguments; | 3486 final List<DartType> typeArguments; |
| 3327 | 3487 |
| 3328 /// The [typeArguments] list must not be modified after this call. If the | 3488 /// The [typeArguments] list must not be modified after this call. If the |
| 3329 /// list is omitted, 'dynamic' type arguments are filled in. | 3489 /// list is omitted, 'dynamic' type arguments are filled in. |
| 3330 InterfaceType(Class classNode, [List<DartType> typeArguments]) | 3490 InterfaceType(Class classNode, [List<DartType> typeArguments]) |
| 3331 : this.classNode = classNode, | 3491 : this.byBox(getBoxOfClass(classNode), |
| 3332 this.typeArguments = typeArguments ?? _defaultTypeArguments(classNode); | 3492 typeArguments ?? _defaultTypeArguments(classNode)); |
| 3493 | |
| 3494 InterfaceType.byBox(this.className, this.typeArguments); | |
| 3495 | |
| 3496 Class get classNode => className.asClass; | |
| 3333 | 3497 |
| 3334 static List<DartType> _defaultTypeArguments(Class classNode) { | 3498 static List<DartType> _defaultTypeArguments(Class classNode) { |
| 3335 if (classNode.typeParameters.length == 0) { | 3499 if (classNode.typeParameters.length == 0) { |
| 3336 // Avoid allocating a list in this very common case. | 3500 // Avoid allocating a list in this very common case. |
| 3337 return const <DartType>[]; | 3501 return const <DartType>[]; |
| 3338 } else { | 3502 } else { |
| 3339 return new List<DartType>.filled( | 3503 return new List<DartType>.filled( |
| 3340 classNode.typeParameters.length, const DynamicType()); | 3504 classNode.typeParameters.length, const DynamicType()); |
| 3341 } | 3505 } |
| 3342 } | 3506 } |
| 3343 | 3507 |
| 3344 accept(DartTypeVisitor v) => v.visitInterfaceType(this); | 3508 accept(DartTypeVisitor v) => v.visitInterfaceType(this); |
| 3345 | 3509 |
| 3346 visitChildren(Visitor v) { | 3510 visitChildren(Visitor v) { |
| 3347 classNode.acceptReference(v); | 3511 classNode.acceptReference(v); |
| 3348 visitList(typeArguments, v); | 3512 visitList(typeArguments, v); |
| 3349 } | 3513 } |
| 3350 | 3514 |
| 3351 bool operator ==(Object other) { | 3515 bool operator ==(Object other) { |
| 3352 if (identical(this, other)) return true; | 3516 if (identical(this, other)) return true; |
| 3353 if (other is InterfaceType) { | 3517 if (other is InterfaceType) { |
| 3354 if (classNode != other.classNode) return false; | 3518 if (className != other.className) return false; |
| 3355 if (typeArguments.length != other.typeArguments.length) return false; | 3519 if (typeArguments.length != other.typeArguments.length) return false; |
| 3356 for (int i = 0; i < typeArguments.length; ++i) { | 3520 for (int i = 0; i < typeArguments.length; ++i) { |
| 3357 if (typeArguments[i] != other.typeArguments[i]) return false; | 3521 if (typeArguments[i] != other.typeArguments[i]) return false; |
| 3358 } | 3522 } |
| 3359 return true; | 3523 return true; |
| 3360 } else { | 3524 } else { |
| 3361 return false; | 3525 return false; |
| 3362 } | 3526 } |
| 3363 } | 3527 } |
| 3364 | 3528 |
| 3365 int get hashCode { | 3529 int get hashCode { |
| 3366 int hash = 0x3fffffff & classNode.hashCode; | 3530 int hash = 0x3fffffff & className.hashCode; |
| 3367 for (int i = 0; i < typeArguments.length; ++i) { | 3531 for (int i = 0; i < typeArguments.length; ++i) { |
| 3368 hash = 0x3fffffff & (hash * 31 + (hash ^ typeArguments[i].hashCode)); | 3532 hash = 0x3fffffff & (hash * 31 + (hash ^ typeArguments[i].hashCode)); |
| 3369 } | 3533 } |
| 3370 return hash; | 3534 return hash; |
| 3371 } | 3535 } |
| 3372 } | 3536 } |
| 3373 | 3537 |
| 3374 /// A possibly generic function type. | 3538 /// A possibly generic function type. |
| 3375 class FunctionType extends DartType { | 3539 class FunctionType extends DartType { |
| 3376 final List<TypeParameter> typeParameters; | 3540 final List<TypeParameter> typeParameters; |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3544 transformChildren(Transformer v) { | 3708 transformChildren(Transformer v) { |
| 3545 bound = v.visitDartType(bound); | 3709 bound = v.visitDartType(bound); |
| 3546 } | 3710 } |
| 3547 | 3711 |
| 3548 /// Returns a possibly synthesized name for this type parameter, consistent | 3712 /// Returns a possibly synthesized name for this type parameter, consistent |
| 3549 /// with the names used across all [toString] calls. | 3713 /// with the names used across all [toString] calls. |
| 3550 String toString() => debugQualifiedTypeParameterName(this); | 3714 String toString() => debugQualifiedTypeParameterName(this); |
| 3551 } | 3715 } |
| 3552 | 3716 |
| 3553 class Supertype extends Node { | 3717 class Supertype extends Node { |
| 3554 final Class classNode; | 3718 final LinkedNodeBox className; |
| 3555 final List<DartType> typeArguments; | 3719 final List<DartType> typeArguments; |
| 3556 | 3720 |
| 3557 Supertype(this.classNode, this.typeArguments); | 3721 Supertype(Class classNode, List<DartType> typeArguments) |
| 3722 : this.byBox(getBoxOfClass(classNode), typeArguments); | |
| 3723 | |
| 3724 Supertype.byBox(this.className, this.typeArguments); | |
| 3725 | |
| 3726 Class get classNode => className.asClass; | |
| 3558 | 3727 |
| 3559 accept(Visitor v) => v.visitSupertype(this); | 3728 accept(Visitor v) => v.visitSupertype(this); |
| 3560 | 3729 |
| 3561 visitChildren(Visitor v) { | 3730 visitChildren(Visitor v) { |
| 3562 classNode.acceptReference(v); | 3731 classNode.acceptReference(v); |
| 3563 visitList(typeArguments, v); | 3732 visitList(typeArguments, v); |
| 3564 } | 3733 } |
| 3565 | 3734 |
| 3566 InterfaceType get asInterfaceType { | 3735 InterfaceType get asInterfaceType { |
| 3567 return new InterfaceType(classNode, typeArguments); | 3736 return new InterfaceType(classNode, typeArguments); |
| 3568 } | 3737 } |
| 3569 | 3738 |
| 3570 bool operator ==(Object other) { | 3739 bool operator ==(Object other) { |
| 3571 if (identical(this, other)) return true; | 3740 if (identical(this, other)) return true; |
| 3572 if (other is Supertype) { | 3741 if (other is Supertype) { |
| 3573 if (classNode != other.classNode) return false; | 3742 if (className != other.className) return false; |
| 3574 if (typeArguments.length != other.typeArguments.length) return false; | 3743 if (typeArguments.length != other.typeArguments.length) return false; |
| 3575 for (int i = 0; i < typeArguments.length; ++i) { | 3744 for (int i = 0; i < typeArguments.length; ++i) { |
| 3576 if (typeArguments[i] != other.typeArguments[i]) return false; | 3745 if (typeArguments[i] != other.typeArguments[i]) return false; |
| 3577 } | 3746 } |
| 3578 return true; | 3747 return true; |
| 3579 } else { | 3748 } else { |
| 3580 return false; | 3749 return false; |
| 3581 } | 3750 } |
| 3582 } | 3751 } |
| 3583 | 3752 |
| 3584 int get hashCode { | 3753 int get hashCode { |
| 3585 int hash = 0x3fffffff & classNode.hashCode; | 3754 int hash = 0x3fffffff & className.hashCode; |
| 3586 for (int i = 0; i < typeArguments.length; ++i) { | 3755 for (int i = 0; i < typeArguments.length; ++i) { |
| 3587 hash = 0x3fffffff & (hash * 31 + (hash ^ typeArguments[i].hashCode)); | 3756 hash = 0x3fffffff & (hash * 31 + (hash ^ typeArguments[i].hashCode)); |
| 3588 } | 3757 } |
| 3589 return hash; | 3758 return hash; |
| 3590 } | 3759 } |
| 3591 } | 3760 } |
| 3592 | 3761 |
| 3593 // ------------------------------------------------------------------------ | 3762 // ------------------------------------------------------------------------ |
| 3594 // PROGRAM | 3763 // PROGRAM |
| 3595 // ------------------------------------------------------------------------ | 3764 // ------------------------------------------------------------------------ |
| 3596 | 3765 |
| 3597 /// A way to bundle up all the libraries in a program. | 3766 /// A way to bundle up all the libraries in a program. |
| 3598 class Program extends TreeNode { | 3767 class Program extends TreeNode { |
| 3768 final CanonicalName root = new CanonicalName.root(); | |
| 3769 | |
| 3599 final List<Library> libraries; | 3770 final List<Library> libraries; |
| 3600 | 3771 |
| 3601 /// Map from a source file uri to a line-starts table and source code. | 3772 /// Map from a source file uri to a line-starts table and source code. |
| 3602 /// Given a source file uri and a offset in that file one can translate | 3773 /// Given a source file uri and a offset in that file one can translate |
| 3603 /// it to a line:column position in that file. | 3774 /// it to a line:column position in that file. |
| 3604 final Map<String, Source> uriToSource; | 3775 final Map<String, Source> uriToSource; |
| 3605 | 3776 |
| 3606 /// Reference to the main method in one of the libraries. | 3777 /// Reference to the main method in one of the libraries. |
| 3607 Procedure mainMethod; | 3778 LinkedNodeBox mainMethodName; |
| 3608 | 3779 |
| 3609 Program([List<Library> libraries, Map<String, Source> uriToSource]) | 3780 Program([List<Library> libraries, Map<String, Source> uriToSource]) |
| 3610 : libraries = libraries ?? <Library>[], | 3781 : libraries = libraries ?? <Library>[], |
| 3611 uriToSource = uriToSource ?? <String, Source>{} { | 3782 uriToSource = uriToSource ?? <String, Source>{} { |
| 3612 setParents(libraries, this); | 3783 setParents(this.libraries, this); |
| 3784 } | |
| 3785 | |
| 3786 void computeCanonicalNames() { | |
| 3787 for (var library in libraries) { | |
| 3788 root.getChildFromUri(library.importUri).bindTo(library.box); | |
| 3789 library.computeCanonicalNames(); | |
| 3790 } | |
| 3791 } | |
| 3792 | |
| 3793 void unbindCanonicalNames() { | |
| 3794 root.unbindAll(); | |
| 3795 } | |
| 3796 | |
| 3797 Procedure get mainMethod => mainMethodName?.asProcedure; | |
| 3798 | |
| 3799 void set mainMethod(Procedure main) { | |
| 3800 mainMethodName = getBoxOfMember(main); | |
| 3613 } | 3801 } |
| 3614 | 3802 |
| 3615 accept(TreeVisitor v) => v.visitProgram(this); | 3803 accept(TreeVisitor v) => v.visitProgram(this); |
| 3616 | 3804 |
| 3617 visitChildren(Visitor v) { | 3805 visitChildren(Visitor v) { |
| 3618 visitList(libraries, v); | 3806 visitList(libraries, v); |
| 3619 mainMethod?.acceptReference(v); | 3807 mainMethod?.acceptReference(v); |
| 3620 } | 3808 } |
| 3621 | 3809 |
| 3622 transformChildren(Transformer v) { | 3810 transformChildren(Transformer v) { |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3745 } | 3933 } |
| 3746 } | 3934 } |
| 3747 } | 3935 } |
| 3748 | 3936 |
| 3749 class Source { | 3937 class Source { |
| 3750 final List<int> lineStarts; | 3938 final List<int> lineStarts; |
| 3751 final String source; | 3939 final String source; |
| 3752 | 3940 |
| 3753 Source(this.lineStarts, this.source); | 3941 Source(this.lineStarts, this.source); |
| 3754 } | 3942 } |
| 3943 | |
| 3944 /// Returns the canonical name of [member], or throws an exception if the | |
| 3945 /// member has not been assigned a canonical name yet. | |
| 3946 /// | |
| 3947 /// Returns `null` if the member is `null`. | |
| 3948 LinkedNodeBox getBoxOfMember(Member member) { | |
| 3949 return member?.box; | |
| 3950 } | |
| 3951 | |
| 3952 /// Returns the canonical name of [class_], or throws an exception if the | |
| 3953 /// class has not been assigned a canonical name yet. | |
| 3954 /// | |
| 3955 /// Returns `null` if the class is `null`. | |
| 3956 LinkedNodeBox getBoxOfClass(Class class_) { | |
| 3957 return class_?.box; | |
| 3958 } | |
| 3959 | |
| 3960 /// Returns the canonical name of [library], or throws an exception if the | |
| 3961 /// library has not been assigned a canonical name yet. | |
| 3962 /// | |
| 3963 /// Returns `null` if the library is `null`. | |
| 3964 LinkedNodeBox getBoxOfLibrary(Library library) { | |
| 3965 return library?.box; | |
| 3966 } | |
| 3967 | |
| 3968 /// Returns the canonical name of [member], or throws an exception if the | |
| 3969 /// member has not been assigned a canonical name yet. | |
| 3970 /// | |
| 3971 /// Returns `null` if the member is `null`. | |
| 3972 CanonicalName getCanonicalNameOfMember(Member member) { | |
| 3973 if (member == null) return null; | |
| 3974 if (member.canonicalName == null) { | |
| 3975 throw '$member has no canonical name'; | |
| 3976 } | |
| 3977 return member.canonicalName; | |
| 3978 } | |
| 3979 | |
| 3980 /// Returns the canonical name of [class_], or throws an exception if the | |
| 3981 /// class has not been assigned a canonical name yet. | |
| 3982 /// | |
| 3983 /// Returns `null` if the class is `null`. | |
| 3984 CanonicalName getCanonicalNameOfClass(Class class_) { | |
| 3985 if (class_ == null) return null; | |
| 3986 if (class_.canonicalName == null) { | |
| 3987 throw '$class_ has no canonical name'; | |
| 3988 } | |
| 3989 return class_.canonicalName; | |
| 3990 } | |
| 3991 | |
| 3992 /// Returns the canonical name of [library], or throws an exception if the | |
| 3993 /// library has not been assigned a canonical name yet. | |
| 3994 /// | |
| 3995 /// Returns `null` if the library is `null`. | |
| 3996 CanonicalName getCanonicalNameOfLibrary(Library library) { | |
| 3997 if (library == null) return null; | |
| 3998 if (library.canonicalName == null) { | |
| 3999 throw '$library has no canonical name'; | |
| 4000 } | |
| 4001 return library.canonicalName; | |
| 4002 } | |
| OLD | NEW |