| OLD | NEW |
| 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, 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 /// Logic to build unlinked summaries. | 5 /// Logic to build unlinked summaries. |
| 6 library summary.src.summary_builder; | 6 library summary.src.summary_builder; |
| 7 | 7 |
| 8 import 'package:front_end/src/fasta/parser/class_member_parser.dart'; | 8 import 'package:front_end/src/fasta/parser/class_member_parser.dart'; |
| 9 import 'package:front_end/src/fasta/parser/identifier_context.dart'; | 9 import 'package:front_end/src/fasta/parser/identifier_context.dart'; |
| 10 import 'package:front_end/src/fasta/parser/parser.dart'; | 10 import 'package:front_end/src/fasta/parser/parser.dart'; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 35 'var': _var_flag, | 35 'var': _var_flag, |
| 36 }; | 36 }; |
| 37 | 37 |
| 38 // bit-masks to encode modifiers as bits on an int. | 38 // bit-masks to encode modifiers as bits on an int. |
| 39 | 39 |
| 40 const _star_flag = 1 << 2; | 40 const _star_flag = 1 << 2; |
| 41 | 41 |
| 42 const _static_flag = 1 << 3; | 42 const _static_flag = 1 << 3; |
| 43 const _sync_flag = 1 << 1; | 43 const _sync_flag = 1 << 1; |
| 44 const _var_flag = 0; | 44 const _var_flag = 0; |
| 45 |
| 45 /// Retrieve the operator from an assignment operator (e.g. + from +=). | 46 /// Retrieve the operator from an assignment operator (e.g. + from +=). |
| 46 /// Operators are encoded using the scanner token kind id. | 47 /// Operators are encoded using the scanner token kind id. |
| 47 int opForAssignOp(int kind) { | 48 int opForAssignOp(int kind) { |
| 48 switch (kind) { | 49 switch (kind) { |
| 49 case AMPERSAND_EQ_TOKEN: | 50 case AMPERSAND_EQ_TOKEN: |
| 50 return AMPERSAND_TOKEN; | 51 return AMPERSAND_TOKEN; |
| 51 // TODO(paulberry): add support for &&= | 52 // TODO(paulberry): add support for &&= |
| 52 // case AMPERSAND_AMPERSAND_EQ_TOKEN: return AMPERSAND_AMPERSAND_TOKEN; | 53 // case AMPERSAND_AMPERSAND_EQ_TOKEN: return AMPERSAND_AMPERSAND_TOKEN; |
| 53 case BAR_EQ_TOKEN: | 54 case BAR_EQ_TOKEN: |
| 54 return BAR_TOKEN; | 55 return BAR_TOKEN; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 73 case STAR_EQ_TOKEN: | 74 case STAR_EQ_TOKEN: |
| 74 return STAR_TOKEN; | 75 return STAR_TOKEN; |
| 75 case TILDE_SLASH_EQ_TOKEN: | 76 case TILDE_SLASH_EQ_TOKEN: |
| 76 return TILDE_SLASH_TOKEN; | 77 return TILDE_SLASH_TOKEN; |
| 77 case PLUS_EQ_TOKEN: | 78 case PLUS_EQ_TOKEN: |
| 78 return PLUS_TOKEN; | 79 return PLUS_TOKEN; |
| 79 default: | 80 default: |
| 80 throw "Unhandled kind $kind"; | 81 throw "Unhandled kind $kind"; |
| 81 } | 82 } |
| 82 } | 83 } |
| 84 |
| 83 /// Create an unlinked summary given a null-terminated byte buffer with the | 85 /// Create an unlinked summary given a null-terminated byte buffer with the |
| 84 /// contents of a file. | 86 /// contents of a file. |
| 85 UnlinkedUnit summarize(Uri uri, List<int> contents) { | 87 UnlinkedUnit summarize(Uri uri, List<int> contents) { |
| 86 var listener = new SummaryBuilder(uri); | 88 var listener = new SummaryBuilder(uri); |
| 87 var parser = new ClassMemberParser(listener); | 89 var parser = new ClassMemberParser(listener); |
| 88 parser.parseUnit(scan(contents).tokens); | 90 parser.parseUnit(scan(contents).tokens); |
| 89 return listener.topScope.unit; | 91 return listener.topScope.unit; |
| 90 } | 92 } |
| 93 |
| 91 /// Builder for constant expressions. | 94 /// Builder for constant expressions. |
| 92 /// | 95 /// |
| 93 /// Any invalid subexpression is denoted with [Invalid]. | 96 /// Any invalid subexpression is denoted with [Invalid]. |
| 94 class ConstExpressionBuilder extends ExpressionListener { | 97 class ConstExpressionBuilder extends ExpressionListener { |
| 95 final Uri uri; | 98 final Uri uri; |
| 96 Parser parser; | 99 Parser parser; |
| 97 ConstExpressionBuilder(this.uri) { | 100 ConstExpressionBuilder(this.uri) { |
| 98 parser = new Parser(this, asyncAwaitKeywordsEnabled: true); | 101 parser = new Parser(this, asyncAwaitKeywordsEnabled: true); |
| 99 } | 102 } |
| 100 bool get forConst => true; | 103 bool get forConst => true; |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 288 } | 291 } |
| 289 | 292 |
| 290 void endLiteralMapEntry(colon, token) { | 293 void endLiteralMapEntry(colon, token) { |
| 291 debugEvent('MapEntry'); | 294 debugEvent('MapEntry'); |
| 292 if (ignore) return; | 295 if (ignore) return; |
| 293 var value = pop(); | 296 var value = pop(); |
| 294 var key = pop(); | 297 var key = pop(); |
| 295 push(new KeyValuePair(key, value)); | 298 push(new KeyValuePair(key, value)); |
| 296 } | 299 } |
| 297 | 300 |
| 298 void endLiteralString(int interpolationCount) { | 301 void endLiteralString(int interpolationCount, Token endToken) { |
| 299 debugEvent("endLiteralString"); | 302 debugEvent("endLiteralString"); |
| 300 if (interpolationCount != 0) { | 303 if (interpolationCount != 0) { |
| 301 popList(2 * interpolationCount + 1); | 304 popList(2 * interpolationCount + 1); |
| 302 push(new StringLiteral("<interpolate $interpolationCount>")); | 305 push(new StringLiteral("<interpolate $interpolationCount>")); |
| 303 } | 306 } |
| 304 } | 307 } |
| 305 | 308 |
| 306 void endLiteralSymbol(token, int dots) { | 309 void endLiteralSymbol(token, int dots) { |
| 307 debugEvent('LiteralSymbol'); | 310 debugEvent('LiteralSymbol'); |
| 308 if (ignore) return; | 311 if (ignore) return; |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 463 var typeArgs = pop() ?? const <TypeRef>[]; | 466 var typeArgs = pop() ?? const <TypeRef>[]; |
| 464 // ignore: strong_mode_down_cast_composite | 467 // ignore: strong_mode_down_cast_composite |
| 465 push(new MapLiteral(typeArgs, values, constKeyword != null)); | 468 push(new MapLiteral(typeArgs, values, constKeyword != null)); |
| 466 } | 469 } |
| 467 | 470 |
| 468 void handleLiteralNull(Token token) { | 471 void handleLiteralNull(Token token) { |
| 469 debugEvent("LiteralNull"); | 472 debugEvent("LiteralNull"); |
| 470 if (ignore) return; | 473 if (ignore) return; |
| 471 push(new NullLiteral()); | 474 push(new NullLiteral()); |
| 472 } | 475 } |
| 476 |
| 473 void handleModifier(Token token) { | 477 void handleModifier(Token token) { |
| 474 debugEvent("Modifier"); | 478 debugEvent("Modifier"); |
| 475 assert(ignore); | 479 assert(ignore); |
| 476 } | 480 } |
| 477 | 481 |
| 478 // TODO(sigmund): remove | 482 // TODO(sigmund): remove |
| 479 void handleModifiers(int count) { | 483 void handleModifiers(int count) { |
| 480 debugEvent("Modifiers"); | 484 debugEvent("Modifiers"); |
| 481 assert(ignore); | 485 assert(ignore); |
| 482 } | 486 } |
| 487 |
| 483 // type-variables are the declared parameters on declarations. | 488 // type-variables are the declared parameters on declarations. |
| 484 void handleNoArguments(Token token) { | 489 void handleNoArguments(Token token) { |
| 485 debugEvent("NoArguments"); | 490 debugEvent("NoArguments"); |
| 486 if (ignore) return; | 491 if (ignore) return; |
| 487 var typeArguments = pop(); | 492 var typeArguments = pop(); |
| 488 assert(typeArguments == null); | 493 assert(typeArguments == null); |
| 489 push(NullValue.Arguments); | 494 push(NullValue.Arguments); |
| 490 } | 495 } |
| 491 | 496 |
| 492 void handleNoFormalParameters(Token token) { | 497 void handleNoFormalParameters(Token token) { |
| 493 debugEvent("NoFormalParameters"); | 498 debugEvent("NoFormalParameters"); |
| 494 assert(ignore); | 499 assert(ignore); |
| 495 } | 500 } |
| 496 | 501 |
| 497 void handleNoFunctionBody(Token token) { | 502 void handleNoFunctionBody(Token token) { |
| 498 debugEvent("NoFunctionBody"); | 503 debugEvent("NoFunctionBody"); |
| 499 assert(ignore); | 504 assert(ignore); |
| 500 } | 505 } |
| 501 | 506 |
| 502 void handleNoInitializer() {} | 507 void handleNoInitializer() {} |
| 503 | 508 |
| 504 void handleNoInitializers() { | 509 void handleNoInitializers() { |
| 505 debugEvent("NoInitializers"); | 510 debugEvent("NoInitializers"); |
| 506 assert(ignore); | 511 assert(ignore); |
| 507 } | 512 } |
| 513 |
| 508 void handleNoType(Token token) { | 514 void handleNoType(Token token) { |
| 509 debugEvent("NoType"); | 515 debugEvent("NoType"); |
| 510 if (ignore) return; | 516 if (ignore) return; |
| 511 push(NullValue.Type); | 517 push(NullValue.Type); |
| 512 } | 518 } |
| 513 | 519 |
| 514 void handleNoTypeArguments(Token token) { | 520 void handleNoTypeArguments(Token token) { |
| 515 debugEvent("NoTypeArguments"); | 521 debugEvent("NoTypeArguments"); |
| 516 if (ignore) return; | 522 if (ignore) return; |
| 517 push(NullValue.TypeArguments); | 523 push(NullValue.TypeArguments); |
| 518 } | 524 } |
| 519 | 525 |
| 520 void handleNoTypeVariables(Token token) { | 526 void handleNoTypeVariables(Token token) { |
| 521 debugEvent("NoTypeVariables"); | 527 debugEvent("NoTypeVariables"); |
| 522 if (ignore) return; | 528 if (ignore) return; |
| 523 push(_invariantCheckToken); | 529 push(_invariantCheckToken); |
| 524 } | 530 } |
| 531 |
| 525 void handleQualified(period) { | 532 void handleQualified(period) { |
| 526 debugEvent('Qualified'); | 533 debugEvent('Qualified'); |
| 527 if (ignore) return; | 534 if (ignore) return; |
| 528 Ref name = pop(); | 535 Ref name = pop(); |
| 529 Ref prefix = pop(); | 536 Ref prefix = pop(); |
| 530 assert(name.prefix == null); | 537 assert(name.prefix == null); |
| 531 assert(prefix.prefix == null); | 538 assert(prefix.prefix == null); |
| 532 push(new Ref(name.name, prefix)); | 539 push(new Ref(name.name, prefix)); |
| 533 } | 540 } |
| 534 | 541 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 586 while (current != end) { | 593 while (current != end) { |
| 587 if (!["(", ",", ")"].contains(current.value)) str.write(' '); | 594 if (!["(", ",", ")"].contains(current.value)) str.write(' '); |
| 588 str.write(current.value); | 595 str.write(current.value); |
| 589 current = current.next; | 596 current = current.next; |
| 590 } | 597 } |
| 591 print('exp: $str'); | 598 print('exp: $str'); |
| 592 } | 599 } |
| 593 | 600 |
| 594 void _unhandledSend(); | 601 void _unhandledSend(); |
| 595 } | 602 } |
| 603 |
| 596 /// Builder for initializer expressions. These expressions exclude any nested | 604 /// Builder for initializer expressions. These expressions exclude any nested |
| 597 /// expression that is not needed to infer strong mode types. | 605 /// expression that is not needed to infer strong mode types. |
| 598 class InitializerBuilder extends ExpressionListener { | 606 class InitializerBuilder extends ExpressionListener { |
| 599 final Uri uri; | 607 final Uri uri; |
| 600 Parser parser; | 608 Parser parser; |
| 601 | 609 |
| 602 int _inArguments = 0; | 610 int _inArguments = 0; |
| 603 | 611 |
| 604 InitializerBuilder(this.uri) { | 612 InitializerBuilder(this.uri) { |
| 605 parser = new Parser(this, asyncAwaitKeywordsEnabled: true); | 613 parser = new Parser(this, asyncAwaitKeywordsEnabled: true); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 657 // push(new Opaque(type: new TypeRef(new Ref('bool')))); | 665 // push(new Opaque(type: new TypeRef(new Ref('bool')))); |
| 658 } | 666 } |
| 659 | 667 |
| 660 void handleNamedArgument(colon) { | 668 void handleNamedArgument(colon) { |
| 661 debugEvent("NamedArg"); | 669 debugEvent("NamedArg"); |
| 662 if (ignore) return; | 670 if (ignore) return; |
| 663 pop(); | 671 pop(); |
| 664 pop(); | 672 pop(); |
| 665 push(NullValue.Arguments); | 673 push(NullValue.Arguments); |
| 666 } | 674 } |
| 675 |
| 667 void handleNewExpression(Token token) { | 676 void handleNewExpression(Token token) { |
| 668 debugEvent("NewExpression"); | 677 debugEvent("NewExpression"); |
| 669 if (ignore) return; | 678 if (ignore) return; |
| 670 pop(); // args | 679 pop(); // args |
| 671 /* var ctor = */ pop(); // ctor | 680 /* var ctor = */ pop(); // ctor |
| 672 throw new UnimplementedError(); // TODO(paulberry): fix the code below. | 681 throw new UnimplementedError(); // TODO(paulberry): fix the code below. |
| 673 // push(new Opaque(type: ctor.type, hint: "new")); | 682 // push(new Opaque(type: ctor.type, hint: "new")); |
| 674 } | 683 } |
| 675 | 684 |
| 676 void handleNoConstructorReferenceContinuationAfterTypeArguments(Token token) { | 685 void handleNoConstructorReferenceContinuationAfterTypeArguments(Token token) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 697 | 706 |
| 698 // TODO(paulberry): is this needed? | 707 // TODO(paulberry): is this needed? |
| 699 //void _endCascade() { | 708 //void _endCascade() { |
| 700 // push(new OpaqueOp(pop(), hint: 'cascades')); | 709 // push(new OpaqueOp(pop(), hint: 'cascades')); |
| 701 //} | 710 //} |
| 702 | 711 |
| 703 void _unhandledSend() { | 712 void _unhandledSend() { |
| 704 push(new Opaque(hint: "call")); | 713 push(new Opaque(hint: "call")); |
| 705 } | 714 } |
| 706 } | 715 } |
| 716 |
| 707 /// A listener of parser events that builds summary information as parsing | 717 /// A listener of parser events that builds summary information as parsing |
| 708 /// progresses. | 718 /// progresses. |
| 709 class SummaryBuilder extends StackListener { | 719 class SummaryBuilder extends StackListener { |
| 710 static int parsed = 0; | 720 static int parsed = 0; |
| 711 | 721 |
| 712 static int total = 0; | 722 static int total = 0; |
| 713 | 723 |
| 714 /// Whether 'dart:core' was imported explicitly by the current unit. | 724 /// Whether 'dart:core' was imported explicitly by the current unit. |
| 715 bool isDartCoreImported = false; | 725 bool isDartCoreImported = false; |
| 716 | 726 |
| (...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 986 void endFieldInitializer(Token assignmentOperator) { | 996 void endFieldInitializer(Token assignmentOperator) { |
| 987 debugEvent("FieldInitializer $typeSeen $assignmentOperator"); | 997 debugEvent("FieldInitializer $typeSeen $assignmentOperator"); |
| 988 // This is a variable initializer and it's ignored for now. May also be | 998 // This is a variable initializer and it's ignored for now. May also be |
| 989 // constructor initializer. | 999 // constructor initializer. |
| 990 var initializer = | 1000 var initializer = |
| 991 needInitializer && assignmentOperator != null ? pop() : null; | 1001 needInitializer && assignmentOperator != null ? pop() : null; |
| 992 var name = pop(); | 1002 var name = pop(); |
| 993 push(new _InitializedName( | 1003 push(new _InitializedName( |
| 994 name, new UnlinkedExecutableBuilder(bodyExpr: initializer))); | 1004 name, new UnlinkedExecutableBuilder(bodyExpr: initializer))); |
| 995 } | 1005 } |
| 1006 |
| 996 void endFields( | 1007 void endFields( |
| 997 int count, Token covariantKeyword, Token beginToken, Token endToken) { | 1008 int count, Token covariantKeyword, Token beginToken, Token endToken) { |
| 998 debugEvent("Fields"); | 1009 debugEvent("Fields"); |
| 999 var s = scope; | 1010 var s = scope; |
| 1000 if (s is ClassScope) { | 1011 if (s is ClassScope) { |
| 1001 _endFields(count, s.currentClass.fields, false); | 1012 _endFields(count, s.currentClass.fields, false); |
| 1002 } else { | 1013 } else { |
| 1003 throw new UnimplementedError(); // TODO(paulberry): does this ever occur? | 1014 throw new UnimplementedError(); // TODO(paulberry): does this ever occur? |
| 1004 // _endFields(count, s.currentEnum.values, false); | 1015 // _endFields(count, s.currentEnum.values, false); |
| 1005 } | 1016 } |
| 1006 } | 1017 } |
| 1018 |
| 1007 void endFormalParameter( | 1019 void endFormalParameter( |
| 1008 Token covariantKeyword, Token thisKeyword, FormalParameterType kind) { | 1020 Token covariantKeyword, Token thisKeyword, FormalParameterType kind) { |
| 1009 debugEvent("FormalParameter"); | 1021 debugEvent("FormalParameter"); |
| 1010 // TODO(sigmund): clean up? | 1022 // TODO(sigmund): clean up? |
| 1011 var nameOrFormal = pop(); | 1023 var nameOrFormal = pop(); |
| 1012 if (nameOrFormal is String) { | 1024 if (nameOrFormal is String) { |
| 1013 EntityRef type = pop(); | 1025 EntityRef type = pop(); |
| 1014 pop(); // Modifiers | 1026 pop(); // Modifiers |
| 1015 List metadata = pop(); | 1027 List metadata = pop(); |
| 1016 push(new UnlinkedParamBuilder( | 1028 push(new UnlinkedParamBuilder( |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1142 debugEvent("endLibraryName"); | 1154 debugEvent("endLibraryName"); |
| 1143 String name = pop(); | 1155 String name = pop(); |
| 1144 // ignore: strong_mode_down_cast_composite | 1156 // ignore: strong_mode_down_cast_composite |
| 1145 List<UnlinkedExpr> metadata = pop(); // metadata | 1157 List<UnlinkedExpr> metadata = pop(); // metadata |
| 1146 | 1158 |
| 1147 topScope.unit.libraryName = name; | 1159 topScope.unit.libraryName = name; |
| 1148 topScope.unit.libraryAnnotations = metadata; | 1160 topScope.unit.libraryAnnotations = metadata; |
| 1149 if (name == 'dart.core') isCoreLibrary = true; | 1161 if (name == 'dart.core') isCoreLibrary = true; |
| 1150 } | 1162 } |
| 1151 | 1163 |
| 1152 void endLiteralString(int count) { | 1164 void endLiteralString(int interpolationCount, Token endToken) { |
| 1153 assert(count == 0); // TODO(sigmund): handle interpolation | 1165 assert(interpolationCount == 0); // TODO(sigmund): handle interpolation |
| 1154 } | 1166 } |
| 1155 | 1167 |
| 1156 void endMember() { | 1168 void endMember() { |
| 1157 debugEvent("Member"); | 1169 debugEvent("Member"); |
| 1158 } | 1170 } |
| 1159 | 1171 |
| 1160 // TODO(sigmund): handle metadata (this code is incomplete). | 1172 // TODO(sigmund): handle metadata (this code is incomplete). |
| 1161 void endMetadata(Token beginToken, Token periodBeforeName, Token endToken) { | 1173 void endMetadata(Token beginToken, Token periodBeforeName, Token endToken) { |
| 1162 debugEvent("Metadata"); | 1174 debugEvent("Metadata"); |
| 1163 List arguments = pop(); | 1175 List arguments = pop(); |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1364 )); | 1376 )); |
| 1365 | 1377 |
| 1366 String normalizedName = getOrSet == 'set' ? '$name=' : name; | 1378 String normalizedName = getOrSet == 'set' ? '$name=' : name; |
| 1367 _addNameIfPublic( | 1379 _addNameIfPublic( |
| 1368 normalizedName, | 1380 normalizedName, |
| 1369 getOrSet != null | 1381 getOrSet != null |
| 1370 ? ReferenceKind.topLevelPropertyAccessor | 1382 ? ReferenceKind.topLevelPropertyAccessor |
| 1371 : ReferenceKind.topLevelFunction, | 1383 : ReferenceKind.topLevelFunction, |
| 1372 typeVariables?.length ?? 0 /* todo */); | 1384 typeVariables?.length ?? 0 /* todo */); |
| 1373 } | 1385 } |
| 1386 |
| 1374 void endTypeArguments(int count, Token beginToken, Token endToken) { | 1387 void endTypeArguments(int count, Token beginToken, Token endToken) { |
| 1375 debugEvent("TypeArguments"); | 1388 debugEvent("TypeArguments"); |
| 1376 push(popList(count) ?? const []); | 1389 push(popList(count) ?? const []); |
| 1377 } | 1390 } |
| 1378 | 1391 |
| 1379 void endTypeList(int count) { | 1392 void endTypeList(int count) { |
| 1380 debugEvent("TypeList"); | 1393 debugEvent("TypeList"); |
| 1381 push(popList(count) ?? NullValue.TypeList); | 1394 push(popList(count) ?? NullValue.TypeList); |
| 1382 } | 1395 } |
| 1383 | 1396 |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1576 } | 1589 } |
| 1577 | 1590 |
| 1578 /// Internal representation of an initialized name. | 1591 /// Internal representation of an initialized name. |
| 1579 class _InitializedName { | 1592 class _InitializedName { |
| 1580 final String name; | 1593 final String name; |
| 1581 final UnlinkedExecutableBuilder initializer; | 1594 final UnlinkedExecutableBuilder initializer; |
| 1582 _InitializedName(this.name, this.initializer); | 1595 _InitializedName(this.name, this.initializer); |
| 1583 | 1596 |
| 1584 toString() => "II:" + (initializer != null ? "$name = $initializer" : name); | 1597 toString() => "II:" + (initializer != null ? "$name = $initializer" : name); |
| 1585 } | 1598 } |
| OLD | NEW |