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

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

Issue 1675393002: Fix summarization of unqualified references to class members. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 10 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/lib/src/summary/summarize_elements.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/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
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/lib/src/summary/summarize_elements.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698