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 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
46 /// relatively few nodes. Or use whichever is more convenient. | 46 /// relatively few nodes. Or use whichever is more convenient. |
47 /// | 47 /// |
48 /// The AST can also be mutated by direct field manipulation, but the user then | 48 /// The AST can also be mutated by direct field manipulation, but the user then |
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'; | |
57 export 'type_propagation/type_propagation.dart'; | |
58 | |
59 import 'canonical_name.dart' show CanonicalName; | 56 import 'canonical_name.dart' show CanonicalName; |
60 export 'canonical_name.dart' show CanonicalName; | 57 export 'canonical_name.dart' show CanonicalName; |
61 | 58 |
62 import 'transformations/flags.dart'; | 59 import 'transformations/flags.dart'; |
63 import 'text/ast_to_text.dart'; | 60 import 'text/ast_to_text.dart'; |
64 import 'type_algebra.dart'; | 61 import 'type_algebra.dart'; |
65 import 'type_environment.dart'; | 62 import 'type_environment.dart'; |
66 | 63 |
67 /// Any type of node in the IR. | 64 /// Any type of node in the IR. |
68 abstract class Node { | 65 abstract class Node { |
(...skipping 656 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
725 return transformerFlags & TransformerFlag.superCalls != 0; | 722 return transformerFlags & TransformerFlag.superCalls != 0; |
726 } | 723 } |
727 } | 724 } |
728 | 725 |
729 /// A field declaration. | 726 /// A field declaration. |
730 /// | 727 /// |
731 /// The implied getter and setter for the field are not represented explicitly, | 728 /// The implied getter and setter for the field are not represented explicitly, |
732 /// but can be made explicit if needed. | 729 /// but can be made explicit if needed. |
733 class Field extends Member { | 730 class Field extends Member { |
734 DartType type; // Not null. Defaults to DynamicType. | 731 DartType type; // Not null. Defaults to DynamicType. |
735 InferredValue inferredValue; // May be null. | |
736 int flags = 0; | 732 int flags = 0; |
737 Expression initializer; // May be null. | 733 Expression initializer; // May be null. |
738 | 734 |
739 /// The uri of the source file this field was loaded from. | 735 /// The uri of the source file this field was loaded from. |
740 String fileUri; | 736 String fileUri; |
741 | 737 |
742 Field(Name name, | 738 Field(Name name, |
743 {this.type: const DynamicType(), | 739 {this.type: const DynamicType(), |
744 this.inferredValue, | |
745 this.initializer, | 740 this.initializer, |
746 bool isFinal: false, | 741 bool isFinal: false, |
747 bool isConst: false, | 742 bool isConst: false, |
748 bool isStatic: false, | 743 bool isStatic: false, |
749 bool hasImplicitGetter, | 744 bool hasImplicitGetter, |
750 bool hasImplicitSetter, | 745 bool hasImplicitSetter, |
751 int transformerFlags: 0, | 746 int transformerFlags: 0, |
752 this.fileUri, | 747 this.fileUri, |
753 Reference reference}) | 748 Reference reference}) |
754 : super(name, reference) { | 749 : super(name, reference) { |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
827 if (value) throw 'Fields cannot be external'; | 822 if (value) throw 'Fields cannot be external'; |
828 } | 823 } |
829 | 824 |
830 accept(MemberVisitor v) => v.visitField(this); | 825 accept(MemberVisitor v) => v.visitField(this); |
831 | 826 |
832 acceptReference(MemberReferenceVisitor v) => v.visitFieldReference(this); | 827 acceptReference(MemberReferenceVisitor v) => v.visitFieldReference(this); |
833 | 828 |
834 visitChildren(Visitor v) { | 829 visitChildren(Visitor v) { |
835 visitList(annotations, v); | 830 visitList(annotations, v); |
836 type?.accept(v); | 831 type?.accept(v); |
837 inferredValue?.accept(v); | |
838 name?.accept(v); | 832 name?.accept(v); |
839 initializer?.accept(v); | 833 initializer?.accept(v); |
840 } | 834 } |
841 | 835 |
842 transformChildren(Transformer v) { | 836 transformChildren(Transformer v) { |
843 type = v.visitDartType(type); | 837 type = v.visitDartType(type); |
844 transformList(annotations, v, this); | 838 transformList(annotations, v, this); |
845 if (initializer != null) { | 839 if (initializer != null) { |
846 initializer = initializer.accept(v); | 840 initializer = initializer.accept(v); |
847 initializer?.parent = this; | 841 initializer?.parent = this; |
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1239 /// A Kernel function can represent a Dart function with a different async | 1233 /// A Kernel function can represent a Dart function with a different async |
1240 /// marker. | 1234 /// marker. |
1241 /// | 1235 /// |
1242 /// For example, when async/await is translated away, | 1236 /// For example, when async/await is translated away, |
1243 /// a Dart async function might be represented by a Kernel sync function. | 1237 /// a Dart async function might be represented by a Kernel sync function. |
1244 AsyncMarker dartAsyncMarker; | 1238 AsyncMarker dartAsyncMarker; |
1245 List<TypeParameter> typeParameters; | 1239 List<TypeParameter> typeParameters; |
1246 int requiredParameterCount; | 1240 int requiredParameterCount; |
1247 List<VariableDeclaration> positionalParameters; | 1241 List<VariableDeclaration> positionalParameters; |
1248 List<VariableDeclaration> namedParameters; | 1242 List<VariableDeclaration> namedParameters; |
1249 InferredValue inferredReturnValue; // May be null. | |
1250 DartType returnType; // Not null. | 1243 DartType returnType; // Not null. |
1251 Statement body; | 1244 Statement body; |
1252 | 1245 |
1253 FunctionNode(this.body, | 1246 FunctionNode(this.body, |
1254 {List<TypeParameter> typeParameters, | 1247 {List<TypeParameter> typeParameters, |
1255 List<VariableDeclaration> positionalParameters, | 1248 List<VariableDeclaration> positionalParameters, |
1256 List<VariableDeclaration> namedParameters, | 1249 List<VariableDeclaration> namedParameters, |
1257 int requiredParameterCount, | 1250 int requiredParameterCount, |
1258 this.returnType: const DynamicType(), | 1251 this.returnType: const DynamicType(), |
1259 this.inferredReturnValue, | |
1260 this.asyncMarker: AsyncMarker.Sync, | 1252 this.asyncMarker: AsyncMarker.Sync, |
1261 this.dartAsyncMarker}) | 1253 this.dartAsyncMarker}) |
1262 : this.positionalParameters = | 1254 : this.positionalParameters = |
1263 positionalParameters ?? <VariableDeclaration>[], | 1255 positionalParameters ?? <VariableDeclaration>[], |
1264 this.requiredParameterCount = | 1256 this.requiredParameterCount = |
1265 requiredParameterCount ?? positionalParameters?.length ?? 0, | 1257 requiredParameterCount ?? positionalParameters?.length ?? 0, |
1266 this.namedParameters = namedParameters ?? <VariableDeclaration>[], | 1258 this.namedParameters = namedParameters ?? <VariableDeclaration>[], |
1267 this.typeParameters = typeParameters ?? <TypeParameter>[] { | 1259 this.typeParameters = typeParameters ?? <TypeParameter>[] { |
1268 assert(returnType != null); | 1260 assert(returnType != null); |
1269 setParents(this.typeParameters, this); | 1261 setParents(this.typeParameters, this); |
(...skipping 24 matching lines...) Expand all Loading... |
1294 requiredParameterCount: requiredParameterCount); | 1286 requiredParameterCount: requiredParameterCount); |
1295 } | 1287 } |
1296 | 1288 |
1297 accept(TreeVisitor v) => v.visitFunctionNode(this); | 1289 accept(TreeVisitor v) => v.visitFunctionNode(this); |
1298 | 1290 |
1299 visitChildren(Visitor v) { | 1291 visitChildren(Visitor v) { |
1300 visitList(typeParameters, v); | 1292 visitList(typeParameters, v); |
1301 visitList(positionalParameters, v); | 1293 visitList(positionalParameters, v); |
1302 visitList(namedParameters, v); | 1294 visitList(namedParameters, v); |
1303 returnType?.accept(v); | 1295 returnType?.accept(v); |
1304 inferredReturnValue?.accept(v); | |
1305 body?.accept(v); | 1296 body?.accept(v); |
1306 } | 1297 } |
1307 | 1298 |
1308 transformChildren(Transformer v) { | 1299 transformChildren(Transformer v) { |
1309 transformList(typeParameters, v, this); | 1300 transformList(typeParameters, v, this); |
1310 transformList(positionalParameters, v, this); | 1301 transformList(positionalParameters, v, this); |
1311 transformList(namedParameters, v, this); | 1302 transformList(namedParameters, v, this); |
1312 returnType = v.visitDartType(returnType); | 1303 returnType = v.visitDartType(returnType); |
1313 if (body != null) { | 1304 if (body != null) { |
1314 body = body.accept(v); | 1305 body = body.accept(v); |
(...skipping 2144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3459 int fileEqualsOffset = TreeNode.noOffset; | 3450 int fileEqualsOffset = TreeNode.noOffset; |
3460 | 3451 |
3461 /// For named parameters, this is the name of the parameter. No two named | 3452 /// For named parameters, this is the name of the parameter. No two named |
3462 /// parameters (in the same parameter list) can have the same name. | 3453 /// parameters (in the same parameter list) can have the same name. |
3463 /// | 3454 /// |
3464 /// In all other cases, the name is cosmetic, may be empty or null, | 3455 /// In all other cases, the name is cosmetic, may be empty or null, |
3465 /// and is not necessarily unique. | 3456 /// and is not necessarily unique. |
3466 String name; | 3457 String name; |
3467 int flags = 0; | 3458 int flags = 0; |
3468 DartType type; // Not null, defaults to dynamic. | 3459 DartType type; // Not null, defaults to dynamic. |
3469 InferredValue inferredValue; // May be null. | |
3470 | 3460 |
3471 /// For locals, this is the initial value. | 3461 /// For locals, this is the initial value. |
3472 /// For parameters, this is the default value. | 3462 /// For parameters, this is the default value. |
3473 /// | 3463 /// |
3474 /// Should be null in other cases. | 3464 /// Should be null in other cases. |
3475 Expression initializer; // May be null. | 3465 Expression initializer; // May be null. |
3476 | 3466 |
3477 VariableDeclaration(this.name, | 3467 VariableDeclaration(this.name, |
3478 {this.initializer, | 3468 {this.initializer, |
3479 this.type: const DynamicType(), | 3469 this.type: const DynamicType(), |
3480 this.inferredValue, | |
3481 bool isFinal: false, | 3470 bool isFinal: false, |
3482 bool isConst: false}) { | 3471 bool isConst: false}) { |
3483 assert(type != null); | 3472 assert(type != null); |
3484 initializer?.parent = this; | 3473 initializer?.parent = this; |
3485 this.isFinal = isFinal; | 3474 this.isFinal = isFinal; |
3486 this.isConst = isConst; | 3475 this.isConst = isConst; |
3487 } | 3476 } |
3488 | 3477 |
3489 /// Creates a synthetic variable with the given expression as initializer. | 3478 /// Creates a synthetic variable with the given expression as initializer. |
3490 VariableDeclaration.forValue(this.initializer, | 3479 VariableDeclaration.forValue(this.initializer, |
(...skipping 19 matching lines...) Expand all Loading... |
3510 | 3499 |
3511 void set isConst(bool value) { | 3500 void set isConst(bool value) { |
3512 flags = value ? (flags | FlagConst) : (flags & ~FlagConst); | 3501 flags = value ? (flags | FlagConst) : (flags & ~FlagConst); |
3513 } | 3502 } |
3514 | 3503 |
3515 accept(StatementVisitor v) => v.visitVariableDeclaration(this); | 3504 accept(StatementVisitor v) => v.visitVariableDeclaration(this); |
3516 accept1(StatementVisitor1 v, arg) => v.visitVariableDeclaration(this, arg); | 3505 accept1(StatementVisitor1 v, arg) => v.visitVariableDeclaration(this, arg); |
3517 | 3506 |
3518 visitChildren(Visitor v) { | 3507 visitChildren(Visitor v) { |
3519 type?.accept(v); | 3508 type?.accept(v); |
3520 inferredValue?.accept(v); | |
3521 initializer?.accept(v); | 3509 initializer?.accept(v); |
3522 } | 3510 } |
3523 | 3511 |
3524 transformChildren(Transformer v) { | 3512 transformChildren(Transformer v) { |
3525 type = v.visitDartType(type); | 3513 type = v.visitDartType(type); |
3526 if (initializer != null) { | 3514 if (initializer != null) { |
3527 initializer = initializer.accept(v); | 3515 initializer = initializer.accept(v); |
3528 initializer?.parent = this; | 3516 initializer?.parent = this; |
3529 } | 3517 } |
3530 } | 3518 } |
(...skipping 712 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4243 /// library has not been assigned a canonical name yet. | 4231 /// library has not been assigned a canonical name yet. |
4244 /// | 4232 /// |
4245 /// Returns `null` if the library is `null`. | 4233 /// Returns `null` if the library is `null`. |
4246 CanonicalName getCanonicalNameOfLibrary(Library library) { | 4234 CanonicalName getCanonicalNameOfLibrary(Library library) { |
4247 if (library == null) return null; | 4235 if (library == null) return null; |
4248 if (library.canonicalName == null) { | 4236 if (library.canonicalName == null) { |
4249 throw '$library has no canonical name'; | 4237 throw '$library has no canonical name'; |
4250 } | 4238 } |
4251 return library.canonicalName; | 4239 return library.canonicalName; |
4252 } | 4240 } |
OLD | NEW |