VM: [Kernel] Add toString() support for generated enum classes

R=vegorov@google.com

Review-Url: https://codereview.chromium.org/2625053003 .
This commit is contained in:
Martin Kustermann 2017-01-11 19:50:21 +01:00
parent bfb5ee07b6
commit 23cc9cca41
6 changed files with 36 additions and 15 deletions

View file

@ -2557,35 +2557,55 @@ class ClassBodyBuilder extends GeneralizingAstVisitor<Null> {
visitEnumDeclaration(EnumDeclaration node) {
addAnnotations(node.metadata);
ast.Class classNode = currentClass;
var intType = scope.loader.getCoreClassReference('int').rawType;
var indexFieldElement = element.fields.firstWhere(_isIndexField);
ast.Field indexField = scope.getMemberReference(indexFieldElement);
indexField.type = intType;
classNode.addMember(indexField);
var parameter = new ast.VariableDeclaration('index', type: intType);
var stringType = scope.loader.getCoreClassReference('String').rawType;
ast.Field nameField = new ast.Field(
new ast.Name('_name', scope.currentLibrary),
type: stringType,
isFinal: true,
fileUri: classNode.fileUri);
classNode.addMember(nameField);
var indexParameter = new ast.VariableDeclaration('index', type: intType);
var nameParameter = new ast.VariableDeclaration('name', type: stringType);
var function = new ast.FunctionNode(new ast.EmptyStatement(),
positionalParameters: [parameter]);
positionalParameters: [indexParameter, nameParameter]);
var superConstructor = scope.loader.getRootClassConstructorReference();
var constructor = new ast.Constructor(function,
name: new ast.Name(''),
isConst: true,
initializers: [
new ast.FieldInitializer(indexField, new ast.VariableGet(parameter)),
new ast.FieldInitializer(
indexField, new ast.VariableGet(indexParameter)),
new ast.FieldInitializer(
nameField, new ast.VariableGet(nameParameter)),
new ast.SuperInitializer(superConstructor, new ast.Arguments.empty())
])..fileOffset = element.nameOffset;
classNode.addMember(constructor);
int index = 0;
var enumConstantFields = <ast.Field>[];
for (var constant in node.constants) {
ast.Field field = scope.getMemberReference(constant.element);
field.initializer = new ast.ConstructorInvocation(
constructor, new ast.Arguments([new ast.IntLiteral(index)]),
constructor,
new ast.Arguments([
new ast.IntLiteral(index),
new ast.StringLiteral('${classNode.name}.${field.name.name}')
]),
isConst: true)..parent = field;
field.type = classNode.rawType;
classNode.addMember(field);
++index;
enumConstantFields.add(field);
}
// Add the 'values' field.
var valuesFieldElement = element.fields.firstWhere(_isValuesField);
ast.Field valuesField = scope.getMemberReference(valuesFieldElement);
@ -2597,7 +2617,15 @@ class ClassBodyBuilder extends GeneralizingAstVisitor<Null> {
isConst: true,
typeArgument: enumType)..parent = valuesField;
classNode.addMember(valuesField);
// TODO: Add the toString method.
// Add the 'toString()' method.
var body = new ast.ReturnStatement(
new ast.DirectPropertyGet(new ast.ThisExpression(), nameField));
var toStringFunction = new ast.FunctionNode(body, returnType: stringType);
var toStringMethod = new ast.Procedure(
new ast.Name('toString'), ast.ProcedureKind.Method, toStringFunction,
fileUri: classNode.fileUri);
classNode.addMember(toStringMethod);
}
visitClassTypeAlias(ClassTypeAlias node) {

View file

@ -126,7 +126,6 @@ Language/Classes/Constructors/Generative_Constructors/execution_of_a_superinitia
Language/Classes/Constructors/Generative_Constructors/execution_of_an_initializer_t02: RuntimeError
Language/Classes/Constructors/Generative_Constructors/initializing_formals_execution_t02: RuntimeError
Language/Classes/definition_t23: CompileTimeError
Language/Enums/declaration_equivalent_t01: RuntimeError
Language/Expressions/Constants/string_length_t01: Crash
Language/Expressions/Function_Invocation/Function_Expression_Invocation/not_a_function_expression_t01: RuntimeError
Language/Expressions/Function_Invocation/Unqualified_Invocation/function_expr_invocation_t03: RuntimeError

View file

@ -20,7 +20,7 @@ main() {
Expect.equals('Enum2.A', Enum2.A.toString());
Expect.equals(0, Enum2.A.index);
Expect.listEquals([Enum2.A], Enum2.values);
Expect.identical(const [Enum2.A], Enum2.values);
Expect.identical(const <Enum2>[Enum2.A], Enum2.values);
Enum2.values.forEach(test2);
Expect.equals('Enum3.B', Enum3.B.toString());

View file

@ -11,6 +11,7 @@ async_star_cancel_while_paused_test: RuntimeError
async_star_pause_test: Fail, OK
[ $compiler == none || $compiler == precompiler || $compiler == app_jit ]
enum_test: RuntimeError # Issue 28341
# Other issues:
generic_methods_type_expression_test: RuntimeError # Issue 25869

View file

@ -3,6 +3,7 @@
# BSD-style license that can be found in the LICENSE file.
[ $compiler == dart2js ]
enum_test: Fail # Issue 28340
deferred_not_loaded_check_test: Fail # Issue 27577
getter_setter_in_lib_test: Fail # Issue 23288
method_name_test: Fail # issue 25574

View file

@ -200,14 +200,6 @@ deferred_type_dependency_test/is: RuntimeError
deferred_type_dependency_test/none: RuntimeError
deferred_type_dependency_test/type_annotation: RuntimeError
duplicate_export_negative_test: Fail
enum_duplicate_test/01: RuntimeError
enum_duplicate_test/02: RuntimeError
enum_duplicate_test/none: RuntimeError
enum_mirror_test: RuntimeError
enum_private_test/01: RuntimeError
enum_private_test/02: RuntimeError
enum_private_test/none: RuntimeError
enum_test: RuntimeError
evaluation_redirecting_constructor_test: RuntimeError
example_constructor_test: RuntimeError
external_test/10: MissingRuntimeError