Chromium Code Reviews| OLD | NEW |
|---|---|
| 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/visitor.dart'; | 8 import 'package:analyzer/dart/ast/visitor.dart'; |
| 9 import 'package:analyzer/src/generated/scanner.dart'; | 9 import 'package:analyzer/src/generated/scanner.dart'; |
| 10 import 'package:analyzer/src/generated/utilities_dart.dart'; | 10 import 'package:analyzer/src/generated/utilities_dart.dart'; |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 86 'Unexpected identifier type: ${identifier.runtimeType}'); | 86 'Unexpected identifier type: ${identifier.runtimeType}'); |
| 87 } | 87 } |
| 88 return b; | 88 return b; |
| 89 } | 89 } |
| 90 | 90 |
| 91 @override | 91 @override |
| 92 EntityRefBuilder serializePropertyAccess(PropertyAccess access) { | 92 EntityRefBuilder serializePropertyAccess(PropertyAccess access) { |
| 93 Expression target = access.target; | 93 Expression target = access.target; |
| 94 if (target is Identifier) { | 94 if (target is Identifier) { |
| 95 EntityRefBuilder targetRef = serializeIdentifier(target); | 95 EntityRefBuilder targetRef = serializeIdentifier(target); |
| 96 return new EntityRefBuilder( | 96 return new EntityRefBuilder(reference: visitor.serializeReference( |
| 97 reference: visitor.serializeReference( | 97 targetRef.reference, access.propertyName.name)); |
| 98 targetRef.reference, access.propertyName.name)); | |
| 99 } else { | 98 } else { |
| 100 // TODO(scheglov) should we handle other targets in malformed constants? | 99 // TODO(scheglov) should we handle other targets in malformed constants? |
| 101 throw new StateError('Unexpected target type: ${target.runtimeType}'); | 100 throw new StateError('Unexpected target type: ${target.runtimeType}'); |
| 102 } | 101 } |
| 103 } | 102 } |
| 104 | 103 |
| 105 @override | 104 @override |
| 106 EntityRefBuilder serializeType(TypeName node) { | 105 EntityRefBuilder serializeType(TypeName node) { |
| 107 return visitor.serializeTypeName(node); | 106 return visitor.serializeTypeName(node); |
| 108 } | 107 } |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 163 * 1, and each preceding type parameter has the next higher index. | 162 * 1, and each preceding type parameter has the next higher index. |
| 164 */ | 163 */ |
| 165 final int index; | 164 final int index; |
| 166 | 165 |
| 167 _ScopedTypeParameter(this.index); | 166 _ScopedTypeParameter(this.index); |
| 168 } | 167 } |
| 169 | 168 |
| 170 /** | 169 /** |
| 171 * Visitor used to create a summary from an AST. | 170 * Visitor used to create a summary from an AST. |
| 172 */ | 171 */ |
| 173 class _SummarizeAstVisitor extends SimpleAstVisitor { | 172 class _SummarizeAstVisitor extends RecursiveAstVisitor { |
| 174 /** | 173 /** |
| 175 * List of objects which should be written to [UnlinkedUnit.classes]. | 174 * List of objects which should be written to [UnlinkedUnit.classes]. |
| 176 */ | 175 */ |
| 177 final List<UnlinkedClassBuilder> classes = <UnlinkedClassBuilder>[]; | 176 final List<UnlinkedClassBuilder> classes = <UnlinkedClassBuilder>[]; |
| 178 | 177 |
| 179 /** | 178 /** |
| 180 * List of objects which should be written to [UnlinkedUnit.enums]. | 179 * List of objects which should be written to [UnlinkedUnit.enums]. |
| 181 */ | 180 */ |
| 182 final List<UnlinkedEnumBuilder> enums = <UnlinkedEnumBuilder>[]; | 181 final List<UnlinkedEnumBuilder> enums = <UnlinkedEnumBuilder>[]; |
| 183 | 182 |
| 184 /** | 183 /** |
| 185 * List of objects which should be written to [UnlinkedUnit.executables] | 184 * List of objects which should be written to [UnlinkedUnit.executables], |
| 186 * or [UnlinkedClass.executables]. | 185 * [UnlinkedClass.executables] or [UnlinkedExecutable.executables]. |
| 187 */ | 186 */ |
| 188 List<UnlinkedExecutableBuilder> executables = <UnlinkedExecutableBuilder>[]; | 187 List<UnlinkedExecutableBuilder> executables = <UnlinkedExecutableBuilder>[]; |
| 189 | 188 |
| 190 /** | 189 /** |
| 191 * List of objects which should be written to [UnlinkedUnit.exports]. | 190 * List of objects which should be written to [UnlinkedUnit.exports]. |
| 192 */ | 191 */ |
| 193 final List<UnlinkedExportNonPublicBuilder> exports = | 192 final List<UnlinkedExportNonPublicBuilder> exports = |
| 194 <UnlinkedExportNonPublicBuilder>[]; | 193 <UnlinkedExportNonPublicBuilder>[]; |
| 195 | 194 |
| 196 /** | 195 /** |
| 197 * List of objects which should be written to [UnlinkedUnit.parts]. | 196 * List of objects which should be written to [UnlinkedUnit.parts]. |
| 198 */ | 197 */ |
| 199 final List<UnlinkedPartBuilder> parts = <UnlinkedPartBuilder>[]; | 198 final List<UnlinkedPartBuilder> parts = <UnlinkedPartBuilder>[]; |
| 200 | 199 |
| 201 /** | 200 /** |
| 202 * List of objects which should be written to [UnlinkedUnit.typedefs]. | 201 * List of objects which should be written to [UnlinkedUnit.typedefs]. |
| 203 */ | 202 */ |
| 204 final List<UnlinkedTypedefBuilder> typedefs = <UnlinkedTypedefBuilder>[]; | 203 final List<UnlinkedTypedefBuilder> typedefs = <UnlinkedTypedefBuilder>[]; |
| 205 | 204 |
| 206 /** | 205 /** |
| 207 * List of objects which should be written to [UnlinkedUnit.variables] or | 206 * List of objects which should be written to [UnlinkedUnit.variables], |
| 208 * [UnlinkedClass.fields]. | 207 * [UnlinkedClass.fields] or [UnlinkedExecutable.variables]. |
| 209 */ | 208 */ |
| 210 List<UnlinkedVariableBuilder> variables = <UnlinkedVariableBuilder>[]; | 209 List<UnlinkedVariableBuilder> variables = <UnlinkedVariableBuilder>[]; |
| 211 | 210 |
| 212 /** | 211 /** |
| 213 * The unlinked portion of the "imports table". This is the list of objects | 212 * The unlinked portion of the "imports table". This is the list of objects |
| 214 * which should be written to [UnlinkedUnit.imports]. | 213 * which should be written to [UnlinkedUnit.imports]. |
| 215 */ | 214 */ |
| 216 final List<UnlinkedImportBuilder> unlinkedImports = <UnlinkedImportBuilder>[]; | 215 final List<UnlinkedImportBuilder> unlinkedImports = <UnlinkedImportBuilder>[]; |
| 217 | 216 |
| 218 /** | 217 /** |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 278 * Otherwise `null`. | 277 * Otherwise `null`. |
| 279 */ | 278 */ |
| 280 List<UnlinkedConst> libraryAnnotations = const <UnlinkedConstBuilder>[]; | 279 List<UnlinkedConst> libraryAnnotations = const <UnlinkedConstBuilder>[]; |
| 281 | 280 |
| 282 /** | 281 /** |
| 283 * The number of slot ids which have been assigned to this compilation unit. | 282 * The number of slot ids which have been assigned to this compilation unit. |
| 284 */ | 283 */ |
| 285 int numSlots = 0; | 284 int numSlots = 0; |
| 286 | 285 |
| 287 /** | 286 /** |
| 287 * The [Block] that is being visited now, or `null` for non-local contexts. | |
| 288 */ | |
| 289 Block enclosingBlock = null; | |
| 290 | |
| 291 /** | |
| 288 * A flag indicating whether a variable declaration is in the context of a | 292 * A flag indicating whether a variable declaration is in the context of a |
| 289 * field declaration. | 293 * field declaration. |
| 290 */ | 294 */ |
| 291 bool inFieldContext = false; | 295 bool inFieldContext = false; |
| 292 | 296 |
| 293 /** | 297 /** |
| 294 * Create a slot id for storing a propagated or inferred type. | 298 * Create a slot id for storing a propagated or inferred type. |
| 295 */ | 299 */ |
| 296 int assignTypeSlot() => ++numSlots; | 300 int assignTypeSlot() => ++numSlots; |
| 297 | 301 |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 321 } | 325 } |
| 322 return scope; | 326 return scope; |
| 323 } | 327 } |
| 324 | 328 |
| 325 /** | 329 /** |
| 326 * Serialize the given list of [annotations]. If there are no annotations, | 330 * Serialize the given list of [annotations]. If there are no annotations, |
| 327 * the empty list is returned. | 331 * the empty list is returned. |
| 328 */ | 332 */ |
| 329 List<UnlinkedConstBuilder> serializeAnnotations( | 333 List<UnlinkedConstBuilder> serializeAnnotations( |
| 330 NodeList<Annotation> annotations) { | 334 NodeList<Annotation> annotations) { |
| 331 if (annotations.isEmpty) { | 335 if (annotations == null || annotations.isEmpty) { |
| 332 return const <UnlinkedConstBuilder>[]; | 336 return const <UnlinkedConstBuilder>[]; |
| 333 } | 337 } |
| 334 return annotations.map((Annotation a) { | 338 return annotations.map((Annotation a) { |
| 335 _ConstExprSerializer serializer = new _ConstExprSerializer(this, null); | 339 _ConstExprSerializer serializer = new _ConstExprSerializer(this, null); |
| 336 serializer.serializeAnnotation(a); | 340 serializer.serializeAnnotation(a); |
| 337 return serializer.toBuilder(); | 341 return serializer.toBuilder(); |
| 338 }).toList(); | 342 }).toList(); |
| 339 } | 343 } |
| 340 | 344 |
| 341 /** | 345 /** |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 524 b.parameters[i].inferredTypeSlot = assignTypeSlot(); | 528 b.parameters[i].inferredTypeSlot = assignTypeSlot(); |
| 525 } | 529 } |
| 526 } | 530 } |
| 527 } | 531 } |
| 528 } | 532 } |
| 529 b.documentationComment = serializeDocumentation(documentationComment); | 533 b.documentationComment = serializeDocumentation(documentationComment); |
| 530 b.annotations = serializeAnnotations(annotations); | 534 b.annotations = serializeAnnotations(annotations); |
| 531 if (returnType == null && !isSemanticallyStatic) { | 535 if (returnType == null && !isSemanticallyStatic) { |
| 532 b.inferredReturnTypeSlot = assignTypeSlot(); | 536 b.inferredReturnTypeSlot = assignTypeSlot(); |
| 533 } | 537 } |
| 538 b.visibleOffset = enclosingBlock?.offset; | |
| 539 b.visibleLength = enclosingBlock?.length; | |
| 540 serializeFunctionBody(b, body); | |
| 534 scopes.removeLast(); | 541 scopes.removeLast(); |
| 535 assert(scopes.length == oldScopesLength); | 542 assert(scopes.length == oldScopesLength); |
| 536 return b; | 543 return b; |
| 537 } | 544 } |
| 538 | 545 |
| 546 void serializeFunctionBody(UnlinkedExecutableBuilder b, FunctionBody body) { | |
| 547 List<UnlinkedExecutableBuilder> oldExecutable = executables; | |
|
Paul Berry
2016/02/11 15:29:19
s/oldExecutable/oldExecutables/
scheglov
2016/02/11 15:50:08
Done.
| |
| 548 List<UnlinkedVariableBuilder> oldVariables = variables; | |
| 549 executables = <UnlinkedExecutableBuilder>[]; | |
| 550 variables = <UnlinkedVariableBuilder>[]; | |
| 551 body.accept(this); | |
| 552 b.executables = executables; | |
| 553 b.variables = variables; | |
| 554 executables = oldExecutable; | |
| 555 variables = oldVariables; | |
| 556 } | |
| 557 | |
| 539 /** | 558 /** |
| 540 * Serialize the return type and parameters of a function-typed formal | 559 * Serialize the return type and parameters of a function-typed formal |
| 541 * parameter and store them in [b]. | 560 * parameter and store them in [b]. |
| 542 */ | 561 */ |
| 543 void serializeFunctionTypedParameterDetails(UnlinkedParamBuilder b, | 562 void serializeFunctionTypedParameterDetails(UnlinkedParamBuilder b, |
| 544 TypeName returnType, FormalParameterList parameters) { | 563 TypeName returnType, FormalParameterList parameters) { |
| 545 EntityRefBuilder serializedReturnType = serializeTypeName(returnType); | 564 EntityRefBuilder serializedReturnType = serializeTypeName(returnType); |
| 546 if (serializedReturnType != null) { | 565 if (serializedReturnType != null) { |
| 547 b.type = serializedReturnType; | 566 b.type = serializedReturnType; |
| 548 } | 567 } |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 725 } | 744 } |
| 726 if (variable.initializer != null && | 745 if (variable.initializer != null && |
| 727 (variables.isFinal || variables.isConst)) { | 746 (variables.isFinal || variables.isConst)) { |
| 728 b.propagatedTypeSlot = assignTypeSlot(); | 747 b.propagatedTypeSlot = assignTypeSlot(); |
| 729 } | 748 } |
| 730 bool isSemanticallyStatic = !isField || isDeclaredStatic; | 749 bool isSemanticallyStatic = !isField || isDeclaredStatic; |
| 731 if (variables.type == null && | 750 if (variables.type == null && |
| 732 (variable.initializer != null || !isSemanticallyStatic)) { | 751 (variable.initializer != null || !isSemanticallyStatic)) { |
| 733 b.inferredTypeSlot = assignTypeSlot(); | 752 b.inferredTypeSlot = assignTypeSlot(); |
| 734 } | 753 } |
| 754 b.visibleOffset = enclosingBlock?.offset; | |
| 755 b.visibleLength = enclosingBlock?.length; | |
| 735 this.variables.add(b); | 756 this.variables.add(b); |
| 736 } | 757 } |
| 737 } | 758 } |
| 738 | 759 |
| 739 @override | 760 @override |
| 761 void visitBlock(Block node) { | |
| 762 Block oldBlock = enclosingBlock; | |
| 763 enclosingBlock = node; | |
| 764 super.visitBlock(node); | |
| 765 enclosingBlock = oldBlock; | |
| 766 } | |
| 767 | |
| 768 @override | |
| 740 void visitClassDeclaration(ClassDeclaration node) { | 769 void visitClassDeclaration(ClassDeclaration node) { |
| 741 TypeName superclass = | 770 TypeName superclass = |
| 742 node.extendsClause == null ? null : node.extendsClause.superclass; | 771 node.extendsClause == null ? null : node.extendsClause.superclass; |
| 743 serializeClass( | 772 serializeClass( |
| 744 node.abstractKeyword, | 773 node.abstractKeyword, |
| 745 node.name.name, | 774 node.name.name, |
| 746 node.name.offset, | 775 node.name.offset, |
| 747 node.typeParameters, | 776 node.typeParameters, |
| 748 superclass, | 777 superclass, |
| 749 node.withClause, | 778 node.withClause, |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 806 if (node.constKeyword != null) { | 835 if (node.constKeyword != null) { |
| 807 Set<String> constructorParameterNames = | 836 Set<String> constructorParameterNames = |
| 808 node.parameters.parameters.map((p) => p.identifier.name).toSet(); | 837 node.parameters.parameters.map((p) => p.identifier.name).toSet(); |
| 809 b.constantInitializers = node.initializers | 838 b.constantInitializers = node.initializers |
| 810 .map((ConstructorInitializer initializer) => | 839 .map((ConstructorInitializer initializer) => |
| 811 serializeConstructorInitializer(initializer, (Expression expr) { | 840 serializeConstructorInitializer(initializer, (Expression expr) { |
| 812 return serializeConstExpr(expr, constructorParameterNames); | 841 return serializeConstExpr(expr, constructorParameterNames); |
| 813 })) | 842 })) |
| 814 .toList(); | 843 .toList(); |
| 815 } | 844 } |
| 845 serializeFunctionBody(b, node.body); | |
|
Paul Berry
2016/02/11 15:29:19
Don't we need this in other places? (visitFunctio
scheglov
2016/02/11 15:50:08
Yes, we call it also in serializeExecutable(), whi
Paul Berry
2016/02/11 18:03:52
Whoops, not sure how I missed that. Thanks!
| |
| 816 executables.add(b); | 846 executables.add(b); |
| 817 } | 847 } |
| 818 | 848 |
| 819 @override | 849 @override |
| 820 UnlinkedParamBuilder visitDefaultFormalParameter( | 850 UnlinkedParamBuilder visitDefaultFormalParameter( |
| 821 DefaultFormalParameter node) { | 851 DefaultFormalParameter node) { |
| 822 UnlinkedParamBuilder b = node.parameter.accept(this); | 852 UnlinkedParamBuilder b = node.parameter.accept(this); |
| 823 if (node.defaultValue != null) { | 853 if (node.defaultValue != null) { |
| 824 b.defaultValue = serializeConstExpr(node.defaultValue); | 854 b.defaultValue = serializeConstExpr(node.defaultValue); |
| 825 } | 855 } |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1001 UnlinkedTypeParamBuilder b = new UnlinkedTypeParamBuilder(); | 1031 UnlinkedTypeParamBuilder b = new UnlinkedTypeParamBuilder(); |
| 1002 b.name = node.name.name; | 1032 b.name = node.name.name; |
| 1003 b.nameOffset = node.name.offset; | 1033 b.nameOffset = node.name.offset; |
| 1004 if (node.bound != null) { | 1034 if (node.bound != null) { |
| 1005 b.bound = serializeTypeName(node.bound); | 1035 b.bound = serializeTypeName(node.bound); |
| 1006 } | 1036 } |
| 1007 b.annotations = serializeAnnotations(node.metadata); | 1037 b.annotations = serializeAnnotations(node.metadata); |
| 1008 return b; | 1038 return b; |
| 1009 } | 1039 } |
| 1010 | 1040 |
| 1041 @override | |
| 1042 void visitVariableDeclarationStatement(VariableDeclarationStatement node) { | |
| 1043 serializeVariables(node.variables, false, null, null, false); | |
| 1044 } | |
| 1045 | |
| 1011 /** | 1046 /** |
| 1012 * Helper method to determine if a given [typeName] refers to `dynamic`. | 1047 * Helper method to determine if a given [typeName] refers to `dynamic`. |
| 1013 */ | 1048 */ |
| 1014 static bool isDynamic(TypeName typeName) { | 1049 static bool isDynamic(TypeName typeName) { |
| 1015 Identifier name = typeName.name; | 1050 Identifier name = typeName.name; |
| 1016 return name is SimpleIdentifier && name.name == 'dynamic'; | 1051 return name is SimpleIdentifier && name.name == 'dynamic'; |
| 1017 } | 1052 } |
| 1018 } | 1053 } |
| 1019 | 1054 |
| 1020 /** | 1055 /** |
| 1021 * A [_TypeParameterScope] is a [_Scope] which defines [_ScopedTypeParameter]s. | 1056 * A [_TypeParameterScope] is a [_Scope] which defines [_ScopedTypeParameter]s. |
| 1022 */ | 1057 */ |
| 1023 class _TypeParameterScope extends _Scope { | 1058 class _TypeParameterScope extends _Scope { |
| 1024 /** | 1059 /** |
| 1025 * Get the number of [_ScopedTypeParameter]s defined in this | 1060 * Get the number of [_ScopedTypeParameter]s defined in this |
| 1026 * [_TypeParameterScope]. | 1061 * [_TypeParameterScope]. |
| 1027 */ | 1062 */ |
| 1028 int get length => _definedNames.length; | 1063 int get length => _definedNames.length; |
| 1029 } | 1064 } |
| OLD | NEW |