Chromium Code Reviews| Index: pkg/compiler/lib/src/dart_backend/backend_ast_emitter.dart |
| diff --git a/pkg/compiler/lib/src/dart_backend/backend_ast_emitter.dart b/pkg/compiler/lib/src/dart_backend/backend_ast_emitter.dart |
| index 5a0a277ece943677132c490945f0aa43181db1f0..8a40614a9182ceda0a095a9ec1d0ae2fbda8e684 100644 |
| --- a/pkg/compiler/lib/src/dart_backend/backend_ast_emitter.dart |
| +++ b/pkg/compiler/lib/src/dart_backend/backend_ast_emitter.dart |
| @@ -284,7 +284,8 @@ class ASTEmitter |
| continue; // Discard unused constants declarations. |
| } |
| String name = context.getConstantName(constDecl.element); |
| - Expression value = emitConstant(constDecl.expression, context); |
| + Expression value = |
| + ConstantEmitter.createExpression(constDecl.expression, context); |
| VariableDeclaration decl = new VariableDeclaration(name, value); |
| decl.element = constDecl.element; |
| constants.add(decl); |
| @@ -307,94 +308,27 @@ class ASTEmitter |
| parameters, |
| body, |
| name: context.currentElement.name, |
| - returnType: emitOptionalType(functionType.returnType), |
| + returnType: TypeGenerator.createOptionalType(functionType.returnType), |
| isGetter: context.currentElement.isGetter, |
| isSetter: context.currentElement.isSetter) |
| ..element = context.currentElement; |
| } |
| - /// TODO(johnniwinther): Remove this when issue 21283 has been resolved. |
| - int pseudoNameCounter = 0; |
| - |
| - Parameter emitParameter(DartType type, |
| - BuilderContext<Statement> context, |
| - {String name, |
| - Element element, |
| - ConstantExpression defaultValue}) { |
| - if (name == null && element != null) { |
| - name = element.name; |
| - } |
| - if (name == null) { |
| - name = '_${pseudoNameCounter++}'; |
| - } |
| - Parameter parameter; |
| - if (type.isFunctionType) { |
| - FunctionType functionType = type; |
| - TypeAnnotation returnType = emitOptionalType(functionType.returnType); |
| - Parameters innerParameters = |
| - emitParametersFromType(functionType, context); |
| - parameter = new Parameter.function(name, returnType, innerParameters); |
| - } else { |
| - TypeAnnotation typeAnnotation = emitOptionalType(type); |
| - parameter = new Parameter(name, type: typeAnnotation); |
| - } |
| - parameter.element = element; |
| - if (defaultValue != null && !defaultValue.value.isNull) { |
| - parameter.defaultValue = emitConstant(defaultValue, context); |
| - } |
| - return parameter; |
| - } |
| - |
| - Parameters emitParametersFromType(FunctionType functionType, |
| - BuilderContext<Statement> context) { |
| - if (functionType.namedParameters.isEmpty) { |
| - return new Parameters( |
| - emitParameters(functionType.parameterTypes, context), |
| - emitParameters(functionType.optionalParameterTypes, context), |
| - false); |
| - } else { |
| - return new Parameters( |
| - emitParameters(functionType.parameterTypes, context), |
| - emitParameters(functionType.namedParameterTypes, context, |
| - names: functionType.namedParameters), |
| - true); |
| - } |
| - } |
| - |
| - List<Parameter> emitParameters( |
| - Iterable<DartType> parameterTypes, |
| - BuilderContext<Statement> context, |
| - {Iterable<String> names: const <String>[], |
| - Iterable<ConstantExpression> defaultValues: const <ConstantExpression>[], |
| - Iterable<Element> elements: const <Element>[]}) { |
| - Iterator<String> name = names.iterator; |
| - Iterator<ConstantExpression> defaultValue = defaultValues.iterator; |
| - Iterator<Element> element = elements.iterator; |
| - return parameterTypes.map((DartType type) { |
| - name.moveNext(); |
| - defaultValue.moveNext(); |
| - element.moveNext(); |
| - return emitParameter(type, context, |
| - name: name.current, |
| - defaultValue: defaultValue.current, |
| - element: element.current); |
| - }).toList(); |
| - } |
| - |
| /// Emits parameters that are not nested inside other parameters. |
| /// Root parameters can have default values, while inner parameters cannot. |
| Parameters emitRootParameters(tree.FunctionDefinition function, |
| BuilderContext<Statement> context) { |
| FunctionType functionType = function.element.type; |
| - List<Parameter> required = emitParameters( |
| - functionType.parameterTypes, context, |
| + List<Parameter> required = TypeGenerator.createParameters( |
| + functionType.parameterTypes, |
| + context: context, |
| elements: function.parameters.map((p) => p.element)); |
| bool optionalParametersAreNamed = !functionType.namedParameters.isEmpty; |
| - List<Parameter> optional = emitParameters( |
| + List<Parameter> optional = TypeGenerator.createParameters( |
| optionalParametersAreNamed |
| ? functionType.namedParameterTypes |
| : functionType.optionalParameterTypes, |
| - context, |
| + context: context, |
| defaultValues: function.defaultParameterValues, |
| elements: function.parameters.skip(required.length) |
| .map((p) => p.element)); |
| @@ -600,7 +534,7 @@ class ASTEmitter |
| @override |
| Expression visitConstant(tree.Constant exp, |
| BuilderContext<Statement> context) { |
| - return emitConstant(exp.expression, context); |
| + return ConstantEmitter.createExpression(exp.expression, context); |
| } |
| @override |
| @@ -626,7 +560,8 @@ class ASTEmitter |
| Expression visitLiteralList(tree.LiteralList exp, |
| BuilderContext<Statement> context) { |
| return new LiteralList(visitExpressions(exp.values, context), |
| - typeArgument: emitOptionalType(exp.type.typeArguments.single)); |
| + typeArgument: |
| + TypeGenerator.createOptionalType(exp.type.typeArguments.single)); |
| } |
| @override |
| @@ -634,11 +569,12 @@ class ASTEmitter |
| BuilderContext<Statement> context) { |
| List<LiteralMapEntry> entries = new List<LiteralMapEntry>.generate( |
| exp.entries.length, |
| - (i) => new LiteralMapEntry(visitExpression(exp.entries[i].key, context), |
| - visitExpression(exp.entries[i].value, context))); |
| + (i) => new LiteralMapEntry( |
| + visitExpression(exp.entries[i].key, context), |
| + visitExpression(exp.entries[i].value, context))); |
| List<TypeAnnotation> typeArguments = exp.type.treatAsRaw |
| ? null |
| - : exp.type.typeArguments.map(createTypeAnnotation) |
| + : exp.type.typeArguments.map(TypeGenerator.createType) |
| .toList(growable: false); |
| return new LiteralMap(entries, typeArguments: typeArguments); |
| } |
| @@ -648,7 +584,7 @@ class ASTEmitter |
| BuilderContext<Statement> context) { |
| return new TypeOperator(visitExpression(exp.receiver, context), |
| exp.operator, |
| - createTypeAnnotation(exp.type)); |
| + TypeGenerator.createType(exp.type)); |
| } |
| List<Argument> emitArguments(tree.Invoke exp, |
| @@ -659,7 +595,8 @@ class ASTEmitter |
| (i) => visitExpression(exp.arguments[i], context)); |
| for (int i = 0; i < exp.selector.namedArgumentCount; ++i) { |
| result.add(new NamedArgument(exp.selector.namedArguments[i], |
| - visitExpression(exp.arguments[positionalArgumentCount + i], context))); |
| + visitExpression( |
|
sigurdm
2014/12/08 13:02:30
Is there trailing whitespace here? It looks like t
Johnni Winther
2014/12/10 08:47:54
No. It's clean.
|
| + exp.arguments[positionalArgumentCount + i], context))); |
| } |
| return result; |
| } |
| @@ -746,7 +683,7 @@ class ASTEmitter |
| List args = emitArguments(exp, context); |
| FunctionElement constructor = exp.target; |
| String name = constructor.name.isEmpty ? null : constructor.name; |
| - return new CallNew(createTypeAnnotation(exp.type), |
| + return new CallNew(TypeGenerator.createType(exp.type), |
| args, |
| constructorName: name, |
| isConst: exp.constant != null) |
| @@ -813,52 +750,128 @@ class ASTEmitter |
| context.addStatement(decl); |
| visitStatement(node.next, context); |
| } |
| +} |
| - Expression emitConstant(ConstantExpression exp, |
| - BuilderContext<Statement> context) { |
| - return const ConstantEmitter().visit(exp, context); |
| +class TypeGenerator { |
|
sigurdm
2014/12/08 13:02:29
All the methods are static. Do we need the class a
Johnni Winther
2014/12/10 08:47:54
We don't need it but I wanted to group all methods
|
| + |
| + /// TODO(johnniwinther): Remove this when issue 21283 has been resolved. |
| + static int pseudoNameCounter = 0; |
| + |
| + static Parameter emitParameter(DartType type, |
| + BuilderContext<Statement> context, |
| + {String name, |
| + Element element, |
| + ConstantExpression defaultValue}) { |
| + if (name == null && element != null) { |
| + name = element.name; |
| + } |
| + if (name == null) { |
| + name = '_${pseudoNameCounter++}'; |
| + } |
| + Parameter parameter; |
| + if (type.isFunctionType) { |
| + FunctionType functionType = type; |
| + TypeAnnotation returnType = createOptionalType(functionType.returnType); |
| + Parameters innerParameters = |
| + createParametersFromType(functionType); |
| + parameter = new Parameter.function(name, returnType, innerParameters); |
| + } else { |
| + TypeAnnotation typeAnnotation = createOptionalType(type); |
| + parameter = new Parameter(name, type: typeAnnotation); |
| + } |
| + parameter.element = element; |
| + if (defaultValue != null && !defaultValue.value.isNull) { |
| + parameter.defaultValue = |
| + ConstantEmitter.createExpression(defaultValue, context); |
| + } |
| + return parameter; |
| } |
| -} |
| -/// Like [createTypeAnnotation] except the dynamic type is converted to null. |
| -TypeAnnotation emitOptionalType(DartType type) { |
| - if (type.treatAsDynamic) { |
| - return null; |
| - } else { |
| - return createTypeAnnotation(type); |
| + static Parameters createParametersFromType(FunctionType functionType) { |
| + pseudoNameCounter = 0; |
| + if (functionType.namedParameters.isEmpty) { |
| + return new Parameters( |
| + createParameters(functionType.parameterTypes), |
| + createParameters(functionType.optionalParameterTypes), |
| + false); |
| + } else { |
| + return new Parameters( |
| + createParameters(functionType.parameterTypes), |
| + createParameters(functionType.namedParameterTypes, |
| + names: functionType.namedParameters), |
| + true); |
| + } |
| + } |
| + |
| + static List<Parameter> createParameters( |
| + Iterable<DartType> parameterTypes, |
| + {BuilderContext<Statement> context, |
| + Iterable<String> names: const <String>[], |
| + Iterable<ConstantExpression> defaultValues: const <ConstantExpression>[], |
| + Iterable<Element> elements: const <Element>[]}) { |
| + Iterator<String> name = names.iterator; |
| + Iterator<ConstantExpression> defaultValue = defaultValues.iterator; |
| + Iterator<Element> element = elements.iterator; |
| + return parameterTypes.map((DartType type) { |
| + name.moveNext(); |
| + defaultValue.moveNext(); |
| + element.moveNext(); |
| + return emitParameter(type, context, |
| + name: name.current, |
| + defaultValue: defaultValue.current, |
| + element: element.current); |
| + }).toList(); |
| } |
| -} |
| -TypeAnnotation createTypeAnnotation(DartType type) { |
| - if (type is GenericType) { |
| - if (type.treatAsRaw) { |
| - return new TypeAnnotation(type.element.name)..dartType = type; |
| + /// Like [createTypeAnnotation] except the dynamic type is converted to null. |
| + static TypeAnnotation createOptionalType(DartType type) { |
| + if (type.treatAsDynamic) { |
| + return null; |
| + } else { |
| + return createType(type); |
| + } |
| + } |
| + |
| + /// Creates the [TypeAnnotation] for a [type] that is not function type. |
| + static TypeAnnotation createType(DartType type) { |
| + if (type is GenericType) { |
| + if (type.treatAsRaw) { |
| + return new TypeAnnotation(type.element.name)..dartType = type; |
| + } |
| + return new TypeAnnotation( |
| + type.element.name, |
| + type.typeArguments.map(createType).toList(growable:false)) |
| + ..dartType = type; |
| + } else if (type is VoidType) { |
| + return new TypeAnnotation('void') |
| + ..dartType = type; |
| + } else if (type is TypeVariableType) { |
| + return new TypeAnnotation(type.name) |
| + ..dartType = type; |
| + } else if (type is DynamicType) { |
| + return new TypeAnnotation("dynamic") |
| + ..dartType = type; |
| + } else if (type is MalformedType) { |
| + return new TypeAnnotation(type.name) |
| + ..dartType = type; |
| + } else { |
| + throw "Unsupported type annotation: $type"; |
| } |
| - return new TypeAnnotation( |
| - type.element.name, |
| - type.typeArguments.map(createTypeAnnotation).toList(growable:false)) |
| - ..dartType = type; |
| - } else if (type is VoidType) { |
| - return new TypeAnnotation('void') |
| - ..dartType = type; |
| - } else if (type is TypeVariableType) { |
| - return new TypeAnnotation(type.name) |
| - ..dartType = type; |
| - } else if (type is DynamicType) { |
| - return new TypeAnnotation("dynamic") |
| - ..dartType = type; |
| - } else if (type is MalformedType) { |
| - return new TypeAnnotation(type.name) |
| - ..dartType = type; |
| - } else { |
| - throw "Unsupported type annotation: $type"; |
| } |
| + |
| } |
| + |
| class ConstantEmitter |
| extends ConstantExpressionVisitor<BuilderContext<Statement>, Expression> { |
| const ConstantEmitter(); |
| + /// Creates the [Expression] for the constant [exp]. |
| + static Expression createExpression(ConstantExpression exp, |
| + BuilderContext<Statement> context) { |
| + return const ConstantEmitter().visit(exp, context); |
| + } |
| + |
| Expression handlePrimitiveConstant(PrimitiveConstantValue value) { |
| // Num constants may be negative, while literals must be non-negative: |
| // Literals are non-negative in the specification, and a negated literal |
| @@ -909,7 +922,8 @@ class ConstantEmitter |
| return new LiteralList( |
| visitExpressions(exp.values, context), |
| isConst: true, |
| - typeArgument: emitOptionalType(exp.type.typeArguments.single)); |
| + typeArgument: |
| + TypeGenerator.createOptionalType(exp.type.typeArguments.single)); |
| } |
| @override |
| @@ -921,7 +935,7 @@ class ConstantEmitter |
| visit(exp.values[i], context))); |
| List<TypeAnnotation> typeArguments = exp.type.treatAsRaw |
| ? null |
| - : exp.type.typeArguments.map(createTypeAnnotation).toList(); |
| + : exp.type.typeArguments.map(TypeGenerator.createType).toList(); |
| return new LiteralMap(entries, isConst: true, typeArguments: typeArguments); |
| } |
| @@ -939,7 +953,7 @@ class ConstantEmitter |
| FunctionElement constructor = exp.target; |
| String name = constructor.name.isEmpty ? null : constructor.name; |
| - return new CallNew(createTypeAnnotation(exp.type), |
| + return new CallNew(TypeGenerator.createType(exp.type), |
| args, |
| constructorName: name, |
| isConst: true) |