| Index: packages/analyzer/test/generated/element_resolver_test.dart
|
| diff --git a/packages/analyzer/test/generated/element_resolver_test.dart b/packages/analyzer/test/generated/element_resolver_test.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..e911f73f658921baace5148d3a191c045c27c6eb
|
| --- /dev/null
|
| +++ b/packages/analyzer/test/generated/element_resolver_test.dart
|
| @@ -0,0 +1,1286 @@
|
| +// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
|
| +// for details. All rights reserved. Use of this source code is governed by a
|
| +// BSD-style license that can be found in the LICENSE file.
|
| +
|
| +library analyzer.test.generated.element_resolver_test;
|
| +
|
| +import 'package:analyzer/dart/ast/ast.dart';
|
| +import 'package:analyzer/dart/ast/token.dart';
|
| +import 'package:analyzer/dart/element/element.dart';
|
| +import 'package:analyzer/dart/element/type.dart';
|
| +import 'package:analyzer/file_system/memory_file_system.dart';
|
| +import 'package:analyzer/src/dart/element/element.dart';
|
| +import 'package:analyzer/src/generated/element_resolver.dart';
|
| +import 'package:analyzer/src/generated/engine.dart';
|
| +import 'package:analyzer/src/generated/resolver.dart';
|
| +import 'package:analyzer/src/generated/source.dart';
|
| +import 'package:analyzer/src/generated/testing/ast_factory.dart';
|
| +import 'package:analyzer/src/generated/testing/element_factory.dart';
|
| +import 'package:analyzer/src/generated/testing/test_type_provider.dart';
|
| +import 'package:analyzer/src/source/source_resource.dart';
|
| +import 'package:test_reflective_loader/test_reflective_loader.dart';
|
| +import 'package:unittest/unittest.dart';
|
| +
|
| +import '../utils.dart';
|
| +import 'analysis_context_factory.dart';
|
| +import 'resolver_test_case.dart';
|
| +import 'test_support.dart';
|
| +
|
| +main() {
|
| + initializeTestEnvironment();
|
| + defineReflectiveTests(ElementResolverCodeTest);
|
| + defineReflectiveTests(ElementResolverTest);
|
| +}
|
| +
|
| +@reflectiveTest
|
| +class ElementResolverCodeTest extends ResolverTestCase {
|
| + void test_annotation_class_namedConstructor() {
|
| + addNamedSource(
|
| + '/a.dart',
|
| + r'''
|
| +class A {
|
| + const A.named();
|
| +}
|
| +''');
|
| + _validateAnnotation('', '@A.named()', (SimpleIdentifier name1,
|
| + SimpleIdentifier name2,
|
| + SimpleIdentifier name3,
|
| + Element annotationElement) {
|
| + expect(name1, isNotNull);
|
| + expect(name1.staticElement, new isInstanceOf<ClassElement>());
|
| + expect(name1.staticElement.displayName, 'A');
|
| + expect(name2, isNotNull);
|
| + expect(name2.staticElement, new isInstanceOf<ConstructorElement>());
|
| + expect(name2.staticElement.displayName, 'named');
|
| + expect(name3, isNull);
|
| + if (annotationElement is ConstructorElement) {
|
| + expect(annotationElement, same(name2.staticElement));
|
| + expect(annotationElement.enclosingElement, name1.staticElement);
|
| + expect(annotationElement.displayName, 'named');
|
| + expect(annotationElement.parameters, isEmpty);
|
| + } else {
|
| + fail('Expected "annotationElement" is ConstructorElement, '
|
| + 'but (${annotationElement?.runtimeType}) $annotationElement found.');
|
| + }
|
| + });
|
| + }
|
| +
|
| + void test_annotation_class_prefixed_namedConstructor() {
|
| + addNamedSource(
|
| + '/a.dart',
|
| + r'''
|
| +class A {
|
| + const A.named();
|
| +}
|
| +''');
|
| + _validateAnnotation('as p', '@p.A.named()', (SimpleIdentifier name1,
|
| + SimpleIdentifier name2,
|
| + SimpleIdentifier name3,
|
| + Element annotationElement) {
|
| + expect(name1, isNotNull);
|
| + expect(name1.staticElement, new isInstanceOf<PrefixElement>());
|
| + expect(name1.staticElement.displayName, 'p');
|
| + expect(name2, isNotNull);
|
| + expect(name2.staticElement, new isInstanceOf<ClassElement>());
|
| + expect(name2.staticElement.displayName, 'A');
|
| + expect(name3, isNotNull);
|
| + expect(name3.staticElement, new isInstanceOf<ConstructorElement>());
|
| + expect(name3.staticElement.displayName, 'named');
|
| + if (annotationElement is ConstructorElement) {
|
| + expect(annotationElement, same(name3.staticElement));
|
| + expect(annotationElement.enclosingElement, name2.staticElement);
|
| + expect(annotationElement.displayName, 'named');
|
| + expect(annotationElement.parameters, isEmpty);
|
| + } else {
|
| + fail('Expected "annotationElement" is ConstructorElement, '
|
| + 'but (${annotationElement?.runtimeType}) $annotationElement found.');
|
| + }
|
| + });
|
| + }
|
| +
|
| + void test_annotation_class_prefixed_staticConstField() {
|
| + addNamedSource(
|
| + '/a.dart',
|
| + r'''
|
| +class A {
|
| + static const V = 0;
|
| +}
|
| +''');
|
| + _validateAnnotation('as p', '@p.A.V', (SimpleIdentifier name1,
|
| + SimpleIdentifier name2,
|
| + SimpleIdentifier name3,
|
| + Element annotationElement) {
|
| + expect(name1, isNotNull);
|
| + expect(name1.staticElement, new isInstanceOf<PrefixElement>());
|
| + expect(name1.staticElement.displayName, 'p');
|
| + expect(name2, isNotNull);
|
| + expect(name2.staticElement, new isInstanceOf<ClassElement>());
|
| + expect(name2.staticElement.displayName, 'A');
|
| + expect(name3, isNotNull);
|
| + expect(name3.staticElement, new isInstanceOf<PropertyAccessorElement>());
|
| + expect(name3.staticElement.displayName, 'V');
|
| + if (annotationElement is PropertyAccessorElement) {
|
| + expect(annotationElement, same(name3.staticElement));
|
| + expect(annotationElement.enclosingElement, name2.staticElement);
|
| + expect(annotationElement.displayName, 'V');
|
| + } else {
|
| + fail('Expected "annotationElement" is PropertyAccessorElement, '
|
| + 'but (${annotationElement?.runtimeType}) $annotationElement found.');
|
| + }
|
| + });
|
| + }
|
| +
|
| + void test_annotation_class_prefixed_unnamedConstructor() {
|
| + addNamedSource(
|
| + '/a.dart',
|
| + r'''
|
| +class A {
|
| + const A();
|
| +}
|
| +''');
|
| + _validateAnnotation('as p', '@p.A', (SimpleIdentifier name1,
|
| + SimpleIdentifier name2,
|
| + SimpleIdentifier name3,
|
| + Element annotationElement) {
|
| + expect(name1, isNotNull);
|
| + expect(name1.staticElement, new isInstanceOf<PrefixElement>());
|
| + expect(name1.staticElement.displayName, 'p');
|
| + expect(name2, isNotNull);
|
| + expect(name2.staticElement, new isInstanceOf<ClassElement>());
|
| + expect(name2.staticElement.displayName, 'A');
|
| + expect(name3, isNull);
|
| + if (annotationElement is ConstructorElement) {
|
| + expect(annotationElement.enclosingElement, name2.staticElement);
|
| + expect(annotationElement.displayName, '');
|
| + expect(annotationElement.parameters, isEmpty);
|
| + } else {
|
| + fail('Expected "annotationElement" is ConstructorElement, '
|
| + 'but (${annotationElement?.runtimeType}) $annotationElement found.');
|
| + }
|
| + });
|
| + }
|
| +
|
| + void test_annotation_class_staticConstField() {
|
| + addNamedSource(
|
| + '/a.dart',
|
| + r'''
|
| +class A {
|
| + static const V = 0;
|
| +}
|
| +''');
|
| + _validateAnnotation('', '@A.V', (SimpleIdentifier name1,
|
| + SimpleIdentifier name2,
|
| + SimpleIdentifier name3,
|
| + Element annotationElement) {
|
| + expect(name1, isNotNull);
|
| + expect(name1.staticElement, new isInstanceOf<ClassElement>());
|
| + expect(name1.staticElement.displayName, 'A');
|
| + expect(name2, isNotNull);
|
| + expect(name2.staticElement, new isInstanceOf<PropertyAccessorElement>());
|
| + expect(name2.staticElement.displayName, 'V');
|
| + expect(name3, isNull);
|
| + if (annotationElement is PropertyAccessorElement) {
|
| + expect(annotationElement, same(name2.staticElement));
|
| + expect(annotationElement.enclosingElement, name1.staticElement);
|
| + expect(annotationElement.displayName, 'V');
|
| + } else {
|
| + fail('Expected "annotationElement" is PropertyAccessorElement, '
|
| + 'but (${annotationElement?.runtimeType}) $annotationElement found.');
|
| + }
|
| + });
|
| + }
|
| +
|
| + void test_annotation_class_unnamedConstructor() {
|
| + addNamedSource(
|
| + '/a.dart',
|
| + r'''
|
| +class A {
|
| + const A();
|
| +}
|
| +''');
|
| + _validateAnnotation('', '@A', (SimpleIdentifier name1,
|
| + SimpleIdentifier name2,
|
| + SimpleIdentifier name3,
|
| + Element annotationElement) {
|
| + expect(name1, isNotNull);
|
| + expect(name1.staticElement, new isInstanceOf<ClassElement>());
|
| + expect(name1.staticElement.displayName, 'A');
|
| + expect(name2, isNull);
|
| + expect(name3, isNull);
|
| + if (annotationElement is ConstructorElement) {
|
| + expect(annotationElement.enclosingElement, name1.staticElement);
|
| + expect(annotationElement.displayName, '');
|
| + expect(annotationElement.parameters, isEmpty);
|
| + } else {
|
| + fail('Expected "annotationElement" is ConstructorElement, '
|
| + 'but (${annotationElement?.runtimeType}) $annotationElement found.');
|
| + }
|
| + });
|
| + }
|
| +
|
| + void test_annotation_topLevelVariable() {
|
| + addNamedSource(
|
| + '/a.dart',
|
| + r'''
|
| +const V = 0;
|
| +''');
|
| + _validateAnnotation('', '@V', (SimpleIdentifier name1,
|
| + SimpleIdentifier name2,
|
| + SimpleIdentifier name3,
|
| + Element annotationElement) {
|
| + expect(name1, isNotNull);
|
| + expect(name1.staticElement, new isInstanceOf<PropertyAccessorElement>());
|
| + expect(name1.staticElement.displayName, 'V');
|
| + expect(name2, isNull);
|
| + expect(name3, isNull);
|
| + if (annotationElement is PropertyAccessorElement) {
|
| + expect(annotationElement, same(name1.staticElement));
|
| + expect(annotationElement.enclosingElement,
|
| + new isInstanceOf<CompilationUnitElement>());
|
| + expect(annotationElement.displayName, 'V');
|
| + } else {
|
| + fail('Expected "annotationElement" is PropertyAccessorElement, '
|
| + 'but (${annotationElement?.runtimeType}) $annotationElement found.');
|
| + }
|
| + });
|
| + }
|
| +
|
| + void test_annotation_topLevelVariable_prefixed() {
|
| + addNamedSource(
|
| + '/a.dart',
|
| + r'''
|
| +const V = 0;
|
| +''');
|
| + _validateAnnotation('as p', '@p.V', (SimpleIdentifier name1,
|
| + SimpleIdentifier name2,
|
| + SimpleIdentifier name3,
|
| + Element annotationElement) {
|
| + expect(name1, isNotNull);
|
| + expect(name1.staticElement, new isInstanceOf<PrefixElement>());
|
| + expect(name1.staticElement.displayName, 'p');
|
| + expect(name2, isNotNull);
|
| + expect(name2.staticElement, new isInstanceOf<PropertyAccessorElement>());
|
| + expect(name2.staticElement.displayName, 'V');
|
| + expect(name3, isNull);
|
| + if (annotationElement is PropertyAccessorElement) {
|
| + expect(annotationElement, same(name2.staticElement));
|
| + expect(annotationElement.enclosingElement,
|
| + new isInstanceOf<CompilationUnitElement>());
|
| + expect(annotationElement.displayName, 'V');
|
| + } else {
|
| + fail('Expected "annotationElement" is PropertyAccessorElement, '
|
| + 'but (${annotationElement?.runtimeType}) $annotationElement found.');
|
| + }
|
| + });
|
| + }
|
| +
|
| + void _validateAnnotation(
|
| + String annotationPrefix,
|
| + String annotationText,
|
| + validator(SimpleIdentifier name1, SimpleIdentifier name2,
|
| + SimpleIdentifier name3, Element annotationElement)) {
|
| + CompilationUnit unit = resolveSource('''
|
| +import 'a.dart' $annotationPrefix;
|
| +$annotationText
|
| +class C {}
|
| +''');
|
| + var clazz = unit.declarations.single as ClassDeclaration;
|
| + Annotation annotation = clazz.metadata.single;
|
| + Identifier name = annotation.name;
|
| + Element annotationElement = annotation.element;
|
| + if (name is SimpleIdentifier) {
|
| + validator(name, null, annotation.constructorName, annotationElement);
|
| + } else if (name is PrefixedIdentifier) {
|
| + validator(name.prefix, name.identifier, annotation.constructorName,
|
| + annotationElement);
|
| + } else {
|
| + fail('Uknown "name": ${name?.runtimeType} $name');
|
| + }
|
| + }
|
| +}
|
| +
|
| +@reflectiveTest
|
| +class ElementResolverTest extends EngineTestCase {
|
| + /**
|
| + * The error listener to which errors will be reported.
|
| + */
|
| + GatheringErrorListener _listener;
|
| +
|
| + /**
|
| + * The type provider used to access the types.
|
| + */
|
| + TestTypeProvider _typeProvider;
|
| +
|
| + /**
|
| + * The library containing the code being resolved.
|
| + */
|
| + LibraryElementImpl _definingLibrary;
|
| +
|
| + /**
|
| + * The resolver visitor that maintains the state for the resolver.
|
| + */
|
| + ResolverVisitor _visitor;
|
| +
|
| + /**
|
| + * The resolver being used to resolve the test cases.
|
| + */
|
| + ElementResolver _resolver;
|
| +
|
| + void fail_visitExportDirective_combinators() {
|
| + fail("Not yet tested");
|
| + // Need to set up the exported library so that the identifier can be
|
| + // resolved.
|
| + ExportDirective directive = AstFactory.exportDirective2(null, [
|
| + AstFactory.hideCombinator2(["A"])
|
| + ]);
|
| + _resolveNode(directive);
|
| + _listener.assertNoErrors();
|
| + }
|
| +
|
| + void fail_visitFunctionExpressionInvocation() {
|
| + fail("Not yet tested");
|
| + _listener.assertNoErrors();
|
| + }
|
| +
|
| + void fail_visitImportDirective_combinators_noPrefix() {
|
| + fail("Not yet tested");
|
| + // Need to set up the imported library so that the identifier can be
|
| + // resolved.
|
| + ImportDirective directive = AstFactory.importDirective3(null, null, [
|
| + AstFactory.showCombinator2(["A"])
|
| + ]);
|
| + _resolveNode(directive);
|
| + _listener.assertNoErrors();
|
| + }
|
| +
|
| + void fail_visitImportDirective_combinators_prefix() {
|
| + fail("Not yet tested");
|
| + // Need to set up the imported library so that the identifiers can be
|
| + // resolved.
|
| + String prefixName = "p";
|
| + _definingLibrary.imports = <ImportElement>[
|
| + ElementFactory.importFor(null, ElementFactory.prefix(prefixName))
|
| + ];
|
| + ImportDirective directive = AstFactory.importDirective3(null, prefixName, [
|
| + AstFactory.showCombinator2(["A"]),
|
| + AstFactory.hideCombinator2(["B"])
|
| + ]);
|
| + _resolveNode(directive);
|
| + _listener.assertNoErrors();
|
| + }
|
| +
|
| + void fail_visitRedirectingConstructorInvocation() {
|
| + fail("Not yet tested");
|
| + _listener.assertNoErrors();
|
| + }
|
| +
|
| + @override
|
| + void setUp() {
|
| + super.setUp();
|
| + _listener = new GatheringErrorListener();
|
| + _typeProvider = new TestTypeProvider();
|
| + _resolver = _createResolver();
|
| + }
|
| +
|
| + void test_lookUpMethodInInterfaces() {
|
| + InterfaceType intType = _typeProvider.intType;
|
| + //
|
| + // abstract class A { int operator[](int index); }
|
| + //
|
| + ClassElementImpl classA = ElementFactory.classElement2("A");
|
| + MethodElement operator =
|
| + ElementFactory.methodElement("[]", intType, [intType]);
|
| + classA.methods = <MethodElement>[operator];
|
| + //
|
| + // class B implements A {}
|
| + //
|
| + ClassElementImpl classB = ElementFactory.classElement2("B");
|
| + classB.interfaces = <InterfaceType>[classA.type];
|
| + //
|
| + // class C extends Object with B {}
|
| + //
|
| + ClassElementImpl classC = ElementFactory.classElement2("C");
|
| + classC.mixins = <InterfaceType>[classB.type];
|
| + //
|
| + // class D extends C {}
|
| + //
|
| + ClassElementImpl classD = ElementFactory.classElement("D", classC.type);
|
| + //
|
| + // D a;
|
| + // a[i];
|
| + //
|
| + SimpleIdentifier array = AstFactory.identifier3("a");
|
| + array.staticType = classD.type;
|
| + IndexExpression expression =
|
| + AstFactory.indexExpression(array, AstFactory.identifier3("i"));
|
| + expect(_resolveIndexExpression(expression), same(operator));
|
| + _listener.assertNoErrors();
|
| + }
|
| +
|
| + void test_visitAssignmentExpression_compound() {
|
| + InterfaceType intType = _typeProvider.intType;
|
| + SimpleIdentifier leftHandSide = AstFactory.identifier3("a");
|
| + leftHandSide.staticType = intType;
|
| + AssignmentExpression assignment = AstFactory.assignmentExpression(
|
| + leftHandSide, TokenType.PLUS_EQ, AstFactory.integer(1));
|
| + _resolveNode(assignment);
|
| + expect(
|
| + assignment.staticElement, same(getMethod(_typeProvider.numType, "+")));
|
| + _listener.assertNoErrors();
|
| + }
|
| +
|
| + void test_visitAssignmentExpression_simple() {
|
| + AssignmentExpression expression = AstFactory.assignmentExpression(
|
| + AstFactory.identifier3("x"), TokenType.EQ, AstFactory.integer(0));
|
| + _resolveNode(expression);
|
| + expect(expression.staticElement, isNull);
|
| + _listener.assertNoErrors();
|
| + }
|
| +
|
| + void test_visitBinaryExpression_bangEq() {
|
| + // String i;
|
| + // var j;
|
| + // i == j
|
| + InterfaceType stringType = _typeProvider.stringType;
|
| + SimpleIdentifier left = AstFactory.identifier3("i");
|
| + left.staticType = stringType;
|
| + BinaryExpression expression = AstFactory.binaryExpression(
|
| + left, TokenType.BANG_EQ, AstFactory.identifier3("j"));
|
| + _resolveNode(expression);
|
| + var stringElement = stringType.element;
|
| + expect(expression.staticElement, isNotNull);
|
| + expect(
|
| + expression.staticElement,
|
| + stringElement.lookUpMethod(
|
| + TokenType.EQ_EQ.lexeme, stringElement.library));
|
| + expect(expression.propagatedElement, isNull);
|
| + _listener.assertNoErrors();
|
| + }
|
| +
|
| + void test_visitBinaryExpression_eq() {
|
| + // String i;
|
| + // var j;
|
| + // i == j
|
| + InterfaceType stringType = _typeProvider.stringType;
|
| + SimpleIdentifier left = AstFactory.identifier3("i");
|
| + left.staticType = stringType;
|
| + BinaryExpression expression = AstFactory.binaryExpression(
|
| + left, TokenType.EQ_EQ, AstFactory.identifier3("j"));
|
| + _resolveNode(expression);
|
| + var stringElement = stringType.element;
|
| + expect(
|
| + expression.staticElement,
|
| + stringElement.lookUpMethod(
|
| + TokenType.EQ_EQ.lexeme, stringElement.library));
|
| + expect(expression.propagatedElement, isNull);
|
| + _listener.assertNoErrors();
|
| + }
|
| +
|
| + void test_visitBinaryExpression_plus() {
|
| + // num i;
|
| + // var j;
|
| + // i + j
|
| + InterfaceType numType = _typeProvider.numType;
|
| + SimpleIdentifier left = AstFactory.identifier3("i");
|
| + left.staticType = numType;
|
| + BinaryExpression expression = AstFactory.binaryExpression(
|
| + left, TokenType.PLUS, AstFactory.identifier3("j"));
|
| + _resolveNode(expression);
|
| + expect(expression.staticElement, getMethod(numType, "+"));
|
| + expect(expression.propagatedElement, isNull);
|
| + _listener.assertNoErrors();
|
| + }
|
| +
|
| + void test_visitBinaryExpression_plus_propagatedElement() {
|
| + // var i = 1;
|
| + // var j;
|
| + // i + j
|
| + InterfaceType numType = _typeProvider.numType;
|
| + SimpleIdentifier left = AstFactory.identifier3("i");
|
| + left.propagatedType = numType;
|
| + BinaryExpression expression = AstFactory.binaryExpression(
|
| + left, TokenType.PLUS, AstFactory.identifier3("j"));
|
| + _resolveNode(expression);
|
| + expect(expression.staticElement, isNull);
|
| + expect(expression.propagatedElement, getMethod(numType, "+"));
|
| + _listener.assertNoErrors();
|
| + }
|
| +
|
| + void test_visitBreakStatement_withLabel() {
|
| + // loop: while (true) {
|
| + // break loop;
|
| + // }
|
| + String label = "loop";
|
| + LabelElementImpl labelElement = new LabelElementImpl.forNode(
|
| + AstFactory.identifier3(label), false, false);
|
| + BreakStatement breakStatement = AstFactory.breakStatement2(label);
|
| + Expression condition = AstFactory.booleanLiteral(true);
|
| + WhileStatement whileStatement =
|
| + AstFactory.whileStatement(condition, breakStatement);
|
| + expect(_resolveBreak(breakStatement, labelElement, whileStatement),
|
| + same(labelElement));
|
| + expect(breakStatement.target, same(whileStatement));
|
| + _listener.assertNoErrors();
|
| + }
|
| +
|
| + void test_visitBreakStatement_withoutLabel() {
|
| + BreakStatement statement = AstFactory.breakStatement();
|
| + _resolveStatement(statement, null, null);
|
| + _listener.assertNoErrors();
|
| + }
|
| +
|
| + void test_visitCommentReference_prefixedIdentifier_class_getter() {
|
| + ClassElementImpl classA = ElementFactory.classElement2("A");
|
| + // set accessors
|
| + String propName = "p";
|
| + PropertyAccessorElement getter =
|
| + ElementFactory.getterElement(propName, false, _typeProvider.intType);
|
| + PropertyAccessorElement setter =
|
| + ElementFactory.setterElement(propName, false, _typeProvider.intType);
|
| + classA.accessors = <PropertyAccessorElement>[getter, setter];
|
| + // set name scope
|
| + _visitor.nameScope = new EnclosedScope(null)
|
| + ..defineNameWithoutChecking('A', classA);
|
| + // prepare "A.p"
|
| + PrefixedIdentifier prefixed = AstFactory.identifier5('A', 'p');
|
| + CommentReference commentReference = new CommentReference(null, prefixed);
|
| + // resolve
|
| + _resolveNode(commentReference);
|
| + expect(prefixed.prefix.staticElement, classA);
|
| + expect(prefixed.identifier.staticElement, getter);
|
| + _listener.assertNoErrors();
|
| + }
|
| +
|
| + void test_visitCommentReference_prefixedIdentifier_class_method() {
|
| + ClassElementImpl classA = ElementFactory.classElement2("A");
|
| + // set method
|
| + MethodElement method =
|
| + ElementFactory.methodElement("m", _typeProvider.intType);
|
| + classA.methods = <MethodElement>[method];
|
| + // set name scope
|
| + _visitor.nameScope = new EnclosedScope(null)
|
| + ..defineNameWithoutChecking('A', classA);
|
| + // prepare "A.m"
|
| + PrefixedIdentifier prefixed = AstFactory.identifier5('A', 'm');
|
| + CommentReference commentReference = new CommentReference(null, prefixed);
|
| + // resolve
|
| + _resolveNode(commentReference);
|
| + expect(prefixed.prefix.staticElement, classA);
|
| + expect(prefixed.identifier.staticElement, method);
|
| + _listener.assertNoErrors();
|
| + }
|
| +
|
| + void test_visitCommentReference_prefixedIdentifier_class_operator() {
|
| + ClassElementImpl classA = ElementFactory.classElement2("A");
|
| + // set method
|
| + MethodElement method =
|
| + ElementFactory.methodElement("==", _typeProvider.boolType);
|
| + classA.methods = <MethodElement>[method];
|
| + // set name scope
|
| + _visitor.nameScope = new EnclosedScope(null)
|
| + ..defineNameWithoutChecking('A', classA);
|
| + // prepare "A.=="
|
| + PrefixedIdentifier prefixed = AstFactory.identifier5('A', '==');
|
| + CommentReference commentReference = new CommentReference(null, prefixed);
|
| + // resolve
|
| + _resolveNode(commentReference);
|
| + expect(prefixed.prefix.staticElement, classA);
|
| + expect(prefixed.identifier.staticElement, method);
|
| + _listener.assertNoErrors();
|
| + }
|
| +
|
| + void test_visitConstructorName_named() {
|
| + ClassElementImpl classA = ElementFactory.classElement2("A");
|
| + String constructorName = "a";
|
| + ConstructorElement constructor =
|
| + ElementFactory.constructorElement2(classA, constructorName);
|
| + classA.constructors = <ConstructorElement>[constructor];
|
| + ConstructorName name = AstFactory.constructorName(
|
| + AstFactory.typeName(classA), constructorName);
|
| + _resolveNode(name);
|
| + expect(name.staticElement, same(constructor));
|
| + _listener.assertNoErrors();
|
| + }
|
| +
|
| + void test_visitConstructorName_unnamed() {
|
| + ClassElementImpl classA = ElementFactory.classElement2("A");
|
| + String constructorName = null;
|
| + ConstructorElement constructor =
|
| + ElementFactory.constructorElement2(classA, constructorName);
|
| + classA.constructors = <ConstructorElement>[constructor];
|
| + ConstructorName name = AstFactory.constructorName(
|
| + AstFactory.typeName(classA), constructorName);
|
| + _resolveNode(name);
|
| + expect(name.staticElement, same(constructor));
|
| + _listener.assertNoErrors();
|
| + }
|
| +
|
| + void test_visitContinueStatement_withLabel() {
|
| + // loop: while (true) {
|
| + // continue loop;
|
| + // }
|
| + String label = "loop";
|
| + LabelElementImpl labelElement = new LabelElementImpl.forNode(
|
| + AstFactory.identifier3(label), false, false);
|
| + ContinueStatement continueStatement = AstFactory.continueStatement(label);
|
| + Expression condition = AstFactory.booleanLiteral(true);
|
| + WhileStatement whileStatement =
|
| + AstFactory.whileStatement(condition, continueStatement);
|
| + expect(_resolveContinue(continueStatement, labelElement, whileStatement),
|
| + same(labelElement));
|
| + expect(continueStatement.target, same(whileStatement));
|
| + _listener.assertNoErrors();
|
| + }
|
| +
|
| + void test_visitContinueStatement_withoutLabel() {
|
| + ContinueStatement statement = AstFactory.continueStatement();
|
| + _resolveStatement(statement, null, null);
|
| + _listener.assertNoErrors();
|
| + }
|
| +
|
| + void test_visitEnumDeclaration() {
|
| + CompilationUnitElementImpl compilationUnitElement =
|
| + ElementFactory.compilationUnit('foo.dart');
|
| + EnumElementImpl enumElement =
|
| + ElementFactory.enumElement(_typeProvider, ('E'));
|
| + compilationUnitElement.enums = <ClassElement>[enumElement];
|
| + EnumDeclaration enumNode = AstFactory.enumDeclaration2('E', []);
|
| + Annotation annotationNode =
|
| + AstFactory.annotation(AstFactory.identifier3('a'));
|
| + annotationNode.element = ElementFactory.classElement2('A');
|
| + annotationNode.elementAnnotation =
|
| + new ElementAnnotationImpl(compilationUnitElement);
|
| + enumNode.metadata.add(annotationNode);
|
| + enumNode.name.staticElement = enumElement;
|
| + List<ElementAnnotation> metadata = <ElementAnnotation>[
|
| + annotationNode.elementAnnotation
|
| + ];
|
| + _resolveNode(enumNode);
|
| + expect(metadata[0].element, annotationNode.element);
|
| + }
|
| +
|
| + void test_visitExportDirective_noCombinators() {
|
| + ExportDirective directive = AstFactory.exportDirective2(null);
|
| + directive.element = ElementFactory
|
| + .exportFor(ElementFactory.library(_definingLibrary.context, "lib"));
|
| + _resolveNode(directive);
|
| + _listener.assertNoErrors();
|
| + }
|
| +
|
| + void test_visitFieldFormalParameter() {
|
| + String fieldName = "f";
|
| + InterfaceType intType = _typeProvider.intType;
|
| + FieldElementImpl fieldElement =
|
| + ElementFactory.fieldElement(fieldName, false, false, false, intType);
|
| + ClassElementImpl classA = ElementFactory.classElement2("A");
|
| + classA.fields = <FieldElement>[fieldElement];
|
| + FieldFormalParameter parameter =
|
| + AstFactory.fieldFormalParameter2(fieldName);
|
| + FieldFormalParameterElementImpl parameterElement =
|
| + ElementFactory.fieldFormalParameter(parameter.identifier);
|
| + parameterElement.field = fieldElement;
|
| + parameterElement.type = intType;
|
| + parameter.identifier.staticElement = parameterElement;
|
| + _resolveInClass(parameter, classA);
|
| + expect(parameter.element.type, same(intType));
|
| + }
|
| +
|
| + void test_visitImportDirective_noCombinators_noPrefix() {
|
| + ImportDirective directive = AstFactory.importDirective3(null, null);
|
| + directive.element = ElementFactory.importFor(
|
| + ElementFactory.library(_definingLibrary.context, "lib"), null);
|
| + _resolveNode(directive);
|
| + _listener.assertNoErrors();
|
| + }
|
| +
|
| + void test_visitImportDirective_noCombinators_prefix() {
|
| + String prefixName = "p";
|
| + ImportElement importElement = ElementFactory.importFor(
|
| + ElementFactory.library(_definingLibrary.context, "lib"),
|
| + ElementFactory.prefix(prefixName));
|
| + _definingLibrary.imports = <ImportElement>[importElement];
|
| + ImportDirective directive = AstFactory.importDirective3(null, prefixName);
|
| + directive.element = importElement;
|
| + _resolveNode(directive);
|
| + _listener.assertNoErrors();
|
| + }
|
| +
|
| + void test_visitImportDirective_withCombinators() {
|
| + ShowCombinator combinator = AstFactory.showCombinator2(["A", "B", "C"]);
|
| + ImportDirective directive =
|
| + AstFactory.importDirective3(null, null, [combinator]);
|
| + LibraryElementImpl library =
|
| + ElementFactory.library(_definingLibrary.context, "lib");
|
| + TopLevelVariableElementImpl varA =
|
| + ElementFactory.topLevelVariableElement2("A");
|
| + TopLevelVariableElementImpl varB =
|
| + ElementFactory.topLevelVariableElement2("B");
|
| + TopLevelVariableElementImpl varC =
|
| + ElementFactory.topLevelVariableElement2("C");
|
| + CompilationUnitElementImpl unit =
|
| + library.definingCompilationUnit as CompilationUnitElementImpl;
|
| + unit.accessors = <PropertyAccessorElement>[
|
| + varA.getter,
|
| + varA.setter,
|
| + varB.getter,
|
| + varC.setter
|
| + ];
|
| + unit.topLevelVariables = <TopLevelVariableElement>[varA, varB, varC];
|
| + directive.element = ElementFactory.importFor(library, null);
|
| + _resolveNode(directive);
|
| + expect(combinator.shownNames[0].staticElement, same(varA));
|
| + expect(combinator.shownNames[1].staticElement, same(varB));
|
| + expect(combinator.shownNames[2].staticElement, same(varC));
|
| + _listener.assertNoErrors();
|
| + }
|
| +
|
| + void test_visitIndexExpression_get() {
|
| + ClassElementImpl classA = ElementFactory.classElement2("A");
|
| + InterfaceType intType = _typeProvider.intType;
|
| + MethodElement getter =
|
| + ElementFactory.methodElement("[]", intType, [intType]);
|
| + classA.methods = <MethodElement>[getter];
|
| + SimpleIdentifier array = AstFactory.identifier3("a");
|
| + array.staticType = classA.type;
|
| + IndexExpression expression =
|
| + AstFactory.indexExpression(array, AstFactory.identifier3("i"));
|
| + expect(_resolveIndexExpression(expression), same(getter));
|
| + _listener.assertNoErrors();
|
| + }
|
| +
|
| + void test_visitIndexExpression_set() {
|
| + ClassElementImpl classA = ElementFactory.classElement2("A");
|
| + InterfaceType intType = _typeProvider.intType;
|
| + MethodElement setter =
|
| + ElementFactory.methodElement("[]=", intType, [intType]);
|
| + classA.methods = <MethodElement>[setter];
|
| + SimpleIdentifier array = AstFactory.identifier3("a");
|
| + array.staticType = classA.type;
|
| + IndexExpression expression =
|
| + AstFactory.indexExpression(array, AstFactory.identifier3("i"));
|
| + AstFactory.assignmentExpression(
|
| + expression, TokenType.EQ, AstFactory.integer(0));
|
| + expect(_resolveIndexExpression(expression), same(setter));
|
| + _listener.assertNoErrors();
|
| + }
|
| +
|
| + void test_visitInstanceCreationExpression_named() {
|
| + ClassElementImpl classA = ElementFactory.classElement2("A");
|
| + String constructorName = "a";
|
| + ConstructorElement constructor =
|
| + ElementFactory.constructorElement2(classA, constructorName);
|
| + classA.constructors = <ConstructorElement>[constructor];
|
| + ConstructorName name = AstFactory.constructorName(
|
| + AstFactory.typeName(classA), constructorName);
|
| + name.staticElement = constructor;
|
| + InstanceCreationExpression creation =
|
| + AstFactory.instanceCreationExpression(Keyword.NEW, name);
|
| + _resolveNode(creation);
|
| + expect(creation.staticElement, same(constructor));
|
| + _listener.assertNoErrors();
|
| + }
|
| +
|
| + void test_visitInstanceCreationExpression_unnamed() {
|
| + ClassElementImpl classA = ElementFactory.classElement2("A");
|
| + String constructorName = null;
|
| + ConstructorElement constructor =
|
| + ElementFactory.constructorElement2(classA, constructorName);
|
| + classA.constructors = <ConstructorElement>[constructor];
|
| + ConstructorName name = AstFactory.constructorName(
|
| + AstFactory.typeName(classA), constructorName);
|
| + name.staticElement = constructor;
|
| + InstanceCreationExpression creation =
|
| + AstFactory.instanceCreationExpression(Keyword.NEW, name);
|
| + _resolveNode(creation);
|
| + expect(creation.staticElement, same(constructor));
|
| + _listener.assertNoErrors();
|
| + }
|
| +
|
| + void test_visitInstanceCreationExpression_unnamed_namedParameter() {
|
| + ClassElementImpl classA = ElementFactory.classElement2("A");
|
| + String constructorName = null;
|
| + ConstructorElementImpl constructor =
|
| + ElementFactory.constructorElement2(classA, constructorName);
|
| + String parameterName = "a";
|
| + ParameterElement parameter = ElementFactory.namedParameter(parameterName);
|
| + constructor.parameters = <ParameterElement>[parameter];
|
| + classA.constructors = <ConstructorElement>[constructor];
|
| + ConstructorName name = AstFactory.constructorName(
|
| + AstFactory.typeName(classA), constructorName);
|
| + name.staticElement = constructor;
|
| + InstanceCreationExpression creation = AstFactory.instanceCreationExpression(
|
| + Keyword.NEW,
|
| + name,
|
| + [AstFactory.namedExpression2(parameterName, AstFactory.integer(0))]);
|
| + _resolveNode(creation);
|
| + expect(creation.staticElement, same(constructor));
|
| + expect(
|
| + (creation.argumentList.arguments[0] as NamedExpression)
|
| + .name
|
| + .label
|
| + .staticElement,
|
| + same(parameter));
|
| + _listener.assertNoErrors();
|
| + }
|
| +
|
| + void test_visitMethodInvocation() {
|
| + InterfaceType numType = _typeProvider.numType;
|
| + SimpleIdentifier left = AstFactory.identifier3("i");
|
| + left.staticType = numType;
|
| + String methodName = "abs";
|
| + MethodInvocation invocation = AstFactory.methodInvocation(left, methodName);
|
| + _resolveNode(invocation);
|
| + expect(invocation.methodName.staticElement,
|
| + same(getMethod(numType, methodName)));
|
| + _listener.assertNoErrors();
|
| + }
|
| +
|
| + void test_visitMethodInvocation_namedParameter() {
|
| + ClassElementImpl classA = ElementFactory.classElement2("A");
|
| + String methodName = "m";
|
| + String parameterName = "p";
|
| + MethodElementImpl method = ElementFactory.methodElement(methodName, null);
|
| + ParameterElement parameter = ElementFactory.namedParameter(parameterName);
|
| + method.parameters = <ParameterElement>[parameter];
|
| + classA.methods = <MethodElement>[method];
|
| + SimpleIdentifier left = AstFactory.identifier3("i");
|
| + left.staticType = classA.type;
|
| + MethodInvocation invocation = AstFactory.methodInvocation(left, methodName,
|
| + [AstFactory.namedExpression2(parameterName, AstFactory.integer(0))]);
|
| + _resolveNode(invocation);
|
| + expect(invocation.methodName.staticElement, same(method));
|
| + expect(
|
| + (invocation.argumentList.arguments[0] as NamedExpression)
|
| + .name
|
| + .label
|
| + .staticElement,
|
| + same(parameter));
|
| + _listener.assertNoErrors();
|
| + }
|
| +
|
| + void test_visitPostfixExpression() {
|
| + InterfaceType numType = _typeProvider.numType;
|
| + SimpleIdentifier operand = AstFactory.identifier3("i");
|
| + operand.staticType = numType;
|
| + PostfixExpression expression =
|
| + AstFactory.postfixExpression(operand, TokenType.PLUS_PLUS);
|
| + _resolveNode(expression);
|
| + expect(expression.staticElement, getMethod(numType, "+"));
|
| + _listener.assertNoErrors();
|
| + }
|
| +
|
| + void test_visitPrefixedIdentifier_dynamic() {
|
| + DartType dynamicType = _typeProvider.dynamicType;
|
| + SimpleIdentifier target = AstFactory.identifier3("a");
|
| + VariableElementImpl variable = ElementFactory.localVariableElement(target);
|
| + variable.type = dynamicType;
|
| + target.staticElement = variable;
|
| + target.staticType = dynamicType;
|
| + PrefixedIdentifier identifier =
|
| + AstFactory.identifier(target, AstFactory.identifier3("b"));
|
| + _resolveNode(identifier);
|
| + expect(identifier.staticElement, isNull);
|
| + expect(identifier.identifier.staticElement, isNull);
|
| + _listener.assertNoErrors();
|
| + }
|
| +
|
| + void test_visitPrefixedIdentifier_nonDynamic() {
|
| + ClassElementImpl classA = ElementFactory.classElement2("A");
|
| + String getterName = "b";
|
| + PropertyAccessorElement getter =
|
| + ElementFactory.getterElement(getterName, false, _typeProvider.intType);
|
| + classA.accessors = <PropertyAccessorElement>[getter];
|
| + SimpleIdentifier target = AstFactory.identifier3("a");
|
| + VariableElementImpl variable = ElementFactory.localVariableElement(target);
|
| + variable.type = classA.type;
|
| + target.staticElement = variable;
|
| + target.staticType = classA.type;
|
| + PrefixedIdentifier identifier =
|
| + AstFactory.identifier(target, AstFactory.identifier3(getterName));
|
| + _resolveNode(identifier);
|
| + expect(identifier.staticElement, same(getter));
|
| + expect(identifier.identifier.staticElement, same(getter));
|
| + _listener.assertNoErrors();
|
| + }
|
| +
|
| + void test_visitPrefixedIdentifier_staticClassMember_getter() {
|
| + ClassElementImpl classA = ElementFactory.classElement2("A");
|
| + // set accessors
|
| + String propName = "b";
|
| + PropertyAccessorElement getter =
|
| + ElementFactory.getterElement(propName, false, _typeProvider.intType);
|
| + PropertyAccessorElement setter =
|
| + ElementFactory.setterElement(propName, false, _typeProvider.intType);
|
| + classA.accessors = <PropertyAccessorElement>[getter, setter];
|
| + // prepare "A.m"
|
| + SimpleIdentifier target = AstFactory.identifier3("A");
|
| + target.staticElement = classA;
|
| + target.staticType = classA.type;
|
| + PrefixedIdentifier identifier =
|
| + AstFactory.identifier(target, AstFactory.identifier3(propName));
|
| + // resolve
|
| + _resolveNode(identifier);
|
| + expect(identifier.staticElement, same(getter));
|
| + expect(identifier.identifier.staticElement, same(getter));
|
| + _listener.assertNoErrors();
|
| + }
|
| +
|
| + void test_visitPrefixedIdentifier_staticClassMember_method() {
|
| + ClassElementImpl classA = ElementFactory.classElement2("A");
|
| + // set methods
|
| + String propName = "m";
|
| + MethodElement method =
|
| + ElementFactory.methodElement("m", _typeProvider.intType);
|
| + classA.methods = <MethodElement>[method];
|
| + // prepare "A.m"
|
| + SimpleIdentifier target = AstFactory.identifier3("A");
|
| + target.staticElement = classA;
|
| + target.staticType = classA.type;
|
| + PrefixedIdentifier identifier =
|
| + AstFactory.identifier(target, AstFactory.identifier3(propName));
|
| + AstFactory.assignmentExpression(
|
| + identifier, TokenType.EQ, AstFactory.nullLiteral());
|
| + // resolve
|
| + _resolveNode(identifier);
|
| + expect(identifier.staticElement, same(method));
|
| + expect(identifier.identifier.staticElement, same(method));
|
| + _listener.assertNoErrors();
|
| + }
|
| +
|
| + void test_visitPrefixedIdentifier_staticClassMember_setter() {
|
| + ClassElementImpl classA = ElementFactory.classElement2("A");
|
| + // set accessors
|
| + String propName = "b";
|
| + PropertyAccessorElement getter =
|
| + ElementFactory.getterElement(propName, false, _typeProvider.intType);
|
| + PropertyAccessorElement setter =
|
| + ElementFactory.setterElement(propName, false, _typeProvider.intType);
|
| + classA.accessors = <PropertyAccessorElement>[getter, setter];
|
| + // prepare "A.b = null"
|
| + SimpleIdentifier target = AstFactory.identifier3("A");
|
| + target.staticElement = classA;
|
| + target.staticType = classA.type;
|
| + PrefixedIdentifier identifier =
|
| + AstFactory.identifier(target, AstFactory.identifier3(propName));
|
| + AstFactory.assignmentExpression(
|
| + identifier, TokenType.EQ, AstFactory.nullLiteral());
|
| + // resolve
|
| + _resolveNode(identifier);
|
| + expect(identifier.staticElement, same(setter));
|
| + expect(identifier.identifier.staticElement, same(setter));
|
| + _listener.assertNoErrors();
|
| + }
|
| +
|
| + void test_visitPrefixExpression() {
|
| + InterfaceType numType = _typeProvider.numType;
|
| + SimpleIdentifier operand = AstFactory.identifier3("i");
|
| + operand.staticType = numType;
|
| + PrefixExpression expression =
|
| + AstFactory.prefixExpression(TokenType.PLUS_PLUS, operand);
|
| + _resolveNode(expression);
|
| + expect(expression.staticElement, getMethod(numType, "+"));
|
| + _listener.assertNoErrors();
|
| + }
|
| +
|
| + void test_visitPropertyAccess_getter_identifier() {
|
| + ClassElementImpl classA = ElementFactory.classElement2("A");
|
| + String getterName = "b";
|
| + PropertyAccessorElement getter =
|
| + ElementFactory.getterElement(getterName, false, _typeProvider.intType);
|
| + classA.accessors = <PropertyAccessorElement>[getter];
|
| + SimpleIdentifier target = AstFactory.identifier3("a");
|
| + target.staticType = classA.type;
|
| + PropertyAccess access = AstFactory.propertyAccess2(target, getterName);
|
| + _resolveNode(access);
|
| + expect(access.propertyName.staticElement, same(getter));
|
| + _listener.assertNoErrors();
|
| + }
|
| +
|
| + void test_visitPropertyAccess_getter_super() {
|
| + //
|
| + // class A {
|
| + // int get b;
|
| + // }
|
| + // class B {
|
| + // ... super.m ...
|
| + // }
|
| + //
|
| + ClassElementImpl classA = ElementFactory.classElement2("A");
|
| + String getterName = "b";
|
| + PropertyAccessorElement getter =
|
| + ElementFactory.getterElement(getterName, false, _typeProvider.intType);
|
| + classA.accessors = <PropertyAccessorElement>[getter];
|
| + SuperExpression target = AstFactory.superExpression();
|
| + target.staticType = ElementFactory.classElement("B", classA.type).type;
|
| + PropertyAccess access = AstFactory.propertyAccess2(target, getterName);
|
| + AstFactory.methodDeclaration2(
|
| + null,
|
| + null,
|
| + null,
|
| + null,
|
| + AstFactory.identifier3("m"),
|
| + AstFactory.formalParameterList(),
|
| + AstFactory.expressionFunctionBody(access));
|
| + _resolveNode(access);
|
| + expect(access.propertyName.staticElement, same(getter));
|
| + _listener.assertNoErrors();
|
| + }
|
| +
|
| + void test_visitPropertyAccess_setter_this() {
|
| + ClassElementImpl classA = ElementFactory.classElement2("A");
|
| + String setterName = "b";
|
| + PropertyAccessorElement setter =
|
| + ElementFactory.setterElement(setterName, false, _typeProvider.intType);
|
| + classA.accessors = <PropertyAccessorElement>[setter];
|
| + ThisExpression target = AstFactory.thisExpression();
|
| + target.staticType = classA.type;
|
| + PropertyAccess access = AstFactory.propertyAccess2(target, setterName);
|
| + AstFactory.assignmentExpression(
|
| + access, TokenType.EQ, AstFactory.integer(0));
|
| + _resolveNode(access);
|
| + expect(access.propertyName.staticElement, same(setter));
|
| + _listener.assertNoErrors();
|
| + }
|
| +
|
| + void test_visitSimpleIdentifier_classScope() {
|
| + InterfaceType doubleType = _typeProvider.doubleType;
|
| + String fieldName = "NAN";
|
| + SimpleIdentifier node = AstFactory.identifier3(fieldName);
|
| + _resolveInClass(node, doubleType.element);
|
| + expect(node.staticElement, getGetter(doubleType, fieldName));
|
| + _listener.assertNoErrors();
|
| + }
|
| +
|
| + void test_visitSimpleIdentifier_dynamic() {
|
| + SimpleIdentifier node = AstFactory.identifier3("dynamic");
|
| + _resolveIdentifier(node);
|
| + expect(node.staticElement, same(_typeProvider.dynamicType.element));
|
| + expect(node.staticType, same(_typeProvider.typeType));
|
| + _listener.assertNoErrors();
|
| + }
|
| +
|
| + void test_visitSimpleIdentifier_lexicalScope() {
|
| + SimpleIdentifier node = AstFactory.identifier3("i");
|
| + VariableElementImpl element = ElementFactory.localVariableElement(node);
|
| + expect(_resolveIdentifier(node, [element]), same(element));
|
| + _listener.assertNoErrors();
|
| + }
|
| +
|
| + void test_visitSimpleIdentifier_lexicalScope_field_setter() {
|
| + InterfaceType intType = _typeProvider.intType;
|
| + ClassElementImpl classA = ElementFactory.classElement2("A");
|
| + String fieldName = "a";
|
| + FieldElement field =
|
| + ElementFactory.fieldElement(fieldName, false, false, false, intType);
|
| + classA.fields = <FieldElement>[field];
|
| + classA.accessors = <PropertyAccessorElement>[field.getter, field.setter];
|
| + SimpleIdentifier node = AstFactory.identifier3(fieldName);
|
| + AstFactory.assignmentExpression(node, TokenType.EQ, AstFactory.integer(0));
|
| + _resolveInClass(node, classA);
|
| + Element element = node.staticElement;
|
| + EngineTestCase.assertInstanceOf((obj) => obj is PropertyAccessorElement,
|
| + PropertyAccessorElement, element);
|
| + expect((element as PropertyAccessorElement).isSetter, isTrue);
|
| + _listener.assertNoErrors();
|
| + }
|
| +
|
| + void test_visitSuperConstructorInvocation() {
|
| + ClassElementImpl superclass = ElementFactory.classElement2("A");
|
| + ConstructorElementImpl superConstructor =
|
| + ElementFactory.constructorElement2(superclass, null);
|
| + superclass.constructors = <ConstructorElement>[superConstructor];
|
| + ClassElementImpl subclass =
|
| + ElementFactory.classElement("B", superclass.type);
|
| + ConstructorElementImpl subConstructor =
|
| + ElementFactory.constructorElement2(subclass, null);
|
| + subclass.constructors = <ConstructorElement>[subConstructor];
|
| + SuperConstructorInvocation invocation =
|
| + AstFactory.superConstructorInvocation();
|
| + AstFactory.classDeclaration(null, 'C', null, null, null, null, [
|
| + AstFactory.constructorDeclaration(null, 'C', null, [invocation])
|
| + ]);
|
| + _resolveInClass(invocation, subclass);
|
| + expect(invocation.staticElement, superConstructor);
|
| + _listener.assertNoErrors();
|
| + }
|
| +
|
| + void test_visitSuperConstructorInvocation_namedParameter() {
|
| + ClassElementImpl superclass = ElementFactory.classElement2("A");
|
| + ConstructorElementImpl superConstructor =
|
| + ElementFactory.constructorElement2(superclass, null);
|
| + String parameterName = "p";
|
| + ParameterElement parameter = ElementFactory.namedParameter(parameterName);
|
| + superConstructor.parameters = <ParameterElement>[parameter];
|
| + superclass.constructors = <ConstructorElement>[superConstructor];
|
| + ClassElementImpl subclass =
|
| + ElementFactory.classElement("B", superclass.type);
|
| + ConstructorElementImpl subConstructor =
|
| + ElementFactory.constructorElement2(subclass, null);
|
| + subclass.constructors = <ConstructorElement>[subConstructor];
|
| + SuperConstructorInvocation invocation = AstFactory
|
| + .superConstructorInvocation([
|
| + AstFactory.namedExpression2(parameterName, AstFactory.integer(0))
|
| + ]);
|
| + AstFactory.classDeclaration(null, 'C', null, null, null, null, [
|
| + AstFactory.constructorDeclaration(null, 'C', null, [invocation])
|
| + ]);
|
| + _resolveInClass(invocation, subclass);
|
| + expect(invocation.staticElement, superConstructor);
|
| + expect(
|
| + (invocation.argumentList.arguments[0] as NamedExpression)
|
| + .name
|
| + .label
|
| + .staticElement,
|
| + same(parameter));
|
| + _listener.assertNoErrors();
|
| + }
|
| +
|
| + /**
|
| + * Create and return the resolver used by the tests.
|
| + */
|
| + ElementResolver _createResolver() {
|
| + MemoryResourceProvider resourceProvider = new MemoryResourceProvider();
|
| + InternalAnalysisContext context = AnalysisContextFactory.contextWithCore(
|
| + resourceProvider: resourceProvider);
|
| + Source source = new FileSource(resourceProvider.getFile("/test.dart"));
|
| + CompilationUnitElementImpl unit =
|
| + new CompilationUnitElementImpl("test.dart");
|
| + unit.librarySource = unit.source = source;
|
| + _definingLibrary = ElementFactory.library(context, "test");
|
| + _definingLibrary.definingCompilationUnit = unit;
|
| + _visitor = new ResolverVisitor(
|
| + _definingLibrary, source, _typeProvider, _listener,
|
| + nameScope: new LibraryScope(_definingLibrary));
|
| + return _visitor.elementResolver;
|
| + }
|
| +
|
| + /**
|
| + * Return the element associated with the label of [statement] after the
|
| + * resolver has resolved it. [labelElement] is the label element to be
|
| + * defined in the statement's label scope, and [labelTarget] is the statement
|
| + * the label resolves to.
|
| + */
|
| + Element _resolveBreak(BreakStatement statement, LabelElementImpl labelElement,
|
| + Statement labelTarget) {
|
| + _resolveStatement(statement, labelElement, labelTarget);
|
| + return statement.label.staticElement;
|
| + }
|
| +
|
| + /**
|
| + * Return the element associated with the label [statement] after the
|
| + * resolver has resolved it. [labelElement] is the label element to be
|
| + * defined in the statement's label scope, and [labelTarget] is the AST node
|
| + * the label resolves to.
|
| + *
|
| + * @param statement the statement to be resolved
|
| + * @param labelElement the label element to be defined in the statement's label scope
|
| + * @return the element to which the statement's label was resolved
|
| + */
|
| + Element _resolveContinue(ContinueStatement statement,
|
| + LabelElementImpl labelElement, AstNode labelTarget) {
|
| + _resolveStatement(statement, labelElement, labelTarget);
|
| + return statement.label.staticElement;
|
| + }
|
| +
|
| + /**
|
| + * Return the element associated with the given identifier after the resolver has resolved the
|
| + * identifier.
|
| + *
|
| + * @param node the expression to be resolved
|
| + * @param definedElements the elements that are to be defined in the scope in which the element is
|
| + * being resolved
|
| + * @return the element to which the expression was resolved
|
| + */
|
| + Element _resolveIdentifier(Identifier node, [List<Element> definedElements]) {
|
| + _resolveNode(node, definedElements);
|
| + return node.staticElement;
|
| + }
|
| +
|
| + /**
|
| + * Return the element associated with the given identifier after the resolver has resolved the
|
| + * identifier.
|
| + *
|
| + * @param node the expression to be resolved
|
| + * @param enclosingClass the element representing the class enclosing the identifier
|
| + * @return the element to which the expression was resolved
|
| + */
|
| + void _resolveInClass(AstNode node, ClassElement enclosingClass) {
|
| + Scope outerScope = _visitor.nameScope;
|
| + try {
|
| + _visitor.enclosingClass = enclosingClass;
|
| + EnclosedScope innerScope = new ClassScope(
|
| + new TypeParameterScope(outerScope, enclosingClass), enclosingClass);
|
| + _visitor.nameScope = innerScope;
|
| + node.accept(_resolver);
|
| + } finally {
|
| + _visitor.enclosingClass = null;
|
| + _visitor.nameScope = outerScope;
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * Return the element associated with the given expression after the resolver has resolved the
|
| + * expression.
|
| + *
|
| + * @param node the expression to be resolved
|
| + * @param definedElements the elements that are to be defined in the scope in which the element is
|
| + * being resolved
|
| + * @return the element to which the expression was resolved
|
| + */
|
| + Element _resolveIndexExpression(IndexExpression node,
|
| + [List<Element> definedElements]) {
|
| + _resolveNode(node, definedElements);
|
| + return node.staticElement;
|
| + }
|
| +
|
| + /**
|
| + * Return the element associated with the given identifier after the resolver has resolved the
|
| + * identifier.
|
| + *
|
| + * @param node the expression to be resolved
|
| + * @param definedElements the elements that are to be defined in the scope in which the element is
|
| + * being resolved
|
| + * @return the element to which the expression was resolved
|
| + */
|
| + void _resolveNode(AstNode node, [List<Element> definedElements]) {
|
| + Scope outerScope = _visitor.nameScope;
|
| + try {
|
| + EnclosedScope innerScope = new EnclosedScope(outerScope);
|
| + if (definedElements != null) {
|
| + for (Element element in definedElements) {
|
| + innerScope.define(element);
|
| + }
|
| + }
|
| + _visitor.nameScope = innerScope;
|
| + node.accept(_resolver);
|
| + } finally {
|
| + _visitor.nameScope = outerScope;
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * Return the element associated with the label of the given statement after the resolver has
|
| + * resolved the statement.
|
| + *
|
| + * @param statement the statement to be resolved
|
| + * @param labelElement the label element to be defined in the statement's label scope
|
| + * @return the element to which the statement's label was resolved
|
| + */
|
| + void _resolveStatement(
|
| + Statement statement, LabelElementImpl labelElement, AstNode labelTarget) {
|
| + LabelScope outerScope = _visitor.labelScope;
|
| + try {
|
| + LabelScope innerScope;
|
| + if (labelElement == null) {
|
| + innerScope = outerScope;
|
| + } else {
|
| + innerScope = new LabelScope(
|
| + outerScope, labelElement.name, labelTarget, labelElement);
|
| + }
|
| + _visitor.labelScope = innerScope;
|
| + statement.accept(_resolver);
|
| + } finally {
|
| + _visitor.labelScope = outerScope;
|
| + }
|
| + }
|
| +}
|
|
|