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

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

Issue 1602883003: Introduce code for computing an unlinked summary directly from an AST. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 11 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/summary_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
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 library serialization.summarize_ast;
6
7 import 'package:analyzer/analyzer.dart';
8 import 'package:analyzer/src/generated/ast.dart';
Brian Wilkerson 2016/01/19 17:53:44 nit: After this weekend, this library is now empty
Paul Berry 2016/01/19 18:21:48 Done.
9 import 'package:analyzer/src/generated/scanner.dart';
10 import 'package:analyzer/src/summary/format.dart';
11 import 'package:analyzer/src/summary/public_namespace_computer.dart';
12
13 /**
14 * Serialize all the declarations in [compilationUnit] to an unlinked summary.
15 */
16 UnlinkedUnitBuilder serializeAstUnlinked(CompilationUnit compilationUnit) {
17 return new _SummarizeAstVisitor().serializeCompilationUnit(compilationUnit);
18 }
19
20 /**
21 * An [_OtherScopedEntity] is a [_ScopedEntity] that does not refer to a type
22 * parameter. Since we don't need to track any special information about these
23 * types of scoped entities, it is a singleton class.
24 */
25 class _OtherScopedEntity extends _ScopedEntity {
26 static final _OtherScopedEntity _instance = new _OtherScopedEntity._();
27
28 factory _OtherScopedEntity() => _instance;
29
30 _OtherScopedEntity._();
31 }
32
33 /**
34 * A [_Scope] represents a set of name/value pairs defined locally within a
35 * limited span of a compilation unit. (Note that the spec also uses the term
36 * "scope" to refer to the set of names defined at top level within a
37 * compilation unit, but we do not use [_Scope] for that purpose).
38 */
39 class _Scope {
40 /**
41 * Names defined in this scope, and their meanings.
42 */
43 Map<String, _ScopedEntity> _definedNames = <String, _ScopedEntity>{};
44
45 /**
46 * Look up the meaning associated with the given [name], and return it. If
47 * [name] is not defined in this scope, return `null`.
48 */
49 _ScopedEntity operator [](String name) => _definedNames[name];
50
51 /**
52 * Let the given [name] refer to [entity] within this scope.
53 */
54 void operator []=(String name, _ScopedEntity entity) {
55 _definedNames[name] = entity;
56 }
57 }
58
59 /**
60 * Base class for entities that can live inside a scope.
61 */
62 abstract class _ScopedEntity {}
63
64 /**
65 * A [_ScopedTypeParameter] is a [_ScopedEntity] that refers to a type
66 * parameter of a class, typedef, or executable.
67 */
68 class _ScopedTypeParameter extends _ScopedEntity {
69 /**
70 * Index of the type parameter within this scope. Since summaries use De
71 * Bruijn indices to refer to type parameters, which count upwards from the
72 * innermost bound name, the last type parameter in the scope has an index of
73 * 1, and each preceding type parameter has the next higher index.
74 */
75 final int index;
76
77 _ScopedTypeParameter(this.index);
78 }
79
80 /**
81 * Visitor used to create a summary from an AST.
82 */
83 class _SummarizeAstVisitor extends SimpleAstVisitor {
84 /**
85 * List of objects which should be written to [UnlinkedUnit.classes].
86 */
87 final List<UnlinkedClassBuilder> classes = <UnlinkedClassBuilder>[];
88
89 /**
90 * List of objects which should be written to [UnlinkedUnit.enums].
91 */
92 final List<UnlinkedEnumBuilder> enums = <UnlinkedEnumBuilder>[];
93
94 /**
95 * List of objects which should be written to [UnlinkedUnit.executables]
96 * or [UnlinkedClass.executables].
97 */
98 List<UnlinkedExecutableBuilder> executables = <UnlinkedExecutableBuilder>[];
Brian Wilkerson 2016/01/19 17:53:44 Seems strange that some lists are 'final' and some
Paul Berry 2016/01/19 18:21:48 `setters` and `variables` were the only lists that
99
100 /**
101 * List of objects which should be written to [UnlinkedUnit.exports].
102 */
103 List<UnlinkedExportNonPublicBuilder> exports =
104 <UnlinkedExportNonPublicBuilder>[];
105
106 /**
107 * List of objects which should be written to [UnlinkedUnit.parts].
108 */
109 List<UnlinkedPartBuilder> parts = <UnlinkedPartBuilder>[];
110
111 /**
112 * List of objects which should be written to [UnlinkedUnit.typedefs].
113 */
114 final List<UnlinkedTypedefBuilder> typedefs = <UnlinkedTypedefBuilder>[];
115
116 /**
117 * List of objects which should be written to [UnlinkedUnit.variables] or
118 * [UnlinkedClass.fields].
119 */
120 List<UnlinkedVariableBuilder> variables = <UnlinkedVariableBuilder>[];
121
122 /**
123 * The unlinked portion of the "imports table". This is the list of objects
124 * which should be written to [UnlinkedUnit.imports].
125 */
126 final List<UnlinkedImportBuilder> unlinkedImports = <UnlinkedImportBuilder>[];
127
128 /**
129 * The unlinked portion of the "references table". This is the list of
130 * objects which should be written to [UnlinkedUnit.references].
131 */
132 final List<UnlinkedReferenceBuilder> unlinkedReferences =
133 <UnlinkedReferenceBuilder>[new UnlinkedReferenceBuilder()];
134
135 /**
136 * The [ClassDeclaration] currently being summarized, or `null` if we are not
137 * currently visiting a [ClassDeclaration].
138 */
139 ClassDeclaration currentClassDeclaration;
140
141 /**
142 * Map associating names used as prefixes in this compilation unit with their
143 * associated indices into [UnlinkedUnit.references].
144 */
145 final Map<String, int> prefixIndices = <String, int>{};
146
147 /**
148 * List of [_Scope]s currently in effect. This is used to resolve type names
149 * to type parameters within classes, typedefs, and executables.
150 */
151 final List<_Scope> scopes = <_Scope>[];
152
153 /**
154 * True if 'dart:core' has been explicitly imported.
155 */
156 bool hasCoreBeenImported = false;
157
158 /**
159 * Names referenced by this compilation unit. Structured as a map from
160 * prefix index to (map from name to reference table index), where "prefix
161 * index" means the index into [UnlinkedUnit.references] of the prefix (or
162 * `null` if there is no prefix), and "reference table index" means the index
163 * into [UnlinkedUnit.references] for the name itself.
164 */
165 final Map<int, Map<String, int>> nameToReference = <int, Map<String, int>>{};
166
167 /**
168 * If the library has a library directive, the library name derived from it.
169 * Otherwise `null`.
170 */
171 String libraryName;
172
173 /**
174 * If the library has a library directive, the offset of the library name.
175 * Otherwise `null`.
176 */
177 int libraryNameOffset;
178
179 /**
180 * If the library has a library directive, the length of the library name, as
181 * it appears in the source file. Otherwise `null`.
182 */
183 int libraryNameLength;
184
185 /**
186 * If the library has a library directive, the documentation comment for it
187 * (if any). Othrwise `null`.
188 */
189 UnlinkedDocumentationCommentBuilder libraryDocumentationComment;
190
191 /**
192 * Build a [_Scope] object containing the names defined within the body of a
193 * class declaration.
194 */
195 _Scope buildClassMemberScope(NodeList<ClassMember> members) {
196 _Scope scope = new _Scope();
197 for (ClassMember member in members) {
198 // TODO(paulbery): consider replacing these if-tests with dynamic method
199 // dispatch.
200 if (member is MethodDeclaration) {
201 if (member.isSetter || member.isOperator) {
202 // We don't have to handle setters or operators because the only
203 // thing we look up is type names.
204 } else {
205 scope[member.name.name] = new _OtherScopedEntity();
206 }
207 } else if (member is FieldDeclaration) {
208 for (VariableDeclaration field in member.fields.variables) {
209 // A field declaration introduces two names, one with a trailing `=`.
210 // We don't have to worry about the one with a trailing `=` because
211 // the only thing we look up is type names.
212 scope[field.name.name] = new _OtherScopedEntity();
213 }
214 }
215 }
216 return scope;
217 }
218
219 /**
220 * Try to find a field with the given [name] in the current class declaration
221 * and return its type. If no field is found, or there isn't a current
222 * class declaration, return null.
223 */
224 TypeName getFieldType(String name) {
225 if (currentClassDeclaration == null) {
226 return null;
227 }
228 for (ClassMember member in currentClassDeclaration.members) {
229 if (member is FieldDeclaration) {
230 for (VariableDeclaration variable in member.fields.variables) {
231 if (variable.name.name == name) {
232 return member.fields.type;
233 }
234 }
235 }
236 }
237 return null;
238 }
239
240 /**
241 * Serialize a [ClassDeclaration] or [ClassTypeAlias] into an [UnlinkedClass]
242 * and store the result in [classes].
243 */
244 void serializeClass(
245 Token abstractKeyword,
246 String name,
247 int nameOffset,
248 TypeParameterList typeParameters,
249 TypeName superclass,
250 WithClause withClause,
251 ImplementsClause implementsClause,
252 NodeList<ClassMember> members,
253 bool isMixinApplication,
254 Comment documentationComment) {
255 int oldScopesLength = scopes.length;
256 List<UnlinkedExecutableBuilder> oldExecutables = executables;
257 executables = <UnlinkedExecutableBuilder>[];
258 List<UnlinkedVariableBuilder> oldVariables = variables;
259 variables = <UnlinkedVariableBuilder>[];
260 _TypeParameterScope typeParameterScope = new _TypeParameterScope();
261 scopes.add(typeParameterScope);
262 UnlinkedClassBuilder b = new UnlinkedClassBuilder();
263 b.name = name;
264 b.nameOffset = nameOffset;
265 b.isMixinApplication = isMixinApplication;
266 b.typeParameters =
267 serializeTypeParameters(typeParameters, typeParameterScope);
268 if (superclass != null) {
269 b.supertype = serializeTypeName(superclass);
270 }
271 if (withClause != null) {
272 b.mixins = withClause.mixinTypes.map(serializeTypeName).toList();
273 }
274 if (implementsClause != null) {
275 b.interfaces =
276 implementsClause.interfaces.map(serializeTypeName).toList();
277 }
278 if (members != null) {
279 scopes.add(buildClassMemberScope(members));
280 for (ClassMember member in members) {
281 member.accept(this);
282 }
283 scopes.removeLast();
284 }
285 b.executables = executables;
286 b.fields = variables;
287 b.isAbstract = abstractKeyword != null;
288 b.documentationComment = serializeDocumentation(documentationComment);
289 classes.add(b);
290 scopes.removeLast();
291 assert(scopes.length == oldScopesLength);
292 executables = oldExecutables;
293 variables = oldVariables;
294 }
295
296 /**
297 * Serialize a [Combinator] into an [UnlinkedCombinator].
298 */
299 UnlinkedCombinatorBuilder serializeCombinator(Combinator combinator) {
300 UnlinkedCombinatorBuilder b = new UnlinkedCombinatorBuilder();
301 if (combinator is ShowCombinator) {
302 b.shows =
303 combinator.shownNames.map((SimpleIdentifier id) => id.name).toList();
304 } else if (combinator is HideCombinator) {
305 b.hides =
306 combinator.hiddenNames.map((SimpleIdentifier id) => id.name).toList();
307 } else {
308 throw new StateError(
309 'Unexpected combinator type: ${combinator.runtimeType}');
310 }
311 return b;
312 }
313
314 /**
315 * Main entry point for serializing an AST.
316 */
317 UnlinkedUnitBuilder serializeCompilationUnit(
318 CompilationUnit compilationUnit) {
319 compilationUnit.directives.accept(this);
320 if (!hasCoreBeenImported) {
321 unlinkedImports.add(new UnlinkedImportBuilder(isImplicit: true));
322 }
323 compilationUnit.declarations.accept(this);
324 UnlinkedUnitBuilder b = new UnlinkedUnitBuilder();
325 b.libraryName = libraryName;
326 b.libraryNameOffset = libraryNameOffset;
327 b.libraryNameLength = libraryNameLength;
328 b.libraryDocumentationComment = libraryDocumentationComment;
329 b.classes = classes;
330 b.enums = enums;
331 b.executables = executables;
332 b.exports = exports;
333 b.imports = unlinkedImports;
334 b.parts = parts;
335 b.references = unlinkedReferences;
336 b.typedefs = typedefs;
337 b.variables = variables;
338 b.publicNamespace = computePublicNamespace(compilationUnit);
339 return b;
340 }
341
342 /**
343 * Serialize a [Comment] node into an [UnlinkedDocumentationComment] object.
344 */
345 UnlinkedDocumentationCommentBuilder serializeDocumentation(
346 Comment documentationComment) {
347 if (documentationComment == null) {
348 return null;
349 }
350 String text = documentationComment.tokens
351 .map((Token t) => t.toString())
352 .join()
353 .replaceAll('\r\n', '\n');
354 return new UnlinkedDocumentationCommentBuilder(
355 text: text,
356 offset: documentationComment.offset,
357 length: documentationComment.length);
358 }
359
360 /**
361 * Serialize a [FunctionDeclaration] or [MethodDeclaration] into an
362 * [UnlinkedExecutable].
363 */
364 UnlinkedExecutableBuilder serializeExecutable(
365 SimpleIdentifier name,
366 bool isGetter,
367 bool isSetter,
368 TypeName returnType,
369 FormalParameterList formalParameters,
370 FunctionBody body,
371 bool isTopLevel,
372 bool isStatic,
373 Comment documentationComment,
374 TypeParameterList typeParameters,
375 bool isExternal) {
376 int oldScopesLength = scopes.length;
377 _TypeParameterScope typeParameterScope = new _TypeParameterScope();
378 scopes.add(typeParameterScope);
379 UnlinkedExecutableBuilder b = new UnlinkedExecutableBuilder();
380 String nameString = name.name;
381 if (isGetter) {
382 b.kind = UnlinkedExecutableKind.getter;
383 } else if (isSetter) {
384 b.kind = UnlinkedExecutableKind.setter;
385 nameString = '$nameString=';
386 } else {
387 b.kind = UnlinkedExecutableKind.functionOrMethod;
388 }
389 b.isAbstract = body is EmptyFunctionBody;
390 b.name = nameString;
391 b.nameOffset = name.offset;
392 b.typeParameters =
393 serializeTypeParameters(typeParameters, typeParameterScope);
394 if (!isTopLevel) {
395 b.isStatic = isStatic;
396 }
397 b.returnType = serializeTypeName(returnType, allowVoid: true);
398 b.hasImplicitReturnType = returnType == null;
399 b.isExternal = isExternal;
400 if (formalParameters != null) {
401 b.parameters = formalParameters.parameters
402 .map((FormalParameter p) => p.accept(this))
403 .toList();
404 }
405 b.documentationComment = serializeDocumentation(documentationComment);
406 scopes.removeLast();
407 assert(scopes.length == oldScopesLength);
408 return b;
409 }
410
411 /**
412 * Serialize the return type and parameters of a function-typed formal
413 * parameter and store them in [b].
414 */
415 void serializeFunctionTypedParameterDetails(UnlinkedParamBuilder b,
416 TypeName returnType, FormalParameterList parameters) {
417 UnlinkedTypeRefBuilder serializedReturnType =
418 serializeTypeName(returnType, allowVoid: true);
419 if (serializedReturnType != null) {
420 b.type = serializedReturnType;
421 }
422 b.parameters = parameters.parameters
423 .map((FormalParameter p) => p.accept(this))
424 .toList();
425 }
426
427 /**
428 * Serialize a [FieldFormalParameter], [FunctionTypedFormalParameter], or
429 * [SimpleFormalParameter] into an [UnlinkedParam].
430 */
431 UnlinkedParamBuilder serializeParameter(NormalFormalParameter node) {
432 UnlinkedParamBuilder b = new UnlinkedParamBuilder();
433 b.name = node.identifier.name;
434 b.nameOffset = node.identifier.offset;
435 switch (node.kind) {
436 case ParameterKind.REQUIRED:
437 b.kind = UnlinkedParamKind.required;
438 break;
439 case ParameterKind.POSITIONAL:
440 b.kind = UnlinkedParamKind.positional;
441 break;
442 case ParameterKind.NAMED:
443 b.kind = UnlinkedParamKind.named;
444 break;
445 default:
446 throw new StateError('Unexpected parameter kind: ${node.kind}');
447 }
448 return b;
449 }
450
451 /**
452 * Serialize a reference to a top level name declared elsewhere, by adding an
453 * entry to the references table if necessary. If [prefixIndex] is not null,
454 * the reference is associated with the prefix having the given index in the
455 * references table.
456 */
457 int serializeReference(int prefixIndex, String name) => nameToReference
458 .putIfAbsent(prefixIndex, () => <String, int>{})
459 .putIfAbsent(name, () {
460 assert(name != 'dynamic');
461 int index = unlinkedReferences.length;
462 unlinkedReferences.add(new UnlinkedReferenceBuilder(
463 prefixReference: prefixIndex, name: name));
464 return index;
465 });
466
467 /**
468 * Serialize a type name (which might be defined in a nested scope, at top
469 * level within this library, or at top level within an imported library) to
470 * an [UnlinkedTypeRef]. Note that this method does the right thing if the
471 * name doesn't refer to an entity other than a type (e.g. a class member).
472 */
473 UnlinkedTypeRefBuilder serializeTypeName(TypeName node,
474 {bool allowVoid: false}) {
475 UnlinkedTypeRefBuilder b = new UnlinkedTypeRefBuilder();
476 if (node != null) {
477 Identifier identifier = node.name;
478 if (identifier is SimpleIdentifier) {
479 String name = identifier.name;
480 int indexOffset = 0;
481 for (int i = scopes.length - 1; i >= 0; i--) {
482 _Scope scope = scopes[i];
483 _ScopedEntity entity = scope[name];
484 if (entity != null) {
485 if (entity is _ScopedTypeParameter) {
486 b.paramReference = indexOffset + entity.index;
487 return b;
488 } else {
489 // None of the other things that can be declared in local scopes
490 // are types, so this is an error and should be treated as a
491 // reference to `dynamic`.
492 return b;
493 }
494 }
495 if (scope is _TypeParameterScope) {
496 indexOffset += scope.length;
497 }
498 }
499 if (allowVoid && name == 'void') {
500 return null;
501 }
502 if (name != 'dynamic') {
503 b.reference = serializeReference(null, name);
504 }
505 } else if (identifier is PrefixedIdentifier) {
506 int prefixIndex = prefixIndices.putIfAbsent(identifier.prefix.name,
507 () => serializeReference(null, identifier.prefix.name));
508 b.reference =
509 serializeReference(prefixIndex, identifier.identifier.name);
510 } else {
511 throw new StateError(
512 'Unexpected identifier type: ${identifier.runtimeType}');
513 }
514 if (node.typeArguments != null &&
515 node.typeArguments.arguments.any(isNotDynamic)) {
516 b.typeArguments =
517 node.typeArguments.arguments.map(serializeTypeName).toList();
518 }
519 }
520 return b;
521 }
522
523 /**
524 * Serialize the given [typeParameters] into a list of [UnlinkedTypeParam]s,
525 * and also store them in [typeParameterScope].
526 */
527 List<UnlinkedTypeParamBuilder> serializeTypeParameters(
528 TypeParameterList typeParameters,
529 _TypeParameterScope typeParameterScope) {
530 if (typeParameters != null) {
531 for (int i = 0; i < typeParameters.typeParameters.length; i++) {
532 TypeParameter typeParameter = typeParameters.typeParameters[i];
533 typeParameterScope[typeParameter.name.name] =
534 new _ScopedTypeParameter(typeParameters.typeParameters.length - i);
535 }
536 return typeParameters.typeParameters.map(visitTypeParameter).toList();
537 }
538 return const <UnlinkedTypeParamBuilder>[];
539 }
540
541 /**
542 * Serialize the given [variables] into [UnlinkedVariable]s, and store them
543 * in [this.variables].
544 */
545 void serializeVariables(VariableDeclarationList variables, bool isStatic,
546 Comment documentationComment) {
547 for (VariableDeclaration variable in variables.variables) {
548 UnlinkedVariableBuilder b = new UnlinkedVariableBuilder();
549 b.isFinal = variables.isFinal;
550 b.isConst = variables.isConst;
551 b.isStatic = isStatic;
552 b.name = variable.name.name;
553 b.nameOffset = variable.name.offset;
554 b.type = serializeTypeName(variables.type);
555 b.hasImplicitType = variables.type == null;
556 b.documentationComment = serializeDocumentation(documentationComment);
557 this.variables.add(b);
558 }
559 }
560
561 @override
562 void visitClassDeclaration(ClassDeclaration node) {
563 currentClassDeclaration = node;
564 TypeName superclass =
565 node.extendsClause == null ? null : node.extendsClause.superclass;
566 serializeClass(
567 node.abstractKeyword,
568 node.name.name,
569 node.name.offset,
570 node.typeParameters,
571 superclass,
572 node.withClause,
573 node.implementsClause,
574 node.members,
575 false,
576 node.documentationComment);
577 currentClassDeclaration = null;
578 }
579
580 @override
581 void visitClassTypeAlias(ClassTypeAlias node) {
582 serializeClass(
583 node.abstractKeyword,
584 node.name.name,
585 node.name.offset,
586 node.typeParameters,
587 node.superclass,
588 node.withClause,
589 node.implementsClause,
590 null,
591 true,
592 node.documentationComment);
593 }
594
595 @override
596 void visitConstructorDeclaration(ConstructorDeclaration node) {
597 UnlinkedExecutableBuilder b = new UnlinkedExecutableBuilder();
598 if (node.name != null) {
599 b.name = node.name.name;
600 b.nameOffset = node.name.offset;
601 } else {
602 b.nameOffset = node.returnType.offset;
603 }
604 b.parameters = node.parameters.parameters
605 .map((FormalParameter p) => p.accept(this))
606 .toList();
607 b.kind = UnlinkedExecutableKind.constructor;
608 b.isFactory = node.factoryKeyword != null;
609 b.isConst = node.constKeyword != null;
610 b.isExternal = node.externalKeyword != null;
611 b.documentationComment = serializeDocumentation(node.documentationComment);
612 executables.add(b);
613 }
614
615 @override
616 UnlinkedParamBuilder visitDefaultFormalParameter(
617 DefaultFormalParameter node) {
618 return node.parameter.accept(this);
619 }
620
621 @override
622 void visitEnumDeclaration(EnumDeclaration node) {
623 UnlinkedEnumBuilder b = new UnlinkedEnumBuilder();
624 b.name = node.name.name;
625 b.nameOffset = node.name.offset;
626 b.values = node.constants
627 .map((EnumConstantDeclaration value) => new UnlinkedEnumValueBuilder(
628 name: value.name.name, nameOffset: value.name.offset))
629 .toList();
630 b.documentationComment = serializeDocumentation(node.documentationComment);
631 enums.add(b);
632 }
633
634 @override
635 void visitExportDirective(ExportDirective node) {
636 UnlinkedExportNonPublicBuilder b = new UnlinkedExportNonPublicBuilder(
637 uriOffset: node.uri.offset, uriEnd: node.uri.end, offset: node.offset);
638 exports.add(b);
639 }
640
641 @override
642 void visitFieldDeclaration(FieldDeclaration node) {
643 serializeVariables(
644 node.fields, node.staticKeyword != null, node.documentationComment);
645 }
646
647 @override
648 UnlinkedParamBuilder visitFieldFormalParameter(FieldFormalParameter node) {
649 UnlinkedParamBuilder b = serializeParameter(node);
650 b.isInitializingFormal = true;
651 if (node.type == null && node.parameters == null) {
652 b.hasImplicitType = true;
653 } else {
654 b.isFunctionTyped = node.parameters != null;
655 if (node.parameters != null) {
656 serializeFunctionTypedParameterDetails(b, node.type, node.parameters);
657 } else {
658 TypeName typeName = node.type;
659 if (typeName == null) {
660 typeName = getFieldType(node.identifier.name);
661 }
662 b.type = serializeTypeName(typeName);
663 }
664 }
665 return b;
666 }
667
668 @override
669 void visitFunctionDeclaration(FunctionDeclaration node) {
670 executables.add(serializeExecutable(
671 node.name,
672 node.isGetter,
673 node.isSetter,
674 node.returnType,
675 node.functionExpression.parameters,
676 node.functionExpression.body,
677 true,
678 false,
679 node.documentationComment,
680 node.functionExpression.typeParameters,
681 node.externalKeyword != null));
682 }
683
684 @override
685 void visitFunctionTypeAlias(FunctionTypeAlias node) {
686 int oldScopesLength = scopes.length;
687 _TypeParameterScope typeParameterScope = new _TypeParameterScope();
688 scopes.add(typeParameterScope);
689 UnlinkedTypedefBuilder b = new UnlinkedTypedefBuilder();
690 b.name = node.name.name;
691 b.nameOffset = node.name.offset;
692 b.typeParameters =
693 serializeTypeParameters(node.typeParameters, typeParameterScope);
694 UnlinkedTypeRefBuilder serializedReturnType =
695 serializeTypeName(node.returnType, allowVoid: true);
696 if (serializedReturnType != null) {
697 b.returnType = serializedReturnType;
698 }
699 b.parameters = node.parameters.parameters
700 .map((FormalParameter p) => p.accept(this))
701 .toList();
702 b.documentationComment = serializeDocumentation(node.documentationComment);
703 typedefs.add(b);
704 scopes.removeLast();
705 assert(scopes.length == oldScopesLength);
706 }
707
708 @override
709 UnlinkedParamBuilder visitFunctionTypedFormalParameter(
710 FunctionTypedFormalParameter node) {
711 UnlinkedParamBuilder b = serializeParameter(node);
712 b.isFunctionTyped = true;
713 serializeFunctionTypedParameterDetails(b, node.returnType, node.parameters);
714 return b;
715 }
716
717 @override
718 void visitImportDirective(ImportDirective node) {
719 UnlinkedImportBuilder b = new UnlinkedImportBuilder();
720 if (node.uri.stringValue == 'dart:core') {
721 hasCoreBeenImported = true;
722 }
723 b.offset = node.offset;
724 b.combinators = node.combinators.map(serializeCombinator).toList();
725 if (node.prefix != null) {
726 b.prefixReference = serializeReference(null, node.prefix.name);
727 b.prefixOffset = node.prefix.offset;
728 }
729 b.isDeferred = node.deferredKeyword != null;
730 b.uri = node.uri.stringValue;
731 b.uriOffset = node.uri.offset;
732 b.uriEnd = node.uri.end;
733 unlinkedImports.add(b);
734 }
735
736 @override
737 void visitLibraryDirective(LibraryDirective node) {
738 libraryName =
739 node.name.components.map((SimpleIdentifier id) => id.name).join('.');
740 libraryNameOffset = node.name.offset;
741 libraryNameLength = node.name.length;
742 libraryDocumentationComment =
743 serializeDocumentation(node.documentationComment);
744 }
745
746 @override
747 void visitMethodDeclaration(MethodDeclaration node) {
748 executables.add(serializeExecutable(
749 node.name,
750 node.isGetter,
751 node.isSetter,
752 node.returnType,
753 node.parameters,
754 node.body,
755 false,
756 node.isStatic,
757 node.documentationComment,
758 node.typeParameters,
759 node.externalKeyword != null));
760 }
761
762 @override
763 void visitPartDirective(PartDirective node) {
764 parts.add(new UnlinkedPartBuilder(
765 uriOffset: node.uri.offset, uriEnd: node.uri.end));
766 }
767
768 @override
769 void visitPartOfDirective(PartOfDirective node) {}
770
771 @override
772 UnlinkedParamBuilder visitSimpleFormalParameter(SimpleFormalParameter node) {
773 UnlinkedParamBuilder b = serializeParameter(node);
774 b.type = serializeTypeName(node.type);
775 b.hasImplicitType = node.type == null;
776 return b;
777 }
778
779 @override
780 void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
781 serializeVariables(node.variables, false, node.documentationComment);
782 }
783
784 @override
785 UnlinkedTypeParamBuilder visitTypeParameter(TypeParameter node) {
786 UnlinkedTypeParamBuilder b = new UnlinkedTypeParamBuilder();
787 b.name = node.name.name;
788 b.nameOffset = node.name.offset;
789 if (node.bound != null) {
790 b.bound = serializeTypeName(node.bound);
791 }
792 return b;
793 }
794
795 /**
796 * Helper method to determine if a given [typeName] refers to `dynamic`.
797 */
798 static bool isNotDynamic(TypeName typeName) {
799 Identifier name = typeName.name;
800 return !(name is SimpleIdentifier && name.name == 'dynamic');
801 }
802 }
803
804 /**
805 * A [_TypeParameterScope] is a [_Scope] which defines [_ScopedTypeParameter]s.
806 */
807 class _TypeParameterScope extends _Scope {
808 /**
809 * Get the number of [_ScopedTypeParameter]s defined in this
810 * [_TypeParameterScope].
811 */
812 int get length => _definedNames.length;
813 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/test/src/summary/summary_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698