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

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

Issue 2990843002: Removed fixed dependencies (Closed)
Patch Set: Created 3 years, 4 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
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/dart/ast/ast.dart';
8 import 'package:analyzer/dart/ast/token.dart';
9 import 'package:analyzer/dart/ast/visitor.dart';
10 import 'package:analyzer/dart/element/type.dart' show DartType;
11 import 'package:analyzer/src/generated/utilities_dart.dart';
12 import 'package:analyzer/src/summary/format.dart';
13 import 'package:analyzer/src/summary/idl.dart';
14 import 'package:analyzer/src/summary/public_namespace_computer.dart';
15 import 'package:analyzer/src/summary/summarize_const_expr.dart';
16
17 /**
18 * Serialize all the declarations in [compilationUnit] to an unlinked summary.
19 */
20 UnlinkedUnitBuilder serializeAstUnlinked(CompilationUnit compilationUnit) {
21 return new _SummarizeAstVisitor().serializeCompilationUnit(compilationUnit);
22 }
23
24 /**
25 * Instances of this class keep track of intermediate state during
26 * serialization of a single constant [Expression].
27 */
28 class _ConstExprSerializer extends AbstractConstExprSerializer {
29 final _SummarizeAstVisitor visitor;
30
31 /**
32 * If the expression being serialized can contain closures, map whose
33 * keys are the offsets of local function nodes representing those closures,
34 * and whose values are indices of those local functions relative to their
35 * siblings.
36 */
37 final Map<int, int> localClosureIndexMap;
38
39 /**
40 * If the expression being serialized appears inside a function body, the name s
41 * of parameters that are in scope. Otherwise `null`.
42 */
43 final Set<String> parameterNames;
44
45 _ConstExprSerializer(
46 this.visitor, this.localClosureIndexMap, this.parameterNames);
47
48 @override
49 bool isParameterName(String name) {
50 return parameterNames?.contains(name) ?? false;
51 }
52
53 @override
54 void serializeAnnotation(Annotation annotation) {
55 if (annotation.arguments == null) {
56 assert(annotation.constructorName == null);
57 serialize(annotation.name);
58 } else {
59 Identifier name = annotation.name;
60 EntityRefBuilder constructor;
61 if (name is PrefixedIdentifier && annotation.constructorName == null) {
62 constructor =
63 serializeConstructorRef(null, name.prefix, null, name.identifier);
64 } else {
65 constructor = serializeConstructorRef(
66 null, annotation.name, null, annotation.constructorName);
67 }
68 serializeInstanceCreation(constructor, annotation.arguments);
69 }
70 }
71
72 @override
73 EntityRefBuilder serializeConstructorRef(DartType type, Identifier typeName,
74 TypeArgumentList typeArguments, SimpleIdentifier name) {
75 EntityRefBuilder typeBuilder = serializeType(type, typeName, typeArguments);
76 if (name == null) {
77 return typeBuilder;
78 } else {
79 int nameRef =
80 visitor.serializeReference(typeBuilder.reference, name.name);
81 return new EntityRefBuilder(
82 reference: nameRef, typeArguments: typeBuilder.typeArguments);
83 }
84 }
85
86 @override
87 List<int> serializeFunctionExpression(FunctionExpression functionExpression) {
88 int localIndex;
89 if (localClosureIndexMap == null) {
90 return null;
91 } else {
92 localIndex = localClosureIndexMap[functionExpression.offset];
93 assert(localIndex != null);
94 return <int>[0, localIndex];
95 }
96 }
97
98 EntityRefBuilder serializeIdentifier(Identifier identifier) {
99 EntityRefBuilder b = new EntityRefBuilder();
100 if (identifier is SimpleIdentifier) {
101 int index = visitor.serializeSimpleReference(identifier.name,
102 allowTypeParameter: true);
103 if (index < 0) {
104 b.paramReference = -index;
105 } else {
106 b.reference = index;
107 }
108 } else if (identifier is PrefixedIdentifier) {
109 int prefix = visitor.serializeSimpleReference(identifier.prefix.name);
110 b.reference =
111 visitor.serializeReference(prefix, identifier.identifier.name);
112 } else {
113 throw new StateError(
114 'Unexpected identifier type: ${identifier.runtimeType}');
115 }
116 return b;
117 }
118
119 @override
120 EntityRefBuilder serializeIdentifierSequence(Expression expr) {
121 if (expr is Identifier) {
122 AstNode parent = expr.parent;
123 if (parent is MethodInvocation &&
124 parent.methodName == expr &&
125 parent.target != null) {
126 int targetId = serializeIdentifierSequence(parent.target).reference;
127 int nameId = visitor.serializeReference(targetId, expr.name);
128 return new EntityRefBuilder(reference: nameId);
129 }
130 return serializeIdentifier(expr);
131 }
132 if (expr is PropertyAccess) {
133 int targetId = serializeIdentifierSequence(expr.target).reference;
134 int nameId = visitor.serializeReference(targetId, expr.propertyName.name);
135 return new EntityRefBuilder(reference: nameId);
136 } else {
137 throw new StateError('Unexpected node type: ${expr.runtimeType}');
138 }
139 }
140
141 @override
142 EntityRefBuilder serializeType(
143 DartType type, Identifier name, TypeArgumentList arguments) {
144 return visitor.serializeType(name, arguments);
145 }
146 }
147
148 /**
149 * A [_Scope] represents a set of name/value pairs defined locally within a
150 * limited span of a compilation unit. (Note that the spec also uses the term
151 * "scope" to refer to the set of names defined at top level within a
152 * compilation unit, but we do not use [_Scope] for that purpose).
153 */
154 class _Scope {
155 /**
156 * Names defined in this scope, and their meanings.
157 */
158 Map<String, _ScopedEntity> _definedNames = <String, _ScopedEntity>{};
159
160 /**
161 * Look up the meaning associated with the given [name], and return it. If
162 * [name] is not defined in this scope, return `null`.
163 */
164 _ScopedEntity operator [](String name) => _definedNames[name];
165
166 /**
167 * Let the given [name] refer to [entity] within this scope.
168 */
169 void operator []=(String name, _ScopedEntity entity) {
170 _definedNames[name] = entity;
171 }
172 }
173
174 /**
175 * A [_ScopedClassMember] is a [_ScopedEntity] refers to a member of a class.
176 */
177 class _ScopedClassMember extends _ScopedEntity {
178 /**
179 * The name of the class.
180 */
181 final String className;
182
183 _ScopedClassMember(this.className);
184 }
185
186 /**
187 * Base class for entities that can live inside a scope.
188 */
189 abstract class _ScopedEntity {}
190
191 /**
192 * A [_ScopedTypeParameter] is a [_ScopedEntity] that refers to a type
193 * parameter of a class, typedef, or executable.
194 */
195 class _ScopedTypeParameter extends _ScopedEntity {
196 /**
197 * Index of the type parameter within this scope. Since summaries use De
198 * Bruijn indices to refer to type parameters, which count upwards from the
199 * innermost bound name, the last type parameter in the scope has an index of
200 * 1, and each preceding type parameter has the next higher index.
201 */
202 final int index;
203
204 _ScopedTypeParameter(this.index);
205 }
206
207 /**
208 * Visitor used to create a summary from an AST.
209 */
210 class _SummarizeAstVisitor extends RecursiveAstVisitor {
211 /**
212 * List of objects which should be written to [UnlinkedUnit.classes].
213 */
214 final List<UnlinkedClassBuilder> classes = <UnlinkedClassBuilder>[];
215
216 /**
217 * List of objects which should be written to [UnlinkedUnit.enums].
218 */
219 final List<UnlinkedEnumBuilder> enums = <UnlinkedEnumBuilder>[];
220
221 /**
222 * List of objects which should be written to [UnlinkedUnit.executables],
223 * [UnlinkedClass.executables] or [UnlinkedExecutable.localFunctions].
224 */
225 List<UnlinkedExecutableBuilder> executables = <UnlinkedExecutableBuilder>[];
226
227 /**
228 * List of objects which should be written to [UnlinkedUnit.exports].
229 */
230 final List<UnlinkedExportNonPublicBuilder> exports =
231 <UnlinkedExportNonPublicBuilder>[];
232
233 /**
234 * List of objects which should be written to
235 * [UnlinkedExecutable.localLabels].
236 */
237 List<UnlinkedLabelBuilder> labels = <UnlinkedLabelBuilder>[];
238
239 /**
240 * List of objects which should be written to [UnlinkedUnit.parts].
241 */
242 final List<UnlinkedPartBuilder> parts = <UnlinkedPartBuilder>[];
243
244 /**
245 * List of objects which should be written to [UnlinkedUnit.typedefs].
246 */
247 final List<UnlinkedTypedefBuilder> typedefs = <UnlinkedTypedefBuilder>[];
248
249 /**
250 * List of objects which should be written to [UnlinkedUnit.variables],
251 * [UnlinkedClass.fields] or [UnlinkedExecutable.localVariables].
252 */
253 List<UnlinkedVariableBuilder> variables = <UnlinkedVariableBuilder>[];
254
255 /**
256 * The unlinked portion of the "imports table". This is the list of objects
257 * which should be written to [UnlinkedUnit.imports].
258 */
259 final List<UnlinkedImportBuilder> unlinkedImports = <UnlinkedImportBuilder>[];
260
261 /**
262 * The unlinked portion of the "references table". This is the list of
263 * objects which should be written to [UnlinkedUnit.references].
264 */
265 final List<UnlinkedReferenceBuilder> unlinkedReferences =
266 <UnlinkedReferenceBuilder>[new UnlinkedReferenceBuilder()];
267
268 /**
269 * Map associating names used as prefixes in this compilation unit with their
270 * associated indices into [UnlinkedUnit.references].
271 */
272 final Map<String, int> prefixIndices = <String, int>{};
273
274 /**
275 * List of [_Scope]s currently in effect. This is used to resolve type names
276 * to type parameters within classes, typedefs, and executables, as well as
277 * references to class members.
278 */
279 final List<_Scope> scopes = <_Scope>[];
280
281 /**
282 * True if 'dart:core' has been explicitly imported.
283 */
284 bool hasCoreBeenImported = false;
285
286 /**
287 * Names referenced by this compilation unit. Structured as a map from
288 * prefix index to (map from name to reference table index), where "prefix
289 * index" means the index into [UnlinkedUnit.references] of the prefix (or
290 * `null` if there is no prefix), and "reference table index" means the index
291 * into [UnlinkedUnit.references] for the name itself.
292 */
293 final Map<int, Map<String, int>> nameToReference = <int, Map<String, int>>{};
294
295 /**
296 * True if the 'dart:core' library is been summarized.
297 */
298 bool isCoreLibrary = false;
299
300 /**
301 * If the library has a library directive, the library name derived from it.
302 * Otherwise `null`.
303 */
304 String libraryName;
305
306 /**
307 * If the library has a library directive, the offset of the library name.
308 * Otherwise `null`.
309 */
310 int libraryNameOffset;
311
312 /**
313 * If the library has a library directive, the length of the library name, as
314 * it appears in the source file. Otherwise `null`.
315 */
316 int libraryNameLength;
317
318 /**
319 * If the library has a library directive, the documentation comment for it
320 * (if any). Otherwise `null`.
321 */
322 UnlinkedDocumentationCommentBuilder libraryDocumentationComment;
323
324 /**
325 * If the library has a library directive, the annotations for it (if any).
326 * Otherwise `null`.
327 */
328 List<UnlinkedConst> libraryAnnotations = const <UnlinkedConstBuilder>[];
329
330 /**
331 * The number of slot ids which have been assigned to this compilation unit.
332 */
333 int numSlots = 0;
334
335 /**
336 * The [Block] that is being visited now, or `null` for non-local contexts.
337 */
338 Block enclosingBlock = null;
339
340 /**
341 * If an expression is being serialized which can contain closures, map whose
342 * keys are the offsets of local function nodes representing those closures,
343 * and whose values are indices of those local functions relative to their
344 * siblings.
345 */
346 Map<int, int> _localClosureIndexMap;
347
348 /**
349 * Indicates whether closure function bodies should be serialized. This flag
350 * is set while visiting the bodies of initializer expressions that will be
351 * needed by type inference.
352 */
353 bool _serializeClosureBodyExprs = false;
354
355 /**
356 * If a closure function body is being serialized, the set of closure
357 * parameter names which are currently in scope. Otherwise `null`.
358 */
359 Set<String> _parameterNames;
360
361 /**
362 * Indicates whether parameters found during visitors might inherit
363 * covariance.
364 */
365 bool _parametersMayInheritCovariance = false;
366
367 /**
368 * Create a slot id for storing a propagated or inferred type or const cycle
369 * info.
370 */
371 int assignSlot() => ++numSlots;
372
373 /**
374 * Build a [_Scope] object containing the names defined within the body of a
375 * class declaration.
376 */
377 _Scope buildClassMemberScope(
378 String className, NodeList<ClassMember> members) {
379 _Scope scope = new _Scope();
380 for (ClassMember member in members) {
381 if (member is MethodDeclaration) {
382 if (member.isSetter || member.isOperator) {
383 // We don't have to handle setters or operators because the only
384 // things we look up are type names and identifiers.
385 } else {
386 scope[member.name.name] = new _ScopedClassMember(className);
387 }
388 } else if (member is FieldDeclaration) {
389 for (VariableDeclaration field in member.fields.variables) {
390 // A field declaration introduces two names, one with a trailing `=`.
391 // We don't have to worry about the one with a trailing `=` because
392 // the only things we look up are type names and identifiers.
393 scope[field.name.name] = new _ScopedClassMember(className);
394 }
395 }
396 }
397 return scope;
398 }
399
400 /**
401 * Serialize the given list of [annotations]. If there are no annotations,
402 * the empty list is returned.
403 */
404 List<UnlinkedConstBuilder> serializeAnnotations(
405 NodeList<Annotation> annotations) {
406 if (annotations == null || annotations.isEmpty) {
407 return const <UnlinkedConstBuilder>[];
408 }
409 return annotations.map((Annotation a) {
410 // Closures can't appear inside annotations, so we don't need a
411 // localClosureIndexMap.
412 Map<int, int> localClosureIndexMap = null;
413 _ConstExprSerializer serializer =
414 new _ConstExprSerializer(this, localClosureIndexMap, null);
415 serializer.serializeAnnotation(a);
416 return serializer.toBuilder();
417 }).toList();
418 }
419
420 /**
421 * Serialize a [ClassDeclaration] or [ClassTypeAlias] into an [UnlinkedClass]
422 * and store the result in [classes].
423 */
424 void serializeClass(
425 AstNode node,
426 Token abstractKeyword,
427 String name,
428 int nameOffset,
429 TypeParameterList typeParameters,
430 TypeName superclass,
431 WithClause withClause,
432 ImplementsClause implementsClause,
433 NodeList<ClassMember> members,
434 bool isMixinApplication,
435 Comment documentationComment,
436 NodeList<Annotation> annotations) {
437 int oldScopesLength = scopes.length;
438 List<UnlinkedExecutableBuilder> oldExecutables = executables;
439 executables = <UnlinkedExecutableBuilder>[];
440 List<UnlinkedVariableBuilder> oldVariables = variables;
441 variables = <UnlinkedVariableBuilder>[];
442 _TypeParameterScope typeParameterScope = new _TypeParameterScope();
443 scopes.add(typeParameterScope);
444 UnlinkedClassBuilder b = new UnlinkedClassBuilder();
445 b.name = name;
446 b.nameOffset = nameOffset;
447 b.isMixinApplication = isMixinApplication;
448 b.typeParameters =
449 serializeTypeParameters(typeParameters, typeParameterScope);
450 if (superclass != null) {
451 b.supertype = serializeTypeName(superclass);
452 } else {
453 b.hasNoSupertype = isCoreLibrary && name == 'Object';
454 }
455 if (withClause != null) {
456 b.mixins = withClause.mixinTypes.map(serializeTypeName).toList();
457 }
458 if (implementsClause != null) {
459 b.interfaces =
460 implementsClause.interfaces.map(serializeTypeName).toList();
461 }
462 if (members != null) {
463 scopes.add(buildClassMemberScope(name, members));
464 for (ClassMember member in members) {
465 member.accept(this);
466 }
467 scopes.removeLast();
468 }
469 b.executables = executables;
470 b.fields = variables;
471 b.isAbstract = abstractKeyword != null;
472 b.documentationComment = serializeDocumentation(documentationComment);
473 b.annotations = serializeAnnotations(annotations);
474 b.codeRange = serializeCodeRange(node);
475 classes.add(b);
476 scopes.removeLast();
477 assert(scopes.length == oldScopesLength);
478 executables = oldExecutables;
479 variables = oldVariables;
480 }
481
482 /**
483 * Create a [CodeRangeBuilder] for the given [node].
484 */
485 CodeRangeBuilder serializeCodeRange(AstNode node) {
486 return new CodeRangeBuilder(offset: node.offset, length: node.length);
487 }
488
489 /**
490 * Serialize a [Combinator] into an [UnlinkedCombinator].
491 */
492 UnlinkedCombinatorBuilder serializeCombinator(Combinator combinator) {
493 UnlinkedCombinatorBuilder b = new UnlinkedCombinatorBuilder();
494 if (combinator is ShowCombinator) {
495 b.shows =
496 combinator.shownNames.map((SimpleIdentifier id) => id.name).toList();
497 b.offset = combinator.offset;
498 b.end = combinator.end;
499 } else if (combinator is HideCombinator) {
500 b.hides =
501 combinator.hiddenNames.map((SimpleIdentifier id) => id.name).toList();
502 } else {
503 throw new StateError(
504 'Unexpected combinator type: ${combinator.runtimeType}');
505 }
506 return b;
507 }
508
509 /**
510 * Main entry point for serializing an AST.
511 */
512 UnlinkedUnitBuilder serializeCompilationUnit(
513 CompilationUnit compilationUnit) {
514 compilationUnit.directives.accept(this);
515 if (!hasCoreBeenImported) {
516 unlinkedImports.add(new UnlinkedImportBuilder(isImplicit: true));
517 }
518 compilationUnit.declarations.accept(this);
519 UnlinkedUnitBuilder b = new UnlinkedUnitBuilder();
520 b.lineStarts = compilationUnit.lineInfo?.lineStarts;
521 b.libraryName = libraryName;
522 b.libraryNameOffset = libraryNameOffset;
523 b.libraryNameLength = libraryNameLength;
524 b.libraryDocumentationComment = libraryDocumentationComment;
525 b.libraryAnnotations = libraryAnnotations;
526 b.codeRange = serializeCodeRange(compilationUnit);
527 b.classes = classes;
528 b.enums = enums;
529 b.executables = executables;
530 b.exports = exports;
531 b.imports = unlinkedImports;
532 b.parts = parts;
533 b.references = unlinkedReferences;
534 b.typedefs = typedefs;
535 b.variables = variables;
536 b.publicNamespace = computePublicNamespace(compilationUnit);
537 return b;
538 }
539
540 /**
541 * Serialize the given [expression], creating an [UnlinkedConstBuilder].
542 */
543 UnlinkedConstBuilder serializeConstExpr(
544 Map<int, int> localClosureIndexMap, Expression expression,
545 [Set<String> parameterNames]) {
546 _ConstExprSerializer serializer =
547 new _ConstExprSerializer(this, localClosureIndexMap, parameterNames);
548 serializer.serialize(expression);
549 return serializer.toBuilder();
550 }
551
552 /**
553 * Serialize the given [declaredIdentifier] into [UnlinkedVariable], and
554 * store it in [variables].
555 */
556 void serializeDeclaredIdentifier(
557 AstNode scopeNode,
558 Comment documentationComment,
559 NodeList<Annotation> annotations,
560 bool isFinal,
561 bool isConst,
562 TypeName type,
563 bool assignPropagatedTypeSlot,
564 SimpleIdentifier declaredIdentifier) {
565 UnlinkedVariableBuilder b = new UnlinkedVariableBuilder();
566 b.isFinal = isFinal;
567 b.isConst = isConst;
568 b.name = declaredIdentifier.name;
569 b.nameOffset = declaredIdentifier.offset;
570 b.type = serializeTypeName(type);
571 b.documentationComment = serializeDocumentation(documentationComment);
572 b.annotations = serializeAnnotations(annotations);
573 b.codeRange = serializeCodeRange(declaredIdentifier);
574 if (assignPropagatedTypeSlot) {
575 b.propagatedTypeSlot = assignSlot();
576 }
577 b.visibleOffset = scopeNode?.offset;
578 b.visibleLength = scopeNode?.length;
579 this.variables.add(b);
580 }
581
582 /**
583 * Serialize a [Comment] node into an [UnlinkedDocumentationComment] object.
584 */
585 UnlinkedDocumentationCommentBuilder serializeDocumentation(
586 Comment documentationComment) {
587 if (documentationComment == null) {
588 return null;
589 }
590 String text = documentationComment.tokens
591 .map((Token t) => t.toString())
592 .join()
593 .replaceAll('\r\n', '\n');
594 return new UnlinkedDocumentationCommentBuilder(text: text);
595 }
596
597 /**
598 * Serialize a [FunctionDeclaration] or [MethodDeclaration] into an
599 * [UnlinkedExecutable].
600 *
601 * If [serializeBodyExpr] is `true`, then the function definition is stored
602 * in [UnlinkedExecutableBuilder.bodyExpr].
603 */
604 UnlinkedExecutableBuilder serializeExecutable(
605 AstNode node,
606 String name,
607 int nameOffset,
608 bool isGetter,
609 bool isSetter,
610 TypeName returnType,
611 FormalParameterList formalParameters,
612 FunctionBody body,
613 bool isTopLevel,
614 bool isDeclaredStatic,
615 Comment documentationComment,
616 NodeList<Annotation> annotations,
617 TypeParameterList typeParameters,
618 bool isExternal,
619 bool serializeBodyExpr) {
620 int oldScopesLength = scopes.length;
621 _TypeParameterScope typeParameterScope = new _TypeParameterScope();
622 scopes.add(typeParameterScope);
623 UnlinkedExecutableBuilder b = new UnlinkedExecutableBuilder();
624 String nameString = name;
625 if (isGetter) {
626 b.kind = UnlinkedExecutableKind.getter;
627 } else if (isSetter) {
628 b.kind = UnlinkedExecutableKind.setter;
629 nameString = '$nameString=';
630 } else {
631 b.kind = UnlinkedExecutableKind.functionOrMethod;
632 }
633 b.isExternal = isExternal;
634 b.isAbstract = !isExternal && body is EmptyFunctionBody;
635 b.isAsynchronous = body.isAsynchronous;
636 b.isGenerator = body.isGenerator;
637 b.name = nameString;
638 b.nameOffset = nameOffset;
639 b.typeParameters =
640 serializeTypeParameters(typeParameters, typeParameterScope);
641 if (!isTopLevel) {
642 b.isStatic = isDeclaredStatic;
643 }
644 b.returnType = serializeTypeName(returnType);
645 bool isSemanticallyStatic = isTopLevel || isDeclaredStatic;
646 if (formalParameters != null) {
647 bool oldMayInheritCovariance = _parametersMayInheritCovariance;
648 _parametersMayInheritCovariance = !isTopLevel && !isDeclaredStatic;
649 b.parameters = formalParameters.parameters
650 .map((FormalParameter p) => p.accept(this) as UnlinkedParamBuilder)
651 .toList();
652 _parametersMayInheritCovariance = oldMayInheritCovariance;
653 if (!isSemanticallyStatic) {
654 for (int i = 0; i < formalParameters.parameters.length; i++) {
655 if (!b.parameters[i].isFunctionTyped &&
656 b.parameters[i].type == null) {
657 b.parameters[i].inferredTypeSlot = assignSlot();
658 }
659 }
660 }
661 }
662 b.documentationComment = serializeDocumentation(documentationComment);
663 b.annotations = serializeAnnotations(annotations);
664 b.codeRange = serializeCodeRange(node);
665 if (returnType == null && !isSemanticallyStatic) {
666 b.inferredReturnTypeSlot = assignSlot();
667 }
668 b.visibleOffset = enclosingBlock?.offset;
669 b.visibleLength = enclosingBlock?.length;
670 Set<String> oldParameterNames = _parameterNames;
671 if (formalParameters != null && formalParameters.parameters.isNotEmpty) {
672 _parameterNames =
673 _parameterNames == null ? new Set<String>() : _parameterNames.toSet();
674 _parameterNames.addAll(formalParameters.parameters
675 .map((FormalParameter p) => p.identifier.name));
676 }
677 serializeFunctionBody(b, null, body, serializeBodyExpr);
678 _parameterNames = oldParameterNames;
679 scopes.removeLast();
680 assert(scopes.length == oldScopesLength);
681 return b;
682 }
683
684 /**
685 * Record local functions and variables into the given executable. The given
686 * [body] is usually an actual [FunctionBody], but may be an [Expression]
687 * when we process a synthetic variable initializer function.
688 *
689 * If [initializers] is non-`null`, closures occurring inside the initializers
690 * are serialized first.
691 *
692 * If [serializeBodyExpr] is `true`, then the function definition is stored
693 * in [UnlinkedExecutableBuilder.bodyExpr], and closures occurring inside
694 * [initializers] and [body] have their function bodies serialized as well.
695 *
696 * The return value is a map whose keys are the offsets of local function
697 * nodes representing closures inside [initializers] and [body], and whose
698 * values are the indices of those local functions relative to their siblings.
699 */
700 Map<int, int> serializeFunctionBody(
701 UnlinkedExecutableBuilder b,
702 List<ConstructorInitializer> initializers,
703 AstNode body,
704 bool serializeBodyExpr) {
705 if (body is BlockFunctionBody || body is ExpressionFunctionBody) {
706 for (UnlinkedParamBuilder parameter in b.parameters) {
707 parameter.visibleOffset = body.offset;
708 parameter.visibleLength = body.length;
709 }
710 }
711 List<UnlinkedExecutableBuilder> oldExecutables = executables;
712 List<UnlinkedLabelBuilder> oldLabels = labels;
713 List<UnlinkedVariableBuilder> oldVariables = variables;
714 Map<int, int> oldLocalClosureIndexMap = _localClosureIndexMap;
715 bool oldSerializeClosureBodyExprs = _serializeClosureBodyExprs;
716 executables = <UnlinkedExecutableBuilder>[];
717 labels = <UnlinkedLabelBuilder>[];
718 variables = <UnlinkedVariableBuilder>[];
719 _localClosureIndexMap = <int, int>{};
720 _serializeClosureBodyExprs = serializeBodyExpr;
721 if (initializers != null) {
722 for (ConstructorInitializer initializer in initializers) {
723 initializer.accept(this);
724 }
725 }
726 body.accept(this);
727 if (serializeBodyExpr) {
728 if (body is Expression) {
729 b.bodyExpr =
730 serializeConstExpr(_localClosureIndexMap, body, _parameterNames);
731 } else if (body is ExpressionFunctionBody) {
732 b.bodyExpr = serializeConstExpr(
733 _localClosureIndexMap, body.expression, _parameterNames);
734 } else {
735 // TODO(paulberry): serialize other types of function bodies.
736 }
737 }
738 b.localFunctions = executables;
739 b.localLabels = labels;
740 b.localVariables = variables;
741 Map<int, int> localClosureIndexMap = _localClosureIndexMap;
742 executables = oldExecutables;
743 labels = oldLabels;
744 variables = oldVariables;
745 _localClosureIndexMap = oldLocalClosureIndexMap;
746 _serializeClosureBodyExprs = oldSerializeClosureBodyExprs;
747 return localClosureIndexMap;
748 }
749
750 /**
751 * Serialize the return type and parameters of a function-typed formal
752 * parameter and store them in [b].
753 */
754 void serializeFunctionTypedParameterDetails(UnlinkedParamBuilder b,
755 TypeName returnType, FormalParameterList parameters) {
756 EntityRefBuilder serializedReturnType = serializeTypeName(returnType);
757 if (serializedReturnType != null) {
758 b.type = serializedReturnType;
759 }
760 bool oldMayInheritCovariance = _parametersMayInheritCovariance;
761 _parametersMayInheritCovariance = false;
762 b.parameters = parameters.parameters
763 .map((FormalParameter p) => p.accept(this) as UnlinkedParamBuilder)
764 .toList();
765 _parametersMayInheritCovariance = oldMayInheritCovariance;
766 }
767
768 /**
769 * If the given [expression] is not `null`, serialize it as an
770 * [UnlinkedExecutableBuilder], otherwise return `null`.
771 *
772 * If [serializeBodyExpr] is `true`, then the initializer expression is stored
773 * in [UnlinkedExecutableBuilder.bodyExpr].
774 */
775 UnlinkedExecutableBuilder serializeInitializerFunction(
776 Expression expression, bool serializeBodyExpr) {
777 if (expression == null) {
778 return null;
779 }
780 UnlinkedExecutableBuilder initializer =
781 new UnlinkedExecutableBuilder(nameOffset: expression.offset);
782 serializeFunctionBody(initializer, null, expression, serializeBodyExpr);
783 initializer.inferredReturnTypeSlot = assignSlot();
784 return initializer;
785 }
786
787 /**
788 * Serialize a [FieldFormalParameter], [FunctionTypedFormalParameter], or
789 * [SimpleFormalParameter] into an [UnlinkedParam].
790 */
791 UnlinkedParamBuilder serializeParameter(NormalFormalParameter node) {
792 UnlinkedParamBuilder b = new UnlinkedParamBuilder();
793 b.name = node.identifier.name;
794 b.nameOffset = node.identifier.offset;
795 b.annotations = serializeAnnotations(node.metadata);
796 b.codeRange = serializeCodeRange(node);
797 if (_parametersMayInheritCovariance) {
798 b.inheritsCovariantSlot = assignSlot();
799 }
800 switch (node.kind) {
801 case ParameterKind.REQUIRED:
802 b.kind = UnlinkedParamKind.required;
803 break;
804 case ParameterKind.POSITIONAL:
805 b.kind = UnlinkedParamKind.positional;
806 break;
807 case ParameterKind.NAMED:
808 b.kind = UnlinkedParamKind.named;
809 break;
810 default:
811 throw new StateError('Unexpected parameter kind: ${node.kind}');
812 }
813 return b;
814 }
815
816 /**
817 * Serialize a reference to a top level name declared elsewhere, by adding an
818 * entry to the references table if necessary. If [prefixIndex] is not null,
819 * the reference is associated with the prefix having the given index in the
820 * references table.
821 */
822 int serializeReference(int prefixIndex, String name) => nameToReference
823 .putIfAbsent(prefixIndex, () => <String, int>{})
824 .putIfAbsent(name, () {
825 int index = unlinkedReferences.length;
826 unlinkedReferences.add(new UnlinkedReferenceBuilder(
827 prefixReference: prefixIndex, name: name));
828 return index;
829 });
830
831 /**
832 * Serialize a reference to a name declared either at top level or in a
833 * nested scope.
834 *
835 * If [allowTypeParameter] is `true`, then references to type
836 * parameters are allowed, and are returned as negative numbers.
837 */
838 int serializeSimpleReference(String name, {bool allowTypeParameter: false}) {
839 int indexOffset = 0;
840 for (int i = scopes.length - 1; i >= 0; i--) {
841 _Scope scope = scopes[i];
842 _ScopedEntity entity = scope[name];
843 if (entity != null) {
844 if (entity is _ScopedClassMember) {
845 return serializeReference(
846 serializeReference(null, entity.className), name);
847 } else if (allowTypeParameter && entity is _ScopedTypeParameter) {
848 int paramReference = indexOffset + entity.index;
849 return -paramReference;
850 } else {
851 // Invalid reference to a type parameter. Should never happen in
852 // legal Dart code.
853 // TODO(paulberry): could this exception ever be uncaught in illegal
854 // code?
855 throw new StateError('Invalid identifier reference');
856 }
857 }
858 if (scope is _TypeParameterScope) {
859 indexOffset += scope.length;
860 }
861 }
862 return serializeReference(null, name);
863 }
864
865 /**
866 * Serialize a type name (which might be defined in a nested scope, at top
867 * level within this library, or at top level within an imported library) to
868 * a [EntityRef]. Note that this method does the right thing if the
869 * name doesn't refer to an entity other than a type (e.g. a class member).
870 */
871 EntityRefBuilder serializeType(
872 Identifier identifier, TypeArgumentList typeArguments) {
873 if (identifier == null) {
874 return null;
875 } else {
876 EntityRefBuilder b = new EntityRefBuilder();
877 if (identifier is SimpleIdentifier) {
878 String name = identifier.name;
879 int indexOffset = 0;
880 for (int i = scopes.length - 1; i >= 0; i--) {
881 _Scope scope = scopes[i];
882 _ScopedEntity entity = scope[name];
883 if (entity != null) {
884 if (entity is _ScopedTypeParameter) {
885 b.paramReference = indexOffset + entity.index;
886 return b;
887 } else {
888 // None of the other things that can be declared in local scopes
889 // are types, so this is an error and should be treated as a
890 // reference to `dynamic`.
891 b.reference = serializeReference(null, 'dynamic');
892 return b;
893 }
894 }
895 if (scope is _TypeParameterScope) {
896 indexOffset += scope.length;
897 }
898 }
899 b.reference = serializeReference(null, name);
900 } else if (identifier is PrefixedIdentifier) {
901 int prefixIndex = prefixIndices.putIfAbsent(identifier.prefix.name,
902 () => serializeSimpleReference(identifier.prefix.name));
903 b.reference =
904 serializeReference(prefixIndex, identifier.identifier.name);
905 } else {
906 throw new StateError(
907 'Unexpected identifier type: ${identifier.runtimeType}');
908 }
909 if (typeArguments != null) {
910 b.typeArguments =
911 typeArguments.arguments.map(serializeTypeName).toList();
912 }
913 return b;
914 }
915 }
916
917 /**
918 * Serialize a type name (which might be defined in a nested scope, at top
919 * level within this library, or at top level within an imported library) to
920 * a [EntityRef]. Note that this method does the right thing if the
921 * name doesn't refer to an entity other than a type (e.g. a class member).
922 */
923 EntityRefBuilder serializeTypeName(TypeName node) {
924 return serializeType(node?.name, node?.typeArguments);
925 }
926
927 /**
928 * Serialize the given [typeParameters] into a list of [UnlinkedTypeParam]s,
929 * and also store them in [typeParameterScope].
930 */
931 List<UnlinkedTypeParamBuilder> serializeTypeParameters(
932 TypeParameterList typeParameters,
933 _TypeParameterScope typeParameterScope) {
934 if (typeParameters != null) {
935 for (int i = 0; i < typeParameters.typeParameters.length; i++) {
936 TypeParameter typeParameter = typeParameters.typeParameters[i];
937 typeParameterScope[typeParameter.name.name] =
938 new _ScopedTypeParameter(typeParameters.typeParameters.length - i);
939 }
940 return typeParameters.typeParameters.map(visitTypeParameter).toList();
941 }
942 return const <UnlinkedTypeParamBuilder>[];
943 }
944
945 /**
946 * Serialize the given [variables] into [UnlinkedVariable]s, and store them
947 * in [this.variables].
948 */
949 void serializeVariables(
950 AstNode scopeNode,
951 VariableDeclarationList variables,
952 bool isDeclaredStatic,
953 Comment documentationComment,
954 NodeList<Annotation> annotations,
955 bool isField) {
956 for (VariableDeclaration variable in variables.variables) {
957 UnlinkedVariableBuilder b = new UnlinkedVariableBuilder();
958 b.isFinal = variables.isFinal;
959 b.isConst = variables.isConst;
960 b.isStatic = isDeclaredStatic;
961 b.name = variable.name.name;
962 b.nameOffset = variable.name.offset;
963 b.type = serializeTypeName(variables.type);
964 b.documentationComment = serializeDocumentation(documentationComment);
965 b.annotations = serializeAnnotations(annotations);
966 b.codeRange = serializeCodeRange(variables.parent);
967 bool serializeBodyExpr = variable.isConst ||
968 variable.isFinal && isField && !isDeclaredStatic ||
969 variables.type == null;
970 b.initializer =
971 serializeInitializerFunction(variable.initializer, serializeBodyExpr);
972 if (variable.initializer != null &&
973 (variables.isFinal || variables.isConst)) {
974 b.propagatedTypeSlot = assignSlot();
975 }
976 bool isSemanticallyStatic = !isField || isDeclaredStatic;
977 if (variables.type == null &&
978 (variable.initializer != null || !isSemanticallyStatic)) {
979 b.inferredTypeSlot = assignSlot();
980 }
981 b.visibleOffset = scopeNode?.offset;
982 b.visibleLength = scopeNode?.length;
983 this.variables.add(b);
984 }
985 }
986
987 @override
988 void visitBlock(Block node) {
989 Block oldBlock = enclosingBlock;
990 enclosingBlock = node;
991 super.visitBlock(node);
992 enclosingBlock = oldBlock;
993 }
994
995 @override
996 void visitCatchClause(CatchClause node) {
997 SimpleIdentifier exception = node.exceptionParameter;
998 SimpleIdentifier st = node.stackTraceParameter;
999 if (exception != null) {
1000 serializeDeclaredIdentifier(
1001 node, null, null, false, false, node.exceptionType, false, exception);
1002 }
1003 if (st != null) {
1004 serializeDeclaredIdentifier(
1005 node, null, null, false, false, null, false, st);
1006 }
1007 super.visitCatchClause(node);
1008 }
1009
1010 @override
1011 void visitClassDeclaration(ClassDeclaration node) {
1012 TypeName superclass =
1013 node.extendsClause == null ? null : node.extendsClause.superclass;
1014 serializeClass(
1015 node,
1016 node.abstractKeyword,
1017 node.name.name,
1018 node.name.offset,
1019 node.typeParameters,
1020 superclass,
1021 node.withClause,
1022 node.implementsClause,
1023 node.members,
1024 false,
1025 node.documentationComment,
1026 node.metadata);
1027 }
1028
1029 @override
1030 void visitClassTypeAlias(ClassTypeAlias node) {
1031 serializeClass(
1032 node,
1033 node.abstractKeyword,
1034 node.name.name,
1035 node.name.offset,
1036 node.typeParameters,
1037 node.superclass,
1038 node.withClause,
1039 node.implementsClause,
1040 null,
1041 true,
1042 node.documentationComment,
1043 node.metadata);
1044 }
1045
1046 @override
1047 void visitConstructorDeclaration(ConstructorDeclaration node) {
1048 UnlinkedExecutableBuilder b = new UnlinkedExecutableBuilder();
1049 if (node.name != null) {
1050 b.name = node.name.name;
1051 b.nameOffset = node.name.offset;
1052 b.periodOffset = node.period.offset;
1053 b.nameEnd = node.name.end;
1054 } else {
1055 b.nameOffset = node.returnType.offset;
1056 }
1057 b.parameters = node.parameters.parameters
1058 .map((FormalParameter p) => p.accept(this) as UnlinkedParamBuilder)
1059 .toList();
1060 b.kind = UnlinkedExecutableKind.constructor;
1061 if (node.factoryKeyword != null) {
1062 b.isFactory = true;
1063 if (node.redirectedConstructor != null) {
1064 b.isRedirectedConstructor = true;
1065 TypeName typeName = node.redirectedConstructor.type;
1066 // Closures can't appear inside factory constructor redirections, so we
1067 // don't need a localClosureIndexMap.
1068 Map<int, int> localClosureIndexMap = null;
1069 b.redirectedConstructor =
1070 new _ConstExprSerializer(this, localClosureIndexMap, null)
1071 .serializeConstructorRef(null, typeName.name,
1072 typeName.typeArguments, node.redirectedConstructor.name);
1073 }
1074 } else {
1075 for (ConstructorInitializer initializer in node.initializers) {
1076 if (initializer is RedirectingConstructorInvocation) {
1077 b.isRedirectedConstructor = true;
1078 b.redirectedConstructorName = initializer.constructorName?.name;
1079 }
1080 }
1081 }
1082 if (node.constKeyword != null) {
1083 b.isConst = true;
1084 b.constCycleSlot = assignSlot();
1085 }
1086 b.isExternal = node.externalKeyword != null;
1087 b.documentationComment = serializeDocumentation(node.documentationComment);
1088 b.annotations = serializeAnnotations(node.metadata);
1089 b.codeRange = serializeCodeRange(node);
1090 Map<int, int> localClosureIndexMap = serializeFunctionBody(
1091 b, node.initializers, node.body, node.constKeyword != null);
1092 if (node.constKeyword != null) {
1093 Set<String> constructorParameterNames =
1094 node.parameters.parameters.map((p) => p.identifier.name).toSet();
1095 b.constantInitializers = node.initializers
1096 .map((ConstructorInitializer initializer) =>
1097 serializeConstructorInitializer(initializer, (Expression expr) {
1098 return serializeConstExpr(
1099 localClosureIndexMap, expr, constructorParameterNames);
1100 }))
1101 .toList();
1102 }
1103 executables.add(b);
1104 }
1105
1106 @override
1107 UnlinkedParamBuilder visitDefaultFormalParameter(
1108 DefaultFormalParameter node) {
1109 UnlinkedParamBuilder b =
1110 node.parameter.accept(this) as UnlinkedParamBuilder;
1111 b.initializer = serializeInitializerFunction(node.defaultValue, true);
1112 if (node.defaultValue != null) {
1113 b.defaultValueCode = node.defaultValue.toSource();
1114 }
1115 b.codeRange = serializeCodeRange(node);
1116 return b;
1117 }
1118
1119 @override
1120 void visitEnumDeclaration(EnumDeclaration node) {
1121 UnlinkedEnumBuilder b = new UnlinkedEnumBuilder();
1122 b.name = node.name.name;
1123 b.nameOffset = node.name.offset;
1124 b.values = node.constants
1125 .map((EnumConstantDeclaration value) => new UnlinkedEnumValueBuilder(
1126 documentationComment:
1127 serializeDocumentation(value.documentationComment),
1128 name: value.name.name,
1129 nameOffset: value.name.offset))
1130 .toList();
1131 b.documentationComment = serializeDocumentation(node.documentationComment);
1132 b.annotations = serializeAnnotations(node.metadata);
1133 b.codeRange = serializeCodeRange(node);
1134 enums.add(b);
1135 }
1136
1137 @override
1138 void visitExportDirective(ExportDirective node) {
1139 UnlinkedExportNonPublicBuilder b = new UnlinkedExportNonPublicBuilder(
1140 uriOffset: node.uri.offset, uriEnd: node.uri.end, offset: node.offset);
1141 b.annotations = serializeAnnotations(node.metadata);
1142 exports.add(b);
1143 }
1144
1145 @override
1146 void visitFieldDeclaration(FieldDeclaration node) {
1147 serializeVariables(null, node.fields, node.staticKeyword != null,
1148 node.documentationComment, node.metadata, true);
1149 }
1150
1151 @override
1152 UnlinkedParamBuilder visitFieldFormalParameter(FieldFormalParameter node) {
1153 UnlinkedParamBuilder b = serializeParameter(node);
1154 b.isInitializingFormal = true;
1155 if (node.type != null || node.parameters != null) {
1156 b.isFunctionTyped = node.parameters != null;
1157 if (node.parameters != null) {
1158 serializeFunctionTypedParameterDetails(b, node.type, node.parameters);
1159 } else {
1160 b.type = serializeTypeName(node.type);
1161 }
1162 }
1163 return b;
1164 }
1165
1166 @override
1167 void visitForEachStatement(ForEachStatement node) {
1168 DeclaredIdentifier loopVariable = node.loopVariable;
1169 if (loopVariable != null) {
1170 serializeDeclaredIdentifier(
1171 node,
1172 loopVariable.documentationComment,
1173 loopVariable.metadata,
1174 loopVariable.isFinal,
1175 loopVariable.isConst,
1176 loopVariable.type,
1177 true,
1178 loopVariable.identifier);
1179 }
1180 super.visitForEachStatement(node);
1181 }
1182
1183 @override
1184 void visitForStatement(ForStatement node) {
1185 VariableDeclarationList declaredVariables = node.variables;
1186 if (declaredVariables != null) {
1187 serializeVariables(node, declaredVariables, false, null, null, false);
1188 }
1189 super.visitForStatement(node);
1190 }
1191
1192 @override
1193 void visitFunctionDeclaration(FunctionDeclaration node) {
1194 executables.add(serializeExecutable(
1195 node,
1196 node.name.name,
1197 node.name.offset,
1198 node.isGetter,
1199 node.isSetter,
1200 node.returnType,
1201 node.functionExpression.parameters,
1202 node.functionExpression.body,
1203 true,
1204 false,
1205 node.documentationComment,
1206 node.metadata,
1207 node.functionExpression.typeParameters,
1208 node.externalKeyword != null,
1209 false));
1210 }
1211
1212 @override
1213 void visitFunctionExpression(FunctionExpression node) {
1214 if (node.parent is! FunctionDeclaration) {
1215 if (_localClosureIndexMap != null) {
1216 _localClosureIndexMap[node.offset] = executables.length;
1217 }
1218 executables.add(serializeExecutable(
1219 node,
1220 null,
1221 node.offset,
1222 false,
1223 false,
1224 null,
1225 node.parameters,
1226 node.body,
1227 false,
1228 false,
1229 null,
1230 null,
1231 node.typeParameters,
1232 false,
1233 _serializeClosureBodyExprs));
1234 }
1235 }
1236
1237 @override
1238 void visitFunctionTypeAlias(FunctionTypeAlias node) {
1239 int oldScopesLength = scopes.length;
1240 _TypeParameterScope typeParameterScope = new _TypeParameterScope();
1241 scopes.add(typeParameterScope);
1242 UnlinkedTypedefBuilder b = new UnlinkedTypedefBuilder();
1243 b.name = node.name.name;
1244 b.nameOffset = node.name.offset;
1245 b.typeParameters =
1246 serializeTypeParameters(node.typeParameters, typeParameterScope);
1247 EntityRefBuilder serializedReturnType = serializeTypeName(node.returnType);
1248 if (serializedReturnType != null) {
1249 b.returnType = serializedReturnType;
1250 }
1251 b.parameters = node.parameters.parameters
1252 .map((FormalParameter p) => p.accept(this) as UnlinkedParamBuilder)
1253 .toList();
1254 b.documentationComment = serializeDocumentation(node.documentationComment);
1255 b.annotations = serializeAnnotations(node.metadata);
1256 b.codeRange = serializeCodeRange(node);
1257 typedefs.add(b);
1258 scopes.removeLast();
1259 assert(scopes.length == oldScopesLength);
1260 }
1261
1262 @override
1263 UnlinkedParamBuilder visitFunctionTypedFormalParameter(
1264 FunctionTypedFormalParameter node) {
1265 UnlinkedParamBuilder b = serializeParameter(node);
1266 b.isFunctionTyped = true;
1267 serializeFunctionTypedParameterDetails(b, node.returnType, node.parameters);
1268 return b;
1269 }
1270
1271 @override
1272 void visitImportDirective(ImportDirective node) {
1273 UnlinkedImportBuilder b = new UnlinkedImportBuilder();
1274 b.annotations = serializeAnnotations(node.metadata);
1275 if (node.uri.stringValue == 'dart:core') {
1276 hasCoreBeenImported = true;
1277 }
1278 b.offset = node.offset;
1279 b.combinators = node.combinators.map(serializeCombinator).toList();
1280 b.configurations = node.configurations.map(serializeConfiguration).toList();
1281 if (node.prefix != null) {
1282 b.prefixReference = serializeReference(null, node.prefix.name);
1283 b.prefixOffset = node.prefix.offset;
1284 }
1285 b.isDeferred = node.deferredKeyword != null;
1286 b.uri = node.uri.stringValue;
1287 b.uriOffset = node.uri.offset;
1288 b.uriEnd = node.uri.end;
1289 unlinkedImports.add(b);
1290 }
1291
1292 @override
1293 void visitLabel(Label node) {
1294 AstNode parent = node.parent;
1295 if (parent is! NamedExpression) {
1296 labels.add(new UnlinkedLabelBuilder(
1297 name: node.label.name,
1298 nameOffset: node.offset,
1299 isOnSwitchMember: parent is SwitchMember,
1300 isOnSwitchStatement: parent is LabeledStatement &&
1301 parent.statement is SwitchStatement));
1302 }
1303 }
1304
1305 @override
1306 void visitLibraryDirective(LibraryDirective node) {
1307 libraryName =
1308 node.name.components.map((SimpleIdentifier id) => id.name).join('.');
1309 libraryNameOffset = node.name.offset;
1310 libraryNameLength = node.name.length;
1311 isCoreLibrary = libraryName == 'dart.core';
1312 libraryDocumentationComment =
1313 serializeDocumentation(node.documentationComment);
1314 libraryAnnotations = serializeAnnotations(node.metadata);
1315 }
1316
1317 @override
1318 void visitMethodDeclaration(MethodDeclaration node) {
1319 executables.add(serializeExecutable(
1320 node,
1321 node.name.name,
1322 node.name.offset,
1323 node.isGetter,
1324 node.isSetter,
1325 node.returnType,
1326 node.parameters,
1327 node.body,
1328 false,
1329 node.isStatic,
1330 node.documentationComment,
1331 node.metadata,
1332 node.typeParameters,
1333 node.externalKeyword != null,
1334 false));
1335 }
1336
1337 @override
1338 void visitPartDirective(PartDirective node) {
1339 parts.add(new UnlinkedPartBuilder(
1340 uriOffset: node.uri.offset,
1341 uriEnd: node.uri.end,
1342 annotations: serializeAnnotations(node.metadata)));
1343 }
1344
1345 @override
1346 void visitPartOfDirective(PartOfDirective node) {
1347 isCoreLibrary = node.libraryName.name == 'dart.core';
1348 }
1349
1350 @override
1351 UnlinkedParamBuilder visitSimpleFormalParameter(SimpleFormalParameter node) {
1352 UnlinkedParamBuilder b = serializeParameter(node);
1353 b.type = serializeTypeName(node.type);
1354 return b;
1355 }
1356
1357 @override
1358 void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
1359 serializeVariables(null, node.variables, false, node.documentationComment,
1360 node.metadata, false);
1361 }
1362
1363 @override
1364 UnlinkedTypeParamBuilder visitTypeParameter(TypeParameter node) {
1365 UnlinkedTypeParamBuilder b = new UnlinkedTypeParamBuilder();
1366 b.name = node.name.name;
1367 b.nameOffset = node.name.offset;
1368 if (node.bound != null) {
1369 b.bound = serializeTypeName(node.bound);
1370 }
1371 b.annotations = serializeAnnotations(node.metadata);
1372 b.codeRange = serializeCodeRange(node);
1373 return b;
1374 }
1375
1376 @override
1377 void visitVariableDeclarationStatement(VariableDeclarationStatement node) {
1378 serializeVariables(
1379 enclosingBlock, node.variables, false, null, null, false);
1380 }
1381
1382 /**
1383 * Helper method to determine if a given [typeName] refers to `dynamic`.
1384 */
1385 static bool isDynamic(TypeName typeName) {
1386 Identifier name = typeName.name;
1387 return name is SimpleIdentifier && name.name == 'dynamic';
1388 }
1389 }
1390
1391 /**
1392 * A [_TypeParameterScope] is a [_Scope] which defines [_ScopedTypeParameter]s.
1393 */
1394 class _TypeParameterScope extends _Scope {
1395 /**
1396 * Get the number of [_ScopedTypeParameter]s defined in this
1397 * [_TypeParameterScope].
1398 */
1399 int get length => _definedNames.length;
1400 }
OLDNEW
« no previous file with comments | « packages/analyzer/lib/src/summary/resynthesize.dart ('k') | packages/analyzer/lib/src/summary/summarize_const_expr.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698