Chromium Code Reviews| Index: lib/compiler/implementation/ssa/builder.dart |
| diff --git a/lib/compiler/implementation/ssa/builder.dart b/lib/compiler/implementation/ssa/builder.dart |
| index 91d2d4567f85ebd1833377a4054c31adfc32ae60..335ef09693fb420a40dcb10cb23a405b57d19351 100644 |
| --- a/lib/compiler/implementation/ssa/builder.dart |
| +++ b/lib/compiler/implementation/ssa/builder.dart |
| @@ -1320,8 +1320,8 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
| // Create the runtime type information, if needed. |
| InterfaceType type = classElement.computeType(compiler); |
| - List<HInstruction> inputs = <HInstruction>[]; |
| - if (compiler.world.needsRti(classElement)) { |
| + List<HInstruction> inputs = <HInstruction>[]; |
| + if (compiler.world.needsRti(classElement)) { |
| classElement.typeVariables.forEach((TypeVariableType typeVariable) { |
| inputs.add(localsHandler.directLocals[typeVariable.element]); |
| }); |
| @@ -2732,39 +2732,85 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
| } |
| HInstruction analyzeTypeArgument(DartType argument, Node currentNode) { |
| - if (argument.element.isTypeVariable()) { |
| + // These variables are shared between invocations of the helper methods. |
| + HInstruction typeInfo; |
| + StringBuffer template = new StringBuffer(); |
| + List<HInstruction> inputs = <HInstruction>[]; |
| + |
| + /** Helper to create an instruction to get the value of a type variable. */ |
|
floitsch
2012/10/10 13:04:44
.. instruction that gets ...
karlklose
2012/10/10 13:44:45
Done.
|
| + void addTypeVariableReference(TypeVariableType type) { |
| Element member = work.element; |
| if (member.enclosingElement.isClosure()) { |
| - member = (member.enclosingElement as ClosureClassElement).methodElement; |
| + ClosureClassElement closureClass = member.enclosingElement; |
| + member = closureClass.methodElement; |
| member = member.getOutermostEnclosingMemberOrTopLevel(); |
| } |
| if (member.isFactoryConstructor()) { |
| - // The type variable is stored in a parameter of the |
| - // factory. |
| - return localsHandler.readLocal(argument.element); |
| + // The type variable is stored in a parameter of the factory. |
| + inputs.add(localsHandler.readLocal(type.element)); |
| } else if (member.isInstanceMember() |
| || member.isGenerativeConstructor()) { |
| // The type variable is stored in [this]. |
| - pushInvokeHelper1(interceptors.getGetRuntimeTypeInfo(), |
| + if (typeInfo == null) { |
| + pushInvokeHelper1(interceptors.getGetRuntimeTypeInfo(), |
| localsHandler.readThis()); |
|
floitsch
2012/10/10 13:04:44
indentation.
karlklose
2012/10/10 13:44:45
Done.
|
| - HInstruction typeInfo = pop(); |
| + typeInfo = pop(); |
| + } |
| HInstruction foreign = new HForeign( |
| - new LiteralDartString('#.$argument'), |
| + new LiteralDartString('#.${type.name.slowToString()}'), |
| new LiteralDartString('String'), |
| <HInstruction>[typeInfo]); |
| add(foreign); |
| - return foreign; |
| + inputs.add(foreign); |
| } else { |
| // TODO(ngeoffray): Match the VM behavior and throw an |
| // exception at runtime. |
| compiler.cancel('Unimplemented unresolved type variable', |
| node: currentNode); |
| } |
| - } else { |
| - // The type variable is a type (e.g. int). |
| - return graph.addConstantString( |
| - new LiteralDartString('$argument'), currentNode, constantSystem); |
| } |
| + |
| + /** |
| + * Helper to build an instruction that builds the string representation for |
| + * this type, where type variables are substituted by their runtime value. |
|
floitsch
2012/10/10 13:04:44
Add example output (of the template).
karlklose
2012/10/10 13:44:45
Done.
|
| + */ |
| + void buildTypeString(DartType type, {isInQuotes: false}) { |
| + if (type is TypeVariableType) { |
| + addTypeVariableReference(type); |
| + template.add(isInQuotes ? "' + # +'" : "#"); |
| + } else if (type is InterfaceType) { |
| + bool isFirstVariable = true; |
| + InterfaceType interfaceType = type; |
| + bool hasTypeArguments = !interfaceType.arguments.isEmpty(); |
| + if (!isInQuotes) template.add("'"); |
| + template.add("${type.element.name.slowToString()}"); |
| + if (hasTypeArguments) { |
| + template.add("<"); |
| + for (DartType argument in interfaceType.arguments) { |
| + if (!isFirstVariable) { |
| + template.add(", "); |
| + } |
| + buildTypeString(argument, isInQuotes: true); |
| + isFirstVariable = false; |
|
floitsch
2012/10/10 13:04:44
move isFirstVariable up into the if.
karlklose
2012/10/10 13:44:45
Done, moved into else branch.
|
| + } |
| + template.add(">"); |
| + } |
| + if (!isInQuotes) template.add("'"); |
| + } else { |
|
floitsch
2012/10/10 13:04:44
add explanation what it must be. for example.
asse
karlklose
2012/10/10 13:44:45
Done.
|
| + if (!isInQuotes) template.add("'"); |
| + // TODO(karlklose): handle typedefs. |
| + template.add(argument.toString()); |
| + if (!isInQuotes) template.add("'"); |
| + } |
| + } |
| + |
| + buildTypeString(argument, isInQuotes: false); |
| + HInstruction result = |
| + new HForeign(new LiteralDartString("$template"), |
| + new LiteralDartString('String'), |
| + inputs); |
| + add(result); |
| + return result; |
| } |
| void handleListConstructor(InterfaceType type, |