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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/dart_backend/placeholder_collector.dart

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

Powered by Google App Engine
This is Rietveld 408576698