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

Side by Side Diff: frog/member.dart

Issue 9222004: passing and good perf (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 11 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 Member method; 8 Member method;
9 9
10 String name; 10 String name;
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 // I hope this trust is well placed! 153 // I hope this trust is well placed!
154 return world.nonNullBool; 154 return world.nonNullBool;
155 } 155 }
156 return t; 156 return t;
157 } 157 }
158 158
159 Definition get definition() => null; 159 Definition get definition() => null;
160 160
161 List<Parameter> get parameters() => []; 161 List<Parameter> get parameters() => [];
162 162
163 MemberSet _preciseMemberSet, _potentialMemberSet;
164
165 MemberSet get preciseMemberSet() {
166 if (_preciseMemberSet === null) {
167 _preciseMemberSet = new MemberSet(this);
168 }
169 return _preciseMemberSet;
170 }
171
172 MemberSet get potentialMemberSet() {
173 if (_potentialMemberSet === null) {
174 if (declaringType.isObject) {
175 _potentialMemberSet = world._members[name];
176 return _potentialMemberSet;
177 }
178
179 final mems = new Set<Member>();
180 if (declaringType.isClass) mems.add(this);
181
182
183 for (var subtype in declaringType.subtypes) {
184 if (!subtype.isClass) continue;
185 var mem = subtype.members[name];
186 if (mem !== null) {
187 mems.add(mem);
188 } else if (!declaringType.isClass) {
189 // Handles weird interface case.
Jennifer Messerly 2012/01/18 00:03:00 might be worth expanding this comment :) as I rea
190 mem = subtype.getMember(name);
191 if (mem !== null) {
192 mems.add(mem);
193 }
194 }
195 }
196
197 if (mems.length != 0) {
198 for (var mem in mems) {
199 if (_potentialMemberSet === null) {
200 _potentialMemberSet = new MemberSet(mem);
201 } else {
202 _potentialMemberSet.add(mem);
203 }
204 }
205 }
206 }
207 return _potentialMemberSet;
208 }
209
210 // If I have an object of [type] could I be invoking this member?
211 bool isDefinedOn(Type type) {
212 if (type.isClass) {
213 if (declaringType.isSubtypeOf(type)) {
214 return true;
215 } else if (type.isSubtypeOf(declaringType)) {
216 // maybe - but not if overridden somewhere
217 // !!! horrible hack for today - awful perf props
218 return type.getMember(name) == this;
219 //return true;
220 } else {
221 return false;
222 }
223 } else {
224 if (declaringType.isSubtypeOf(type)) {
225 return true;
226 } else {
227 // If this is an interface, the actual implementation may
228 // come from a class that does not implement this interface.
229 for (var t in declaringType.subtypes) {
230 if (t.isSubtypeOf(type) && t.getMember(name) == this) {
231 return true;
232 }
233 }
234 return false;
235 }
236 }
237 }
238
163 // TODO(jmesserly): isDynamic isn't a great name for this, something better? 239 // TODO(jmesserly): isDynamic isn't a great name for this, something better?
164 abstract Value _get(MethodGenerator context, Node node, Value target, 240 abstract Value _get(MethodGenerator context, Node node, Value target,
165 [bool isDynamic]); 241 [bool isDynamic]);
166 242
167 abstract Value _set(MethodGenerator context, Node node, Value target, 243 abstract Value _set(MethodGenerator context, Node node, Value target,
168 Value value, [bool isDynamic]); 244 Value value, [bool isDynamic]);
169 245
170 bool canInvoke(MethodGenerator context, Arguments args) { 246 bool canInvoke(MethodGenerator context, Arguments args) {
171 // No source location needed because canInvoke may not produce errors. 247 // No source location needed because canInvoke may not produce errors.
172 return canGet && 248 return canGet &&
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 343
268 bool isStatic; 344 bool isStatic;
269 bool isFinal; 345 bool isFinal;
270 bool isNative; 346 bool isNative;
271 347
272 // TODO(jimhug): Better notion of fields that need special handling... 348 // TODO(jimhug): Better notion of fields that need special handling...
273 bool get overridesProperty() { 349 bool get overridesProperty() {
274 if (isStatic) return false; 350 if (isStatic) return false;
275 351
276 if (declaringType.parent != null) { 352 if (declaringType.parent != null) {
277 var p = declaringType.parent.resolveMember(name); 353 var p = declaringType.parent.getProperty(name);
278 if (p != null && p.containsProperties) { 354 if (p != null && p.isProperty) return true;
279 return true; 355 if (p is FieldMember && p != this) return p.overridesProperty;
280 }
281 } 356 }
282 return false; 357 return false;
283 } 358 }
284 359
285 bool override(Member other) { 360 bool override(Member other) {
286 if (!super.override(other)) return false; 361 if (!super.override(other)) return false;
287 362
288 // fields can override properties - but nothing else? 363 // fields can override properties - but nothing else?
289 if (other.isProperty) { 364 if (other.isProperty) {
290 // TODO(jimhug): 365 // TODO(jimhug):
(...skipping 1031 matching lines...) Expand 10 before | Expand all | Expand 10 after
1322 } 1397 }
1323 } 1398 }
1324 return _treatAsField; 1399 return _treatAsField;
1325 } 1400 }
1326 1401
1327 Value _get(MethodGenerator context, Node node, Value target, 1402 Value _get(MethodGenerator context, Node node, Value target,
1328 [bool isDynamic=false]) { 1403 [bool isDynamic=false]) {
1329 // If this is the global MemberSet from world, always bind dynamically. 1404 // If this is the global MemberSet from world, always bind dynamically.
1330 // Note: we need this for proper noSuchMethod and REPL behavior. 1405 // Note: we need this for proper noSuchMethod and REPL behavior.
1331 Value returnValue; 1406 Value returnValue;
1407 if (members.length == 1 && !isVar) {
1408 return members[0]._get(context, node, target, isDynamic);
1409 }
1410
1411
1332 final targets = members.filter((m) => m.canGet); 1412 final targets = members.filter((m) => m.canGet);
1333 if (isVar) { 1413 if (isVar) {
1334 targets.forEach((m) => m._get(context, node, target, isDynamic: true)); 1414 targets.forEach((m) => m._get(context, node, target, isDynamic: true));
1335 returnValue = new Value(_foldTypes(targets), null, node.span); 1415 returnValue = new Value(_foldTypes(targets), null, node.span);
1336 } else { 1416 } else {
1337 if (members.length == 1) { 1417 if (members.length == 1) {
1338 return members[0]._get(context, node, target, isDynamic); 1418 return members[0]._get(context, node, target, isDynamic);
1339 } else if (targets.length == 1) { 1419 } else if (targets.length == 1) {
1340 return targets[0]._get(context, node, target, isDynamic); 1420 return targets[0]._get(context, node, target, isDynamic);
1341 } 1421 }
(...skipping 16 matching lines...) Expand all
1358 node.span); 1438 node.span);
1359 } 1439 }
1360 } 1440 }
1361 return returnValue; 1441 return returnValue;
1362 } 1442 }
1363 1443
1364 Value _set(MethodGenerator context, Node node, Value target, Value value, 1444 Value _set(MethodGenerator context, Node node, Value target, Value value,
1365 [bool isDynamic=false]) { 1445 [bool isDynamic=false]) {
1366 // If this is the global MemberSet from world, always bind dynamically. 1446 // If this is the global MemberSet from world, always bind dynamically.
1367 // Note: we need this for proper noSuchMethod and REPL behavior. 1447 // Note: we need this for proper noSuchMethod and REPL behavior.
1448 if (members.length == 1 && !isVar) {
1449 return members[0]._set(context, node, target, value, isDynamic);
1450 }
1451
1368 Value returnValue; 1452 Value returnValue;
1369 final targets = members.filter((m) => m.canSet); 1453 final targets = members.filter((m) => m.canSet);
1370 if (isVar) { 1454 if (isVar) {
1371 targets.forEach((m) => 1455 targets.forEach((m) =>
1372 m._set(context, node, target, value, isDynamic: true)); 1456 m._set(context, node, target, value, isDynamic: true));
1373 returnValue = new Value(_foldTypes(targets), null, node.span); 1457 returnValue = new Value(_foldTypes(targets), null, node.span);
1374 } else { 1458 } else {
1375 if (members.length == 1) { 1459 if (members.length == 1) {
1376 return members[0]._set(context, node, target, value, isDynamic); 1460 return members[0]._set(context, node, target, value, isDynamic);
1377 } else if (targets.length == 1) { 1461 } else if (targets.length == 1) {
(...skipping 22 matching lines...) Expand all
1400 } 1484 }
1401 1485
1402 Value invoke(MethodGenerator context, Node node, Value target, 1486 Value invoke(MethodGenerator context, Node node, Value target,
1403 Arguments args, [bool isDynamic=false]) { 1487 Arguments args, [bool isDynamic=false]) {
1404 // If this is the global MemberSet from world, always bind dynamically. 1488 // If this is the global MemberSet from world, always bind dynamically.
1405 // Note: we need this for proper noSuchMethod and REPL behavior. 1489 // Note: we need this for proper noSuchMethod and REPL behavior.
1406 if (isVar && !isOperator) { 1490 if (isVar && !isOperator) {
1407 return invokeOnVar(context, node, target, args); 1491 return invokeOnVar(context, node, target, args);
1408 } 1492 }
1409 1493
1410 if (members.length == 1) { 1494 if (members.length == 1 && !isVar) {
1411 return members[0].invoke(context, node, target, args, isDynamic); 1495 return members[0].invoke(context, node, target, args, isDynamic);
1412 } 1496 }
1497
1413 final targets = members.filter((m) => m.canInvoke(context, args)); 1498 final targets = members.filter((m) => m.canInvoke(context, args));
1414 if (targets.length == 1) { 1499 if (targets.length == 1) {
1415 return targets[0].invoke(context, node, target, args, isDynamic); 1500 return targets[0].invoke(context, node, target, args, isDynamic);
1416 } 1501 }
1417 1502
1418 Value returnValue = null; 1503 Value returnValue = null;
1419 for (var member in targets) { 1504 if (targets.length < 1000) {
Jennifer Messerly 2012/01/18 00:03:00 nice fix. I like having limits for all of these po
1420 final res = member.invoke(context, node, target, args, isDynamic:true); 1505 for (var member in targets) {
1421 // TODO(jmesserly): If the code has different type checks, it will fail to 1506 final res = member.invoke(context, node, target, args, isDynamic:true);
1422 // unify and go through a dynamic stub. Good so far. However, we'll end 1507 // TODO(jmesserly): If the code has different type checks, it will fail to
1423 // up with a bogus unused temp generated (usually "var $0"). We need a way 1508 // unify and go through a dynamic stub. Good so far. However, we'll end
1424 // to throw away temps when we throw away the code. 1509 // up with a bogus unused temp generated (usually "var $0"). We need a w ay
1425 returnValue = _tryUnion(returnValue, res, node); 1510 // to throw away temps when we throw away the code.
1426 } 1511 returnValue = _tryUnion(returnValue, res, node);
1512 }
1427 1513
1428 if (returnValue == null) { 1514 if (returnValue == null) {
1429 return _makeError(node, target, 'method'); 1515 return _makeError(node, target, 'method');
1516 }
1517 } else {
1518 returnValue = new Value(world.varType, null, node.span);
1430 } 1519 }
1431 1520
1432 if (returnValue.code == null) { 1521 if (returnValue.code == null) {
1433 if (name == ':call') { 1522 if (name == ':call') {
1434 // TODO(jmesserly): reconcile this with similar code in Value 1523 // TODO(jmesserly): reconcile this with similar code in Value
1435 return target._varCall(context, node, args); 1524 return target._varCall(context, node, args);
1436 } else if (isOperator) { 1525 } else if (isOperator) {
1437 // TODO(jmesserly): make operators less special. 1526 // TODO(jmesserly): make operators less special.
1438 return invokeSpecial(target, args, returnValue.type); 1527 return invokeSpecial(target, args, returnValue.type);
1439 } else { 1528 } else {
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
1593 } 1682 }
1594 1683
1595 void forEach(void f(Member member)) { 1684 void forEach(void f(Member member)) {
1596 factories.forEach((_, Map constructors) { 1685 factories.forEach((_, Map constructors) {
1597 constructors.forEach((_, Member member) { 1686 constructors.forEach((_, Member member) {
1598 f(member); 1687 f(member);
1599 }); 1688 });
1600 }); 1689 });
1601 } 1690 }
1602 } 1691 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698