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 2495 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2506 | 2506 |
2507 /// True for the `values` field of an `enum` class. | 2507 /// True for the `values` field of an `enum` class. |
2508 static bool _isValuesField(FieldElement field) => field.name == 'values'; | 2508 static bool _isValuesField(FieldElement field) => field.name == 'values'; |
2509 | 2509 |
2510 /// True for the `index` field of an `enum` class. | 2510 /// True for the `index` field of an `enum` class. |
2511 static bool _isIndexField(FieldElement field) => field.name == 'index'; | 2511 static bool _isIndexField(FieldElement field) => field.name == 'index'; |
2512 | 2512 |
2513 visitEnumDeclaration(EnumDeclaration node) { | 2513 visitEnumDeclaration(EnumDeclaration node) { |
2514 addAnnotations(node.metadata); | 2514 addAnnotations(node.metadata); |
2515 ast.Class classNode = currentClass; | 2515 ast.Class classNode = currentClass; |
| 2516 |
2516 var intType = scope.loader.getCoreClassReference('int').rawType; | 2517 var intType = scope.loader.getCoreClassReference('int').rawType; |
2517 var indexFieldElement = element.fields.firstWhere(_isIndexField); | 2518 var indexFieldElement = element.fields.firstWhere(_isIndexField); |
2518 ast.Field indexField = scope.getMemberReference(indexFieldElement); | 2519 ast.Field indexField = scope.getMemberReference(indexFieldElement); |
2519 indexField.type = intType; | 2520 indexField.type = intType; |
2520 classNode.addMember(indexField); | 2521 classNode.addMember(indexField); |
2521 var parameter = new ast.VariableDeclaration('index', type: intType); | 2522 |
| 2523 var stringType = scope.loader.getCoreClassReference('String').rawType; |
| 2524 ast.Field nameField = new ast.Field( |
| 2525 new ast.Name('_name', scope.currentLibrary), |
| 2526 type: stringType, |
| 2527 isFinal: true, |
| 2528 fileUri: classNode.fileUri); |
| 2529 classNode.addMember(nameField); |
| 2530 |
| 2531 var indexParameter = new ast.VariableDeclaration('index', type: intType); |
| 2532 var nameParameter = new ast.VariableDeclaration('name', type: stringType); |
2522 var function = new ast.FunctionNode(new ast.EmptyStatement(), | 2533 var function = new ast.FunctionNode(new ast.EmptyStatement(), |
2523 positionalParameters: [parameter]); | 2534 positionalParameters: [indexParameter, nameParameter]); |
2524 var superConstructor = scope.loader.getRootClassConstructorReference(); | 2535 var superConstructor = scope.loader.getRootClassConstructorReference(); |
2525 var constructor = new ast.Constructor(function, | 2536 var constructor = new ast.Constructor(function, |
2526 name: new ast.Name(''), | 2537 name: new ast.Name(''), |
2527 isConst: true, | 2538 isConst: true, |
2528 initializers: [ | 2539 initializers: [ |
2529 new ast.FieldInitializer(indexField, new ast.VariableGet(parameter)), | 2540 new ast.FieldInitializer( |
| 2541 indexField, new ast.VariableGet(indexParameter)), |
| 2542 new ast.FieldInitializer( |
| 2543 nameField, new ast.VariableGet(nameParameter)), |
2530 new ast.SuperInitializer(superConstructor, new ast.Arguments.empty()) | 2544 new ast.SuperInitializer(superConstructor, new ast.Arguments.empty()) |
2531 ])..fileOffset = element.nameOffset; | 2545 ])..fileOffset = element.nameOffset; |
2532 classNode.addMember(constructor); | 2546 classNode.addMember(constructor); |
| 2547 |
2533 int index = 0; | 2548 int index = 0; |
2534 var enumConstantFields = <ast.Field>[]; | 2549 var enumConstantFields = <ast.Field>[]; |
2535 for (var constant in node.constants) { | 2550 for (var constant in node.constants) { |
2536 ast.Field field = scope.getMemberReference(constant.element); | 2551 ast.Field field = scope.getMemberReference(constant.element); |
2537 field.initializer = new ast.ConstructorInvocation( | 2552 field.initializer = new ast.ConstructorInvocation( |
2538 constructor, new ast.Arguments([new ast.IntLiteral(index)]), | 2553 constructor, |
| 2554 new ast.Arguments([ |
| 2555 new ast.IntLiteral(index), |
| 2556 new ast.StringLiteral('${classNode.name}.${field.name.name}') |
| 2557 ]), |
2539 isConst: true)..parent = field; | 2558 isConst: true)..parent = field; |
2540 field.type = classNode.rawType; | 2559 field.type = classNode.rawType; |
2541 classNode.addMember(field); | 2560 classNode.addMember(field); |
2542 ++index; | 2561 ++index; |
2543 enumConstantFields.add(field); | 2562 enumConstantFields.add(field); |
2544 } | 2563 } |
| 2564 |
2545 // Add the 'values' field. | 2565 // Add the 'values' field. |
2546 var valuesFieldElement = element.fields.firstWhere(_isValuesField); | 2566 var valuesFieldElement = element.fields.firstWhere(_isValuesField); |
2547 ast.Field valuesField = scope.getMemberReference(valuesFieldElement); | 2567 ast.Field valuesField = scope.getMemberReference(valuesFieldElement); |
2548 var enumType = classNode.rawType; | 2568 var enumType = classNode.rawType; |
2549 valuesField.type = new ast.InterfaceType( | 2569 valuesField.type = new ast.InterfaceType( |
2550 scope.loader.getCoreClassReference('List'), <ast.DartType>[enumType]); | 2570 scope.loader.getCoreClassReference('List'), <ast.DartType>[enumType]); |
2551 valuesField.initializer = new ast.ListLiteral( | 2571 valuesField.initializer = new ast.ListLiteral( |
2552 enumConstantFields.map(_makeStaticGet).toList(), | 2572 enumConstantFields.map(_makeStaticGet).toList(), |
2553 isConst: true, | 2573 isConst: true, |
2554 typeArgument: enumType)..parent = valuesField; | 2574 typeArgument: enumType)..parent = valuesField; |
2555 classNode.addMember(valuesField); | 2575 classNode.addMember(valuesField); |
2556 // TODO: Add the toString method. | 2576 |
| 2577 // Add the 'toString()' method. |
| 2578 var body = new ast.ReturnStatement( |
| 2579 new ast.DirectPropertyGet(new ast.ThisExpression(), nameField)); |
| 2580 var toStringFunction = new ast.FunctionNode(body, returnType: stringType); |
| 2581 var toStringMethod = new ast.Procedure( |
| 2582 new ast.Name('toString'), ast.ProcedureKind.Method, toStringFunction, |
| 2583 fileUri: classNode.fileUri); |
| 2584 classNode.addMember(toStringMethod); |
2557 } | 2585 } |
2558 | 2586 |
2559 visitClassTypeAlias(ClassTypeAlias node) { | 2587 visitClassTypeAlias(ClassTypeAlias node) { |
2560 addAnnotations(node.metadata); | 2588 addAnnotations(node.metadata); |
2561 assert(node.withClause != null && node.withClause.mixinTypes.isNotEmpty); | 2589 assert(node.withClause != null && node.withClause.mixinTypes.isNotEmpty); |
2562 ast.Class classNode = currentClass; | 2590 ast.Class classNode = currentClass; |
2563 for (var constructor in element.constructors) { | 2591 for (var constructor in element.constructors) { |
2564 var constructorNode = scope.getMemberReference(constructor); | 2592 var constructorNode = scope.getMemberReference(constructor); |
2565 classNode.addMember(constructorNode); | 2593 classNode.addMember(constructorNode); |
2566 buildMixinConstructor(constructorNode, constructor); | 2594 buildMixinConstructor(constructorNode, constructor); |
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2892 if (list[i - 1].compareTo(item) == 0) { | 2920 if (list[i - 1].compareTo(item) == 0) { |
2893 ++deleted; | 2921 ++deleted; |
2894 } else if (deleted > 0) { | 2922 } else if (deleted > 0) { |
2895 list[i - deleted] = item; | 2923 list[i - deleted] = item; |
2896 } | 2924 } |
2897 } | 2925 } |
2898 if (deleted > 0) { | 2926 if (deleted > 0) { |
2899 list.length -= deleted; | 2927 list.length -= deleted; |
2900 } | 2928 } |
2901 } | 2929 } |
OLD | NEW |