| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |