Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1533)

Unified Diff: pkg/compiler/lib/src/constants/constructors.dart

Issue 1115183002: Add ConstantConstructor to ConstantExpression system. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Updated cf. comments. Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/compiler/lib/src/compiler.dart ('k') | pkg/compiler/lib/src/constants/expressions.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/constants/constructors.dart
diff --git a/pkg/compiler/lib/src/constants/constructors.dart b/pkg/compiler/lib/src/constants/constructors.dart
new file mode 100644
index 0000000000000000000000000000000000000000..3c09a94bc6086b6fdc761009017603dee8b6b718
--- /dev/null
+++ b/pkg/compiler/lib/src/constants/constructors.dart
@@ -0,0 +1,376 @@
+// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dart2js.constants.constructors;
+
+import '../elements/elements.dart';
+import 'expressions.dart';
+import 'values.dart';
+import '../dart_types.dart';
+import '../resolution/resolution.dart';
+import '../resolution/operators.dart';
+import '../resolution/semantic_visitor.dart';
+import '../resolution/send_structure.dart';
+import '../dart2jslib.dart';
+import '../tree/tree.dart';
+
+ConstantConstructor computeConstantConstructor(ResolvedAst resolvedAst) {
+ ConstantConstructorComputer visitor =
+ new ConstantConstructorComputer(resolvedAst.elements);
+ return resolvedAst.node.accept(visitor);
+}
+
+class ConstantConstructorComputer extends SemanticVisitor
+ with SemanticDeclarationResolvedMixin,
+ DeclarationResolverMixin,
+ GetBulkMixin,
+ SetBulkMixin,
+ ErrorBulkMixin,
+ InvokeBulkMixin,
+ IndexSetBulkMixin,
+ CompoundBulkMixin,
+ UnaryBulkMixin,
+ BaseBulkMixin,
+ BinaryBulkMixin,
+ PrefixBulkMixin,
+ PostfixBulkMixin,
+ NewBulkMixin,
+ InitializerBulkMixin,
+ FunctionBulkMixin,
+ VariableBulkMixin
+ implements SemanticDeclarationVisitor, SemanticSendVisitor {
+ final Map<FieldElement, ConstantExpression> fieldMap =
+ <FieldElement, ConstantExpression>{};
+ final Map<dynamic/*int|String*/, ConstantExpression> defaultValues =
+ <dynamic/*int|String*/, ConstantExpression>{};
+
+ ConstantConstructorComputer(TreeElements elements)
+ : super(elements);
+
+ SemanticDeclarationVisitor get declVisitor => this;
+
+ SemanticSendVisitor get sendVisitor => this;
+
+ ClassElement get currentClass => currentConstructor.enclosingClass;
+
+ ConstructorElement get currentConstructor => elements.analyzedElement;
+
+ apply(Node node, [_]) => node.accept(this);
+
+ visitNode(Node node) {
+ internalError(node, 'Unhandled node $node: ${node.toDebugString()}');
+ }
+
+ @override
+ bulkHandleNode(Node node, String template, _) {
+ internalError(node, template.replaceFirst('#' , '$node'));
+ }
+
+ internalError(Node node, String message) {
+ throw new UnsupportedError(message);
+ }
+
+ ConstantConstructor visitGenerativeConstructorDeclaration(
+ FunctionExpression node,
+ ConstructorElement constructor,
+ NodeList parameters,
+ NodeList initializers,
+ Node body,
+ _) {
+ applyParameters(parameters, _);
+ ConstructedConstantExpression constructorInvocation =
+ applyInitializers(initializers, _);
+ return new GenerativeConstantConstructor(
+ currentClass.thisType, defaultValues, fieldMap, constructorInvocation);
+ }
+
+ ConstantConstructor visitRedirectingGenerativeConstructorDeclaration(
+ FunctionExpression node,
+ ConstructorElement constructor,
+ NodeList parameters,
+ NodeList initializers,
+ _) {
+ applyParameters(parameters, _);
+ ConstructedConstantExpression constructorInvocation =
+ applyInitializers(initializers, _);
+ return new RedirectingGenerativeConstantConstructor(
+ defaultValues, constructorInvocation);
+ }
+
+ ConstantConstructor visitRedirectingFactoryConstructorDeclaration(
+ FunctionExpression node,
+ ConstructorElement constructor,
+ NodeList parameters,
+ InterfaceType redirectionType,
+ ConstructorElement redirectionTarget,
+ _) {
+ List<String> argumentNames = [];
+ List<ConstantExpression> arguments = [];
+ int index = 0;
+ for (ParameterElement parameter in constructor.parameters) {
+ if (parameter.isNamed) {
+ String name = parameter.name;
+ argumentNames.add(name);
+ arguments.add(new NamedArgumentReference(name));
+ } else {
+ arguments.add(new PositionalArgumentReference(index));
+ }
+ index++;
+ }
+ CallStructure callStructure = new CallStructure(index, argumentNames);
+
+ return new RedirectingFactoryConstantConstructor(
+ new ConstructedConstantExpression(null,
+ redirectionType,
+ redirectionTarget,
+ callStructure,
+ arguments));
+ }
+
+ @override
+ visitFactoryConstructorDeclaration(
+ FunctionExpression node,
+ ConstructorElement constructor,
+ NodeList parameters,
+ Node body, _) {
+ // TODO(johnniwinther): Handle constant constructors with errors.
+ internalError(node, "Factory constructor cannot be constant.");
+ }
+
+ applyParameters(NodeList parameters, _) {
+ computeParameterStructures(parameters).forEach((s) => s.dispatch(this, _));
+ }
+
+ visitParameterDeclaration(
+ VariableDefinitions node,
+ Node definition,
+ ParameterElement parameter,
+ int index,
+ _) {
+ // Do nothing.
+ }
+
+ visitOptionalParameterDeclaration(
+ VariableDefinitions node,
+ Node definition,
+ ParameterElement parameter,
+ ConstantExpression defaultValue,
+ int index,
+ _) {
+ assert(invariant(node, defaultValue != null));
+ defaultValues[index] = defaultValue;
+ }
+
+ visitNamedParameterDeclaration(
+ VariableDefinitions node,
+ Node definition,
+ ParameterElement parameter,
+ ConstantExpression defaultValue,
+ _) {
+ assert(invariant(node, defaultValue != null));
+ String name = parameter.name;
+ defaultValues[name] = defaultValue;
+ }
+
+ visitInitializingFormalDeclaration(
+ VariableDefinitions node,
+ Node definition,
+ InitializingFormalElement parameter,
+ int index,
+ _) {
+ fieldMap[parameter.fieldElement] = new PositionalArgumentReference(index);
+ }
+
+ visitOptionalInitializingFormalDeclaration(
+ VariableDefinitions node,
+ Node definition,
+ InitializingFormalElement parameter,
+ ConstantExpression defaultValue,
+ int index,
+ _) {
+ assert(invariant(node, defaultValue != null));
+ defaultValues[index] = defaultValue;
+ fieldMap[parameter.fieldElement] = new PositionalArgumentReference(index);
+ }
+
+ visitNamedInitializingFormalDeclaration(
+ VariableDefinitions node,
+ Node definition,
+ InitializingFormalElement parameter,
+ ConstantExpression defaultValue,
+ _) {
+ assert(invariant(node, defaultValue != null));
+ String name = parameter.name;
+ defaultValues[name] = defaultValue;
+ fieldMap[parameter.fieldElement] = new NamedArgumentReference(name);
+ }
+
+ /// Apply this visitor to the constructor [initializers].
+ ConstructedConstantExpression applyInitializers(NodeList initializers, _) {
+ ConstructedConstantExpression constructorInvocation;
+ if (initializers != null) {
+ for (Node initializer in initializers) {
+ InitializerStructure structure =
+ computeInitializerStructure(initializer);
+ if (structure is SuperConstructorInvokeStructure ||
+ structure is ThisConstructorInvokeStructure) {
+ constructorInvocation = structure.dispatch(this, initializer, _);
+ } else {
+ structure.dispatch(this, initializer, _);
+ }
+ }
+ }
+ if (constructorInvocation == null && !currentClass.isObject) {
+ constructorInvocation =
+ new ConstructedConstantExpression(null,
+ currentClass.supertype,
+ currentClass.superclass.lookupDefaultConstructor(),
+ CallStructure.NO_ARGS,
+ const <ConstantExpression>[]);
+ }
+ return constructorInvocation;
+ }
+
+ visitFieldInitializer(
+ SendSet node,
+ FieldElement field,
+ Node initializer,
+ _) {
+ fieldMap[field] = apply(initializer);
+ }
+
+ visitParameterGet(
+ Send node,
+ ParameterElement parameter,
+ _) {
+ if (parameter.isNamed) {
+ return new NamedArgumentReference(parameter.name);
+ } else {
+ return new PositionalArgumentReference(
+ parameter.functionDeclaration.parameters.indexOf(parameter));
+ }
+ }
+
+ ConstructedConstantExpression visitSuperConstructorInvoke(
+ Send node,
+ ConstructorElement superConstructor,
+ InterfaceType type,
+ NodeList arguments,
+ Selector selector,
+ _) {
+ List<ConstantExpression> argumentExpression =
+ arguments.nodes.map((a) => apply(a)).toList();
+ return new ConstructedConstantExpression(null,
+ type,
+ superConstructor,
+ selector.callStructure,
+ argumentExpression);
+ }
+
+ ConstructedConstantExpression visitThisConstructorInvoke(
+ Send node,
+ ConstructorElement thisConstructor,
+ NodeList arguments,
+ Selector selector,
+ _) {
+ List<ConstantExpression> argumentExpression =
+ arguments.nodes.map((a) => apply(a)).toList();
+ return new ConstructedConstantExpression(null,
+ currentClass.thisType,
+ thisConstructor,
+ selector.callStructure,
+ argumentExpression);
+ }
+
+ @override
+ ConstantExpression visitBinary(
+ Send node,
+ Node left,
+ BinaryOperator operator,
+ Node right,
+ _) {
+ return new BinaryConstantExpression(null,
+ apply(left), operator, apply(right));
+ }
+
+
+ @override
+ ConstantExpression visitUnary(
+ Send node,
+ UnaryOperator operator,
+ Node expression,
+ _) {
+ return new UnaryConstantExpression(null,
+ operator, apply(expression));
+ }
+
+ @override
+ ConstantExpression visitStaticFieldGet(
+ Send node,
+ FieldElement field,
+ _) {
+ return new VariableConstantExpression(null, field);
+ }
+
+ @override
+ ConstantExpression visitTopLevelFieldGet(
+ Send node,
+ FieldElement field,
+ _) {
+ return new VariableConstantExpression(null, field);
+ }
+
+ @override
+ ConstantExpression visitLiteralInt(LiteralInt node) {
+ return new IntConstantExpression(
+ node.value, new IntConstantValue(node.value));
+ }
+
+ @override
+ ConstantExpression visitLiteralBool(LiteralBool node) {
+ return new BoolConstantExpression(node.value, null);
+ }
+
+ @override
+ ConstantExpression visitLiteralNull(LiteralNull node) {
+ return new NullConstantExpression(new NullConstantValue());
+ }
+
+ @override
+ ConstantExpression visitLiteralString(LiteralString node) {
+ return new StringConstantExpression(node.dartString.slowToString(), null);
+ }
+
+ @override
+ ConstantExpression visitConditional(Conditional node) {
+ return new ConditionalConstantExpression(null,
+ apply(node.condition),
+ apply(node.thenExpression),
+ apply(node.elseExpression));
+ }
+
+ @override
+ ConstantExpression visitParenthesizedExpression(ParenthesizedExpression node) {
+ return apply(node.expression);
+ }
+
+ @override
+ ConstantExpression visitTopLevelFunctionInvoke(
+ Send node,
+ MethodElement function,
+ NodeList arguments,
+ CallStructure callStructure,
+ _) {
+ if (function.name != 'identical' || !function.library.isDartCore) {
+ throw new UnsupportedError("Unexpected function call: $function");
+ }
+ return new IdenticalConstantExpression(
+ null, apply(arguments.nodes.head), apply(arguments.nodes.tail.head));
+ }
+
+ @override
+ ConstantExpression visitNamedArgument(NamedArgument node) {
+ return apply(node.expression);
+ }
+}
« no previous file with comments | « pkg/compiler/lib/src/compiler.dart ('k') | pkg/compiler/lib/src/constants/expressions.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698