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

Side by Side Diff: pkg/analyzer/lib/src/dart/element/builder.dart

Issue 1659973002: Move ElementBuilder and CompilationUnitBuilder into builder.dart. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | pkg/analyzer/lib/src/generated/incremental_resolver.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library analyzer.src.dart.element.builder; 5 library analyzer.src.dart.element.builder;
6 6
7 import 'dart:collection'; 7 import 'dart:collection';
8 8
9 import 'package:analyzer/dart/ast/ast.dart'; 9 import 'package:analyzer/dart/ast/ast.dart';
10 import 'package:analyzer/dart/ast/visitor.dart'; 10 import 'package:analyzer/dart/ast/visitor.dart';
11 import 'package:analyzer/dart/element/element.dart'; 11 import 'package:analyzer/dart/element/element.dart';
12 import 'package:analyzer/dart/element/type.dart';
12 import 'package:analyzer/src/dart/element/element.dart'; 13 import 'package:analyzer/src/dart/element/element.dart';
14 import 'package:analyzer/src/dart/element/type.dart';
13 import 'package:analyzer/src/generated/engine.dart'; 15 import 'package:analyzer/src/generated/engine.dart';
14 import 'package:analyzer/src/generated/error.dart'; 16 import 'package:analyzer/src/generated/error.dart';
17 import 'package:analyzer/src/generated/java_engine.dart';
18 import 'package:analyzer/src/generated/resolver.dart';
15 import 'package:analyzer/src/generated/scanner.dart'; 19 import 'package:analyzer/src/generated/scanner.dart';
16 import 'package:analyzer/src/generated/sdk.dart'; 20 import 'package:analyzer/src/generated/sdk.dart';
17 import 'package:analyzer/src/generated/source.dart'; 21 import 'package:analyzer/src/generated/source.dart';
22 import 'package:analyzer/src/generated/utilities_dart.dart';
23
24 /**
25 * A `CompilationUnitBuilder` builds an element model for a single compilation
26 * unit.
27 */
28 class CompilationUnitBuilder {
29 /**
30 * Build the compilation unit element for the given [source] based on the
31 * compilation [unit] associated with the source. Throw an AnalysisException
32 * if the element could not be built. [librarySource] is the source for the
33 * containing library.
34 */
35 CompilationUnitElementImpl buildCompilationUnit(
36 Source source, CompilationUnit unit, Source librarySource) {
37 return PerformanceStatistics.resolve.makeCurrentWhile(() {
38 if (unit == null) {
39 return null;
40 }
41 ElementHolder holder = new ElementHolder();
42 ElementBuilder builder = new ElementBuilder(holder);
43 unit.accept(builder);
44 CompilationUnitElementImpl element =
45 new CompilationUnitElementImpl(source.shortName);
46 element.accessors = holder.accessors;
47 element.enums = holder.enums;
48 element.functions = holder.functions;
49 element.source = source;
50 element.librarySource = librarySource;
51 element.typeAliases = holder.typeAliases;
52 element.types = holder.types;
53 element.topLevelVariables = holder.topLevelVariables;
54 unit.element = element;
55 holder.validate();
56 return element;
57 });
58 }
59 }
18 60
19 /** 61 /**
20 * Instances of the class `DirectiveElementBuilder` build elements for top 62 * Instances of the class `DirectiveElementBuilder` build elements for top
21 * level library directives. 63 * level library directives.
22 */ 64 */
23 class DirectiveElementBuilder extends SimpleAstVisitor<Object> { 65 class DirectiveElementBuilder extends SimpleAstVisitor<Object> {
24 /** 66 /**
25 * The analysis context within which directive elements are being built. 67 * The analysis context within which directive elements are being built.
26 */ 68 */
27 final AnalysisContext context; 69 final AnalysisContext context;
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 _NamespaceCombinatorBuilder namespaceCombinatorBuilder = 265 _NamespaceCombinatorBuilder namespaceCombinatorBuilder =
224 new _NamespaceCombinatorBuilder(); 266 new _NamespaceCombinatorBuilder();
225 for (Combinator combinator in directive.combinators) { 267 for (Combinator combinator in directive.combinators) {
226 combinator.accept(namespaceCombinatorBuilder); 268 combinator.accept(namespaceCombinatorBuilder);
227 } 269 }
228 return namespaceCombinatorBuilder.combinators; 270 return namespaceCombinatorBuilder.combinators;
229 } 271 }
230 } 272 }
231 273
232 /** 274 /**
275 * Instances of the class `ElementBuilder` traverse an AST structure and build t he element
276 * model representing the AST structure.
277 */
278 class ElementBuilder extends RecursiveAstVisitor<Object> {
279 /**
280 * The element holder associated with the element that is currently being buil t.
281 */
282 ElementHolder _currentHolder;
283
284 /**
285 * A flag indicating whether a variable declaration is in the context of a fie ld declaration.
286 */
287 bool _inFieldContext = false;
288
289 /**
290 * A flag indicating whether a variable declaration is within the body of a me thod or function.
291 */
292 bool _inFunction = false;
293
294 /**
295 * A collection holding the elements defined in a class that need to have
296 * their function type fixed to take into account type parameters of the
297 * enclosing class, or `null` if we are not currently processing nodes within
298 * a class.
299 */
300 List<ExecutableElementImpl> _functionTypesToFix = null;
301
302 /**
303 * A table mapping field names to field elements for the fields defined in the current class, or
304 * `null` if we are not in the scope of a class.
305 */
306 HashMap<String, FieldElement> _fieldMap;
307
308 /**
309 * Initialize a newly created element builder to build the elements for a comp ilation unit.
310 *
311 * @param initialHolder the element holder associated with the compilation uni t being built
312 */
313 ElementBuilder(ElementHolder initialHolder) {
314 _currentHolder = initialHolder;
315 }
316
317 @override
318 Object visitBlock(Block node) {
319 bool wasInField = _inFieldContext;
320 _inFieldContext = false;
321 try {
322 node.visitChildren(this);
323 } finally {
324 _inFieldContext = wasInField;
325 }
326 return null;
327 }
328
329 @override
330 Object visitCatchClause(CatchClause node) {
331 SimpleIdentifier exceptionParameter = node.exceptionParameter;
332 if (exceptionParameter != null) {
333 // exception
334 LocalVariableElementImpl exception =
335 new LocalVariableElementImpl.forNode(exceptionParameter);
336 if (node.exceptionType == null) {
337 exception.hasImplicitType = true;
338 }
339 _currentHolder.addLocalVariable(exception);
340 exceptionParameter.staticElement = exception;
341 // stack trace
342 SimpleIdentifier stackTraceParameter = node.stackTraceParameter;
343 if (stackTraceParameter != null) {
344 LocalVariableElementImpl stackTrace =
345 new LocalVariableElementImpl.forNode(stackTraceParameter);
346 _currentHolder.addLocalVariable(stackTrace);
347 stackTraceParameter.staticElement = stackTrace;
348 }
349 }
350 return super.visitCatchClause(node);
351 }
352
353 @override
354 Object visitClassDeclaration(ClassDeclaration node) {
355 ElementHolder holder = new ElementHolder();
356 _functionTypesToFix = new List<ExecutableElementImpl>();
357 //
358 // Process field declarations before constructors and methods so that field
359 // formal parameters can be correctly resolved to their fields.
360 //
361 ElementHolder previousHolder = _currentHolder;
362 _currentHolder = holder;
363 try {
364 List<ClassMember> nonFields = new List<ClassMember>();
365 node.visitChildren(
366 new _ElementBuilder_visitClassDeclaration(this, nonFields));
367 _buildFieldMap(holder.fieldsWithoutFlushing);
368 int count = nonFields.length;
369 for (int i = 0; i < count; i++) {
370 nonFields[i].accept(this);
371 }
372 } finally {
373 _currentHolder = previousHolder;
374 }
375 SimpleIdentifier className = node.name;
376 ClassElementImpl element = new ClassElementImpl.forNode(className);
377 List<TypeParameterElement> typeParameters = holder.typeParameters;
378 List<DartType> typeArguments = _createTypeParameterTypes(typeParameters);
379 InterfaceTypeImpl interfaceType = new InterfaceTypeImpl(element);
380 interfaceType.typeArguments = typeArguments;
381 element.type = interfaceType;
382 element.typeParameters = typeParameters;
383 _setDoc(element, node);
384 element.abstract = node.isAbstract;
385 element.accessors = holder.accessors;
386 List<ConstructorElement> constructors = holder.constructors;
387 if (constructors.isEmpty) {
388 constructors = _createDefaultConstructors(element);
389 }
390 element.constructors = constructors;
391 element.fields = holder.fields;
392 element.methods = holder.methods;
393 // Function types must be initialized after the enclosing element has been
394 // set, for them to pick up the type parameters.
395 for (ExecutableElementImpl e in _functionTypesToFix) {
396 e.type = new FunctionTypeImpl(e);
397 }
398 _functionTypesToFix = null;
399 _currentHolder.addType(element);
400 className.staticElement = element;
401 _fieldMap = null;
402 holder.validate();
403 return null;
404 }
405
406 /**
407 * Implementation of this method should be synchronized with
408 * [visitClassDeclaration].
409 */
410 void visitClassDeclarationIncrementally(ClassDeclaration node) {
411 //
412 // Process field declarations before constructors and methods so that field
413 // formal parameters can be correctly resolved to their fields.
414 //
415 ClassElement classElement = node.element;
416 _buildFieldMap(classElement.fields);
417 }
418
419 @override
420 Object visitClassTypeAlias(ClassTypeAlias node) {
421 ElementHolder holder = new ElementHolder();
422 _visitChildren(holder, node);
423 SimpleIdentifier className = node.name;
424 ClassElementImpl element = new ClassElementImpl.forNode(className);
425 element.abstract = node.abstractKeyword != null;
426 element.mixinApplication = true;
427 List<TypeParameterElement> typeParameters = holder.typeParameters;
428 element.typeParameters = typeParameters;
429 List<DartType> typeArguments = _createTypeParameterTypes(typeParameters);
430 InterfaceTypeImpl interfaceType = new InterfaceTypeImpl(element);
431 interfaceType.typeArguments = typeArguments;
432 element.type = interfaceType;
433 _setDoc(element, node);
434 _currentHolder.addType(element);
435 className.staticElement = element;
436 holder.validate();
437 return null;
438 }
439
440 @override
441 Object visitConstructorDeclaration(ConstructorDeclaration node) {
442 ElementHolder holder = new ElementHolder();
443 bool wasInFunction = _inFunction;
444 _inFunction = true;
445 try {
446 _visitChildren(holder, node);
447 } finally {
448 _inFunction = wasInFunction;
449 }
450 FunctionBody body = node.body;
451 SimpleIdentifier constructorName = node.name;
452 ConstructorElementImpl element =
453 new ConstructorElementImpl.forNode(constructorName);
454 _setDoc(element, node);
455 if (node.externalKeyword != null) {
456 element.external = true;
457 }
458 if (node.factoryKeyword != null) {
459 element.factory = true;
460 }
461 element.functions = holder.functions;
462 element.labels = holder.labels;
463 element.localVariables = holder.localVariables;
464 element.parameters = holder.parameters;
465 element.const2 = node.constKeyword != null;
466 if (body.isAsynchronous) {
467 element.asynchronous = true;
468 }
469 if (body.isGenerator) {
470 element.generator = true;
471 }
472 _currentHolder.addConstructor(element);
473 node.element = element;
474 if (constructorName == null) {
475 Identifier returnType = node.returnType;
476 if (returnType != null) {
477 element.nameOffset = returnType.offset;
478 element.nameEnd = returnType.end;
479 }
480 } else {
481 constructorName.staticElement = element;
482 element.periodOffset = node.period.offset;
483 element.nameEnd = constructorName.end;
484 }
485 holder.validate();
486 return null;
487 }
488
489 @override
490 Object visitDeclaredIdentifier(DeclaredIdentifier node) {
491 SimpleIdentifier variableName = node.identifier;
492 LocalVariableElementImpl element =
493 new LocalVariableElementImpl.forNode(variableName);
494 ForEachStatement statement = node.parent as ForEachStatement;
495 int declarationEnd = node.offset + node.length;
496 int statementEnd = statement.offset + statement.length;
497 element.setVisibleRange(declarationEnd, statementEnd - declarationEnd - 1);
498 element.const3 = node.isConst;
499 element.final2 = node.isFinal;
500 if (node.type == null) {
501 element.hasImplicitType = true;
502 }
503 _currentHolder.addLocalVariable(element);
504 variableName.staticElement = element;
505 return super.visitDeclaredIdentifier(node);
506 }
507
508 @override
509 Object visitDefaultFormalParameter(DefaultFormalParameter node) {
510 ElementHolder holder = new ElementHolder();
511 NormalFormalParameter normalParameter = node.parameter;
512 SimpleIdentifier parameterName = normalParameter.identifier;
513 ParameterElementImpl parameter;
514 if (normalParameter is FieldFormalParameter) {
515 parameter = new DefaultFieldFormalParameterElementImpl(parameterName);
516 FieldElement field =
517 _fieldMap == null ? null : _fieldMap[parameterName.name];
518 if (field != null) {
519 (parameter as DefaultFieldFormalParameterElementImpl).field = field;
520 }
521 } else {
522 parameter = new DefaultParameterElementImpl(parameterName);
523 }
524 parameter.const3 = node.isConst;
525 parameter.final2 = node.isFinal;
526 parameter.parameterKind = node.kind;
527 // set initializer, default value range
528 Expression defaultValue = node.defaultValue;
529 if (defaultValue != null) {
530 _visit(holder, defaultValue);
531 FunctionElementImpl initializer =
532 new FunctionElementImpl.forOffset(defaultValue.beginToken.offset);
533 initializer.functions = holder.functions;
534 initializer.labels = holder.labels;
535 initializer.localVariables = holder.localVariables;
536 initializer.parameters = holder.parameters;
537 initializer.synthetic = true;
538 parameter.initializer = initializer;
539 parameter.defaultValueCode = defaultValue.toSource();
540 }
541 // visible range
542 _setParameterVisibleRange(node, parameter);
543 if (normalParameter is SimpleFormalParameter &&
544 normalParameter.type == null) {
545 parameter.hasImplicitType = true;
546 }
547 _currentHolder.addParameter(parameter);
548 parameterName.staticElement = parameter;
549 normalParameter.accept(this);
550 holder.validate();
551 return null;
552 }
553
554 @override
555 Object visitEnumDeclaration(EnumDeclaration node) {
556 SimpleIdentifier enumName = node.name;
557 ClassElementImpl enumElement = new ClassElementImpl.forNode(enumName);
558 enumElement.enum2 = true;
559 _setDoc(enumElement, node);
560 InterfaceTypeImpl enumType = new InterfaceTypeImpl(enumElement);
561 enumElement.type = enumType;
562 // The equivalent code for enums in the spec shows a single constructor,
563 // but that constructor is not callable (since it is a compile-time error
564 // to subclass, mix-in, implement, or explicitly instantiate an enum). So
565 // we represent this as having no constructors.
566 enumElement.constructors = ConstructorElement.EMPTY_LIST;
567 _currentHolder.addEnum(enumElement);
568 enumName.staticElement = enumElement;
569 return super.visitEnumDeclaration(node);
570 }
571
572 @override
573 Object visitFieldDeclaration(FieldDeclaration node) {
574 bool wasInField = _inFieldContext;
575 _inFieldContext = true;
576 try {
577 node.visitChildren(this);
578 } finally {
579 _inFieldContext = wasInField;
580 }
581 return null;
582 }
583
584 @override
585 Object visitFieldFormalParameter(FieldFormalParameter node) {
586 if (node.parent is! DefaultFormalParameter) {
587 SimpleIdentifier parameterName = node.identifier;
588 FieldElement field =
589 _fieldMap == null ? null : _fieldMap[parameterName.name];
590 FieldFormalParameterElementImpl parameter =
591 new FieldFormalParameterElementImpl(parameterName);
592 parameter.const3 = node.isConst;
593 parameter.final2 = node.isFinal;
594 parameter.parameterKind = node.kind;
595 if (field != null) {
596 parameter.field = field;
597 }
598 _currentHolder.addParameter(parameter);
599 parameterName.staticElement = parameter;
600 }
601 //
602 // The children of this parameter include any parameters defined on the type
603 // of this parameter.
604 //
605 ElementHolder holder = new ElementHolder();
606 _visitChildren(holder, node);
607 ParameterElementImpl element = node.element;
608 element.parameters = holder.parameters;
609 element.typeParameters = holder.typeParameters;
610 holder.validate();
611 return null;
612 }
613
614 @override
615 Object visitFunctionDeclaration(FunctionDeclaration node) {
616 FunctionExpression expression = node.functionExpression;
617 if (expression != null) {
618 ElementHolder holder = new ElementHolder();
619 bool wasInFunction = _inFunction;
620 _inFunction = true;
621 try {
622 _visitChildren(holder, node);
623 } finally {
624 _inFunction = wasInFunction;
625 }
626 FunctionBody body = expression.body;
627 Token property = node.propertyKeyword;
628 if (property == null || _inFunction) {
629 SimpleIdentifier functionName = node.name;
630 FunctionElementImpl element =
631 new FunctionElementImpl.forNode(functionName);
632 _setDoc(element, node);
633 if (node.externalKeyword != null) {
634 element.external = true;
635 }
636 element.functions = holder.functions;
637 element.labels = holder.labels;
638 element.localVariables = holder.localVariables;
639 element.parameters = holder.parameters;
640 element.typeParameters = holder.typeParameters;
641 if (body.isAsynchronous) {
642 element.asynchronous = true;
643 }
644 if (body.isGenerator) {
645 element.generator = true;
646 }
647 if (_inFunction) {
648 Block enclosingBlock = node.getAncestor((node) => node is Block);
649 if (enclosingBlock != null) {
650 int functionEnd = node.offset + node.length;
651 int blockEnd = enclosingBlock.offset + enclosingBlock.length;
652 element.setVisibleRange(functionEnd, blockEnd - functionEnd - 1);
653 }
654 }
655 if (node.returnType == null) {
656 element.hasImplicitReturnType = true;
657 }
658 _currentHolder.addFunction(element);
659 expression.element = element;
660 functionName.staticElement = element;
661 } else {
662 SimpleIdentifier propertyNameNode = node.name;
663 if (propertyNameNode == null) {
664 // TODO(brianwilkerson) Report this internal error.
665 return null;
666 }
667 String propertyName = propertyNameNode.name;
668 TopLevelVariableElementImpl variable = _currentHolder
669 .getTopLevelVariable(propertyName) as TopLevelVariableElementImpl;
670 if (variable == null) {
671 variable = new TopLevelVariableElementImpl(node.name.name, -1);
672 variable.final2 = true;
673 variable.synthetic = true;
674 _currentHolder.addTopLevelVariable(variable);
675 }
676 if (node.isGetter) {
677 PropertyAccessorElementImpl getter =
678 new PropertyAccessorElementImpl.forNode(propertyNameNode);
679 _setDoc(getter, node);
680 if (node.externalKeyword != null) {
681 getter.external = true;
682 }
683 getter.functions = holder.functions;
684 getter.labels = holder.labels;
685 getter.localVariables = holder.localVariables;
686 if (body.isAsynchronous) {
687 getter.asynchronous = true;
688 }
689 if (body.isGenerator) {
690 getter.generator = true;
691 }
692 getter.variable = variable;
693 getter.getter = true;
694 getter.static = true;
695 variable.getter = getter;
696 if (node.returnType == null) {
697 getter.hasImplicitReturnType = true;
698 }
699 _currentHolder.addAccessor(getter);
700 expression.element = getter;
701 propertyNameNode.staticElement = getter;
702 } else {
703 PropertyAccessorElementImpl setter =
704 new PropertyAccessorElementImpl.forNode(propertyNameNode);
705 _setDoc(setter, node);
706 if (node.externalKeyword != null) {
707 setter.external = true;
708 }
709 setter.functions = holder.functions;
710 setter.labels = holder.labels;
711 setter.localVariables = holder.localVariables;
712 setter.parameters = holder.parameters;
713 if (body.isAsynchronous) {
714 setter.asynchronous = true;
715 }
716 if (body.isGenerator) {
717 setter.generator = true;
718 }
719 setter.variable = variable;
720 setter.setter = true;
721 setter.static = true;
722 if (node.returnType == null) {
723 setter.hasImplicitReturnType = true;
724 }
725 variable.setter = setter;
726 variable.final2 = false;
727 _currentHolder.addAccessor(setter);
728 expression.element = setter;
729 propertyNameNode.staticElement = setter;
730 }
731 }
732 holder.validate();
733 }
734 return null;
735 }
736
737 @override
738 Object visitFunctionExpression(FunctionExpression node) {
739 if (node.parent is FunctionDeclaration) {
740 // visitFunctionDeclaration has already created the element for the
741 // declaration. We just need to visit children.
742 return super.visitFunctionExpression(node);
743 }
744 ElementHolder holder = new ElementHolder();
745 bool wasInFunction = _inFunction;
746 _inFunction = true;
747 try {
748 _visitChildren(holder, node);
749 } finally {
750 _inFunction = wasInFunction;
751 }
752 FunctionBody body = node.body;
753 FunctionElementImpl element =
754 new FunctionElementImpl.forOffset(node.beginToken.offset);
755 element.functions = holder.functions;
756 element.labels = holder.labels;
757 element.localVariables = holder.localVariables;
758 element.parameters = holder.parameters;
759 element.typeParameters = holder.typeParameters;
760 if (body.isAsynchronous) {
761 element.asynchronous = true;
762 }
763 if (body.isGenerator) {
764 element.generator = true;
765 }
766 if (_inFunction) {
767 Block enclosingBlock = node.getAncestor((node) => node is Block);
768 if (enclosingBlock != null) {
769 int functionEnd = node.offset + node.length;
770 int blockEnd = enclosingBlock.offset + enclosingBlock.length;
771 element.setVisibleRange(functionEnd, blockEnd - functionEnd - 1);
772 }
773 }
774 if (_functionTypesToFix != null) {
775 _functionTypesToFix.add(element);
776 } else {
777 element.type = new FunctionTypeImpl(element);
778 }
779 element.hasImplicitReturnType = true;
780 _currentHolder.addFunction(element);
781 node.element = element;
782 holder.validate();
783 return null;
784 }
785
786 @override
787 Object visitFunctionTypeAlias(FunctionTypeAlias node) {
788 ElementHolder holder = new ElementHolder();
789 _visitChildren(holder, node);
790 SimpleIdentifier aliasName = node.name;
791 List<ParameterElement> parameters = holder.parameters;
792 List<TypeParameterElement> typeParameters = holder.typeParameters;
793 FunctionTypeAliasElementImpl element =
794 new FunctionTypeAliasElementImpl.forNode(aliasName);
795 _setDoc(element, node);
796 element.parameters = parameters;
797 element.typeParameters = typeParameters;
798 _createTypeParameterTypes(typeParameters);
799 element.type = new FunctionTypeImpl.forTypedef(element);
800 _currentHolder.addTypeAlias(element);
801 aliasName.staticElement = element;
802 holder.validate();
803 return null;
804 }
805
806 @override
807 Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
808 if (node.parent is! DefaultFormalParameter) {
809 SimpleIdentifier parameterName = node.identifier;
810 ParameterElementImpl parameter =
811 new ParameterElementImpl.forNode(parameterName);
812 parameter.parameterKind = node.kind;
813 _setParameterVisibleRange(node, parameter);
814 _currentHolder.addParameter(parameter);
815 parameterName.staticElement = parameter;
816 }
817 //
818 // The children of this parameter include any parameters defined on the type
819 //of this parameter.
820 //
821 ElementHolder holder = new ElementHolder();
822 _visitChildren(holder, node);
823 ParameterElementImpl element = node.element;
824 element.parameters = holder.parameters;
825 element.typeParameters = holder.typeParameters;
826 holder.validate();
827 return null;
828 }
829
830 @override
831 Object visitLabeledStatement(LabeledStatement node) {
832 bool onSwitchStatement = node.statement is SwitchStatement;
833 for (Label label in node.labels) {
834 SimpleIdentifier labelName = label.label;
835 LabelElementImpl element =
836 new LabelElementImpl(labelName, onSwitchStatement, false);
837 _currentHolder.addLabel(element);
838 labelName.staticElement = element;
839 }
840 return super.visitLabeledStatement(node);
841 }
842
843 @override
844 Object visitMethodDeclaration(MethodDeclaration node) {
845 try {
846 ElementHolder holder = new ElementHolder();
847 bool wasInFunction = _inFunction;
848 _inFunction = true;
849 try {
850 _visitChildren(holder, node);
851 } finally {
852 _inFunction = wasInFunction;
853 }
854 bool isStatic = node.isStatic;
855 Token property = node.propertyKeyword;
856 FunctionBody body = node.body;
857 if (property == null) {
858 SimpleIdentifier methodName = node.name;
859 String nameOfMethod = methodName.name;
860 if (nameOfMethod == TokenType.MINUS.lexeme &&
861 node.parameters.parameters.length == 0) {
862 nameOfMethod = "unary-";
863 }
864 MethodElementImpl element =
865 new MethodElementImpl(nameOfMethod, methodName.offset);
866 _setDoc(element, node);
867 element.abstract = node.isAbstract;
868 if (node.externalKeyword != null) {
869 element.external = true;
870 }
871 element.functions = holder.functions;
872 element.labels = holder.labels;
873 element.localVariables = holder.localVariables;
874 element.parameters = holder.parameters;
875 element.static = isStatic;
876 element.typeParameters = holder.typeParameters;
877 if (body.isAsynchronous) {
878 element.asynchronous = true;
879 }
880 if (body.isGenerator) {
881 element.generator = true;
882 }
883 if (node.returnType == null) {
884 element.hasImplicitReturnType = true;
885 }
886 _currentHolder.addMethod(element);
887 methodName.staticElement = element;
888 } else {
889 SimpleIdentifier propertyNameNode = node.name;
890 String propertyName = propertyNameNode.name;
891 FieldElementImpl field =
892 _currentHolder.getField(propertyName) as FieldElementImpl;
893 if (field == null) {
894 field = new FieldElementImpl(node.name.name, -1);
895 field.final2 = true;
896 field.static = isStatic;
897 field.synthetic = true;
898 _currentHolder.addField(field);
899 }
900 if (node.isGetter) {
901 PropertyAccessorElementImpl getter =
902 new PropertyAccessorElementImpl.forNode(propertyNameNode);
903 _setDoc(getter, node);
904 if (node.externalKeyword != null) {
905 getter.external = true;
906 }
907 getter.functions = holder.functions;
908 getter.labels = holder.labels;
909 getter.localVariables = holder.localVariables;
910 if (body.isAsynchronous) {
911 getter.asynchronous = true;
912 }
913 if (body.isGenerator) {
914 getter.generator = true;
915 }
916 getter.variable = field;
917 getter.abstract = node.isAbstract;
918 getter.getter = true;
919 getter.static = isStatic;
920 field.getter = getter;
921 if (node.returnType == null) {
922 getter.hasImplicitReturnType = true;
923 }
924 _currentHolder.addAccessor(getter);
925 propertyNameNode.staticElement = getter;
926 } else {
927 PropertyAccessorElementImpl setter =
928 new PropertyAccessorElementImpl.forNode(propertyNameNode);
929 _setDoc(setter, node);
930 if (node.externalKeyword != null) {
931 setter.external = true;
932 }
933 setter.functions = holder.functions;
934 setter.labels = holder.labels;
935 setter.localVariables = holder.localVariables;
936 setter.parameters = holder.parameters;
937 if (body.isAsynchronous) {
938 setter.asynchronous = true;
939 }
940 if (body.isGenerator) {
941 setter.generator = true;
942 }
943 setter.variable = field;
944 setter.abstract = node.isAbstract;
945 setter.setter = true;
946 setter.static = isStatic;
947 if (node.returnType == null) {
948 setter.hasImplicitReturnType = true;
949 }
950 field.setter = setter;
951 field.final2 = false;
952 _currentHolder.addAccessor(setter);
953 propertyNameNode.staticElement = setter;
954 }
955 }
956 holder.validate();
957 } catch (exception, stackTrace) {
958 if (node.name.staticElement == null) {
959 ClassDeclaration classNode =
960 node.getAncestor((node) => node is ClassDeclaration);
961 StringBuffer buffer = new StringBuffer();
962 buffer.write("The element for the method ");
963 buffer.write(node.name);
964 buffer.write(" in ");
965 buffer.write(classNode.name);
966 buffer.write(" was not set while trying to build the element model.");
967 AnalysisEngine.instance.logger.logError(
968 buffer.toString(), new CaughtException(exception, stackTrace));
969 } else {
970 String message =
971 "Exception caught in ElementBuilder.visitMethodDeclaration()";
972 AnalysisEngine.instance.logger
973 .logError(message, new CaughtException(exception, stackTrace));
974 }
975 } finally {
976 if (node.name.staticElement == null) {
977 ClassDeclaration classNode =
978 node.getAncestor((node) => node is ClassDeclaration);
979 StringBuffer buffer = new StringBuffer();
980 buffer.write("The element for the method ");
981 buffer.write(node.name);
982 buffer.write(" in ");
983 buffer.write(classNode.name);
984 buffer.write(" was not set while trying to resolve types.");
985 AnalysisEngine.instance.logger.logError(
986 buffer.toString(),
987 new CaughtException(
988 new AnalysisException(buffer.toString()), null));
989 }
990 }
991 return null;
992 }
993
994 @override
995 Object visitSimpleFormalParameter(SimpleFormalParameter node) {
996 if (node.parent is! DefaultFormalParameter) {
997 SimpleIdentifier parameterName = node.identifier;
998 ParameterElementImpl parameter =
999 new ParameterElementImpl.forNode(parameterName);
1000 parameter.const3 = node.isConst;
1001 parameter.final2 = node.isFinal;
1002 parameter.parameterKind = node.kind;
1003 _setParameterVisibleRange(node, parameter);
1004 if (node.type == null) {
1005 parameter.hasImplicitType = true;
1006 }
1007 _currentHolder.addParameter(parameter);
1008 parameterName.staticElement = parameter;
1009 }
1010 return super.visitSimpleFormalParameter(node);
1011 }
1012
1013 @override
1014 Object visitSwitchCase(SwitchCase node) {
1015 for (Label label in node.labels) {
1016 SimpleIdentifier labelName = label.label;
1017 LabelElementImpl element = new LabelElementImpl(labelName, false, true);
1018 _currentHolder.addLabel(element);
1019 labelName.staticElement = element;
1020 }
1021 return super.visitSwitchCase(node);
1022 }
1023
1024 @override
1025 Object visitSwitchDefault(SwitchDefault node) {
1026 for (Label label in node.labels) {
1027 SimpleIdentifier labelName = label.label;
1028 LabelElementImpl element = new LabelElementImpl(labelName, false, true);
1029 _currentHolder.addLabel(element);
1030 labelName.staticElement = element;
1031 }
1032 return super.visitSwitchDefault(node);
1033 }
1034
1035 @override
1036 Object visitTypeParameter(TypeParameter node) {
1037 SimpleIdentifier parameterName = node.name;
1038 TypeParameterElementImpl typeParameter =
1039 new TypeParameterElementImpl.forNode(parameterName);
1040 TypeParameterTypeImpl typeParameterType =
1041 new TypeParameterTypeImpl(typeParameter);
1042 typeParameter.type = typeParameterType;
1043 _currentHolder.addTypeParameter(typeParameter);
1044 parameterName.staticElement = typeParameter;
1045 return super.visitTypeParameter(node);
1046 }
1047
1048 @override
1049 Object visitVariableDeclaration(VariableDeclaration node) {
1050 bool isConst = node.isConst;
1051 bool isFinal = node.isFinal;
1052 bool hasInitializer = node.initializer != null;
1053 VariableElementImpl element;
1054 if (_inFieldContext) {
1055 SimpleIdentifier fieldName = node.name;
1056 FieldElementImpl field;
1057 if ((isConst || isFinal) && hasInitializer) {
1058 field = new ConstFieldElementImpl.forNode(fieldName);
1059 } else {
1060 field = new FieldElementImpl.forNode(fieldName);
1061 }
1062 element = field;
1063 if (node.parent.parent is FieldDeclaration) {
1064 _setDoc(element, node.parent.parent);
1065 }
1066 if ((node.parent as VariableDeclarationList).type == null) {
1067 field.hasImplicitType = true;
1068 }
1069 _currentHolder.addField(field);
1070 fieldName.staticElement = field;
1071 } else if (_inFunction) {
1072 SimpleIdentifier variableName = node.name;
1073 LocalVariableElementImpl variable;
1074 if (isConst && hasInitializer) {
1075 variable = new ConstLocalVariableElementImpl.forNode(variableName);
1076 } else {
1077 variable = new LocalVariableElementImpl.forNode(variableName);
1078 }
1079 element = variable;
1080 Block enclosingBlock = node.getAncestor((node) => node is Block);
1081 // TODO(brianwilkerson) This isn't right for variables declared in a for
1082 // loop.
1083 variable.setVisibleRange(enclosingBlock.offset, enclosingBlock.length);
1084 if ((node.parent as VariableDeclarationList).type == null) {
1085 variable.hasImplicitType = true;
1086 }
1087 _currentHolder.addLocalVariable(variable);
1088 variableName.staticElement = element;
1089 } else {
1090 SimpleIdentifier variableName = node.name;
1091 TopLevelVariableElementImpl variable;
1092 if (isConst && hasInitializer) {
1093 variable = new ConstTopLevelVariableElementImpl.forNode(variableName);
1094 } else {
1095 variable = new TopLevelVariableElementImpl.forNode(variableName);
1096 }
1097 element = variable;
1098 if (node.parent.parent is TopLevelVariableDeclaration) {
1099 _setDoc(element, node.parent.parent);
1100 }
1101 if ((node.parent as VariableDeclarationList).type == null) {
1102 variable.hasImplicitType = true;
1103 }
1104 _currentHolder.addTopLevelVariable(variable);
1105 variableName.staticElement = element;
1106 }
1107 element.const3 = isConst;
1108 element.final2 = isFinal;
1109 if (hasInitializer) {
1110 ElementHolder holder = new ElementHolder();
1111 bool wasInFieldContext = _inFieldContext;
1112 _inFieldContext = false;
1113 try {
1114 _visit(holder, node.initializer);
1115 } finally {
1116 _inFieldContext = wasInFieldContext;
1117 }
1118 FunctionElementImpl initializer =
1119 new FunctionElementImpl.forOffset(node.initializer.beginToken.offset);
1120 initializer.functions = holder.functions;
1121 initializer.labels = holder.labels;
1122 initializer.localVariables = holder.localVariables;
1123 initializer.synthetic = true;
1124 element.initializer = initializer;
1125 holder.validate();
1126 }
1127 if (element is PropertyInducingElementImpl) {
1128 if (_inFieldContext) {
1129 (element as FieldElementImpl).static =
1130 (node.parent.parent as FieldDeclaration).isStatic;
1131 }
1132 PropertyAccessorElementImpl getter =
1133 new PropertyAccessorElementImpl.forVariable(element);
1134 getter.getter = true;
1135 if (element.hasImplicitType) {
1136 getter.hasImplicitReturnType = true;
1137 }
1138 _currentHolder.addAccessor(getter);
1139 element.getter = getter;
1140 if (!isConst && !isFinal) {
1141 PropertyAccessorElementImpl setter =
1142 new PropertyAccessorElementImpl.forVariable(element);
1143 setter.setter = true;
1144 ParameterElementImpl parameter =
1145 new ParameterElementImpl("_${element.name}", element.nameOffset);
1146 parameter.synthetic = true;
1147 parameter.parameterKind = ParameterKind.REQUIRED;
1148 setter.parameters = <ParameterElement>[parameter];
1149 _currentHolder.addAccessor(setter);
1150 element.setter = setter;
1151 }
1152 }
1153 return null;
1154 }
1155
1156 /**
1157 * Build the table mapping field names to field elements for the fields define d in the current
1158 * class.
1159 *
1160 * @param fields the field elements defined in the current class
1161 */
1162 void _buildFieldMap(List<FieldElement> fields) {
1163 _fieldMap = new HashMap<String, FieldElement>();
1164 int count = fields.length;
1165 for (int i = 0; i < count; i++) {
1166 FieldElement field = fields[i];
1167 _fieldMap[field.name] = field;
1168 }
1169 }
1170
1171 /**
1172 * Creates the [ConstructorElement]s array with the single default constructor element.
1173 *
1174 * @param interfaceType the interface type for which to create a default const ructor
1175 * @return the [ConstructorElement]s array with the single default constructor element
1176 */
1177 List<ConstructorElement> _createDefaultConstructors(
1178 ClassElementImpl definingClass) {
1179 ConstructorElementImpl constructor =
1180 new ConstructorElementImpl.forNode(null);
1181 constructor.synthetic = true;
1182 constructor.returnType = definingClass.type;
1183 constructor.enclosingElement = definingClass;
1184 constructor.type = new FunctionTypeImpl(constructor);
1185 return <ConstructorElement>[constructor];
1186 }
1187
1188 /**
1189 * Create the types associated with the given type parameters, setting the typ e of each type
1190 * parameter, and return an array of types corresponding to the given paramete rs.
1191 *
1192 * @param typeParameters the type parameters for which types are to be created
1193 * @return an array of types corresponding to the given parameters
1194 */
1195 List<DartType> _createTypeParameterTypes(
1196 List<TypeParameterElement> typeParameters) {
1197 int typeParameterCount = typeParameters.length;
1198 List<DartType> typeArguments = new List<DartType>(typeParameterCount);
1199 for (int i = 0; i < typeParameterCount; i++) {
1200 TypeParameterElementImpl typeParameter =
1201 typeParameters[i] as TypeParameterElementImpl;
1202 TypeParameterTypeImpl typeParameterType =
1203 new TypeParameterTypeImpl(typeParameter);
1204 typeParameter.type = typeParameterType;
1205 typeArguments[i] = typeParameterType;
1206 }
1207 return typeArguments;
1208 }
1209
1210 /**
1211 * Return the body of the function that contains the given parameter, or `null ` if no
1212 * function body could be found.
1213 *
1214 * @param node the parameter contained in the function whose body is to be ret urned
1215 * @return the body of the function that contains the given parameter
1216 */
1217 FunctionBody _getFunctionBody(FormalParameter node) {
1218 AstNode parent = node.parent;
1219 while (parent != null) {
1220 if (parent is ConstructorDeclaration) {
1221 return parent.body;
1222 } else if (parent is FunctionExpression) {
1223 return parent.body;
1224 } else if (parent is MethodDeclaration) {
1225 return parent.body;
1226 }
1227 parent = parent.parent;
1228 }
1229 return null;
1230 }
1231
1232 /**
1233 * If the given [node] has a documentation comment, remember its content
1234 * and range into the given [element].
1235 */
1236 void _setDoc(ElementImpl element, AnnotatedNode node) {
1237 Comment comment = node.documentationComment;
1238 if (comment != null && comment.isDocumentation) {
1239 element.documentationComment =
1240 comment.tokens.map((Token t) => t.lexeme).join('\n');
1241 element.setDocRange(comment.offset, comment.length);
1242 }
1243 }
1244
1245 /**
1246 * Sets the visible source range for formal parameter.
1247 */
1248 void _setParameterVisibleRange(
1249 FormalParameter node, ParameterElementImpl element) {
1250 FunctionBody body = _getFunctionBody(node);
1251 if (body != null) {
1252 element.setVisibleRange(body.offset, body.length);
1253 }
1254 }
1255
1256 /**
1257 * Make the given holder be the current holder while visiting the given node.
1258 *
1259 * @param holder the holder that will gather elements that are built while vis iting the children
1260 * @param node the node to be visited
1261 */
1262 void _visit(ElementHolder holder, AstNode node) {
1263 if (node != null) {
1264 ElementHolder previousHolder = _currentHolder;
1265 _currentHolder = holder;
1266 try {
1267 node.accept(this);
1268 } finally {
1269 _currentHolder = previousHolder;
1270 }
1271 }
1272 }
1273
1274 /**
1275 * Make the given holder be the current holder while visiting the children of the given node.
1276 *
1277 * @param holder the holder that will gather elements that are built while vis iting the children
1278 * @param node the node whose children are to be visited
1279 */
1280 void _visitChildren(ElementHolder holder, AstNode node) {
1281 if (node != null) {
1282 ElementHolder previousHolder = _currentHolder;
1283 _currentHolder = holder;
1284 try {
1285 node.visitChildren(this);
1286 } finally {
1287 _currentHolder = previousHolder;
1288 }
1289 }
1290 }
1291 }
1292
1293 class _ElementBuilder_visitClassDeclaration extends UnifyingAstVisitor<Object> {
1294 final ElementBuilder builder;
1295
1296 List<ClassMember> nonFields;
1297
1298 _ElementBuilder_visitClassDeclaration(this.builder, this.nonFields) : super();
1299
1300 @override
1301 Object visitConstructorDeclaration(ConstructorDeclaration node) {
1302 nonFields.add(node);
1303 return null;
1304 }
1305
1306 @override
1307 Object visitMethodDeclaration(MethodDeclaration node) {
1308 nonFields.add(node);
1309 return null;
1310 }
1311
1312 @override
1313 Object visitNode(AstNode node) => node.accept(builder);
1314 }
1315
1316 /**
233 * Instances of the class [_NamespaceCombinatorBuilder] can be used to visit 1317 * Instances of the class [_NamespaceCombinatorBuilder] can be used to visit
234 * [Combinator] AST nodes and generate [NamespaceCombinator] elements. 1318 * [Combinator] AST nodes and generate [NamespaceCombinator] elements.
235 */ 1319 */
236 class _NamespaceCombinatorBuilder extends SimpleAstVisitor<Object> { 1320 class _NamespaceCombinatorBuilder extends SimpleAstVisitor<Object> {
237 /** 1321 /**
238 * Elements generated so far. 1322 * Elements generated so far.
239 */ 1323 */
240 final List<NamespaceCombinator> combinators = <NamespaceCombinator>[]; 1324 final List<NamespaceCombinator> combinators = <NamespaceCombinator>[];
241 1325
242 @override 1326 @override
(...skipping 14 matching lines...) Expand all
257 return null; 1341 return null;
258 } 1342 }
259 1343
260 /** 1344 /**
261 * Return the lexical identifiers associated with the given [identifiers]. 1345 * Return the lexical identifiers associated with the given [identifiers].
262 */ 1346 */
263 static List<String> _getIdentifiers(NodeList<SimpleIdentifier> identifiers) { 1347 static List<String> _getIdentifiers(NodeList<SimpleIdentifier> identifiers) {
264 return identifiers.map((identifier) => identifier.name).toList(); 1348 return identifiers.map((identifier) => identifier.name).toList();
265 } 1349 }
266 } 1350 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/lib/src/generated/incremental_resolver.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698