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 library kernel.analyzer.ast_from_analyzer; | 4 library kernel.analyzer.ast_from_analyzer; |
5 | 5 |
6 import '../ast.dart' as ast; | 6 import '../ast.dart' as ast; |
7 import '../frontend/accessors.dart'; | 7 import '../frontend/accessors.dart'; |
8 import '../frontend/super_initializers.dart'; | 8 import '../frontend/super_initializers.dart'; |
9 import '../log.dart'; | 9 import '../log.dart'; |
10 import '../type_algebra.dart'; | 10 import '../type_algebra.dart'; |
(...skipping 2539 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2550 | 2550 |
2551 /// True for the `values` field of an `enum` class. | 2551 /// True for the `values` field of an `enum` class. |
2552 static bool _isValuesField(FieldElement field) => field.name == 'values'; | 2552 static bool _isValuesField(FieldElement field) => field.name == 'values'; |
2553 | 2553 |
2554 /// True for the `index` field of an `enum` class. | 2554 /// True for the `index` field of an `enum` class. |
2555 static bool _isIndexField(FieldElement field) => field.name == 'index'; | 2555 static bool _isIndexField(FieldElement field) => field.name == 'index'; |
2556 | 2556 |
2557 visitEnumDeclaration(EnumDeclaration node) { | 2557 visitEnumDeclaration(EnumDeclaration node) { |
2558 addAnnotations(node.metadata); | 2558 addAnnotations(node.metadata); |
2559 ast.Class classNode = currentClass; | 2559 ast.Class classNode = currentClass; |
| 2560 |
2560 var intType = scope.loader.getCoreClassReference('int').rawType; | 2561 var intType = scope.loader.getCoreClassReference('int').rawType; |
2561 var indexFieldElement = element.fields.firstWhere(_isIndexField); | 2562 var indexFieldElement = element.fields.firstWhere(_isIndexField); |
2562 ast.Field indexField = scope.getMemberReference(indexFieldElement); | 2563 ast.Field indexField = scope.getMemberReference(indexFieldElement); |
2563 indexField.type = intType; | 2564 indexField.type = intType; |
2564 classNode.addMember(indexField); | 2565 classNode.addMember(indexField); |
2565 var parameter = new ast.VariableDeclaration('index', type: intType); | 2566 |
| 2567 var stringType = scope.loader.getCoreClassReference('String').rawType; |
| 2568 ast.Field nameField = new ast.Field( |
| 2569 new ast.Name('_name', scope.currentLibrary), |
| 2570 type: stringType, |
| 2571 isFinal: true, |
| 2572 fileUri: classNode.fileUri); |
| 2573 classNode.addMember(nameField); |
| 2574 |
| 2575 var indexParameter = new ast.VariableDeclaration('index', type: intType); |
| 2576 var nameParameter = new ast.VariableDeclaration('name', type: stringType); |
2566 var function = new ast.FunctionNode(new ast.EmptyStatement(), | 2577 var function = new ast.FunctionNode(new ast.EmptyStatement(), |
2567 positionalParameters: [parameter]); | 2578 positionalParameters: [indexParameter, nameParameter]); |
2568 var superConstructor = scope.loader.getRootClassConstructorReference(); | 2579 var superConstructor = scope.loader.getRootClassConstructorReference(); |
2569 var constructor = new ast.Constructor(function, | 2580 var constructor = new ast.Constructor(function, |
2570 name: new ast.Name(''), | 2581 name: new ast.Name(''), |
2571 isConst: true, | 2582 isConst: true, |
2572 initializers: [ | 2583 initializers: [ |
2573 new ast.FieldInitializer(indexField, new ast.VariableGet(parameter)), | 2584 new ast.FieldInitializer( |
| 2585 indexField, new ast.VariableGet(indexParameter)), |
| 2586 new ast.FieldInitializer( |
| 2587 nameField, new ast.VariableGet(nameParameter)), |
2574 new ast.SuperInitializer(superConstructor, new ast.Arguments.empty()) | 2588 new ast.SuperInitializer(superConstructor, new ast.Arguments.empty()) |
2575 ])..fileOffset = element.nameOffset; | 2589 ])..fileOffset = element.nameOffset; |
2576 classNode.addMember(constructor); | 2590 classNode.addMember(constructor); |
| 2591 |
2577 int index = 0; | 2592 int index = 0; |
2578 var enumConstantFields = <ast.Field>[]; | 2593 var enumConstantFields = <ast.Field>[]; |
2579 for (var constant in node.constants) { | 2594 for (var constant in node.constants) { |
2580 ast.Field field = scope.getMemberReference(constant.element); | 2595 ast.Field field = scope.getMemberReference(constant.element); |
2581 field.initializer = new ast.ConstructorInvocation( | 2596 field.initializer = new ast.ConstructorInvocation( |
2582 constructor, new ast.Arguments([new ast.IntLiteral(index)]), | 2597 constructor, |
| 2598 new ast.Arguments([ |
| 2599 new ast.IntLiteral(index), |
| 2600 new ast.StringLiteral('${classNode.name}.${field.name.name}') |
| 2601 ]), |
2583 isConst: true)..parent = field; | 2602 isConst: true)..parent = field; |
2584 field.type = classNode.rawType; | 2603 field.type = classNode.rawType; |
2585 classNode.addMember(field); | 2604 classNode.addMember(field); |
2586 ++index; | 2605 ++index; |
2587 enumConstantFields.add(field); | 2606 enumConstantFields.add(field); |
2588 } | 2607 } |
| 2608 |
2589 // Add the 'values' field. | 2609 // Add the 'values' field. |
2590 var valuesFieldElement = element.fields.firstWhere(_isValuesField); | 2610 var valuesFieldElement = element.fields.firstWhere(_isValuesField); |
2591 ast.Field valuesField = scope.getMemberReference(valuesFieldElement); | 2611 ast.Field valuesField = scope.getMemberReference(valuesFieldElement); |
2592 var enumType = classNode.rawType; | 2612 var enumType = classNode.rawType; |
2593 valuesField.type = new ast.InterfaceType( | 2613 valuesField.type = new ast.InterfaceType( |
2594 scope.loader.getCoreClassReference('List'), <ast.DartType>[enumType]); | 2614 scope.loader.getCoreClassReference('List'), <ast.DartType>[enumType]); |
2595 valuesField.initializer = new ast.ListLiteral( | 2615 valuesField.initializer = new ast.ListLiteral( |
2596 enumConstantFields.map(_makeStaticGet).toList(), | 2616 enumConstantFields.map(_makeStaticGet).toList(), |
2597 isConst: true, | 2617 isConst: true, |
2598 typeArgument: enumType)..parent = valuesField; | 2618 typeArgument: enumType)..parent = valuesField; |
2599 classNode.addMember(valuesField); | 2619 classNode.addMember(valuesField); |
2600 // TODO: Add the toString method. | 2620 |
| 2621 // Add the 'toString()' method. |
| 2622 var body = new ast.ReturnStatement( |
| 2623 new ast.DirectPropertyGet(new ast.ThisExpression(), nameField)); |
| 2624 var toStringFunction = new ast.FunctionNode(body, returnType: stringType); |
| 2625 var toStringMethod = new ast.Procedure( |
| 2626 new ast.Name('toString'), ast.ProcedureKind.Method, toStringFunction, |
| 2627 fileUri: classNode.fileUri); |
| 2628 classNode.addMember(toStringMethod); |
2601 } | 2629 } |
2602 | 2630 |
2603 visitClassTypeAlias(ClassTypeAlias node) { | 2631 visitClassTypeAlias(ClassTypeAlias node) { |
2604 addAnnotations(node.metadata); | 2632 addAnnotations(node.metadata); |
2605 assert(node.withClause != null && node.withClause.mixinTypes.isNotEmpty); | 2633 assert(node.withClause != null && node.withClause.mixinTypes.isNotEmpty); |
2606 ast.Class classNode = currentClass; | 2634 ast.Class classNode = currentClass; |
2607 for (var constructor in element.constructors) { | 2635 for (var constructor in element.constructors) { |
2608 var constructorNode = scope.getMemberReference(constructor); | 2636 var constructorNode = scope.getMemberReference(constructor); |
2609 classNode.addMember(constructorNode); | 2637 classNode.addMember(constructorNode); |
2610 buildMixinConstructor(constructorNode, constructor); | 2638 buildMixinConstructor(constructorNode, constructor); |
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2936 if (list[i - 1].compareTo(item) == 0) { | 2964 if (list[i - 1].compareTo(item) == 0) { |
2937 ++deleted; | 2965 ++deleted; |
2938 } else if (deleted > 0) { | 2966 } else if (deleted > 0) { |
2939 list[i - deleted] = item; | 2967 list[i - deleted] = item; |
2940 } | 2968 } |
2941 } | 2969 } |
2942 if (deleted > 0) { | 2970 if (deleted > 0) { |
2943 list.length -= deleted; | 2971 list.length -= deleted; |
2944 } | 2972 } |
2945 } | 2973 } |
OLD | NEW |