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

Side by Side Diff: pkg/compiler/lib/src/tree/nodes.dart

Issue 1151163004: Implementation of null-aware operators. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 7 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
« no previous file with comments | « pkg/compiler/lib/src/ssa/builder.dart ('k') | pkg/compiler/lib/src/tree/unparser.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 part of tree; 5 part of tree;
6 6
7 abstract class Visitor<R> { 7 abstract class Visitor<R> {
8 const Visitor(); 8 const Visitor();
9 9
10 R visitNode(Node node); 10 R visitNode(Node node);
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after
350 * A message send aka method invocation. In Dart, most operations can 350 * A message send aka method invocation. In Dart, most operations can
351 * (and should) be considered as message sends. Getters and setters 351 * (and should) be considered as message sends. Getters and setters
352 * are just methods with a special syntax. Consequently, we model 352 * are just methods with a special syntax. Consequently, we model
353 * property access, assignment, operators, and method calls with this 353 * property access, assignment, operators, and method calls with this
354 * one node. 354 * one node.
355 */ 355 */
356 class Send extends Expression with StoredTreeElementMixin { 356 class Send extends Expression with StoredTreeElementMixin {
357 final Node receiver; 357 final Node receiver;
358 final Node selector; 358 final Node selector;
359 final NodeList argumentsNode; 359 final NodeList argumentsNode;
360
361 /// Whether this is a conditinal send of the form `a?.b`.
362 final bool isConditional;
363
360 Link<Node> get arguments => argumentsNode.nodes; 364 Link<Node> get arguments => argumentsNode.nodes;
361 365
362 Send([this.receiver, this.selector, this.argumentsNode]); 366 Send([this.receiver, this.selector, this.argumentsNode,
363 Send.postfix(this.receiver, this.selector, [Node argument = null]) 367 this.isConditional = false]);
368 Send.postfix(this.receiver, this.selector,
369 [Node argument = null, this.isConditional = false])
364 : argumentsNode = (argument == null) 370 : argumentsNode = (argument == null)
365 ? new Postfix() 371 ? new Postfix()
366 : new Postfix.singleton(argument); 372 : new Postfix.singleton(argument);
367 Send.prefix(this.receiver, this.selector, [Node argument = null]) 373 Send.prefix(this.receiver, this.selector,
374 [Node argument = null, this.isConditional = false])
368 : argumentsNode = (argument == null) 375 : argumentsNode = (argument == null)
369 ? new Prefix() 376 ? new Prefix()
370 : new Prefix.singleton(argument); 377 : new Prefix.singleton(argument);
371 378
372 Send asSend() => this; 379 Send asSend() => this;
373 380
374 accept(Visitor visitor) => visitor.visitSend(this); 381 accept(Visitor visitor) => visitor.visitSend(this);
375 382
376 visitChildren(Visitor visitor) { 383 visitChildren(Visitor visitor) {
377 if (receiver != null) receiver.accept(visitor); 384 if (receiver != null) receiver.accept(visitor);
(...skipping 13 matching lines...) Expand all
391 bool get isFunctionObjectInvocation => selector == null; 398 bool get isFunctionObjectInvocation => selector == null;
392 bool get isPrefix => argumentsNode is Prefix; 399 bool get isPrefix => argumentsNode is Prefix;
393 bool get isPostfix => argumentsNode is Postfix; 400 bool get isPostfix => argumentsNode is Postfix;
394 bool get isCall => !isOperator && !isPropertyAccess; 401 bool get isCall => !isOperator && !isPropertyAccess;
395 bool get isIndex => 402 bool get isIndex =>
396 isOperator && identical(selector.asOperator().source, '[]'); 403 isOperator && identical(selector.asOperator().source, '[]');
397 bool get isLogicalAnd => 404 bool get isLogicalAnd =>
398 isOperator && identical(selector.asOperator().source, '&&'); 405 isOperator && identical(selector.asOperator().source, '&&');
399 bool get isLogicalOr => 406 bool get isLogicalOr =>
400 isOperator && identical(selector.asOperator().source, '||'); 407 isOperator && identical(selector.asOperator().source, '||');
408 bool get isIfNull =>
409 isOperator && identical(selector.asOperator().source, '??');
401 410
402 bool get isTypeCast { 411 bool get isTypeCast {
403 return isOperator 412 return isOperator
404 && identical(selector.asOperator().source, 'as'); 413 && identical(selector.asOperator().source, 'as');
405 } 414 }
406 415
407 bool get isTypeTest { 416 bool get isTypeTest {
408 return isOperator 417 return isOperator
409 && identical(selector.asOperator().source, 'is'); 418 && identical(selector.asOperator().source, 'is');
410 } 419 }
(...skipping 23 matching lines...) Expand all
434 return null; 443 return null;
435 } 444 }
436 if (!isPostfix && argumentsNode != null) { 445 if (!isPostfix && argumentsNode != null) {
437 Token token = argumentsNode.getEndToken(); 446 Token token = argumentsNode.getEndToken();
438 if (token != null) return token; 447 if (token != null) return token;
439 } 448 }
440 if (selector != null) return selector.getEndToken(); 449 if (selector != null) return selector.getEndToken();
441 return getBeginToken(); 450 return getBeginToken();
442 } 451 }
443 452
444 Send copyWithReceiver(Node newReceiver) { 453 Send copyWithReceiver(Node newReceiver, bool isConditional) {
445 assert(receiver == null); 454 assert(receiver == null);
446 return new Send(newReceiver, selector, argumentsNode); 455 return new Send(newReceiver, selector, argumentsNode, isConditional);
447 } 456 }
448 } 457 }
449 458
450 class Postfix extends NodeList { 459 class Postfix extends NodeList {
451 Postfix() : super(null, const Link<Node>()); 460 Postfix() : super(null, const Link<Node>());
452 Postfix.singleton(Node argument) : super.singleton(argument); 461 Postfix.singleton(Node argument) : super.singleton(argument);
453 } 462 }
454 463
455 class Prefix extends NodeList { 464 class Prefix extends NodeList {
456 Prefix() : super(null, const Link<Node>()); 465 Prefix() : super(null, const Link<Node>());
457 Prefix.singleton(Node argument) : super.singleton(argument); 466 Prefix.singleton(Node argument) : super.singleton(argument);
458 } 467 }
459 468
460 class SendSet extends Send { 469 class SendSet extends Send {
461 final Operator assignmentOperator; 470 final Operator assignmentOperator;
462 SendSet(receiver, selector, this.assignmentOperator, argumentsNode) 471 SendSet(receiver, selector, this.assignmentOperator, argumentsNode,
463 : super(receiver, selector, argumentsNode); 472 [bool isConditional = false])
473 : super(receiver, selector, argumentsNode, isConditional);
464 SendSet.postfix(receiver, 474 SendSet.postfix(receiver,
465 selector, 475 selector,
466 this.assignmentOperator, 476 this.assignmentOperator,
467 [Node argument = null]) 477 [Node argument = null, bool isConditional = false])
468 : super.postfix(receiver, selector, argument); 478 : super.postfix(receiver, selector, argument, isConditional);
469 SendSet.prefix(receiver, 479 SendSet.prefix(receiver,
470 selector, 480 selector,
471 this.assignmentOperator, 481 this.assignmentOperator,
472 [Node argument = null]) 482 [Node argument = null, bool isConditional = false])
473 : super.prefix(receiver, selector, argument); 483 : super.prefix(receiver, selector, argument, isConditional);
474 484
475 SendSet asSendSet() => this; 485 SendSet asSendSet() => this;
476 486
477 accept(Visitor visitor) => visitor.visitSendSet(this); 487 accept(Visitor visitor) => visitor.visitSendSet(this);
478 488
489 /// Whether this is an if-null assignment of the form `a ??= b`.
490 bool get isIfNullAssignment =>
491 identical(assignmentOperator.source, '??=');
492
479 visitChildren(Visitor visitor) { 493 visitChildren(Visitor visitor) {
480 super.visitChildren(visitor); 494 super.visitChildren(visitor);
481 if (assignmentOperator != null) assignmentOperator.accept(visitor); 495 if (assignmentOperator != null) assignmentOperator.accept(visitor);
482 } 496 }
483 497
484 Send copyWithReceiver(Node newReceiver) { 498 Send copyWithReceiver(Node newReceiver, bool isConditional) {
485 assert(receiver == null); 499 assert(receiver == null);
486 return new SendSet(newReceiver, selector, assignmentOperator, 500 return new SendSet(newReceiver, selector, assignmentOperator,
487 argumentsNode); 501 argumentsNode, isConditional);
488 } 502 }
489 503
490 Token getBeginToken() { 504 Token getBeginToken() {
491 if (isPrefix) return assignmentOperator.getBeginToken(); 505 if (isPrefix) return assignmentOperator.getBeginToken();
492 return super.getBeginToken(); 506 return super.getBeginToken();
493 } 507 }
494 508
495 Token getEndToken() { 509 Token getEndToken() {
496 if (isPostfix) return assignmentOperator.getEndToken(); 510 if (isPostfix) return assignmentOperator.getEndToken();
497 return super.getEndToken(); 511 return super.getEndToken();
(...skipping 542 matching lines...) Expand 10 before | Expand all | Expand 10 after
1040 visitChildren(Visitor visitor) {} 1054 visitChildren(Visitor visitor) {}
1041 1055
1042 Token getBeginToken() => token; 1056 Token getBeginToken() => token;
1043 1057
1044 Token getEndToken() => token; 1058 Token getEndToken() => token;
1045 } 1059 }
1046 1060
1047 class Operator extends Identifier { 1061 class Operator extends Identifier {
1048 static const COMPLEX_OPERATORS = 1062 static const COMPLEX_OPERATORS =
1049 const ["--", "++", '+=', "-=", "*=", "/=", "%=", "&=", "|=", "~/=", "^=", 1063 const ["--", "++", '+=', "-=", "*=", "/=", "%=", "&=", "|=", "~/=", "^=",
1050 ">>=", "<<="]; 1064 ">>=", "<<=", "??="];
1051 1065
1052 static const INCREMENT_OPERATORS = const <String>["++", "--"]; 1066 static const INCREMENT_OPERATORS = const <String>["++", "--"];
1053 1067
1054 Operator(Token token) : super(token); 1068 Operator(Token token) : super(token);
1055 1069
1056 Operator asOperator() => this; 1070 Operator asOperator() => this;
1057 1071
1058 accept(Visitor visitor) => visitor.visitOperator(this); 1072 accept(Visitor visitor) => visitor.visitOperator(this);
1059 } 1073 }
1060 1074
(...skipping 1182 matching lines...) Expand 10 before | Expand all | Expand 10 after
2243 Token getBeginToken() => token; 2257 Token getBeginToken() => token;
2244 2258
2245 Token getEndToken() => expression.getEndToken(); 2259 Token getEndToken() => expression.getEndToken();
2246 } 2260 }
2247 2261
2248 class Initializers { 2262 class Initializers {
2249 static bool isSuperConstructorCall(Send node) { 2263 static bool isSuperConstructorCall(Send node) {
2250 return (node.receiver == null && node.selector.isSuper()) || 2264 return (node.receiver == null && node.selector.isSuper()) ||
2251 (node.receiver != null && 2265 (node.receiver != null &&
2252 node.receiver.isSuper() && 2266 node.receiver.isSuper() &&
2267 !node.isConditional &&
2253 node.selector.asIdentifier() != null); 2268 node.selector.asIdentifier() != null);
2254 } 2269 }
2255 2270
2256 static bool isConstructorRedirect(Send node) { 2271 static bool isConstructorRedirect(Send node) {
2257 return (node.receiver == null && node.selector.isThis()) || 2272 return (node.receiver == null && node.selector.isThis()) ||
2258 (node.receiver != null && 2273 (node.receiver != null &&
2259 node.receiver.isThis() && 2274 node.receiver.isThis() &&
2275 !node.isConditional &&
2260 node.selector.asIdentifier() != null); 2276 node.selector.asIdentifier() != null);
2261 } 2277 }
2262 } 2278 }
2263 2279
2264 class GetDartStringVisitor extends Visitor<DartString> { 2280 class GetDartStringVisitor extends Visitor<DartString> {
2265 const GetDartStringVisitor(); 2281 const GetDartStringVisitor();
2266 DartString visitNode(Node node) => null; 2282 DartString visitNode(Node node) => null;
2267 DartString visitStringJuxtaposition(StringJuxtaposition node) 2283 DartString visitStringJuxtaposition(StringJuxtaposition node)
2268 => node.dartString; 2284 => node.dartString;
2269 DartString visitLiteralString(LiteralString node) => node.dartString; 2285 DartString visitLiteralString(LiteralString node) => node.dartString;
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
2324 2340
2325 // VariableDefinitions. 2341 // VariableDefinitions.
2326 get metadata => null; 2342 get metadata => null;
2327 get type => null; 2343 get type => null;
2328 2344
2329 // Typedef. 2345 // Typedef.
2330 get typeParameters => null; 2346 get typeParameters => null;
2331 get formals => null; 2347 get formals => null;
2332 get typedefKeyword => null; 2348 get typedefKeyword => null;
2333 } 2349 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/ssa/builder.dart ('k') | pkg/compiler/lib/src/tree/unparser.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698