Chromium Code Reviews| Index: lib/compiler/implementation/compile_time_constants.dart |
| diff --git a/lib/compiler/implementation/compile_time_constants.dart b/lib/compiler/implementation/compile_time_constants.dart |
| index 4d47b96d62fb344250774770fae086da3d5475c0..707adf753e699cc1996ff37ebefe8d6d10981977 100644 |
| --- a/lib/compiler/implementation/compile_time_constants.dart |
| +++ b/lib/compiler/implementation/compile_time_constants.dart |
| @@ -947,25 +947,30 @@ class CompileTimeConstantEvaluator extends AbstractVisitor { |
| error(node); |
| } |
| - /** Returns the list of constants that are passed to the static function. */ |
| - List<Constant> evaluateArgumentsToConstructor(Send send, |
| + /** |
| + * Returns the list of constants that are passed to the static function. |
| + * Retruns [:null:] if the [target] does not apply to the selector. |
|
karlklose
2012/04/12 13:33:51
Retruns -> returns.
floitsch
2012/04/16 14:23:14
As discussed now asserts that it succeeded. So nev
|
| + */ |
| + List<Constant> evaluateArgumentsToConstructor(Selector selector, |
| + Link<Node> arguments, |
| FunctionElement target) { |
| FunctionParameters parameters = target.computeParameters(compiler); |
| - List<Constant> arguments = <Constant>[]; |
| - Selector selector = elements.getSelector(send); |
| + List<Constant> compiledArguments = <Constant>[]; |
| Function compileArgument = evaluate; |
| Function compileConstant = compiler.compileVariable; |
| - bool succeeded = selector.addSendArgumentsToList( |
| - send, arguments, parameters, compileArgument, compileConstant); |
| - if (!succeeded) error(send); |
| - return arguments; |
| + bool succeeded = selector.addArgumentsToList(arguments, compiledArguments, |
| + parameters, compileArgument, |
| + compileConstant); |
| + if (!succeeded) return null; |
| + return compiledArguments; |
| } |
| Constant visitNewExpression(NewExpression node) { |
| if (!node.isConst()) error(node); |
| - FunctionElement constructor = elements[node.send]; |
| + Send send = node.send; |
| + FunctionElement constructor = elements[send]; |
| ClassElement classElement = constructor.enclosingElement; |
| if (classElement.isInterface()) { |
| compiler.resolver.resolveMethodElement(constructor); |
| @@ -973,8 +978,10 @@ class CompileTimeConstantEvaluator extends AbstractVisitor { |
| classElement = constructor.enclosingElement; |
| } |
| + Selector selector = elements.getSelector(send); |
| List<Constant> arguments = |
| - evaluateArgumentsToConstructor(node.send, constructor); |
| + evaluateArgumentsToConstructor(selector, send.arguments, constructor); |
| + if (arguments === null) error(node); |
| ConstructorEvaluator evaluator = |
| new ConstructorEvaluator(constructor, compiler); |
| evaluator.evaluateConstructorFieldValues(arguments); |
| @@ -1043,13 +1050,20 @@ class ConstructorEvaluator extends CompileTimeConstantEvaluator { |
| }); |
| } |
| - void evaluateSuperOrRedirectSend(FunctionElement targetConstructor, |
| - List<Constant> targetArguments) { |
| + /** Returns, if the [targetConstructor] applies to the [selector]. */ |
| + bool evaluateSuperOrRedirectSend(Selector selector, |
| + Link<Node> arguments, |
| + FunctionElement targetConstructor) { |
| + List<Constant> compiledArguments = |
| + evaluateArgumentsToConstructor(selector, arguments, targetConstructor); |
| + if (arguments === null) return false; |
|
karlklose
2012/04/12 13:33:51
arguments -> compiledArguments? Remove?
floitsch
2012/04/16 14:23:14
removed.
|
| + |
| ConstructorEvaluator evaluator = |
| new ConstructorEvaluator(targetConstructor, compiler); |
| - evaluator.evaluateConstructorFieldValues(targetArguments); |
| + evaluator.evaluateConstructorFieldValues(compiledArguments); |
| // Copy over the fieldValues from the super/redirect-constructor. |
| evaluator.fieldValues.forEach((key, value) => fieldValues[key] = value); |
| + return true; |
| } |
| /** |
| @@ -1071,9 +1085,11 @@ class ConstructorEvaluator extends CompileTimeConstantEvaluator { |
| // A super initializer or constructor redirection. |
| Send call = link.head; |
| FunctionElement targetConstructor = elements[call]; |
| - List<Constant> targetArguments = |
| - evaluateArgumentsToConstructor(call, targetConstructor); |
| - evaluateSuperOrRedirectSend(targetConstructor, targetArguments); |
| + Selector selector = elements.getSelector(call); |
| + Link<Node> arguments = call.arguments; |
| + bool succeeded = evaluateSuperOrRedirectSend(selector, arguments, |
| + targetConstructor); |
| + if (!succeeded) error(call); |
| foundSuperOrRedirect = true; |
| } else { |
| // A field initializer. |
| @@ -1097,9 +1113,14 @@ class ConstructorEvaluator extends CompileTimeConstantEvaluator { |
| FunctionElement targetConstructor = |
| superClass.lookupConstructor(superClass.name); |
| if (targetConstructor === null) { |
| - compiler.internalError("no default constructor available"); |
| + compiler.internalError("no default constructor available", |
| + node: functionNode); |
| } |
| - evaluateSuperOrRedirectSend(targetConstructor, const <Constant>[]); |
| + |
| + bool succeeded = evaluateSuperOrRedirectSend(Selector.INVOCATION_0, |
| + const EmptyLink<Node>(), |
| + targetConstructor); |
| + if (!succeeded) error(functionNode); |
| } |
| } |
| } |