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

Side by Side Diff: pkg/kernel/lib/transformations/reify/transformation/transformer.dart

Issue 2713163002: Pass type arguments as a list in generic methods invocations (Closed)
Patch Set: Simplify 'isGenericMethod' procedure Created 3 years, 9 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library kernel.transformations.reify.transformation.transformer; 5 library kernel.transformations.reify.transformation.transformer;
6 6
7 import '../analysis/program_analysis.dart'; 7 import '../analysis/program_analysis.dart';
8 import 'package:kernel/ast.dart'; 8 import 'package:kernel/ast.dart';
9 import 'binding.dart' show RuntimeLibrary; 9 import 'binding.dart' show RuntimeLibrary;
10 import 'builder.dart' show RuntimeTypeSupportBuilder; 10 import 'builder.dart' show RuntimeTypeSupportBuilder;
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 ReifyVisitor(this.rtiLibrary, this.builder, this.knowledge, 96 ReifyVisitor(this.rtiLibrary, this.builder, this.knowledge,
97 [this.libraryToTransform]); 97 [this.libraryToTransform]);
98 98
99 /// If not null, the transformation will only be applied to classes declared 99 /// If not null, the transformation will only be applied to classes declared
100 /// in this library. 100 /// in this library.
101 final Library libraryToTransform; 101 final Library libraryToTransform;
102 102
103 // TODO(karlklose): find a way to get rid of this state in the visitor. 103 // TODO(karlklose): find a way to get rid of this state in the visitor.
104 TransformationContext context; 104 TransformationContext context;
105 105
106 static const String genericMethodTypeParametersName = r"$typeParameters";
107
106 bool libraryShouldBeTransformed(Library library) { 108 bool libraryShouldBeTransformed(Library library) {
107 return libraryToTransform == null || libraryToTransform == library; 109 return libraryToTransform == null || libraryToTransform == library;
108 } 110 }
109 111
110 bool needsTypeInformation(Class cls) { 112 bool needsTypeInformation(Class cls) {
111 return !isObject(cls) && 113 return !isObject(cls) &&
112 !rtiLibrary.contains(cls) && 114 !rtiLibrary.contains(cls) &&
113 libraryShouldBeTransformed(cls.enclosingLibrary); 115 libraryShouldBeTransformed(cls.enclosingLibrary);
114 } 116 }
115 117
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 175
174 Procedure target = invocation.target; 176 Procedure target = invocation.target;
175 if (target == rtiLibrary.reifyFunction) { 177 if (target == rtiLibrary.reifyFunction) {
176 /// Rewrite calls to reify(TypeLiteral) to a reified type. 178 /// Rewrite calls to reify(TypeLiteral) to a reified type.
177 TypeLiteral literal = invocation.arguments.positional.single; 179 TypeLiteral literal = invocation.arguments.positional.single;
178 return createRuntimeType(literal.type); 180 return createRuntimeType(literal.type);
179 } else if (target.kind == ProcedureKind.Factory) { 181 } else if (target.kind == ProcedureKind.Factory) {
180 // Intercept calls to factories of classes we do not transform 182 // Intercept calls to factories of classes we do not transform
181 return interceptInstantiation(invocation, target); 183 return interceptInstantiation(invocation, target);
182 } 184 }
185
186 addTypeArgumentToGenericInvocation(invocation);
187
183 return invocation; 188 return invocation;
184 } 189 }
185 190
186 Library visitLibrary(Library library) { 191 Library visitLibrary(Library library) {
187 trace(library); 192 trace(library);
188 193
189 if (libraryShouldBeTransformed(library)) { 194 if (libraryShouldBeTransformed(library)) {
190 library.transformChildren(this); 195 library.transformChildren(this);
191 } 196 }
192 return library; 197 return library;
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 417
413 RuntimeTypeStorage access = context.runtimeTypeStorage; 418 RuntimeTypeStorage access = context.runtimeTypeStorage;
414 assert(access != RuntimeTypeStorage.none); 419 assert(access != RuntimeTypeStorage.none);
415 return access == RuntimeTypeStorage.field || 420 return access == RuntimeTypeStorage.field ||
416 access == RuntimeTypeStorage.inheritedField; 421 access == RuntimeTypeStorage.inheritedField;
417 } 422 }
418 423
419 FunctionNode visitFunctionNode(FunctionNode node) { 424 FunctionNode visitFunctionNode(FunctionNode node) {
420 trace(node); 425 trace(node);
421 426
427 addTypeArgumentToGenericDeclaration(node);
428
422 // If we have a [TransformationContext] with a runtime type field and we 429 // If we have a [TransformationContext] with a runtime type field and we
423 // translate a constructor or factory, we need a parameter that the code of 430 // translate a constructor or factory, we need a parameter that the code of
424 // initializers or the factory body can use to access type arguments. 431 // initializers or the factory body can use to access type arguments.
425 // The parameter field in the context will be reset in the visit-method of 432 // The parameter field in the context will be reset in the visit-method of
426 // the parent. 433 // the parent.
427 if (context != null && needsParameterForRuntimeType(node.parent)) { 434 if (context != null && needsParameterForRuntimeType(node.parent)) {
428 assert(context.parameter == null); 435 assert(context.parameter == null);
429 // Create the parameter and insert it as the function's first parameter. 436 // Create the parameter and insert it as the function's first parameter.
430 context.parameter = new VariableDeclaration( 437 context.parameter = new VariableDeclaration(
431 rtiLibrary.runtimeTypeName.name, 438 rtiLibrary.runtimeTypeName.name,
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
565 } 572 }
566 573
567 Expression visitMapLiteral(MapLiteral node) { 574 Expression visitMapLiteral(MapLiteral node) {
568 trace(node); 575 trace(node);
569 node.transformChildren(this); 576 node.transformChildren(this);
570 return builder.callAttachType( 577 return builder.callAttachType(
571 node, 578 node,
572 new InterfaceType(builder.coreTypes.mapClass, 579 new InterfaceType(builder.coreTypes.mapClass,
573 <DartType>[node.keyType, node.valueType])); 580 <DartType>[node.keyType, node.valueType]));
574 } 581 }
582
583 Expression visitMethodInvocation(MethodInvocation node) {
584 node.transformChildren(this);
585 addTypeArgumentToGenericInvocation(node);
586 return node;
587 }
588
589 bool isGenericMethod(FunctionNode node) {
590 if (node.parent is Member) {
591 Member member = node.parent;
592 if (member is Constructor ||
593 member is Procedure && member.kind == ProcedureKind.Factory) {
594 return member.enclosingClass.typeParameters.length <
595 node.typeParameters.length;
596 }
597 }
598 return node.typeParameters.isNotEmpty;
599 }
600
601 void addTypeArgumentToGenericInvocation(InvocationExpression expression) {
602 if (expression.arguments.types.length > 0) {
603 ListLiteral genericMethodTypeParameters = new ListLiteral(
604 expression.arguments.types
605 .map(createRuntimeType)
606 .toList(growable: false),
607 typeArgument: rtiLibrary.typeType);
608 expression.arguments.named.add(new NamedExpression(
609 genericMethodTypeParametersName, genericMethodTypeParameters)
610 ..parent = expression.arguments);
611 }
612 }
613
614 void addTypeArgumentToGenericDeclaration(FunctionNode node) {
615 if (isGenericMethod(node)) {
616 VariableDeclaration genericMethodTypeParameters = new VariableDeclaration(
617 genericMethodTypeParametersName,
618 type: new InterfaceType(
619 builder.coreTypes.listClass, <DartType>[rtiLibrary.typeType]));
620 genericMethodTypeParameters.parent = node;
621 node.namedParameters.insert(0, genericMethodTypeParameters);
622 }
623 }
575 } 624 }
OLDNEW
« no previous file with comments | « pkg/kernel/lib/transformations/reify/transformation/remove_generics.dart ('k') | pkg/kernel/test/reify/suite.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698