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

Side by Side Diff: frog/member.dart

Issue 8334035: Reduces code generated by dynamic calls. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 9 years, 1 month 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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 /** A formal parameter to a [Method]. */ 5 /** A formal parameter to a [Method]. */
6 class Parameter { 6 class Parameter {
7 FormalNode definition; 7 FormalNode definition;
8 8
9 String name; 9 String name;
10 Type type; 10 Type type;
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 92
93 void provideFieldSyntax() => world.internalError('can not be field', span); 93 void provideFieldSyntax() => world.internalError('can not be field', span);
94 void providePropertySyntax() => 94 void providePropertySyntax() =>
95 world.internalError('can not be property', span); 95 world.internalError('can not be property', span);
96 96
97 Definition get definition() => null; 97 Definition get definition() => null;
98 98
99 List<Parameter> get parameters() => []; 99 List<Parameter> get parameters() => [];
100 100
101 // TODO(jimhug): Fix these names once get/set are truly pseudo-keywords. 101 // TODO(jimhug): Fix these names once get/set are truly pseudo-keywords.
102 abstract Value get_(MethodGenerator context, Node node, Value target); 102 // TODO(jmesserly): isDynamic isn't a great name for this, something better?
103 abstract Value get_(MethodGenerator context, Node node, Value target,
104 [bool isDynamic]);
103 105
104 abstract Value set_(MethodGenerator context, Node node, Value target, 106 abstract Value set_(MethodGenerator context, Node node, Value target,
105 Value value, [bool checked]); 107 Value value, [bool isDynamic]);
106 108
107 bool canInvoke(MethodGenerator context, Arguments args) { 109 bool canInvoke(MethodGenerator context, Arguments args) {
108 return canGet && new Value(returnType, null).canInvoke(context, '\$call', ar gs); 110 return canGet && new Value(returnType, null).canInvoke(context, '\$call', ar gs);
109 } 111 }
110 112
111 Value invoke(MethodGenerator context, Node node, Value target, Arguments args, 113 Value invoke(MethodGenerator context, Node node, Value target, Arguments args,
112 [bool checked=true]) { 114 [bool isDynamic=false]) {
113 var newTarget = get_(context, node, target); 115 var newTarget = get_(context, node, target, isDynamic);
114 return newTarget.invoke(context, '\$call', node, args, checked); 116 return newTarget.invoke(context, '\$call', node, args, isDynamic);
115 } 117 }
116 118
117 bool override(Member other) { 119 bool override(Member other) {
118 if (isStatic) { 120 if (isStatic) {
119 world.error('static members can not hide parent members', 121 world.error('static members can not hide parent members',
120 span, other.span); 122 span, other.span);
121 return false; 123 return false;
122 } else if (other.isStatic) { 124 } else if (other.isStatic) {
123 world.error('can not override static member', span, other.span); 125 world.error('can not override static member', span, other.span);
124 return false; 126 return false;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 158
157 // If this really becomes first class, this should return typeof(Type) 159 // If this really becomes first class, this should return typeof(Type)
158 Type get returnType() => world.isVar; 160 Type get returnType() => world.isVar;
159 161
160 bool canInvoke(MethodGenerator context, Arguments args) => false; 162 bool canInvoke(MethodGenerator context, Arguments args) => false;
161 bool get canGet() => true; 163 bool get canGet() => true;
162 bool get canSet() => false; 164 bool get canSet() => false;
163 165
164 void resolve(Type inType) {} 166 void resolve(Type inType) {}
165 167
166 Value get_(MethodGenerator context, Node node, Value target) { 168 Value get_(MethodGenerator context, Node node, Value target,
167 // TODO(jmesserly): is just using the raw type name good enough to ensure we 169 [bool isDynamic=false]) {
168 // don't have type name collisions on the JS side? 170 assert(target == null || target.type.isTop);
169 // TODO(jmesserly): assert(target == null); 171 // TODO(jmesserly): named args
170 // TODO(jimhug): named args.
171 return new Value(type, type.jsname, false, false, true); 172 return new Value(type, type.jsname, false, false, true);
172 } 173 }
173 174
174 Value set_(MethodGenerator context, Node node, Value target, Value value, 175 Value set_(MethodGenerator context, Node node, Value target, Value value,
175 [bool checked=true]) { 176 [bool isDynamic=false]) {
176 world.error('can not set type', type.definition.span); 177 world.error('can not set type', type.definition.span);
177 } 178 }
178 179
179 Value invoke(MethodGenerator context, Node node, Value target, Arguments args, 180 Value invoke(MethodGenerator context, Node node, Value target, Arguments args,
180 [bool checked=true]) { 181 [bool isDynamic=false]) {
181 world.error('can not invoke type', type.definition.span); 182 world.error('can not invoke type', type.definition.span);
182 } 183 }
183 } 184 }
184 185
185 /** Represents a Dart field from source code. */ 186 /** Represents a Dart field from source code. */
186 class FieldMember extends Member { 187 class FieldMember extends Member {
187 final VariableDefinition definition; 188 final VariableDefinition definition;
188 final Expression value; 189 final Expression value;
189 190
190 Type type; 191 Type type;
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
303 304
304 if (isStatic) { 305 if (isStatic) {
305 _computedValue = world.gen.globalForStaticField( 306 _computedValue = world.gen.globalForStaticField(
306 this, _computedValue, [_computedValue]); 307 this, _computedValue, [_computedValue]);
307 } 308 }
308 _computing = false; 309 _computing = false;
309 } 310 }
310 return _computedValue; 311 return _computedValue;
311 } 312 }
312 313
313 Value get_(MethodGenerator context, Node node, Value target) { 314 Value get_(MethodGenerator context, Node node, Value target,
314 declaringType.markUsed(); 315 [bool isDynamic=false]) {
316 if (!isDynamic) {
317 declaringType.markUsed();
318 }
315 if (isStatic) { 319 if (isStatic) {
316 // Make sure to compute the value of all static fields, even if we don't 320 // Make sure to compute the value of all static fields, even if we don't
317 // use this value immediately. 321 // use this value immediately.
318 var cv = computeValue(); 322 var cv = computeValue();
319 if (isFinal) { 323 if (isFinal) {
320 return cv; 324 return cv;
321 } 325 }
322 if (declaringType.isTop) { 326 if (declaringType.isTop) {
323 return new Value(type, '$jsname'); 327 return new Value(type, '$jsname');
324 } else { 328 } else {
325 return new Value(type, '${declaringType.jsname}.$jsname'); 329 return new Value(type, '${declaringType.jsname}.$jsname');
326 } 330 }
327 } else if (target.isConst && isFinal) { 331 } else if (target.isConst && isFinal) {
328 // take advantage of consts and retrieve the value directly if possible 332 // take advantage of consts and retrieve the value directly if possible
329 var constTarget = target is GlobalValue ? target.exp : target; 333 var constTarget = target is GlobalValue ? target.exp : target;
330 if (constTarget is ConstObjectValue) { 334 if (constTarget is ConstObjectValue) {
331 return constTarget.fields[name]; 335 return constTarget.fields[name];
332 } else if (constTarget.type == world.stringType && name == 'length') { 336 } else if (constTarget.type == world.stringType && name == 'length') {
333 return new Value(type, '${constTarget.actualValue.length}'); 337 return new Value(type, '${constTarget.actualValue.length}');
334 } 338 }
335 } 339 }
336 return new Value(type, '${target.code}.$jsname'); 340 return new Value(type, '${target.code}.$jsname');
337 } 341 }
338 342
339 Value set_(MethodGenerator context, Node node, Value target, Value value, 343 Value set_(MethodGenerator context, Node node, Value target, Value value,
340 [bool checked=true]) { 344 [bool isDynamic=false]) {
341 var lhs = get_(context, node, target); 345 var lhs = get_(context, node, target, isDynamic);
342 value = value.convertTo(context, type, node, checked); 346 value = value.convertTo(context, type, node, isDynamic);
343 return new Value(type, '${lhs.code} = ${value.code}'); 347 return new Value(type, '${lhs.code} = ${value.code}');
344 } 348 }
345 } 349 }
346 350
347 class PropertyMember extends Member { 351 class PropertyMember extends Member {
348 MethodMember getter; 352 MethodMember getter;
349 MethodMember setter; 353 MethodMember setter;
350 354
351 bool _provideFieldSyntax = false; 355 bool _provideFieldSyntax = false;
352 356
(...skipping 29 matching lines...) Expand all
382 // other.returnType.ensureAssignableFrom(returnType, null, true); 386 // other.returnType.ensureAssignableFrom(returnType, null, true);
383 if (other.isProperty) addFromParent(other); 387 if (other.isProperty) addFromParent(other);
384 return true; 388 return true;
385 } else { 389 } else {
386 world.error('property can only override field or property', 390 world.error('property can only override field or property',
387 span, other.span); 391 span, other.span);
388 return false; 392 return false;
389 } 393 }
390 } 394 }
391 395
392 Value get_(MethodGenerator context, Node node, Value target) { 396 Value get_(MethodGenerator context, Node node, Value target,
397 [bool isDynamic=false]) {
393 if (getter == null) { 398 if (getter == null) {
394 // TODO(jmesserly): fix this! should call noSuchMethod. 399 return target.invokeNoSuchMethod(context, 'get:$name', node);
395 world.warning('no getter on ${declaringType.name}.$name', node.span);
396 return new Value(null, '${target.code}.$name()/*NoGetter*/');
397 } 400 }
398 return getter.invoke(context, node, target, Arguments.EMPTY); 401 return getter.invoke(context, node, target, Arguments.EMPTY);
399 } 402 }
400 403
401 Value set_(MethodGenerator context, Node node, Value target, Value value, 404 Value set_(MethodGenerator context, Node node, Value target, Value value,
402 [bool checked=true]) { 405 [bool isDynamic=false]) {
403 return setter.invoke(context, node, target, new Arguments(null, [value]), 406 return setter.invoke(context, node, target, new Arguments(null, [value]),
404 checked); 407 isDynamic);
405 } 408 }
406 409
407 addFromParent(Member parentMember) { 410 addFromParent(Member parentMember) {
408 // TODO(jimhug): Egregious Hack! 411 // TODO(jimhug): Egregious Hack!
409 if (parentMember is ConcreteMember) { 412 if (parentMember is ConcreteMember) {
410 parentMember = parentMember.baseMember; 413 parentMember = parentMember.baseMember;
411 } 414 }
412 415
413 if (getter == null) getter = parentMember.getter; 416 if (getter == null) getter = parentMember.getter;
414 if (setter == null) setter = parentMember.setter; 417 if (setter == null) setter = parentMember.setter;
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
481 Definition set initDelegate(ctor) { baseMember.initDelegate = ctor; } 484 Definition set initDelegate(ctor) { baseMember.initDelegate = ctor; }
482 485
483 Type resolveType(TypeReference node, bool isRequired) { 486 Type resolveType(TypeReference node, bool isRequired) {
484 var type = baseMember.resolveType(node, isRequired); 487 var type = baseMember.resolveType(node, isRequired);
485 return type.resolveTypeParams(declaringType); 488 return type.resolveTypeParams(declaringType);
486 } 489 }
487 490
488 // TODO(jimhug): Add support for type params. 491 // TODO(jimhug): Add support for type params.
489 bool override(Member other) => baseMember.override(other); 492 bool override(Member other) => baseMember.override(other);
490 493
491 Value get_(MethodGenerator context, Node node, Value target) { 494 Value get_(MethodGenerator context, Node node, Value target,
492 Value ret = baseMember.get_(context, node, target); 495 [bool isDynamic=false]) {
496 Value ret = baseMember.get_(context, node, target, isDynamic);
493 return new Value(returnType, ret.code); 497 return new Value(returnType, ret.code);
494 } 498 }
495 499
496 Value set_(MethodGenerator context, Node node, Value target, Value value, 500 Value set_(MethodGenerator context, Node node, Value target, Value value,
497 [bool checked=true]) { 501 [bool isDynamic=false]) {
498 // TODO(jimhug): Check arg types in context of concrete type. 502 // TODO(jimhug): Check arg types in context of concrete type.
499 Value ret = baseMember.set_(context, node, target, value, checked); 503 Value ret = baseMember.set_(context, node, target, value, isDynamic);
500 return new Value(returnType, ret.code); 504 return new Value(returnType, ret.code);
501 } 505 }
502 506
503 Value invoke(MethodGenerator context, Node node, Value target, Arguments args, 507 Value invoke(MethodGenerator context, Node node, Value target, Arguments args,
504 [bool checked=true]) { 508 [bool isDynamic=false]) {
505 // TODO(jimhug): Check arg types in context of concrete type. 509 // TODO(jimhug): Check arg types in context of concrete type.
506 Value ret = baseMember.invoke(context, node, target, args, checked); 510 Value ret = baseMember.invoke(context, node, target, args, isDynamic);
507 var code = ret.code; 511 var code = ret.code;
508 if (isConstructor) { 512 if (isConstructor) {
509 // TODO(jimhug): Egregious hack - won't live through the weekend. 513 // TODO(jimhug): Egregious hack - won't live through the weekend.
510 code = code.replaceFirst( 514 code = code.replaceFirst(
511 declaringType.genericType.jsname, declaringType.jsname); 515 declaringType.genericType.jsname, declaringType.jsname);
512 } 516 }
513 world.gen.genMethod(this); 517 declaringType.genMethod(this);
514 return new Value(returnType, code); 518 return new Value(returnType, code);
515 } 519 }
516 } 520 }
517 521
518 522
519 /** Represents a Dart method or top-level function. */ 523 /** Represents a Dart method or top-level function. */
520 class MethodMember extends Member { 524 class MethodMember extends Member {
521 FunctionDefinition definition; 525 FunctionDefinition definition;
522 Type returnType; 526 Type returnType;
523 List<Parameter> parameters; 527 List<Parameter> parameters;
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
643 return type; 647 return type;
644 } 648 }
645 649
646 bool get prefersPropertySyntax() => true; 650 bool get prefersPropertySyntax() => true;
647 bool get requiresFieldSyntax() => false; 651 bool get requiresFieldSyntax() => false;
648 652
649 void provideFieldSyntax() => _provideFieldSyntax = true; 653 void provideFieldSyntax() => _provideFieldSyntax = true;
650 void providePropertySyntax() => _providePropertySyntax = true; 654 void providePropertySyntax() => _providePropertySyntax = true;
651 655
652 Value set_(MethodGenerator context, Node, Value target, Value value, 656 Value set_(MethodGenerator context, Node, Value target, Value value,
653 [bool checked=true]) { 657 [bool isDynamic=false]) {
654 world.error('can not set method', definition.span); 658 world.error('can not set method', definition.span);
655 } 659 }
656 660
657 Value get_(MethodGenerator context, Node node, Value target) { 661 Value get_(MethodGenerator context, Node node, Value target,
658 world.gen.genMethod(this); // TODO(jimhug): Would prefer to invoke! 662 [bool isDynamic=false]) {
663 // TODO(jimhug): Would prefer to invoke!
664 declaringType.genMethod(this);
659 _provideOptionalParamInfo = true; 665 _provideOptionalParamInfo = true;
660 if (isStatic) { 666 if (isStatic) {
661 var type = declaringType.isTop ? '' : '${declaringType.jsname}.'; 667 var type = declaringType.isTop ? '' : '${declaringType.jsname}.';
662 return new Value(functionType, '$type$jsname'); 668 return new Value(functionType, '$type$jsname');
663 } 669 }
664 _providePropertySyntax = true; 670 _providePropertySyntax = true;
665 return new Value(functionType, '${target.code}.get\$$jsname()'); 671 return new Value(functionType, '${target.code}.get\$$jsname()');
666 } 672 }
667 673
668 bool namesInOrder(Arguments args) { 674 bool namesInOrder(Arguments args) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
702 genParameterValues() { 708 genParameterValues() {
703 // Pure lazy? 709 // Pure lazy?
704 for (var p in parameters) p.genValue(this, generator); 710 for (var p in parameters) p.genValue(this, generator);
705 } 711 }
706 712
707 /** 713 /**
708 * Invokes this method on the given [target] with the given [args]. 714 * Invokes this method on the given [target] with the given [args].
709 * [node] provides a [SourceSpan] for any error messages. 715 * [node] provides a [SourceSpan] for any error messages.
710 */ 716 */
711 Value invoke(MethodGenerator context, Node node, Value target, 717 Value invoke(MethodGenerator context, Node node, Value target,
712 Arguments args, [bool checked=true]) { 718 Arguments args, [bool isDynamic=false]) {
713 // TODO(jimhug): Fix this hack for ensuring a method is resolved. 719 // TODO(jimhug): Fix this hack for ensuring a method is resolved.
714 if (parameters == null) { 720 if (parameters == null) {
715 world.info('surprised to need to resolve: ${declaringType.name}.$name'); 721 world.info('surprised to need to resolve: ${declaringType.name}.$name');
716 this.resolve(declaringType); 722 this.resolve(declaringType);
717 } 723 }
718 724
719 if (!isGenerated) { 725 declaringType.genMethod(this);
720 world.gen.genMethod(this);
721 }
722 726
723 if (isStatic || isFactory) { 727 if (isStatic || isFactory) {
724 declaringType.markUsed(); 728 declaringType.markUsed();
725 } 729 }
726 730
727 if (!namesInOrder(args)) { 731 if (!namesInOrder(args)) {
728 // Names aren't in order. For now, use a var call because it's an 732 // Names aren't in order. For now, use a var call because it's an
729 // easy way to get the right eval order for out of order arguments. 733 // easy way to get the right eval order for out of order arguments.
730 return context.findMembers(name).invokeOnVar(context, node, target, args); 734 return context.findMembers(name).invokeOnVar(context, node, target, args);
731 } 735 }
732 736
733 var argsCode = []; 737 var argsCode = [];
734 if (target != null && (isConstructor || target.isSuper)) { 738 if (target != null && (isConstructor || target.isSuper)) {
735 argsCode.add('this'); 739 argsCode.add('this');
736 } 740 }
737 741
738 int bareCount = args.bareCount; 742 int bareCount = args.bareCount;
739 for (int i = 0; i < bareCount; i++) { 743 for (int i = 0; i < bareCount; i++) {
740 var arg = args.values[i]; 744 var arg = args.values[i];
741 if (i >= parameters.length) { 745 if (i >= parameters.length) {
742 // TODO(jimhug): better error location 746 // TODO(jimhug): better error location
743 var msg = _argCountMsg(args.length, parameters.length); 747 var msg = _argCountMsg(args.length, parameters.length);
744 return _argError(context, node, target, args, msg); 748 return _argError(context, node, target, args, msg);
745 } 749 }
746 arg = arg.convertTo(context, parameters[i].type, node, checked); 750 arg = arg.convertTo(context, parameters[i].type, node, isDynamic);
747 if (isConst && arg.isConst) { 751 if (isConst && arg.isConst) {
748 argsCode.add(arg.canonicalCode); 752 argsCode.add(arg.canonicalCode);
749 } else { 753 } else {
750 argsCode.add(arg.code); 754 argsCode.add(arg.code);
751 } 755 }
752 } 756 }
753 757
754 if (bareCount < parameters.length) { 758 if (bareCount < parameters.length) {
755 genParameterValues(); 759 genParameterValues();
756 760
757 int namedArgsUsed = 0; 761 int namedArgsUsed = 0;
758 for (int i = bareCount; i < parameters.length; i++) { 762 for (int i = bareCount; i < parameters.length; i++) {
759 var arg = args.getValue(parameters[i].name); 763 var arg = args.getValue(parameters[i].name);
760 if (arg == null) { 764 if (arg == null) {
761 arg = parameters[i].value; 765 arg = parameters[i].value;
762 } else { 766 } else {
763 arg = arg.convertTo(context, parameters[i].type, node, checked); 767 arg = arg.convertTo(context, parameters[i].type, node, isDynamic);
764 namedArgsUsed++; 768 namedArgsUsed++;
765 } 769 }
766 770
767 if (arg == null || !parameters[i].isOptional) { 771 if (arg == null || !parameters[i].isOptional) {
768 // TODO(jimhug): better error location 772 // TODO(jimhug): better error location
769 var msg = _argCountMsg(Math.min(i, args.length), i + 1, atLeast:true); 773 var msg = _argCountMsg(Math.min(i, args.length), i + 1, atLeast:true);
770 return _argError(context, node, target, args, msg); 774 return _argError(context, node, target, args, msg);
771 } else { 775 } else {
772 argsCode.add(isConst && arg.isConst 776 argsCode.add(isConst && arg.isConst
773 ? arg.canonicalCode : arg.code); 777 ? arg.canonicalCode : arg.code);
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after
1227 if (_treatAsField) { 1231 if (_treatAsField) {
1228 member.provideFieldSyntax(); 1232 member.provideFieldSyntax();
1229 } else { 1233 } else {
1230 member.providePropertySyntax(); 1234 member.providePropertySyntax();
1231 } 1235 }
1232 } 1236 }
1233 } 1237 }
1234 return _treatAsField; 1238 return _treatAsField;
1235 } 1239 }
1236 1240
1237 Value get_(MethodGenerator context, Node node, Value target) { 1241 Value get_(MethodGenerator context, Node node, Value target,
1238 if (members.length == 1) return members[0].get_(context, node, target); 1242 [bool isDynamic=false]) {
1243 if (members.length == 1) {
1244 return members[0].get_(context, node, target, isDynamic);
1245 }
1246 final targets = members.filter((m) => m.canGet);
1247 if (targets.length == 1) {
1248 return targets[0].get_(context, node, target, isDynamic);
1249 }
1239 1250
1240 Value returnValue = null; 1251 Value returnValue = null;
1241 for (var member in members) { 1252 for (var member in targets) {
1242 if (!member.canGet) continue; 1253 final value = member.get_(context, node, target, isDynamic:true);
1243 final value = member.get_(context, node, target);
1244 returnValue = _tryUnion(returnValue, value, node); 1254 returnValue = _tryUnion(returnValue, value, node);
1245 } 1255 }
1246 if (returnValue == null) { 1256 if (returnValue == null) {
1247 return _makeError(node, target, 'getter'); 1257 return _makeError(node, target, 'getter');
1248 } 1258 }
1249 if (returnValue.code == null) { 1259 if (returnValue.code == null) {
1250 if (treatAsField) { 1260 if (treatAsField) {
1251 return new Value(returnValue.type, '${target.code}.$jsname'); 1261 return new Value(returnValue.type, '${target.code}.$jsname');
1252 } else { 1262 } else {
1253 return new Value(returnValue.type, '${target.code}.get\$$jsname()'); 1263 return new Value(returnValue.type, '${target.code}.get\$$jsname()');
1254 } 1264 }
1255 } 1265 }
1256 return returnValue; 1266 return returnValue;
1257 } 1267 }
1258 1268
1259 Value set_(MethodGenerator context, Node node, Value target, Value value, 1269 Value set_(MethodGenerator context, Node node, Value target, Value value,
1260 [bool checked=true]) { 1270 [bool isDynamic=false]) {
1261 if (members.length == 1) { 1271 if (members.length == 1) {
1262 return members[0].set_(context, node, target, value, checked); 1272 return members[0].set_(context, node, target, value, isDynamic);
1263 } 1273 }
1264 final targets = members.filter((m) => m.canSet); 1274 final targets = members.filter((m) => m.canSet);
1265 if (targets.length == 1) { 1275 if (targets.length == 1) {
1266 return targets[0].set_(context, node, target, value, checked); 1276 return targets[0].set_(context, node, target, value, isDynamic);
1267 } 1277 }
1268 1278
1269 Value returnValue = null; 1279 Value returnValue = null;
1270 for (var member in targets) { 1280 for (var member in targets) {
1271 final setValue = member.set_(context, node, target, value, checked:false); 1281 final res = member.set_(context, node, target, value, isDynamic:true);
1272 returnValue = _tryUnion(returnValue, setValue, node); 1282 returnValue = _tryUnion(returnValue, res, node);
1273 } 1283 }
1274 if (returnValue == null) { 1284 if (returnValue == null) {
1275 return _makeError(node, target, 'setter'); 1285 return _makeError(node, target, 'setter');
1276 } 1286 }
1277 if (returnValue.code == null) { 1287 if (returnValue.code == null) {
1278 if (treatAsField) { 1288 if (treatAsField) {
1279 return new Value(returnValue.type, 1289 return new Value(returnValue.type,
1280 '${target.code}.$jsname = ${value.code}'); 1290 '${target.code}.$jsname = ${value.code}');
1281 } else { 1291 } else {
1282 return new Value(returnValue.type, 1292 return new Value(returnValue.type,
1283 '${target.code}.set\$$jsname(${value.code})'); 1293 '${target.code}.set\$$jsname(${value.code})');
1284 } 1294 }
1285 } 1295 }
1286 return returnValue; 1296 return returnValue;
1287 } 1297 }
1288 1298
1289 Value invoke(MethodGenerator context, Node node, Value target, 1299 Value invoke(MethodGenerator context, Node node, Value target,
1290 Arguments args, [bool checked=true]) { 1300 Arguments args, [bool isDynamic=false]) {
1291 if (members.length == 1) { 1301 if (members.length == 1) {
1292 return members[0].invoke(context, node, target, args, checked); 1302 return members[0].invoke(context, node, target, args, isDynamic);
1293 } 1303 }
1294 final targets = members.filter((m) => m.canInvoke(context, args)); 1304 final targets = members.filter((m) => m.canInvoke(context, args));
1295 if (targets.length == 1) { 1305 if (targets.length == 1) {
1296 return targets[0].invoke(context, node, target, args, checked); 1306 return targets[0].invoke(context, node, target, args, isDynamic);
1297 } 1307 }
1298 1308
1299 Value returnValue = null; 1309 Value returnValue = null;
1300 for (var member in targets) { 1310 for (var member in targets) {
1301 final value = member.invoke(context, node, target, args, checked:false); 1311 final res = member.invoke(context, node, target, args, isDynamic:true);
1302 returnValue = _tryUnion(returnValue, value, node); 1312 returnValue = _tryUnion(returnValue, res, node);
1303 } 1313 }
1304 1314
1305 if (returnValue == null) { 1315 if (returnValue == null) {
1306 return _makeError(node, target, 'method'); 1316 return _makeError(node, target, 'method');
1307 } 1317 }
1308 1318
1309 // If we fail to unify the resulting code, implement as a var call. 1319 // If we fail to unify the resulting code, implement as a var call.
1310 if (returnValue.code == null) { 1320 if (returnValue.code == null) {
1311 if (name.startsWith('\$')) { 1321 if (name.startsWith('\$')) {
1312 return target.invokeSpecial(name, args, returnValue.type); 1322 return target.invokeSpecial(name, args, returnValue.type);
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
1442 } 1452 }
1443 1453
1444 void forEach(void f(MethodMember member)) { 1454 void forEach(void f(MethodMember member)) {
1445 factories.forEach((_, Map constructors) { 1455 factories.forEach((_, Map constructors) {
1446 constructors.forEach((_, Member member) { 1456 constructors.forEach((_, Member member) {
1447 f(member); 1457 f(member);
1448 }); 1458 });
1449 }); 1459 });
1450 } 1460 }
1451 } 1461 }
OLDNEW
« frog/gen.dart ('K') | « frog/gen.dart ('k') | frog/type.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698