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

Side by Side Diff: pkg/analyzer/lib/src/summary/summarize_ast.dart

Issue 2017613003: Refactor AST summarization logic for serializing initializer expressions. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 6 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 | « no previous file | no next file » | 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) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, 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 library serialization.summarize_ast; 5 library serialization.summarize_ast;
6 6
7 import 'package:analyzer/dart/ast/ast.dart'; 7 import 'package:analyzer/dart/ast/ast.dart';
8 import 'package:analyzer/dart/ast/token.dart'; 8 import 'package:analyzer/dart/ast/token.dart';
9 import 'package:analyzer/dart/ast/visitor.dart'; 9 import 'package:analyzer/dart/ast/visitor.dart';
10 import 'package:analyzer/dart/element/type.dart' show DartType; 10 import 'package:analyzer/dart/element/type.dart' show DartType;
(...skipping 625 matching lines...) Expand 10 before | Expand all | Expand 10 after
636 } 636 }
637 } 637 }
638 b.documentationComment = serializeDocumentation(documentationComment); 638 b.documentationComment = serializeDocumentation(documentationComment);
639 b.annotations = serializeAnnotations(annotations); 639 b.annotations = serializeAnnotations(annotations);
640 b.codeRange = serializeCodeRange(node); 640 b.codeRange = serializeCodeRange(node);
641 if (returnType == null && !isSemanticallyStatic) { 641 if (returnType == null && !isSemanticallyStatic) {
642 b.inferredReturnTypeSlot = assignSlot(); 642 b.inferredReturnTypeSlot = assignSlot();
643 } 643 }
644 b.visibleOffset = enclosingBlock?.offset; 644 b.visibleOffset = enclosingBlock?.offset;
645 b.visibleLength = enclosingBlock?.length; 645 b.visibleLength = enclosingBlock?.length;
646 serializeFunctionBody(b, null, body); 646 serializeFunctionBody(b, null, body, false);
647 scopes.removeLast(); 647 scopes.removeLast();
648 assert(scopes.length == oldScopesLength); 648 assert(scopes.length == oldScopesLength);
649 return b; 649 return b;
650 } 650 }
651 651
652 /** 652 /**
653 * Record local functions and variables into the given executable. The given 653 * Record local functions and variables into the given executable. The given
654 * [body] is usually an actual [FunctionBody], but may be an [Expression] 654 * [body] is usually an actual [FunctionBody], but may be an [Expression]
655 * when we process a synthetic variable initializer function. 655 * when we process a synthetic variable initializer function.
656 * 656 *
657 * If [initializers] is non-`null`, closures occurring inside the initializers 657 * If [initializers] is non-`null`, closures occurring inside the initializers
658 * are serialized first. 658 * are serialized first.
659 *
660 * If [serializeBodyExpr] is `true`, then the function definition is stored
661 * in [UnlinkedExecutableBuilder.bodyExpr].
662 *
663 * The return value is a map whose keys are the offsets of local function
664 * nodes representing closures inside [initializers] and [body], and whose
665 * values are the indices of those local functions relative to their siblings.
659 */ 666 */
660 void serializeFunctionBody(UnlinkedExecutableBuilder b, 667 Map<int, int> serializeFunctionBody(
661 List<ConstructorInitializer> initializers, AstNode body) { 668 UnlinkedExecutableBuilder b,
669 List<ConstructorInitializer> initializers,
670 AstNode body,
671 bool serializeBodyExpr) {
662 if (body is BlockFunctionBody || body is ExpressionFunctionBody) { 672 if (body is BlockFunctionBody || body is ExpressionFunctionBody) {
663 for (UnlinkedParamBuilder parameter in b.parameters) { 673 for (UnlinkedParamBuilder parameter in b.parameters) {
664 parameter.visibleOffset = body.offset; 674 parameter.visibleOffset = body.offset;
665 parameter.visibleLength = body.length; 675 parameter.visibleLength = body.length;
666 } 676 }
667 } 677 }
668 List<UnlinkedExecutableBuilder> oldExecutables = executables; 678 List<UnlinkedExecutableBuilder> oldExecutables = executables;
669 List<UnlinkedLabelBuilder> oldLabels = labels; 679 List<UnlinkedLabelBuilder> oldLabels = labels;
670 List<UnlinkedVariableBuilder> oldVariables = variables; 680 List<UnlinkedVariableBuilder> oldVariables = variables;
681 Map<int, int> oldLocalClosureIndexMap = _localClosureIndexMap;
671 executables = <UnlinkedExecutableBuilder>[]; 682 executables = <UnlinkedExecutableBuilder>[];
672 labels = <UnlinkedLabelBuilder>[]; 683 labels = <UnlinkedLabelBuilder>[];
673 variables = <UnlinkedVariableBuilder>[]; 684 variables = <UnlinkedVariableBuilder>[];
685 _localClosureIndexMap = <int, int>{};
674 if (initializers != null) { 686 if (initializers != null) {
675 for (ConstructorInitializer initializer in initializers) { 687 for (ConstructorInitializer initializer in initializers) {
676 initializer.accept(this); 688 initializer.accept(this);
677 } 689 }
678 } 690 }
679 body.accept(this); 691 body.accept(this);
692 if (serializeBodyExpr) {
693 if (body is Expression) {
694 b.bodyExpr = serializeConstExpr(_localClosureIndexMap, body);
695 } else {
696 // TODO(paulberry): serialize other types of function bodies.
697 }
698 }
680 b.localFunctions = executables; 699 b.localFunctions = executables;
681 b.localLabels = labels; 700 b.localLabels = labels;
682 b.localVariables = variables; 701 b.localVariables = variables;
702 Map<int, int> localClosureIndexMap = _localClosureIndexMap;
683 executables = oldExecutables; 703 executables = oldExecutables;
684 labels = oldLabels; 704 labels = oldLabels;
685 variables = oldVariables; 705 variables = oldVariables;
706 _localClosureIndexMap = oldLocalClosureIndexMap;
707 return localClosureIndexMap;
686 } 708 }
687 709
688 /** 710 /**
689 * Serialize the return type and parameters of a function-typed formal 711 * Serialize the return type and parameters of a function-typed formal
690 * parameter and store them in [b]. 712 * parameter and store them in [b].
691 */ 713 */
692 void serializeFunctionTypedParameterDetails(UnlinkedParamBuilder b, 714 void serializeFunctionTypedParameterDetails(UnlinkedParamBuilder b,
693 TypeName returnType, FormalParameterList parameters) { 715 TypeName returnType, FormalParameterList parameters) {
694 EntityRefBuilder serializedReturnType = serializeTypeName(returnType); 716 EntityRefBuilder serializedReturnType = serializeTypeName(returnType);
695 if (serializedReturnType != null) { 717 if (serializedReturnType != null) {
696 b.type = serializedReturnType; 718 b.type = serializedReturnType;
697 } 719 }
698 b.parameters = parameters.parameters 720 b.parameters = parameters.parameters
699 .map((FormalParameter p) => p.accept(this)) 721 .map((FormalParameter p) => p.accept(this))
700 .toList(); 722 .toList();
701 } 723 }
702 724
703 /** 725 /**
704 * If the given [expression] is not `null`, serialize it as an 726 * If the given [expression] is not `null`, serialize it as an
705 * [UnlinkedExecutableBuilder], otherwise return `null`. 727 * [UnlinkedExecutableBuilder], otherwise return `null`.
728 *
729 * If [serializeBodyExpr] is `true`, then the initializer expression is stored
730 * in [UnlinkedExecutableBuilder.bodyExpr].
706 */ 731 */
707 UnlinkedExecutableBuilder serializeInitializerFunction( 732 UnlinkedExecutableBuilder serializeInitializerFunction(
708 Expression expression) { 733 Expression expression, bool serializeBodyExpr) {
709 if (expression == null) { 734 if (expression == null) {
710 return null; 735 return null;
711 } 736 }
712 UnlinkedExecutableBuilder initializer = 737 UnlinkedExecutableBuilder initializer =
713 new UnlinkedExecutableBuilder(nameOffset: expression.offset); 738 new UnlinkedExecutableBuilder(nameOffset: expression.offset);
714 serializeFunctionBody(initializer, null, expression); 739 serializeFunctionBody(initializer, null, expression, serializeBodyExpr);
715 initializer.inferredReturnTypeSlot = assignSlot(); 740 initializer.inferredReturnTypeSlot = assignSlot();
716 return initializer; 741 return initializer;
717 } 742 }
718 743
719 /** 744 /**
720 * Serialize a [FieldFormalParameter], [FunctionTypedFormalParameter], or 745 * Serialize a [FieldFormalParameter], [FunctionTypedFormalParameter], or
721 * [SimpleFormalParameter] into an [UnlinkedParam]. 746 * [SimpleFormalParameter] into an [UnlinkedParam].
722 */ 747 */
723 UnlinkedParamBuilder serializeParameter(NormalFormalParameter node) { 748 UnlinkedParamBuilder serializeParameter(NormalFormalParameter node) {
724 UnlinkedParamBuilder b = new UnlinkedParamBuilder(); 749 UnlinkedParamBuilder b = new UnlinkedParamBuilder();
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
886 UnlinkedVariableBuilder b = new UnlinkedVariableBuilder(); 911 UnlinkedVariableBuilder b = new UnlinkedVariableBuilder();
887 b.isFinal = variables.isFinal; 912 b.isFinal = variables.isFinal;
888 b.isConst = variables.isConst; 913 b.isConst = variables.isConst;
889 b.isStatic = isDeclaredStatic; 914 b.isStatic = isDeclaredStatic;
890 b.name = variable.name.name; 915 b.name = variable.name.name;
891 b.nameOffset = variable.name.offset; 916 b.nameOffset = variable.name.offset;
892 b.type = serializeTypeName(variables.type); 917 b.type = serializeTypeName(variables.type);
893 b.documentationComment = serializeDocumentation(documentationComment); 918 b.documentationComment = serializeDocumentation(documentationComment);
894 b.annotations = serializeAnnotations(annotations); 919 b.annotations = serializeAnnotations(annotations);
895 b.codeRange = serializeCodeRange(variables.parent); 920 b.codeRange = serializeCodeRange(variables.parent);
896 Map<int, int> localClosureIndexMap = _withLocalClosureIndexMap(() { 921 bool serializeBodyExpr = variable.isConst ||
897 b.initializer = serializeInitializerFunction(variable.initializer);
898 });
899 if (variable.isConst ||
900 variable.isFinal && isField && !isDeclaredStatic || 922 variable.isFinal && isField && !isDeclaredStatic ||
901 variables.type == null) { 923 variables.type == null;
902 Expression initializer = variable.initializer; 924 b.initializer =
903 if (initializer != null) { 925 serializeInitializerFunction(variable.initializer, serializeBodyExpr);
904 b.initializer.bodyExpr =
905 serializeConstExpr(localClosureIndexMap, initializer);
906 }
907 }
908 if (variable.initializer != null && 926 if (variable.initializer != null &&
909 (variables.isFinal || variables.isConst)) { 927 (variables.isFinal || variables.isConst)) {
910 b.propagatedTypeSlot = assignSlot(); 928 b.propagatedTypeSlot = assignSlot();
911 } 929 }
912 bool isSemanticallyStatic = !isField || isDeclaredStatic; 930 bool isSemanticallyStatic = !isField || isDeclaredStatic;
913 if (variables.type == null && 931 if (variables.type == null &&
914 (variable.initializer != null || !isSemanticallyStatic)) { 932 (variable.initializer != null || !isSemanticallyStatic)) {
915 b.inferredTypeSlot = assignSlot(); 933 b.inferredTypeSlot = assignSlot();
916 } 934 }
917 b.visibleOffset = scopeNode?.offset; 935 b.visibleOffset = scopeNode?.offset;
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
1016 } 1034 }
1017 } 1035 }
1018 if (node.constKeyword != null) { 1036 if (node.constKeyword != null) {
1019 b.isConst = true; 1037 b.isConst = true;
1020 b.constCycleSlot = assignSlot(); 1038 b.constCycleSlot = assignSlot();
1021 } 1039 }
1022 b.isExternal = node.externalKeyword != null; 1040 b.isExternal = node.externalKeyword != null;
1023 b.documentationComment = serializeDocumentation(node.documentationComment); 1041 b.documentationComment = serializeDocumentation(node.documentationComment);
1024 b.annotations = serializeAnnotations(node.metadata); 1042 b.annotations = serializeAnnotations(node.metadata);
1025 b.codeRange = serializeCodeRange(node); 1043 b.codeRange = serializeCodeRange(node);
1026 Map<int, int> localClosureIndexMap = _withLocalClosureIndexMap(() { 1044 Map<int, int> localClosureIndexMap = serializeFunctionBody(
1027 serializeFunctionBody(b, node.initializers, node.body); 1045 b, node.initializers, node.body, node.constKeyword != null);
1028 });
1029 if (node.constKeyword != null) { 1046 if (node.constKeyword != null) {
1030 Set<String> constructorParameterNames = 1047 Set<String> constructorParameterNames =
1031 node.parameters.parameters.map((p) => p.identifier.name).toSet(); 1048 node.parameters.parameters.map((p) => p.identifier.name).toSet();
1032 b.constantInitializers = node.initializers 1049 b.constantInitializers = node.initializers
1033 .map((ConstructorInitializer initializer) => 1050 .map((ConstructorInitializer initializer) =>
1034 serializeConstructorInitializer(initializer, (Expression expr) { 1051 serializeConstructorInitializer(initializer, (Expression expr) {
1035 return serializeConstExpr( 1052 return serializeConstExpr(
1036 localClosureIndexMap, expr, constructorParameterNames); 1053 localClosureIndexMap, expr, constructorParameterNames);
1037 })) 1054 }))
1038 .toList(); 1055 .toList();
1039 } 1056 }
1040 executables.add(b); 1057 executables.add(b);
1041 } 1058 }
1042 1059
1043 @override 1060 @override
1044 UnlinkedParamBuilder visitDefaultFormalParameter( 1061 UnlinkedParamBuilder visitDefaultFormalParameter(
1045 DefaultFormalParameter node) { 1062 DefaultFormalParameter node) {
1046 UnlinkedParamBuilder b = node.parameter.accept(this); 1063 UnlinkedParamBuilder b = node.parameter.accept(this);
1047 b.initializer = serializeInitializerFunction(node.defaultValue); 1064 b.initializer = serializeInitializerFunction(node.defaultValue, true);
1048 if (node.defaultValue != null) { 1065 if (node.defaultValue != null) {
1049 // Closures can't appear inside default values, so we don't need a
1050 // localClosureIndexMap.
1051 Map<int, int> localClosureIndexMap = null;
1052 b.initializer?.bodyExpr =
1053 serializeConstExpr(localClosureIndexMap, node.defaultValue);
1054 b.defaultValueCode = node.defaultValue.toSource(); 1066 b.defaultValueCode = node.defaultValue.toSource();
1055 } 1067 }
1056 b.codeRange = serializeCodeRange(node); 1068 b.codeRange = serializeCodeRange(node);
1057 return b; 1069 return b;
1058 } 1070 }
1059 1071
1060 @override 1072 @override
1061 void visitEnumDeclaration(EnumDeclaration node) { 1073 void visitEnumDeclaration(EnumDeclaration node) {
1062 UnlinkedEnumBuilder b = new UnlinkedEnumBuilder(); 1074 UnlinkedEnumBuilder b = new UnlinkedEnumBuilder();
1063 b.name = node.name.name; 1075 b.name = node.name.name;
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
1310 return b; 1322 return b;
1311 } 1323 }
1312 1324
1313 @override 1325 @override
1314 void visitVariableDeclarationStatement(VariableDeclarationStatement node) { 1326 void visitVariableDeclarationStatement(VariableDeclarationStatement node) {
1315 serializeVariables( 1327 serializeVariables(
1316 enclosingBlock, node.variables, false, null, null, false); 1328 enclosingBlock, node.variables, false, null, null, false);
1317 } 1329 }
1318 1330
1319 /** 1331 /**
1320 * Execute [callback], gathering any local closures in
1321 * [_localClosureIndexMap], and return the resulting map.
1322 *
1323 * Properly handles cases where one closure is nested within another.
1324 */
1325 Map<int, int> _withLocalClosureIndexMap(void callback()) {
1326 Map<int, int> prevLocalClosureIndexMap = _localClosureIndexMap;
1327 _localClosureIndexMap = <int, int>{};
1328 callback();
1329 Map<int, int> localClosureIndexMap = _localClosureIndexMap;
1330 _localClosureIndexMap = prevLocalClosureIndexMap;
1331 return localClosureIndexMap;
1332 }
1333
1334 /**
1335 * Helper method to determine if a given [typeName] refers to `dynamic`. 1332 * Helper method to determine if a given [typeName] refers to `dynamic`.
1336 */ 1333 */
1337 static bool isDynamic(TypeName typeName) { 1334 static bool isDynamic(TypeName typeName) {
1338 Identifier name = typeName.name; 1335 Identifier name = typeName.name;
1339 return name is SimpleIdentifier && name.name == 'dynamic'; 1336 return name is SimpleIdentifier && name.name == 'dynamic';
1340 } 1337 }
1341 } 1338 }
1342 1339
1343 /** 1340 /**
1344 * A [_TypeParameterScope] is a [_Scope] which defines [_ScopedTypeParameter]s. 1341 * A [_TypeParameterScope] is a [_Scope] which defines [_ScopedTypeParameter]s.
1345 */ 1342 */
1346 class _TypeParameterScope extends _Scope { 1343 class _TypeParameterScope extends _Scope {
1347 /** 1344 /**
1348 * Get the number of [_ScopedTypeParameter]s defined in this 1345 * Get the number of [_ScopedTypeParameter]s defined in this
1349 * [_TypeParameterScope]. 1346 * [_TypeParameterScope].
1350 */ 1347 */
1351 int get length => _definedNames.length; 1348 int get length => _definedNames.length;
1352 } 1349 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698