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

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

Issue 1968063002: Handle more corner cases of closures while doing ast-based summaries. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 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 | « no previous file | pkg/analyzer/test/src/summary/resynthesize_ast_test.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) 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 370 matching lines...) Expand 10 before | Expand all | Expand 10 after
381 /** 381 /**
382 * Serialize the given list of [annotations]. If there are no annotations, 382 * Serialize the given list of [annotations]. If there are no annotations,
383 * the empty list is returned. 383 * the empty list is returned.
384 */ 384 */
385 List<UnlinkedConstBuilder> serializeAnnotations( 385 List<UnlinkedConstBuilder> serializeAnnotations(
386 NodeList<Annotation> annotations) { 386 NodeList<Annotation> annotations) {
387 if (annotations == null || annotations.isEmpty) { 387 if (annotations == null || annotations.isEmpty) {
388 return const <UnlinkedConstBuilder>[]; 388 return const <UnlinkedConstBuilder>[];
389 } 389 }
390 return annotations.map((Annotation a) { 390 return annotations.map((Annotation a) {
391 Map<int, int> localClosureIndexMap = null; // TODO(paulberry): fix. 391 // Closures can't appear inside annotations, so we don't need a
392 // localClosureIndexMap.
393 Map<int, int> localClosureIndexMap = null;
392 _ConstExprSerializer serializer = 394 _ConstExprSerializer serializer =
393 new _ConstExprSerializer(this, localClosureIndexMap, null); 395 new _ConstExprSerializer(this, localClosureIndexMap, null);
394 serializer.serializeAnnotation(a); 396 serializer.serializeAnnotation(a);
395 return serializer.toBuilder(); 397 return serializer.toBuilder();
396 }).toList(); 398 }).toList();
397 } 399 }
398 400
399 /** 401 /**
400 * Serialize a [ClassDeclaration] or [ClassTypeAlias] into an [UnlinkedClass] 402 * Serialize a [ClassDeclaration] or [ClassTypeAlias] into an [UnlinkedClass]
401 * and store the result in [classes]. 403 * and store the result in [classes].
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
634 } 636 }
635 } 637 }
636 b.documentationComment = serializeDocumentation(documentationComment); 638 b.documentationComment = serializeDocumentation(documentationComment);
637 b.annotations = serializeAnnotations(annotations); 639 b.annotations = serializeAnnotations(annotations);
638 b.codeRange = serializeCodeRange(node); 640 b.codeRange = serializeCodeRange(node);
639 if (returnType == null && !isSemanticallyStatic) { 641 if (returnType == null && !isSemanticallyStatic) {
640 b.inferredReturnTypeSlot = assignSlot(); 642 b.inferredReturnTypeSlot = assignSlot();
641 } 643 }
642 b.visibleOffset = enclosingBlock?.offset; 644 b.visibleOffset = enclosingBlock?.offset;
643 b.visibleLength = enclosingBlock?.length; 645 b.visibleLength = enclosingBlock?.length;
644 serializeFunctionBody(b, body); 646 serializeFunctionBody(b, null, body);
645 scopes.removeLast(); 647 scopes.removeLast();
646 assert(scopes.length == oldScopesLength); 648 assert(scopes.length == oldScopesLength);
647 return b; 649 return b;
648 } 650 }
649 651
650 /** 652 /**
651 * Record local functions and variables into the given executable. The given 653 * Record local functions and variables into the given executable. The given
652 * [body] is usually an actual [FunctionBody], but may be an [Expression] 654 * [body] is usually an actual [FunctionBody], but may be an [Expression]
653 * when we process a synthetic variable initializer function. 655 * when we process a synthetic variable initializer function.
656 *
657 * If [initializers] is non-`null`, closures occurring inside the initializers
658 * are serialized first.
654 */ 659 */
655 void serializeFunctionBody(UnlinkedExecutableBuilder b, AstNode body) { 660 void serializeFunctionBody(UnlinkedExecutableBuilder b,
661 List<ConstructorInitializer> initializers, AstNode body) {
656 if (body is BlockFunctionBody || body is ExpressionFunctionBody) { 662 if (body is BlockFunctionBody || body is ExpressionFunctionBody) {
657 for (UnlinkedParamBuilder parameter in b.parameters) { 663 for (UnlinkedParamBuilder parameter in b.parameters) {
658 parameter.visibleOffset = body.offset; 664 parameter.visibleOffset = body.offset;
659 parameter.visibleLength = body.length; 665 parameter.visibleLength = body.length;
660 } 666 }
661 } 667 }
662 List<UnlinkedExecutableBuilder> oldExecutables = executables; 668 List<UnlinkedExecutableBuilder> oldExecutables = executables;
663 List<UnlinkedLabelBuilder> oldLabels = labels; 669 List<UnlinkedLabelBuilder> oldLabels = labels;
664 List<UnlinkedVariableBuilder> oldVariables = variables; 670 List<UnlinkedVariableBuilder> oldVariables = variables;
665 executables = <UnlinkedExecutableBuilder>[]; 671 executables = <UnlinkedExecutableBuilder>[];
666 labels = <UnlinkedLabelBuilder>[]; 672 labels = <UnlinkedLabelBuilder>[];
667 variables = <UnlinkedVariableBuilder>[]; 673 variables = <UnlinkedVariableBuilder>[];
674 if (initializers != null) {
675 for (ConstructorInitializer initializer in initializers) {
676 initializer.accept(this);
677 }
678 }
668 body.accept(this); 679 body.accept(this);
669 b.localFunctions = executables; 680 b.localFunctions = executables;
670 b.localLabels = labels; 681 b.localLabels = labels;
671 b.localVariables = variables; 682 b.localVariables = variables;
672 executables = oldExecutables; 683 executables = oldExecutables;
673 labels = oldLabels; 684 labels = oldLabels;
674 variables = oldVariables; 685 variables = oldVariables;
675 } 686 }
676 687
677 /** 688 /**
(...skipping 15 matching lines...) Expand all
693 * If the given [expression] is not `null`, serialize it as an 704 * If the given [expression] is not `null`, serialize it as an
694 * [UnlinkedExecutableBuilder], otherwise return `null`. 705 * [UnlinkedExecutableBuilder], otherwise return `null`.
695 */ 706 */
696 UnlinkedExecutableBuilder serializeInitializerFunction( 707 UnlinkedExecutableBuilder serializeInitializerFunction(
697 Expression expression) { 708 Expression expression) {
698 if (expression == null) { 709 if (expression == null) {
699 return null; 710 return null;
700 } 711 }
701 UnlinkedExecutableBuilder initializer = 712 UnlinkedExecutableBuilder initializer =
702 new UnlinkedExecutableBuilder(nameOffset: expression.offset); 713 new UnlinkedExecutableBuilder(nameOffset: expression.offset);
703 serializeFunctionBody(initializer, expression); 714 serializeFunctionBody(initializer, null, expression);
704 initializer.inferredReturnTypeSlot = assignSlot(); 715 initializer.inferredReturnTypeSlot = assignSlot();
705 return initializer; 716 return initializer;
706 } 717 }
707 718
708 /** 719 /**
709 * Serialize a [FieldFormalParameter], [FunctionTypedFormalParameter], or 720 * Serialize a [FieldFormalParameter], [FunctionTypedFormalParameter], or
710 * [SimpleFormalParameter] into an [UnlinkedParam]. 721 * [SimpleFormalParameter] into an [UnlinkedParam].
711 */ 722 */
712 UnlinkedParamBuilder serializeParameter(NormalFormalParameter node) { 723 UnlinkedParamBuilder serializeParameter(NormalFormalParameter node) {
713 UnlinkedParamBuilder b = new UnlinkedParamBuilder(); 724 UnlinkedParamBuilder b = new UnlinkedParamBuilder();
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after
980 } 991 }
981 b.parameters = node.parameters.parameters 992 b.parameters = node.parameters.parameters
982 .map((FormalParameter p) => p.accept(this)) 993 .map((FormalParameter p) => p.accept(this))
983 .toList(); 994 .toList();
984 b.kind = UnlinkedExecutableKind.constructor; 995 b.kind = UnlinkedExecutableKind.constructor;
985 if (node.factoryKeyword != null) { 996 if (node.factoryKeyword != null) {
986 b.isFactory = true; 997 b.isFactory = true;
987 if (node.redirectedConstructor != null) { 998 if (node.redirectedConstructor != null) {
988 b.isRedirectedConstructor = true; 999 b.isRedirectedConstructor = true;
989 TypeName typeName = node.redirectedConstructor.type; 1000 TypeName typeName = node.redirectedConstructor.type;
990 Map<int, int> localClosureIndexMap = null; // TODO(paulberry): fix. 1001 // Closures can't appear inside factory constructor redirections, so we
1002 // don't need a localClosureIndexMap.
1003 Map<int, int> localClosureIndexMap = null;
991 b.redirectedConstructor = 1004 b.redirectedConstructor =
992 new _ConstExprSerializer(this, localClosureIndexMap, null) 1005 new _ConstExprSerializer(this, localClosureIndexMap, null)
993 .serializeConstructorRef(null, typeName.name, 1006 .serializeConstructorRef(null, typeName.name,
994 typeName.typeArguments, node.redirectedConstructor.name); 1007 typeName.typeArguments, node.redirectedConstructor.name);
995 } 1008 }
996 } else { 1009 } else {
997 for (ConstructorInitializer initializer in node.initializers) { 1010 for (ConstructorInitializer initializer in node.initializers) {
998 if (initializer is RedirectingConstructorInvocation) { 1011 if (initializer is RedirectingConstructorInvocation) {
999 b.isRedirectedConstructor = true; 1012 b.isRedirectedConstructor = true;
1000 b.redirectedConstructorName = initializer.constructorName?.name; 1013 b.redirectedConstructorName = initializer.constructorName?.name;
1001 } 1014 }
1002 } 1015 }
1003 } 1016 }
1004 if (node.constKeyword != null) { 1017 if (node.constKeyword != null) {
1005 b.isConst = true; 1018 b.isConst = true;
1006 b.constCycleSlot = assignSlot(); 1019 b.constCycleSlot = assignSlot();
1007 } 1020 }
1008 b.isExternal = node.externalKeyword != null; 1021 b.isExternal = node.externalKeyword != null;
1009 b.documentationComment = serializeDocumentation(node.documentationComment); 1022 b.documentationComment = serializeDocumentation(node.documentationComment);
1010 b.annotations = serializeAnnotations(node.metadata); 1023 b.annotations = serializeAnnotations(node.metadata);
1011 b.codeRange = serializeCodeRange(node); 1024 b.codeRange = serializeCodeRange(node);
1025 Map<int, int> localClosureIndexMap = _withLocalClosureIndexMap(() {
1026 serializeFunctionBody(b, node.initializers, node.body);
1027 });
1012 if (node.constKeyword != null) { 1028 if (node.constKeyword != null) {
1013 Set<String> constructorParameterNames = 1029 Set<String> constructorParameterNames =
1014 node.parameters.parameters.map((p) => p.identifier.name).toSet(); 1030 node.parameters.parameters.map((p) => p.identifier.name).toSet();
1015 Map<int, int> localClosureIndexMap = null; // TODO(paulberry): fix.
1016 b.constantInitializers = node.initializers 1031 b.constantInitializers = node.initializers
1017 .map((ConstructorInitializer initializer) => 1032 .map((ConstructorInitializer initializer) =>
1018 serializeConstructorInitializer(initializer, (Expression expr) { 1033 serializeConstructorInitializer(initializer, (Expression expr) {
1019 return serializeConstExpr( 1034 return serializeConstExpr(
1020 localClosureIndexMap, expr, constructorParameterNames); 1035 localClosureIndexMap, expr, constructorParameterNames);
1021 })) 1036 }))
1022 .toList(); 1037 .toList();
1023 } 1038 }
1024 serializeFunctionBody(b, node.body);
1025 executables.add(b); 1039 executables.add(b);
1026 } 1040 }
1027 1041
1028 @override 1042 @override
1029 UnlinkedParamBuilder visitDefaultFormalParameter( 1043 UnlinkedParamBuilder visitDefaultFormalParameter(
1030 DefaultFormalParameter node) { 1044 DefaultFormalParameter node) {
1031 UnlinkedParamBuilder b = node.parameter.accept(this); 1045 UnlinkedParamBuilder b = node.parameter.accept(this);
1032 if (node.defaultValue != null) { 1046 if (node.defaultValue != null) {
1033 Map<int, int> localClosureIndexMap = null; // TODO(paulberry): fix. 1047 // Closures can't appear inside default values, so we don't need a
1048 // localClosureIndexMap.
1049 Map<int, int> localClosureIndexMap = null;
1034 b.defaultValue = 1050 b.defaultValue =
1035 serializeConstExpr(localClosureIndexMap, node.defaultValue); 1051 serializeConstExpr(localClosureIndexMap, node.defaultValue);
1036 b.defaultValueCode = node.defaultValue.toSource(); 1052 b.defaultValueCode = node.defaultValue.toSource();
1037 } 1053 }
1038 b.initializer = serializeInitializerFunction(node.defaultValue); 1054 b.initializer = serializeInitializerFunction(node.defaultValue);
1039 b.codeRange = serializeCodeRange(node); 1055 b.codeRange = serializeCodeRange(node);
1040 return b; 1056 return b;
1041 } 1057 }
1042 1058
1043 @override 1059 @override
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
1326 /** 1342 /**
1327 * A [_TypeParameterScope] is a [_Scope] which defines [_ScopedTypeParameter]s. 1343 * A [_TypeParameterScope] is a [_Scope] which defines [_ScopedTypeParameter]s.
1328 */ 1344 */
1329 class _TypeParameterScope extends _Scope { 1345 class _TypeParameterScope extends _Scope {
1330 /** 1346 /**
1331 * Get the number of [_ScopedTypeParameter]s defined in this 1347 * Get the number of [_ScopedTypeParameter]s defined in this
1332 * [_TypeParameterScope]. 1348 * [_TypeParameterScope].
1333 */ 1349 */
1334 int get length => _definedNames.length; 1350 int get length => _definedNames.length;
1335 } 1351 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/test/src/summary/resynthesize_ast_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698