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

Side by Side Diff: pkg/compiler/lib/src/dart_backend/placeholder_collector.dart

Issue 2213673002: Delete dart_backend from compiler. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 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) 2012, 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 part of dart_backend;
6
7 class LocalPlaceholder {
8 final String identifier;
9 final Set<Node> nodes;
10 LocalPlaceholder(this.identifier) : nodes = new Set<Node>();
11 int get hashCode => identifier.hashCode;
12 String toString() => 'local_placeholder[id($identifier), nodes($nodes)]';
13 }
14
15 class FunctionScope {
16 final Set<String> parameterIdentifiers;
17 final Set<LocalPlaceholder> localPlaceholders;
18 FunctionScope()
19 : parameterIdentifiers = new Set<String>(),
20 localPlaceholders = new Set<LocalPlaceholder>();
21 void registerParameter(Identifier node) {
22 parameterIdentifiers.add(node.source);
23 }
24 }
25
26 class ConstructorPlaceholder {
27 final Identifier node;
28 final ConstructorElement element;
29
30 ConstructorPlaceholder(this.node, this.element);
31 }
32
33 class DeclarationTypePlaceholder {
34 final TypeAnnotation typeNode;
35 final bool requiresVar;
36 DeclarationTypePlaceholder(this.typeNode, this.requiresVar);
37 }
38
39 class SendVisitor extends Visitor {
40 final TreeElements elements;
41 final PlaceholderCollector collector;
42
43 SendVisitor(this.collector, this.elements);
44
45 visitSend(Send node) {
46 Element element = elements[node];
47 if (elements.isTypeLiteral(node)) {
48 DartType type = elements.getTypeLiteralType(node);
49 if (!type.isDynamic) {
50 if (type is TypeVariableType) {
51 collector.makeTypeVariablePlaceholder(node.selector, type);
52 } else {
53 collector.makeTypePlaceholder(node.selector, type);
54 }
55 }
56 } else if (node.isSuperCall) {
57 if (element != null && element.isConstructor) {
58 collector.tryMakeConstructorPlaceholder(node, element);
59 } else {
60 collector.tryMakeMemberPlaceholder(node.selector);
61 }
62 } else if (node.isOperator) {
63 return;
64 } else if (node.isPropertyAccess) {
65 if (!Elements.isUnresolved(element) && element.impliesType) {
66 collector.makeElementPlaceholder(node, element);
67 } else {
68 visitGetterSend(node);
69 }
70 } else if (element != null && Initializers.isConstructorRedirect(node)) {
71 visitStaticSend(node);
72 } else if (Elements.isClosureSend(node, element)) {
73 if (element != null) {
74 collector.tryMakeLocalPlaceholder(element, node.selector);
75 }
76 } else {
77 if (Elements.isUnresolved(element)) {
78 if (element == null) {
79 // Example: f() with 'f' unbound.
80 // This can only happen inside an instance method.
81 visitDynamicSend(node);
82 } else {
83 visitStaticSend(node);
84 }
85 } else if (element.isInstanceMember) {
86 // Example: f() with 'f' bound to instance method.
87 visitDynamicSend(node);
88 } else if (!element.isInstanceMember) {
89 // Example: A.f() or f() with 'f' bound to a static function.
90 // Also includes new A() or new A.named() which is treated like a
91 // static call to a factory.
92 visitStaticSend(node);
93 }
94 }
95 }
96
97 visitDynamicSend(Send node) {
98 final element = elements[node];
99 if (element == null || !element.isMalformed) {
100 collector.tryMakeMemberPlaceholder(node.selector);
101 }
102 }
103
104 visitGetterSend(Send node) {
105 final element = elements[node];
106 // element == null means dynamic property access.
107 if (element == null) {
108 collector.tryMakeMemberPlaceholder(node.selector);
109 } else if (element.isMalformed) {
110 collector.makeUnresolvedPlaceholder(node);
111 return;
112 } else if (element.isPrefix) {
113 // Node is prefix part in case of source 'lib.somesetter = 5;'
114 collector.makeErasePrefixPlaceholder(node);
115 } else if (Elements.isStaticOrTopLevel(element)) {
116 // Unqualified or prefixed top level or static.
117 collector.makeElementPlaceholder(node.selector, element);
118 } else if (!element.isTopLevel) {
119 if (element.isInstanceMember) {
120 collector.tryMakeMemberPlaceholder(node.selector);
121 } else {
122 // May get FunctionExpression here in selector
123 // in case of A(int this.f());
124 if (node.selector is Identifier) {
125 collector.tryMakeLocalPlaceholder(element, node.selector);
126 } else {
127 assert(node.selector is FunctionExpression);
128 }
129 }
130 }
131 }
132
133 visitStaticSend(Send node) {
134 Element element = elements[node];
135 collector.mirrorRenamer
136 .registerStaticSend(collector.currentElement, element, node);
137
138 if (Elements.isUnresolved(element) || element.isDeferredLoaderGetter) {
139 return;
140 }
141 if (element.isConstructor || element.isFactoryConstructor) {
142 // Rename named constructor in redirection position:
143 // class C { C.named(); C.redirecting() : this.named(); }
144 if (node.receiver is Identifier &&
145 node.receiver.asIdentifier().isThis()) {
146 assert(node.selector is Identifier);
147 collector.tryMakeConstructorPlaceholder(node, element);
148 }
149 return;
150 }
151 collector.makeElementPlaceholder(node.selector, element);
152 // Another ugly case: <lib prefix>.<top level> is represented as
153 // receiver: lib prefix, selector: top level.
154 if (element.isTopLevel && node.receiver != null) {
155 assert(elements[node.receiver].isPrefix);
156 // Hack: putting null into map overrides receiver of original node.
157 collector.makeErasePrefixPlaceholder(node.receiver);
158 }
159 }
160
161 internalError(Spannable node, String reason) {
162 collector.internalError(reason, node: node);
163 }
164
165 visitNode(Node node) {
166 internalError(node, "Unhandled node");
167 }
168 }
169
170 class PlaceholderCollector extends Visitor {
171 final DiagnosticReporter reporter;
172 final MirrorRenamer mirrorRenamer;
173 final FunctionElement mainFunction;
174 final Set<String> fixedMemberNames; // member names which cannot be renamed.
175 final Map<Element, ElementAst> elementAsts;
176 final Set<Node> prefixNodesToErase = new Set<Node>();
177 final Set<Node> unresolvedNodes = new Set<Node>();
178 final Map<Element, Set<Node>> elementNodes = new Map<Element, Set<Node>>();
179 final Map<FunctionElement, FunctionScope> functionScopes =
180 new Map<FunctionElement, FunctionScope>();
181 final Map<LibraryElement, Set<Identifier>> privateNodes =
182 new Map<LibraryElement, Set<Identifier>>();
183 final List<DeclarationTypePlaceholder> declarationTypePlaceholders =
184 new List<DeclarationTypePlaceholder>();
185 final Map<String, Set<Identifier>> memberPlaceholders =
186 new Map<String, Set<Identifier>>();
187 final List<ConstructorPlaceholder> constructorPlaceholders =
188 new List<ConstructorPlaceholder>();
189 Map<String, LocalPlaceholder> currentLocalPlaceholders;
190 Element currentElement;
191 FunctionElement topmostEnclosingFunction;
192 TreeElements treeElements;
193
194 get currentFunctionScope => functionScopes.putIfAbsent(
195 topmostEnclosingFunction, () => new FunctionScope());
196
197 PlaceholderCollector(this.reporter, this.mirrorRenamer, this.fixedMemberNames,
198 this.elementAsts, this.mainFunction);
199
200 void collectFunctionDeclarationPlaceholders(
201 FunctionElement element, FunctionExpression node) {
202 if (element.isConstructor) {
203 ConstructorElement constructor = element;
204 tryMakeConstructorPlaceholder(node.name, element);
205 RedirectingFactoryBody bodyAsRedirectingFactoryBody =
206 node.body.asRedirectingFactoryBody();
207 if (bodyAsRedirectingFactoryBody != null) {
208 // Factory redirection.
209 FunctionElement redirectTarget = constructor.immediateRedirectionTarget;
210 assert(redirectTarget != null && redirectTarget != element);
211 tryMakeConstructorPlaceholder(
212 bodyAsRedirectingFactoryBody.constructorReference, redirectTarget);
213 }
214 } else if (Elements.isStaticOrTopLevel(element)) {
215 // Note: this code should only rename private identifiers for class'
216 // fields/getters/setters/methods. Top-level identifiers are renamed
217 // just to escape conflicts and that should be enough as we shouldn't
218 // be able to resolve private identifiers for other libraries.
219 makeElementPlaceholder(node.name, element);
220 } else if (element.isClassMember) {
221 if (node.name is Identifier) {
222 tryMakeMemberPlaceholder(node.name);
223 } else {
224 assert(node.name.asSend().isOperator);
225 }
226 }
227 }
228
229 void collectFieldDeclarationPlaceholders(Element element, Node node) {
230 Identifier name = node is Identifier ? node : node.asSend().selector;
231 if (Elements.isStaticOrTopLevel(element)) {
232 makeElementPlaceholder(name, element);
233 } else if (Elements.isInstanceField(element)) {
234 tryMakeMemberPlaceholder(name);
235 }
236 }
237
238 void collect(Element element) {
239 this.currentElement = element;
240 this.topmostEnclosingFunction = null;
241 final ElementAst elementAst = elementAsts[element];
242 this.treeElements = elementAst.treeElements;
243 Node elementNode = elementAst.ast;
244 if (element is FunctionElement) {
245 collectFunctionDeclarationPlaceholders(element, elementNode);
246 } else if (element is VariableElement) {
247 VariableDefinitions definitions = elementNode;
248 Node definition = definitions.definitions.nodes.head;
249 collectFieldDeclarationPlaceholders(element, definition);
250 makeVarDeclarationTypePlaceholder(definitions);
251 } else {
252 assert(element is ClassElement || element is TypedefElement);
253 }
254 currentLocalPlaceholders = new Map<String, LocalPlaceholder>();
255 if (!(element is ConstructorElement && element.isRedirectingFactory)) {
256 // Do not visit the body of redirecting factories.
257 reporter.withCurrentElement(element, () {
258 elementNode.accept(this);
259 });
260 }
261 }
262
263 // TODO(karlklose): should we create placeholders for these?
264 bool isTypedefParameter(Element element) {
265 return element != null &&
266 element.enclosingElement != null &&
267 element.enclosingElement.isTypedef;
268 }
269
270 void tryMakeLocalPlaceholder(Element element, Identifier node) {
271 bool isNamedOptionalParameter() {
272 FunctionTypedElement function = element.enclosingElement;
273 FunctionSignature signature = function.functionSignature;
274 if (!signature.optionalParametersAreNamed) return false;
275 for (Element parameter in signature.optionalParameters) {
276 if (identical(parameter, element)) return true;
277 }
278 return false;
279 }
280 if (element.isRegularParameter &&
281 !isTypedefParameter(element) &&
282 isNamedOptionalParameter()) {
283 currentFunctionScope.registerParameter(node);
284 } else if (Elements.isLocal(element) && !isTypedefParameter(element)) {
285 makeLocalPlaceholder(node);
286 }
287 }
288
289 void tryMakeMemberPlaceholder(Identifier node) {
290 assert(node != null);
291 if (node is Operator) return;
292 String identifier = node.source;
293 if (fixedMemberNames.contains(identifier)) return;
294 memberPlaceholders
295 .putIfAbsent(identifier, () => new Set<Identifier>())
296 .add(node);
297 }
298
299 void makeTypePlaceholder(Node node, DartType type) {
300 Send send = node.asSend();
301 if (send != null) {
302 // Prefix.
303 assert(send.receiver is Identifier);
304 assert(send.selector is Identifier);
305 makeErasePrefixPlaceholder(send.receiver);
306 node = send.selector;
307 }
308 makeElementPlaceholder(node, type.element);
309 }
310
311 void makeTypeVariablePlaceholder(Node node, TypeVariableType type) {
312 Send send = node.asSend();
313 if (send != null) {
314 // Prefix.
315 assert(send.receiver is Identifier);
316 assert(send.selector is Identifier);
317 makeErasePrefixPlaceholder(send.receiver);
318 node = send.selector;
319 }
320 tryMakeMemberPlaceholder(node);
321 }
322
323 void makeOmitDeclarationTypePlaceholder(TypeAnnotation type) {
324 if (type == null) return;
325 declarationTypePlaceholders
326 .add(new DeclarationTypePlaceholder(type, false));
327 }
328
329 void makeVarDeclarationTypePlaceholder(VariableDefinitions node) {
330 // TODO(smok): Maybe instead of calling this method and
331 // makeDeclaratioTypePlaceholder have type declaration placeholder
332 // collector logic in visitVariableDefinitions when resolver becomes better
333 // and/or catch syntax changes.
334 if (node.type == null) return;
335 bool requiresVar = !node.modifiers.isFinalOrConst;
336 declarationTypePlaceholders
337 .add(new DeclarationTypePlaceholder(node.type, requiresVar));
338 }
339
340 /// Marks [node] to be erased in the output.
341 /// This is done for library prefixes because they are not used in the output
342 /// because all imports are flattened and conflicts are renamed away.
343 void makeErasePrefixPlaceholder(Node node) {
344 assert(node is Identifier || node is Send);
345 prefixNodesToErase.add(node);
346 }
347
348 void makeElementPlaceholder(Node node, Element element) {
349 assert(node != null);
350 assert(element != null);
351 LibraryElement library = element.library;
352 if (identical(element, mainFunction)) return;
353 if (library.isDartCore) return;
354
355 if (library.isPlatformLibrary && !element.isTopLevel) {
356 return;
357 }
358
359 ClassElement cls = element.enclosingClass;
360 if (cls != null && cls.isEnumClass) {
361 // Enums and enum values cannot be changed, since the semantics of
362 // `toString` is defined by the names of the declarations.
363 return;
364 }
365
366 if (element.isAccessor) {
367 element = (element as AccessorElement).abstractField;
368 }
369 elementNodes.putIfAbsent(element, () => new Set<Node>()).add(node);
370 }
371
372 /// Marks [node] to be renamed per-library if it names an instance member
373 /// and has a private name.
374 void tryMakePrivateIdentifier(Node node, Element element) {
375 if (node is Identifier &&
376 !Elements.isStaticOrTopLevel(element) &&
377 !Elements.isLocal(element) &&
378 Name.isPrivateName(node.source)) {
379 privateNodes
380 .putIfAbsent(currentElement.library, () => new Set<Identifier>())
381 .add(node);
382 }
383 }
384
385 void makeUnresolvedPlaceholder(Node node) {
386 unresolvedNodes.add(node);
387 }
388
389 void makeLocalPlaceholder(Identifier identifier) {
390 LocalPlaceholder getLocalPlaceholder() {
391 String name = identifier.source;
392 return currentLocalPlaceholders.putIfAbsent(name, () {
393 LocalPlaceholder localPlaceholder = new LocalPlaceholder(name);
394 currentFunctionScope.localPlaceholders.add(localPlaceholder);
395 return localPlaceholder;
396 });
397 }
398 getLocalPlaceholder().nodes.add(identifier);
399 }
400
401 /// Finds the first constructor on the chain of definingConstructor from
402 /// [element] that is not in a synthetic class.
403 Element findDefiningConstructor(ConstructorElement element) {
404 while (element.definingConstructor != null) {
405 element = element.definingConstructor;
406 }
407 return element;
408 }
409
410 void tryMakeConstructorPlaceholder(Node node, ConstructorElement element) {
411 if (Elements.isUnresolved(element)) {
412 makeUnresolvedPlaceholder(node);
413 return;
414 }
415 // A library prefix.
416 Node prefix;
417 // The name of the class with the constructor.
418 Node className;
419 // Will be null for unnamed constructors.
420 Identifier constructorName;
421 // First deconstruct the constructor, there are 4 possibilities:
422 // ClassName()
423 // prefix.ClassName()
424 // ClassName.constructorName()
425 // prefix.ClassName.constructorName()
426 if (node is Send) {
427 if (node.receiver is Send) {
428 Send receiver = node.receiver;
429 // prefix.ClassName.constructorName()
430 assert(treeElements[receiver.receiver] != null &&
431 treeElements[receiver.receiver].isPrefix);
432 prefix = receiver.receiver;
433 className = receiver.selector;
434 constructorName = node.selector;
435 } else {
436 Element receiverElement = treeElements[node.receiver];
437 if (receiverElement != null && receiverElement.isPrefix) {
438 // prefix.ClassName()
439 prefix = node.receiver;
440 className = node.selector;
441 } else {
442 // ClassName.constructorName()
443 className = node.receiver;
444 constructorName = node.selector;
445 }
446 }
447 } else {
448 // ClassName()
449 className = node;
450 }
451
452 if (prefix != null) {
453 makeErasePrefixPlaceholder(prefix);
454 }
455
456 if (className is TypeAnnotation) {
457 visitTypeAnnotation(className);
458 } else if (Elements.isUnresolved(element)) {
459 // We handle unresolved nodes elsewhere.
460 } else if (className.isThis() || className.isSuper()) {
461 // Do not rename super and this.
462 } else if (className is Identifier) {
463 makeElementPlaceholder(className, element.contextClass);
464 } else {
465 throw "Bad type of constructor name $className";
466 }
467
468 if (constructorName != null) {
469 Element definingConstructor = findDefiningConstructor(element);
470 constructorPlaceholders.add(
471 new ConstructorPlaceholder(constructorName, definingConstructor));
472 tryMakePrivateIdentifier(constructorName, element);
473 }
474 }
475
476 void internalError(String reason, {Node node}) {
477 reporter.internalError(node, reason);
478 }
479
480 visit(Node node) => (node == null) ? null : node.accept(this);
481
482 visitNode(Node node) {
483 node.visitChildren(this);
484 } // We must go deeper.
485
486 visitNewExpression(NewExpression node) {
487 Send send = node.send;
488 DartType type = treeElements.getType(node);
489 assert(type != null);
490 Element constructor = treeElements[send];
491 assert(constructor != null);
492 assert(send.receiver == null);
493 if (!Elements.isMalformed(constructor)) {
494 tryMakeConstructorPlaceholder(node.send.selector, constructor);
495 // TODO(smok): Should this be in visitNamedArgument?
496 // Field names can be exposed as names of optional arguments, e.g.
497 // class C {
498 // final field;
499 // C([this.field]);
500 // }
501 // Do not forget to rename them as well.
502 FunctionElement constructorFunction = constructor;
503 List<Element> optionalParameters =
504 constructorFunction.functionSignature.optionalParameters;
505 for (final argument in send.argumentsNode) {
506 NamedArgument named = argument.asNamedArgument();
507 if (named == null) continue;
508 Identifier name = named.name;
509 String nameAsString = name.source;
510 for (final parameter in optionalParameters) {
511 if (parameter.isInitializingFormal) {
512 if (parameter.name == nameAsString) {
513 tryMakeMemberPlaceholder(name);
514 break;
515 }
516 }
517 }
518 }
519 } else {
520 makeUnresolvedPlaceholder(node.send.selector);
521 }
522 visit(node.send.argumentsNode);
523 }
524
525 visitSend(Send send) {
526 Element element = treeElements[send];
527 tryMakePrivateIdentifier(send.selector, element);
528 new SendVisitor(this, treeElements).visitSend(send);
529 send.visitChildren(this);
530 }
531
532 visitSendSet(SendSet send) {
533 Element element = treeElements[send];
534 if (Elements.isMalformed(element)) {
535 // Complicated case: constructs like receiver.selector++ can resolve
536 // to ErroneousElement. Fortunately, receiver.selector still
537 // can be resoved via treeElements[send.selector], that's all
538 // that is needed to rename the construct properly.
539 element = treeElements[send.selector];
540 }
541 tryMakePrivateIdentifier(send.selector, element);
542 if (element == null) {
543 if (send.receiver != null) tryMakeMemberPlaceholder(send.selector);
544 } else if (!element.isMalformed) {
545 if (Elements.isStaticOrTopLevel(element)) {
546 // TODO(smok): Worth investigating why sometimes we get getter/setter
547 // here and sometimes abstract field.
548 assert(element.isClass ||
549 element is VariableElement ||
550 element.isAccessor ||
551 element.isAbstractField ||
552 element.isFunction ||
553 element.isTypedef ||
554 element is TypeVariableElement);
555 makeElementPlaceholder(send.selector, element);
556 } else {
557 Identifier identifier = send.selector.asIdentifier();
558 if (identifier == null) {
559 // Handle optional function expression parameters with default values.
560 identifier = send.selector.asFunctionExpression().name;
561 }
562 if (Elements.isInstanceField(element)) {
563 tryMakeMemberPlaceholder(identifier);
564 } else {
565 tryMakeLocalPlaceholder(element, identifier);
566 }
567 }
568 }
569 send.visitChildren(this);
570 }
571
572 visitTypeAnnotation(TypeAnnotation node) {
573 final type = treeElements.getType(node);
574 assert(invariant(node, type != null,
575 message: "Missing type for type annotation: $treeElements"));
576 if (!type.isVoid) {
577 if (!type.treatAsDynamic) {
578 if (type is TypeVariableType) {
579 makeTypeVariablePlaceholder(node.typeName, type);
580 } else {
581 makeTypePlaceholder(node.typeName, type);
582 }
583 } else if (!type.isDynamic) {
584 makeUnresolvedPlaceholder(node.typeName);
585 }
586 }
587 // Visit only type arguments, otherwise in case of lib.Class type
588 // annotation typeName is Send and we go to visitGetterSend, as a result
589 // "Class" is added to member placeholders.
590 visit(node.typeArguments);
591 }
592
593 visitVariableDefinitions(VariableDefinitions node) {
594 // Collect only local placeholders.
595 for (Node definition in node.definitions.nodes) {
596 Element definitionElement = treeElements[definition];
597 // definitionElement may be null if we're inside variable definitions
598 // of a function that is a parameter of another function.
599 // TODO(smok): Fix this when resolver correctly deals with
600 // such cases.
601 if (definitionElement == null) continue;
602
603 Send send = definition.asSend();
604 Identifier identifier = definition is Identifier
605 ? definition
606 : definition is Send
607 ? (send.selector is Identifier ? send.selector : null)
608 : null;
609
610 tryMakePrivateIdentifier(identifier, definitionElement);
611
612 if (send != null) {
613 // May get FunctionExpression here in definition.selector
614 // in case of A(int this.f());
615 if (send.selector is Identifier) {
616 if (definitionElement.isInitializingFormal) {
617 tryMakeMemberPlaceholder(send.selector);
618 } else {
619 tryMakeLocalPlaceholder(definitionElement, send.selector);
620 }
621 } else {
622 assert(send.selector is FunctionExpression);
623 if (definitionElement.isInitializingFormal) {
624 tryMakeMemberPlaceholder(send.selector.asFunctionExpression().name);
625 }
626 }
627 } else if (definition is Identifier) {
628 tryMakeLocalPlaceholder(definitionElement, definition);
629 } else if (definition is FunctionExpression) {
630 // Skip, it will be processed in visitFunctionExpression.
631 } else {
632 internalError('Unexpected definition structure $definition');
633 }
634 }
635 node.visitChildren(this);
636 }
637
638 visitFunctionExpression(FunctionExpression node) {
639 bool isKeyword(Identifier id) =>
640 id != null && Keyword.keywords[id.source] != null;
641
642 Element element = treeElements[node];
643 // May get null;
644 if (element != null) {
645 tryMakePrivateIdentifier(node.name, element);
646
647 // Rename only local functions.
648 if (topmostEnclosingFunction == null &&
649 element is! LocalParameterElement &&
650 element is! InitializingFormalElement) {
651 topmostEnclosingFunction = element;
652 }
653 if (!identical(element, currentElement)) {
654 if (node.name != null) {
655 assert(node.name is Identifier);
656 tryMakeLocalPlaceholder(element, node.name);
657 }
658 }
659 }
660
661 node.visitChildren(this);
662
663 // Make sure we don't omit return type of methods which names are
664 // identifiers, because the following works fine:
665 // int interface() => 1;
666 // But omitting 'int' makes VM unhappy.
667 // TODO(smok): Remove it when http://dartbug.com/5278 is fixed.
668 if (node.name == null || !isKeyword(node.name.asIdentifier())) {
669 makeOmitDeclarationTypePlaceholder(node.returnType);
670 }
671 collectFunctionParameters(node.parameters);
672 }
673
674 void collectFunctionParameters(NodeList parameters) {
675 if (parameters == null) return;
676 for (Node parameter in parameters.nodes) {
677 if (parameter is NodeList) {
678 // Optional parameter list.
679 collectFunctionParameters(parameter);
680 } else {
681 assert(parameter is VariableDefinitions);
682 makeOmitDeclarationTypePlaceholder(
683 parameter.asVariableDefinitions().type);
684 }
685 }
686 }
687
688 visitClassNode(ClassNode node) {
689 ClassElement classElement = currentElement;
690 makeElementPlaceholder(node.name, classElement);
691 node.visitChildren(this);
692 }
693
694 visitNamedMixinApplication(NamedMixinApplication node) {
695 ClassElement classElement = currentElement;
696 makeElementPlaceholder(node.name, classElement);
697 node.visitChildren(this);
698 }
699
700 visitTypeVariable(TypeVariable node) {
701 DartType type = treeElements.getType(node);
702 assert(invariant(node, type != null,
703 message: "Missing type for type variable: $treeElements"));
704 makeTypeVariablePlaceholder(node.name, type);
705 node.visitChildren(this);
706 }
707
708 visitTypedef(Typedef node) {
709 assert(currentElement is TypedefElement);
710 makeElementPlaceholder(node.name, currentElement);
711 node.visitChildren(this);
712 makeOmitDeclarationTypePlaceholder(node.returnType);
713 collectFunctionParameters(node.formals);
714 }
715
716 visitBlock(Block node) {
717 for (Node statement in node.statements.nodes) {
718 if (statement is VariableDefinitions) {
719 makeVarDeclarationTypePlaceholder(statement);
720 }
721 }
722 node.visitChildren(this);
723 }
724 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/dart_backend/outputter.dart ('k') | pkg/compiler/lib/src/dart_backend/renamer.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698