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

Side by Side Diff: frog/member.dart

Issue 8567010: Dynamically dispatch getters and setters on dynamically-typed variables. (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 1351 matching lines...) Expand 10 before | Expand all | Expand 10 after
1362 if (!target.type.isVar) { 1362 if (!target.type.isVar) {
1363 world.warning('could not find applicable $action for "$name"', node.span); 1363 world.warning('could not find applicable $action for "$name"', node.span);
1364 } 1364 }
1365 return new Value(world.varType, 1365 return new Value(world.varType,
1366 '${target.code}.$jsname() /*no applicable $action*/', node.span); 1366 '${target.code}.$jsname() /*no applicable $action*/', node.span);
1367 } 1367 }
1368 1368
1369 bool _treatAsField; 1369 bool _treatAsField;
1370 bool get treatAsField() { 1370 bool get treatAsField() {
1371 if (_treatAsField == null) { 1371 if (_treatAsField == null) {
1372 _treatAsField = true; 1372 // If this is the global MemberSet from world, always bind dynamically.
1373 // Note: we need this for proper noSuchMethod and REPL behavior.
1374 _treatAsField = !isVar;
1373 for (var member in members) { 1375 for (var member in members) {
1374 if (member.requiresFieldSyntax) { 1376 if (member.requiresFieldSyntax) {
1375 _treatAsField = true; 1377 _treatAsField = true;
1376 break; 1378 break;
1377 } 1379 }
1378 if (member.prefersPropertySyntax) { 1380 if (member.prefersPropertySyntax) {
1379 _treatAsField = false; 1381 _treatAsField = false;
1380 } 1382 }
1381 } 1383 }
1382 for (var member in members) { 1384 for (var member in members) {
1383 if (_treatAsField) { 1385 if (_treatAsField) {
1384 member.provideFieldSyntax(); 1386 member.provideFieldSyntax();
1385 } else { 1387 } else {
1386 member.providePropertySyntax(); 1388 member.providePropertySyntax();
1387 } 1389 }
1388 } 1390 }
1389 } 1391 }
1390 return _treatAsField; 1392 return _treatAsField;
1391 } 1393 }
1392 1394
1393 Value _get(MethodGenerator context, Node node, Value target, 1395 Value _get(MethodGenerator context, Node node, Value target,
1394 [bool isDynamic=false]) { 1396 [bool isDynamic=false]) {
1395 if (members.length == 1) { 1397 // If this is the global MemberSet from world, always bind dynamically.
1396 return members[0]._get(context, node, target, isDynamic); 1398 // Note: we need this for proper noSuchMethod and REPL behavior.
1397 } 1399 Value returnValue;
1398 final targets = members.filter((m) => m.canGet); 1400 final targets = members.filter((m) => m.canGet);
1399 if (targets.length == 1) { 1401 if (isVar) {
1400 return targets[0]._get(context, node, target, isDynamic); 1402 targets.forEach((m) => m._get(context, node, target, isDynamic: true));
nweiz 2011/11/15 00:04:08 This line seems to be slowing down the compilation
Jennifer Messerly 2011/11/15 04:44:34 Sounds like it. I'd try passing: --new_gen_heap_si
nweiz 2011/11/15 20:59:25 Increasing the heap size seems to do the trick. Is
Jennifer Messerly 2011/11/16 23:42:35 Yes, definitely increase it there too. Maybe frog.
1403 returnValue = new Value(world.varType, null, node.span);
Jennifer Messerly 2011/11/15 04:44:34 I think you want to use a more precise type here,
nweiz 2011/11/15 20:59:25 Done. I guess I was too much in the mindset of --f
1404 } else {
1405 if (members.length == 1) {
1406 return members[0]._get(context, node, target, isDynamic);
1407 } else if (targets.length == 1) {
1408 return targets[0]._get(context, node, target, isDynamic);
1409 }
1410
1411 for (var member in targets) {
1412 final value = member._get(context, node, target, isDynamic:true);
1413 returnValue = _tryUnion(returnValue, value, node);
1414 }
1415 if (returnValue == null) {
1416 return _makeError(node, target, 'getter');
1417 }
1401 } 1418 }
1402 1419
1403 Value returnValue = null;
1404 for (var member in targets) {
1405 final value = member._get(context, node, target, isDynamic:true);
1406 returnValue = _tryUnion(returnValue, value, node);
1407 }
1408 if (returnValue == null) {
1409 return _makeError(node, target, 'getter');
1410 }
1411 if (returnValue.code == null) { 1420 if (returnValue.code == null) {
1412 if (treatAsField) { 1421 if (treatAsField) {
1413 return new Value(returnValue.type, '${target.code}.$jsname', 1422 return new Value(returnValue.type, '${target.code}.$jsname',
1414 node.span); 1423 node.span);
1415 } else { 1424 } else {
1416 return new Value(returnValue.type, '${target.code}.get\$$jsname()', 1425 return new Value(returnValue.type, '${target.code}.get\$$jsname()',
1417 node.span); 1426 node.span);
1418 } 1427 }
1419 } 1428 }
1420 return returnValue; 1429 return returnValue;
1421 } 1430 }
1422 1431
1423 Value _set(MethodGenerator context, Node node, Value target, Value value, 1432 Value _set(MethodGenerator context, Node node, Value target, Value value,
1424 [bool isDynamic=false]) { 1433 [bool isDynamic=false]) {
1425 if (members.length == 1) { 1434 // If this is the global MemberSet from world, always bind dynamically.
1426 return members[0]._set(context, node, target, value, isDynamic); 1435 // Note: we need this for proper noSuchMethod and REPL behavior.
1427 } 1436 Value returnValue;
1428 final targets = members.filter((m) => m.canSet); 1437 final targets = members.filter((m) => m.canSet);
1429 if (targets.length == 1) { 1438 if (isVar) {
1430 return targets[0]._set(context, node, target, value, isDynamic); 1439 targets.forEach((m) =>
1440 m._set(context, node, target, value, isDynamic: true));
1441 returnValue = new Value(world.varType, null, node.span);
1442 } else {
1443 if (members.length == 1) {
1444 return members[0]._set(context, node, target, value, isDynamic);
1445 } else if (targets.length == 1) {
1446 return targets[0]._set(context, node, target, value, isDynamic);
1447 }
1448
1449 for (var member in targets) {
1450 final res = member._set(context, node, target, value, isDynamic:true);
1451 returnValue = _tryUnion(returnValue, res, node);
1452 }
1453 if (returnValue == null) {
1454 return _makeError(node, target, 'setter');
1455 }
1431 } 1456 }
1432 1457
1433 Value returnValue = null;
1434 for (var member in targets) {
1435 final res = member._set(context, node, target, value, isDynamic:true);
1436 returnValue = _tryUnion(returnValue, res, node);
1437 }
1438 if (returnValue == null) {
1439 return _makeError(node, target, 'setter');
1440 }
1441 if (returnValue.code == null) { 1458 if (returnValue.code == null) {
1442 if (treatAsField) { 1459 if (treatAsField) {
1443 return new Value(returnValue.type, 1460 return new Value(returnValue.type,
1444 '${target.code}.$jsname = ${value.code}', node.span); 1461 '${target.code}.$jsname = ${value.code}', node.span);
1445 } else { 1462 } else {
1446 return new Value(returnValue.type, 1463 return new Value(returnValue.type,
1447 '${target.code}.set\$$jsname(${value.code})', node.span); 1464 '${target.code}.set\$$jsname(${value.code})', node.span);
1448 } 1465 }
1449 } 1466 }
1450 return returnValue; 1467 return returnValue;
1451 } 1468 }
1452 1469
1453 Value invoke(MethodGenerator context, Node node, Value target, 1470 Value invoke(MethodGenerator context, Node node, Value target,
1454 Arguments args, [bool isDynamic=false]) { 1471 Arguments args, [bool isDynamic=false]) {
1455 // If this is the global MemberSet from world, always bind dynamically. 1472 // If this is the global MemberSet from world, always bind dynamically.
1456 // Note: we need this for proper noSuchMethod and REPL behavior. 1473 // Note: we need this for proper noSuchMethod and REPL behavior.
1457 if (isVar && !isOperator) { 1474 if (isVar && !isOperator) {
1475 members.filter((m) => m.canInvoke(context, args)).forEach((m) =>
Jennifer Messerly 2011/11/15 04:44:34 why did you need this line? invokeOnVar already t
nweiz 2011/11/15 20:59:25 Oh, I suppose it does. I had assumed that it was n
1476 m.invoke(context, node, target, args, isDynamic: true));
1458 return invokeOnVar(context, node, target, args); 1477 return invokeOnVar(context, node, target, args);
1459 } 1478 }
1460 1479
1461 if (members.length == 1) { 1480 if (members.length == 1) {
1462 return members[0].invoke(context, node, target, args, isDynamic); 1481 return members[0].invoke(context, node, target, args, isDynamic);
1463 } 1482 }
1464 final targets = members.filter((m) => m.canInvoke(context, args)); 1483 final targets = members.filter((m) => m.canInvoke(context, args));
1465 if (targets.length == 1) { 1484 if (targets.length == 1) {
1466 return targets[0].invoke(context, node, target, args, isDynamic); 1485 return targets[0].invoke(context, node, target, args, isDynamic);
1467 } 1486 }
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
1615 } 1634 }
1616 1635
1617 void forEach(void f(Member member)) { 1636 void forEach(void f(Member member)) {
1618 factories.forEach((_, Map constructors) { 1637 factories.forEach((_, Map constructors) {
1619 constructors.forEach((_, Member member) { 1638 constructors.forEach((_, Member member) {
1620 f(member); 1639 f(member);
1621 }); 1640 });
1622 }); 1641 });
1623 } 1642 }
1624 } 1643 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698