| 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 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 69 int nameRef = | 69 int nameRef = |
| 70 visitor.serializeReference(typeBuilder.reference, name.name); | 70 visitor.serializeReference(typeBuilder.reference, name.name); |
| 71 return new EntityRefBuilder( | 71 return new EntityRefBuilder( |
| 72 reference: nameRef, typeArguments: typeBuilder.typeArguments); | 72 reference: nameRef, typeArguments: typeBuilder.typeArguments); |
| 73 } | 73 } |
| 74 } | 74 } |
| 75 | 75 |
| 76 EntityRefBuilder serializeIdentifier(Identifier identifier) { | 76 EntityRefBuilder serializeIdentifier(Identifier identifier) { |
| 77 EntityRefBuilder b = new EntityRefBuilder(); | 77 EntityRefBuilder b = new EntityRefBuilder(); |
| 78 if (identifier is SimpleIdentifier) { | 78 if (identifier is SimpleIdentifier) { |
| 79 b.reference = visitor.serializeReference(null, identifier.name); | 79 b.reference = visitor.serializeSimpleReference(identifier.name); |
| 80 } else if (identifier is PrefixedIdentifier) { | 80 } else if (identifier is PrefixedIdentifier) { |
| 81 int prefix = visitor.serializeReference(null, identifier.prefix.name); | 81 int prefix = visitor.serializeSimpleReference(identifier.prefix.name); |
| 82 b.reference = | 82 b.reference = |
| 83 visitor.serializeReference(prefix, identifier.identifier.name); | 83 visitor.serializeReference(prefix, identifier.identifier.name); |
| 84 } else { | 84 } else { |
| 85 throw new StateError( | 85 throw new StateError( |
| 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 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 102 } | 102 } |
| 103 } | 103 } |
| 104 | 104 |
| 105 @override | 105 @override |
| 106 EntityRefBuilder serializeType(TypeName node) { | 106 EntityRefBuilder serializeType(TypeName node) { |
| 107 return visitor.serializeTypeName(node); | 107 return visitor.serializeTypeName(node); |
| 108 } | 108 } |
| 109 } | 109 } |
| 110 | 110 |
| 111 /** | 111 /** |
| 112 * An [_OtherScopedEntity] is a [_ScopedEntity] that does not refer to a type | |
| 113 * parameter. Since we don't need to track any special information about these | |
| 114 * types of scoped entities, it is a singleton class. | |
| 115 */ | |
| 116 class _OtherScopedEntity extends _ScopedEntity { | |
| 117 static final _OtherScopedEntity _instance = new _OtherScopedEntity._(); | |
| 118 | |
| 119 factory _OtherScopedEntity() => _instance; | |
| 120 | |
| 121 _OtherScopedEntity._(); | |
| 122 } | |
| 123 | |
| 124 /** | |
| 125 * A [_Scope] represents a set of name/value pairs defined locally within a | 112 * A [_Scope] represents a set of name/value pairs defined locally within a |
| 126 * limited span of a compilation unit. (Note that the spec also uses the term | 113 * limited span of a compilation unit. (Note that the spec also uses the term |
| 127 * "scope" to refer to the set of names defined at top level within a | 114 * "scope" to refer to the set of names defined at top level within a |
| 128 * compilation unit, but we do not use [_Scope] for that purpose). | 115 * compilation unit, but we do not use [_Scope] for that purpose). |
| 129 */ | 116 */ |
| 130 class _Scope { | 117 class _Scope { |
| 131 /** | 118 /** |
| 132 * Names defined in this scope, and their meanings. | 119 * Names defined in this scope, and their meanings. |
| 133 */ | 120 */ |
| 134 Map<String, _ScopedEntity> _definedNames = <String, _ScopedEntity>{}; | 121 Map<String, _ScopedEntity> _definedNames = <String, _ScopedEntity>{}; |
| 135 | 122 |
| 136 /** | 123 /** |
| 137 * Look up the meaning associated with the given [name], and return it. If | 124 * Look up the meaning associated with the given [name], and return it. If |
| 138 * [name] is not defined in this scope, return `null`. | 125 * [name] is not defined in this scope, return `null`. |
| 139 */ | 126 */ |
| 140 _ScopedEntity operator [](String name) => _definedNames[name]; | 127 _ScopedEntity operator [](String name) => _definedNames[name]; |
| 141 | 128 |
| 142 /** | 129 /** |
| 143 * Let the given [name] refer to [entity] within this scope. | 130 * Let the given [name] refer to [entity] within this scope. |
| 144 */ | 131 */ |
| 145 void operator []=(String name, _ScopedEntity entity) { | 132 void operator []=(String name, _ScopedEntity entity) { |
| 146 _definedNames[name] = entity; | 133 _definedNames[name] = entity; |
| 147 } | 134 } |
| 148 } | 135 } |
| 149 | 136 |
| 150 /** | 137 /** |
| 138 * A [_ScopedClassMember] is a [_ScopedEntity] refers to a member of a class. |
| 139 */ |
| 140 class _ScopedClassMember extends _ScopedEntity { |
| 141 /** |
| 142 * The name of the class. |
| 143 */ |
| 144 final String className; |
| 145 |
| 146 _ScopedClassMember(this.className); |
| 147 } |
| 148 |
| 149 /** |
| 151 * Base class for entities that can live inside a scope. | 150 * Base class for entities that can live inside a scope. |
| 152 */ | 151 */ |
| 153 abstract class _ScopedEntity {} | 152 abstract class _ScopedEntity {} |
| 154 | 153 |
| 155 /** | 154 /** |
| 156 * A [_ScopedTypeParameter] is a [_ScopedEntity] that refers to a type | 155 * A [_ScopedTypeParameter] is a [_ScopedEntity] that refers to a type |
| 157 * parameter of a class, typedef, or executable. | 156 * parameter of a class, typedef, or executable. |
| 158 */ | 157 */ |
| 159 class _ScopedTypeParameter extends _ScopedEntity { | 158 class _ScopedTypeParameter extends _ScopedEntity { |
| 160 /** | 159 /** |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 224 <UnlinkedReferenceBuilder>[new UnlinkedReferenceBuilder()]; | 223 <UnlinkedReferenceBuilder>[new UnlinkedReferenceBuilder()]; |
| 225 | 224 |
| 226 /** | 225 /** |
| 227 * Map associating names used as prefixes in this compilation unit with their | 226 * Map associating names used as prefixes in this compilation unit with their |
| 228 * associated indices into [UnlinkedUnit.references]. | 227 * associated indices into [UnlinkedUnit.references]. |
| 229 */ | 228 */ |
| 230 final Map<String, int> prefixIndices = <String, int>{}; | 229 final Map<String, int> prefixIndices = <String, int>{}; |
| 231 | 230 |
| 232 /** | 231 /** |
| 233 * List of [_Scope]s currently in effect. This is used to resolve type names | 232 * List of [_Scope]s currently in effect. This is used to resolve type names |
| 234 * to type parameters within classes, typedefs, and executables. | 233 * to type parameters within classes, typedefs, and executables, as well as |
| 234 * references to class members. |
| 235 */ | 235 */ |
| 236 final List<_Scope> scopes = <_Scope>[]; | 236 final List<_Scope> scopes = <_Scope>[]; |
| 237 | 237 |
| 238 /** | 238 /** |
| 239 * True if 'dart:core' has been explicitly imported. | 239 * True if 'dart:core' has been explicitly imported. |
| 240 */ | 240 */ |
| 241 bool hasCoreBeenImported = false; | 241 bool hasCoreBeenImported = false; |
| 242 | 242 |
| 243 /** | 243 /** |
| 244 * Names referenced by this compilation unit. Structured as a map from | 244 * Names referenced by this compilation unit. Structured as a map from |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 292 | 292 |
| 293 /** | 293 /** |
| 294 * Create a slot id for storing a propagated or inferred type. | 294 * Create a slot id for storing a propagated or inferred type. |
| 295 */ | 295 */ |
| 296 int assignTypeSlot() => ++numSlots; | 296 int assignTypeSlot() => ++numSlots; |
| 297 | 297 |
| 298 /** | 298 /** |
| 299 * Build a [_Scope] object containing the names defined within the body of a | 299 * Build a [_Scope] object containing the names defined within the body of a |
| 300 * class declaration. | 300 * class declaration. |
| 301 */ | 301 */ |
| 302 _Scope buildClassMemberScope(NodeList<ClassMember> members) { | 302 _Scope buildClassMemberScope( |
| 303 String className, NodeList<ClassMember> members) { |
| 303 _Scope scope = new _Scope(); | 304 _Scope scope = new _Scope(); |
| 304 for (ClassMember member in members) { | 305 for (ClassMember member in members) { |
| 305 // TODO(paulbery): consider replacing these if-tests with dynamic method | 306 // TODO(paulbery): consider replacing these if-tests with dynamic method |
| 306 // dispatch. | 307 // dispatch. |
| 307 if (member is MethodDeclaration) { | 308 if (member is MethodDeclaration) { |
| 308 if (member.isSetter || member.isOperator) { | 309 if (member.isSetter || member.isOperator) { |
| 309 // We don't have to handle setters or operators because the only | 310 // We don't have to handle setters or operators because the only |
| 310 // thing we look up is type names. | 311 // things we look up are type names and identifiers. |
| 311 } else { | 312 } else { |
| 312 scope[member.name.name] = new _OtherScopedEntity(); | 313 scope[member.name.name] = new _ScopedClassMember(className); |
| 313 } | 314 } |
| 314 } else if (member is FieldDeclaration) { | 315 } else if (member is FieldDeclaration) { |
| 315 for (VariableDeclaration field in member.fields.variables) { | 316 for (VariableDeclaration field in member.fields.variables) { |
| 316 // A field declaration introduces two names, one with a trailing `=`. | 317 // A field declaration introduces two names, one with a trailing `=`. |
| 317 // We don't have to worry about the one with a trailing `=` because | 318 // We don't have to worry about the one with a trailing `=` because |
| 318 // the only thing we look up is type names. | 319 // the only things we look up are type names and identifiers. |
| 319 scope[field.name.name] = new _OtherScopedEntity(); | 320 scope[field.name.name] = new _ScopedClassMember(className); |
| 320 } | 321 } |
| 321 } | 322 } |
| 322 } | 323 } |
| 323 return scope; | 324 return scope; |
| 324 } | 325 } |
| 325 | 326 |
| 326 /** | 327 /** |
| 327 * Serialize the given list of [annotations]. If there are no annotations, | 328 * Serialize the given list of [annotations]. If there are no annotations, |
| 328 * the empty list is returned. | 329 * the empty list is returned. |
| 329 */ | 330 */ |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 372 b.supertype = serializeTypeName(superclass); | 373 b.supertype = serializeTypeName(superclass); |
| 373 } | 374 } |
| 374 if (withClause != null) { | 375 if (withClause != null) { |
| 375 b.mixins = withClause.mixinTypes.map(serializeTypeName).toList(); | 376 b.mixins = withClause.mixinTypes.map(serializeTypeName).toList(); |
| 376 } | 377 } |
| 377 if (implementsClause != null) { | 378 if (implementsClause != null) { |
| 378 b.interfaces = | 379 b.interfaces = |
| 379 implementsClause.interfaces.map(serializeTypeName).toList(); | 380 implementsClause.interfaces.map(serializeTypeName).toList(); |
| 380 } | 381 } |
| 381 if (members != null) { | 382 if (members != null) { |
| 382 scopes.add(buildClassMemberScope(members)); | 383 scopes.add(buildClassMemberScope(name, members)); |
| 383 for (ClassMember member in members) { | 384 for (ClassMember member in members) { |
| 384 member.accept(this); | 385 member.accept(this); |
| 385 } | 386 } |
| 386 scopes.removeLast(); | 387 scopes.removeLast(); |
| 387 } | 388 } |
| 388 b.executables = executables; | 389 b.executables = executables; |
| 389 b.fields = variables; | 390 b.fields = variables; |
| 390 b.isAbstract = abstractKeyword != null; | 391 b.isAbstract = abstractKeyword != null; |
| 391 b.documentationComment = serializeDocumentation(documentationComment); | 392 b.documentationComment = serializeDocumentation(documentationComment); |
| 392 b.annotations = serializeAnnotations(annotations); | 393 b.annotations = serializeAnnotations(annotations); |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 586 int serializeReference(int prefixIndex, String name) => nameToReference | 587 int serializeReference(int prefixIndex, String name) => nameToReference |
| 587 .putIfAbsent(prefixIndex, () => <String, int>{}) | 588 .putIfAbsent(prefixIndex, () => <String, int>{}) |
| 588 .putIfAbsent(name, () { | 589 .putIfAbsent(name, () { |
| 589 int index = unlinkedReferences.length; | 590 int index = unlinkedReferences.length; |
| 590 unlinkedReferences.add(new UnlinkedReferenceBuilder( | 591 unlinkedReferences.add(new UnlinkedReferenceBuilder( |
| 591 prefixReference: prefixIndex, name: name)); | 592 prefixReference: prefixIndex, name: name)); |
| 592 return index; | 593 return index; |
| 593 }); | 594 }); |
| 594 | 595 |
| 595 /** | 596 /** |
| 597 * Serialize a reference to a name declared either at top level or in a |
| 598 * nested scope. |
| 599 */ |
| 600 int serializeSimpleReference(String name) { |
| 601 for (int i = scopes.length - 1; i >= 0; i--) { |
| 602 _Scope scope = scopes[i]; |
| 603 _ScopedEntity entity = scope[name]; |
| 604 if (entity != null) { |
| 605 if (entity is _ScopedClassMember) { |
| 606 return serializeReference( |
| 607 serializeReference(null, entity.className), name); |
| 608 } else { |
| 609 // Invalid reference to a type parameter. Should never happen in |
| 610 // legal Dart code. |
| 611 // TODO(paulberry): could this exception ever be uncaught in illegal |
| 612 // code? |
| 613 throw new StateError('Invalid identifier reference'); |
| 614 } |
| 615 } |
| 616 } |
| 617 return serializeReference(null, name); |
| 618 } |
| 619 |
| 620 /** |
| 596 * Serialize a type name (which might be defined in a nested scope, at top | 621 * Serialize a type name (which might be defined in a nested scope, at top |
| 597 * level within this library, or at top level within an imported library) to | 622 * level within this library, or at top level within an imported library) to |
| 598 * a [EntityRef]. Note that this method does the right thing if the | 623 * a [EntityRef]. Note that this method does the right thing if the |
| 599 * name doesn't refer to an entity other than a type (e.g. a class member). | 624 * name doesn't refer to an entity other than a type (e.g. a class member). |
| 600 */ | 625 */ |
| 601 EntityRefBuilder serializeTypeName(TypeName node) { | 626 EntityRefBuilder serializeTypeName(TypeName node) { |
| 602 if (node == null) { | 627 if (node == null) { |
| 603 return null; | 628 return null; |
| 604 } else { | 629 } else { |
| 605 EntityRefBuilder b = new EntityRefBuilder(); | 630 EntityRefBuilder b = new EntityRefBuilder(); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 622 return b; | 647 return b; |
| 623 } | 648 } |
| 624 } | 649 } |
| 625 if (scope is _TypeParameterScope) { | 650 if (scope is _TypeParameterScope) { |
| 626 indexOffset += scope.length; | 651 indexOffset += scope.length; |
| 627 } | 652 } |
| 628 } | 653 } |
| 629 b.reference = serializeReference(null, name); | 654 b.reference = serializeReference(null, name); |
| 630 } else if (identifier is PrefixedIdentifier) { | 655 } else if (identifier is PrefixedIdentifier) { |
| 631 int prefixIndex = prefixIndices.putIfAbsent(identifier.prefix.name, | 656 int prefixIndex = prefixIndices.putIfAbsent(identifier.prefix.name, |
| 632 () => serializeReference(null, identifier.prefix.name)); | 657 () => serializeSimpleReference(identifier.prefix.name)); |
| 633 b.reference = | 658 b.reference = |
| 634 serializeReference(prefixIndex, identifier.identifier.name); | 659 serializeReference(prefixIndex, identifier.identifier.name); |
| 635 } else { | 660 } else { |
| 636 throw new StateError( | 661 throw new StateError( |
| 637 'Unexpected identifier type: ${identifier.runtimeType}'); | 662 'Unexpected identifier type: ${identifier.runtimeType}'); |
| 638 } | 663 } |
| 639 if (node.typeArguments != null) { | 664 if (node.typeArguments != null) { |
| 640 // Trailing type arguments of type 'dynamic' should be omitted. | 665 // Trailing type arguments of type 'dynamic' should be omitted. |
| 641 NodeList<TypeName> args = node.typeArguments.arguments; | 666 NodeList<TypeName> args = node.typeArguments.arguments; |
| 642 int numArgsToSerialize = args.length; | 667 int numArgsToSerialize = args.length; |
| (...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 982 /** | 1007 /** |
| 983 * A [_TypeParameterScope] is a [_Scope] which defines [_ScopedTypeParameter]s. | 1008 * A [_TypeParameterScope] is a [_Scope] which defines [_ScopedTypeParameter]s. |
| 984 */ | 1009 */ |
| 985 class _TypeParameterScope extends _Scope { | 1010 class _TypeParameterScope extends _Scope { |
| 986 /** | 1011 /** |
| 987 * Get the number of [_ScopedTypeParameter]s defined in this | 1012 * Get the number of [_ScopedTypeParameter]s defined in this |
| 988 * [_TypeParameterScope]. | 1013 * [_TypeParameterScope]. |
| 989 */ | 1014 */ |
| 990 int get length => _definedNames.length; | 1015 int get length => _definedNames.length; |
| 991 } | 1016 } |
| OLD | NEW |