blob: e89fb065b2e3c0242797d4ce5882c078d8de3ecd [file] [log] [blame]
// Copyright (c) 2014, 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.
// This code was auto-generated, is not intended to be edited, and is subject to
// significant change. Please see the README file for more information.
library engine.element_test;
import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/element.dart';
import 'package:analyzer/src/generated/engine.dart' show AnalysisContext,
AnalysisContextImpl;
import 'package:analyzer/src/generated/java_core.dart';
import 'package:analyzer/src/generated/source_io.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:unittest/unittest.dart';
import '../reflective_tests.dart';
import 'resolver_test.dart' show TestTypeProvider, AnalysisContextHelper;
import 'test_support.dart';
main() {
groupSep = ' | ';
runReflectiveTests(ElementKindTest);
runReflectiveTests(FunctionTypeImplTest);
runReflectiveTests(InterfaceTypeImplTest);
runReflectiveTests(TypeParameterTypeImplTest);
runReflectiveTests(UnionTypeImplTest);
runReflectiveTests(VoidTypeImplTest);
runReflectiveTests(ClassElementImplTest);
runReflectiveTests(CompilationUnitElementImplTest);
runReflectiveTests(ElementLocationImplTest);
runReflectiveTests(ElementImplTest);
runReflectiveTests(HtmlElementImplTest);
runReflectiveTests(LibraryElementImplTest);
runReflectiveTests(MultiplyDefinedElementImplTest);
}
@reflectiveTest
class ClassElementImplTest extends EngineTestCase {
void test_getAllSupertypes_interface() {
ClassElement classA = ElementFactory.classElement2("A");
ClassElement classB = ElementFactory.classElement("B", classA.type);
ClassElementImpl elementC = ElementFactory.classElement2("C");
InterfaceType typeObject = classA.supertype;
InterfaceType typeA = classA.type;
InterfaceType typeB = classB.type;
InterfaceType typeC = elementC.type;
elementC.interfaces = <InterfaceType>[typeB];
List<InterfaceType> supers = elementC.allSupertypes;
List<InterfaceType> types = new List<InterfaceType>();
types.addAll(supers);
expect(types.contains(typeA), isTrue);
expect(types.contains(typeB), isTrue);
expect(types.contains(typeObject), isTrue);
expect(types.contains(typeC), isFalse);
}
void test_getAllSupertypes_mixins() {
ClassElement classA = ElementFactory.classElement2("A");
ClassElement classB = ElementFactory.classElement("B", classA.type);
ClassElementImpl classC = ElementFactory.classElement2("C");
InterfaceType typeObject = classA.supertype;
InterfaceType typeA = classA.type;
InterfaceType typeB = classB.type;
InterfaceType typeC = classC.type;
classC.mixins = <InterfaceType>[typeB];
List<InterfaceType> supers = classC.allSupertypes;
List<InterfaceType> types = new List<InterfaceType>();
types.addAll(supers);
expect(types.contains(typeA), isFalse);
expect(types.contains(typeB), isTrue);
expect(types.contains(typeObject), isTrue);
expect(types.contains(typeC), isFalse);
}
void test_getAllSupertypes_recursive() {
ClassElementImpl classA = ElementFactory.classElement2("A");
ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
classA.supertype = classB.type;
List<InterfaceType> supers = classB.allSupertypes;
expect(supers, hasLength(1));
}
void test_getField() {
ClassElementImpl classA = ElementFactory.classElement2("A");
String fieldName = "f";
FieldElementImpl field =
ElementFactory.fieldElement(fieldName, false, false, false, null);
classA.fields = <FieldElement>[field];
expect(classA.getField(fieldName), same(field));
expect(field.isEnumConstant, false);
// no such field
expect(classA.getField("noSuchField"), same(null));
}
void test_getMethod_declared() {
ClassElementImpl classA = ElementFactory.classElement2("A");
String methodName = "m";
MethodElement method = ElementFactory.methodElement(methodName, null);
classA.methods = <MethodElement>[method];
expect(classA.getMethod(methodName), same(method));
}
void test_getMethod_undeclared() {
ClassElementImpl classA = ElementFactory.classElement2("A");
String methodName = "m";
MethodElement method = ElementFactory.methodElement(methodName, null);
classA.methods = <MethodElement>[method];
expect(classA.getMethod("${methodName}x"), isNull);
}
void test_getNode() {
AnalysisContextHelper contextHelper = new AnalysisContextHelper();
AnalysisContext context = contextHelper.context;
Source source = contextHelper.addSource("/test.dart", r'''
class A {}
class B {}''');
// prepare CompilationUnitElement
LibraryElement libraryElement = context.computeLibraryElement(source);
CompilationUnitElement unitElement = libraryElement.definingCompilationUnit;
// A
{
ClassElement elementA = unitElement.getType("A");
ClassDeclaration nodeA = elementA.node;
expect(nodeA, isNotNull);
expect(nodeA.name.name, "A");
expect(nodeA.element, same(elementA));
}
// B
{
ClassElement elementB = unitElement.getType("B");
ClassDeclaration nodeB = elementB.node;
expect(nodeB, isNotNull);
expect(nodeB.name.name, "B");
expect(nodeB.element, same(elementB));
}
}
void test_hasNonFinalField_false_const() {
ClassElementImpl classA = ElementFactory.classElement2("A");
classA.fields = <FieldElement>[
ElementFactory.fieldElement("f", false, false, true, classA.type)];
expect(classA.hasNonFinalField, isFalse);
}
void test_hasNonFinalField_false_final() {
ClassElementImpl classA = ElementFactory.classElement2("A");
classA.fields = <FieldElement>[
ElementFactory.fieldElement("f", false, true, false, classA.type)];
expect(classA.hasNonFinalField, isFalse);
}
void test_hasNonFinalField_false_recursive() {
ClassElementImpl classA = ElementFactory.classElement2("A");
ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
classA.supertype = classB.type;
expect(classA.hasNonFinalField, isFalse);
}
void test_hasNonFinalField_true_immediate() {
ClassElementImpl classA = ElementFactory.classElement2("A");
classA.fields = <FieldElement>[
ElementFactory.fieldElement("f", false, false, false, classA.type)];
expect(classA.hasNonFinalField, isTrue);
}
void test_hasNonFinalField_true_inherited() {
ClassElementImpl classA = ElementFactory.classElement2("A");
ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
classA.fields = <FieldElement>[
ElementFactory.fieldElement("f", false, false, false, classA.type)];
expect(classB.hasNonFinalField, isTrue);
}
void test_hasStaticMember_false_empty() {
ClassElementImpl classA = ElementFactory.classElement2("A");
// no members
expect(classA.hasStaticMember, isFalse);
}
void test_hasStaticMember_false_instanceMethod() {
ClassElementImpl classA = ElementFactory.classElement2("A");
MethodElement method = ElementFactory.methodElement("foo", null);
classA.methods = <MethodElement>[method];
expect(classA.hasStaticMember, isFalse);
}
void test_hasStaticMember_instanceGetter() {
ClassElementImpl classA = ElementFactory.classElement2("A");
PropertyAccessorElement getter =
ElementFactory.getterElement("foo", false, null);
classA.accessors = <PropertyAccessorElement>[getter];
expect(classA.hasStaticMember, isFalse);
}
void test_hasStaticMember_true_getter() {
ClassElementImpl classA = ElementFactory.classElement2("A");
PropertyAccessorElementImpl getter =
ElementFactory.getterElement("foo", false, null);
classA.accessors = <PropertyAccessorElement>[getter];
// "foo" is static
getter.static = true;
expect(classA.hasStaticMember, isTrue);
}
void test_hasStaticMember_true_method() {
ClassElementImpl classA = ElementFactory.classElement2("A");
MethodElementImpl method = ElementFactory.methodElement("foo", null);
classA.methods = <MethodElement>[method];
// "foo" is static
method.static = true;
expect(classA.hasStaticMember, isTrue);
}
void test_hasStaticMember_true_setter() {
ClassElementImpl classA = ElementFactory.classElement2("A");
PropertyAccessorElementImpl setter =
ElementFactory.setterElement("foo", false, null);
classA.accessors = <PropertyAccessorElement>[setter];
// "foo" is static
setter.static = true;
expect(classA.hasStaticMember, isTrue);
}
void test_isEnum() {
String firstConst = "A";
String secondConst = "B";
ClassElementImpl enumE = ElementFactory.enumElement(
new TestTypeProvider(),
"E",
[firstConst, secondConst]);
// E is an enum
expect(enumE.isEnum, true);
// A and B are static members
expect(enumE.getField(firstConst).isEnumConstant, true);
expect(enumE.getField(secondConst).isEnumConstant, true);
}
void test_lookUpConcreteMethod_declared() {
// class A {
// m() {}
// }
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
ClassElementImpl classA = ElementFactory.classElement2("A");
String methodName = "m";
MethodElement method = ElementFactory.methodElement(methodName, null);
classA.methods = <MethodElement>[method];
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA];
expect(classA.lookUpConcreteMethod(methodName, library), same(method));
}
void test_lookUpConcreteMethod_declaredAbstract() {
// class A {
// m();
// }
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
ClassElementImpl classA = ElementFactory.classElement2("A");
String methodName = "m";
MethodElementImpl method = ElementFactory.methodElement(methodName, null);
method.abstract = true;
classA.methods = <MethodElement>[method];
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA];
expect(classA.lookUpConcreteMethod(methodName, library), isNull);
}
void test_lookUpConcreteMethod_declaredAbstractAndInherited() {
// class A {
// m() {}
// }
// class B extends A {
// m();
// }
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
ClassElementImpl classA = ElementFactory.classElement2("A");
String methodName = "m";
MethodElement inheritedMethod =
ElementFactory.methodElement(methodName, null);
classA.methods = <MethodElement>[inheritedMethod];
ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
MethodElementImpl method = ElementFactory.methodElement(methodName, null);
method.abstract = true;
classB.methods = <MethodElement>[method];
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA, classB];
expect(
classB.lookUpConcreteMethod(methodName, library),
same(inheritedMethod));
}
void test_lookUpConcreteMethod_declaredAndInherited() {
// class A {
// m() {}
// }
// class B extends A {
// m() {}
// }
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
ClassElementImpl classA = ElementFactory.classElement2("A");
String methodName = "m";
MethodElement inheritedMethod =
ElementFactory.methodElement(methodName, null);
classA.methods = <MethodElement>[inheritedMethod];
ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
MethodElement method = ElementFactory.methodElement(methodName, null);
classB.methods = <MethodElement>[method];
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA, classB];
expect(classB.lookUpConcreteMethod(methodName, library), same(method));
}
void test_lookUpConcreteMethod_declaredAndInheritedAbstract() {
// abstract class A {
// m();
// }
// class B extends A {
// m() {}
// }
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
ClassElementImpl classA = ElementFactory.classElement2("A");
classA.abstract = true;
String methodName = "m";
MethodElementImpl inheritedMethod =
ElementFactory.methodElement(methodName, null);
inheritedMethod.abstract = true;
classA.methods = <MethodElement>[inheritedMethod];
ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
MethodElement method = ElementFactory.methodElement(methodName, null);
classB.methods = <MethodElement>[method];
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA, classB];
expect(classB.lookUpConcreteMethod(methodName, library), same(method));
}
void test_lookUpConcreteMethod_inherited() {
// class A {
// m() {}
// }
// class B extends A {
// }
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
ClassElementImpl classA = ElementFactory.classElement2("A");
String methodName = "m";
MethodElement inheritedMethod =
ElementFactory.methodElement(methodName, null);
classA.methods = <MethodElement>[inheritedMethod];
ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA, classB];
expect(
classB.lookUpConcreteMethod(methodName, library),
same(inheritedMethod));
}
void test_lookUpConcreteMethod_undeclared() {
// class A {
// }
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
ClassElementImpl classA = ElementFactory.classElement2("A");
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA];
expect(classA.lookUpConcreteMethod("m", library), isNull);
}
void test_lookUpGetter_declared() {
// class A {
// get g {}
// }
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
ClassElementImpl classA = ElementFactory.classElement2("A");
String getterName = "g";
PropertyAccessorElement getter =
ElementFactory.getterElement(getterName, false, null);
classA.accessors = <PropertyAccessorElement>[getter];
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA];
expect(classA.lookUpGetter(getterName, library), same(getter));
}
void test_lookUpGetter_inherited() {
// class A {
// get g {}
// }
// class B extends A {
// }
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
ClassElementImpl classA = ElementFactory.classElement2("A");
String getterName = "g";
PropertyAccessorElement getter =
ElementFactory.getterElement(getterName, false, null);
classA.accessors = <PropertyAccessorElement>[getter];
ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA, classB];
expect(classB.lookUpGetter(getterName, library), same(getter));
}
void test_lookUpGetter_undeclared() {
// class A {
// }
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
ClassElementImpl classA = ElementFactory.classElement2("A");
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA];
expect(classA.lookUpGetter("g", library), isNull);
}
void test_lookUpGetter_undeclared_recursive() {
// class A extends B {
// }
// class B extends A {
// }
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
ClassElementImpl classA = ElementFactory.classElement2("A");
ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
classA.supertype = classB.type;
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA, classB];
expect(classA.lookUpGetter("g", library), isNull);
}
void test_lookUpInheritedConcreteGetter_declared() {
// class A {
// get g {}
// }
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
ClassElementImpl classA = ElementFactory.classElement2("A");
String getterName = "g";
PropertyAccessorElement getter =
ElementFactory.getterElement(getterName, false, null);
classA.accessors = <PropertyAccessorElement>[getter];
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA];
expect(classA.lookUpInheritedConcreteGetter(getterName, library), isNull);
}
void test_lookUpInheritedConcreteGetter_inherited() {
// class A {
// get g {}
// }
// class B extends A {
// }
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
ClassElementImpl classA = ElementFactory.classElement2("A");
String getterName = "g";
PropertyAccessorElement inheritedGetter =
ElementFactory.getterElement(getterName, false, null);
classA.accessors = <PropertyAccessorElement>[inheritedGetter];
ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA, classB];
expect(
classB.lookUpInheritedConcreteGetter(getterName, library),
same(inheritedGetter));
}
void test_lookUpInheritedConcreteGetter_undeclared() {
// class A {
// }
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
ClassElementImpl classA = ElementFactory.classElement2("A");
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA];
expect(classA.lookUpInheritedConcreteGetter("g", library), isNull);
}
void test_lookUpInheritedConcreteGetter_undeclared_recursive() {
// class A extends B {
// }
// class B extends A {
// }
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
ClassElementImpl classA = ElementFactory.classElement2("A");
ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
classA.supertype = classB.type;
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA, classB];
expect(classA.lookUpInheritedConcreteGetter("g", library), isNull);
}
void test_lookUpInheritedConcreteMethod_declared() {
// class A {
// m() {}
// }
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
ClassElementImpl classA = ElementFactory.classElement2("A");
String methodName = "m";
MethodElement method = ElementFactory.methodElement(methodName, null);
classA.methods = <MethodElement>[method];
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA];
expect(classA.lookUpInheritedConcreteMethod(methodName, library), isNull);
}
void test_lookUpInheritedConcreteMethod_declaredAbstractAndInherited() {
// class A {
// m() {}
// }
// class B extends A {
// m();
// }
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
ClassElementImpl classA = ElementFactory.classElement2("A");
String methodName = "m";
MethodElement inheritedMethod =
ElementFactory.methodElement(methodName, null);
classA.methods = <MethodElement>[inheritedMethod];
ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
MethodElementImpl method = ElementFactory.methodElement(methodName, null);
method.abstract = true;
classB.methods = <MethodElement>[method];
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA, classB];
expect(
classB.lookUpInheritedConcreteMethod(methodName, library),
same(inheritedMethod));
}
void test_lookUpInheritedConcreteMethod_declaredAndInherited() {
// class A {
// m() {}
// }
// class B extends A {
// m() {}
// }
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
ClassElementImpl classA = ElementFactory.classElement2("A");
String methodName = "m";
MethodElement inheritedMethod =
ElementFactory.methodElement(methodName, null);
classA.methods = <MethodElement>[inheritedMethod];
ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
MethodElement method = ElementFactory.methodElement(methodName, null);
classB.methods = <MethodElement>[method];
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA, classB];
expect(
classB.lookUpInheritedConcreteMethod(methodName, library),
same(inheritedMethod));
}
void test_lookUpInheritedConcreteMethod_declaredAndInheritedAbstract() {
// abstract class A {
// m();
// }
// class B extends A {
// m() {}
// }
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
ClassElementImpl classA = ElementFactory.classElement2("A");
classA.abstract = true;
String methodName = "m";
MethodElementImpl inheritedMethod =
ElementFactory.methodElement(methodName, null);
inheritedMethod.abstract = true;
classA.methods = <MethodElement>[inheritedMethod];
ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
MethodElement method = ElementFactory.methodElement(methodName, null);
classB.methods = <MethodElement>[method];
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA, classB];
expect(classB.lookUpInheritedConcreteMethod(methodName, library), isNull);
}
void
test_lookUpInheritedConcreteMethod_declaredAndInheritedWithAbstractBetween() {
// class A {
// m() {}
// }
// class B extends A {
// m();
// }
// class C extends B {
// m() {}
// }
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
ClassElementImpl classA = ElementFactory.classElement2("A");
String methodName = "m";
MethodElement inheritedMethod =
ElementFactory.methodElement(methodName, null);
classA.methods = <MethodElement>[inheritedMethod];
ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
MethodElementImpl abstractMethod =
ElementFactory.methodElement(methodName, null);
abstractMethod.abstract = true;
classB.methods = <MethodElement>[abstractMethod];
ClassElementImpl classC = ElementFactory.classElement("C", classB.type);
MethodElementImpl method = ElementFactory.methodElement(methodName, null);
classC.methods = <MethodElement>[method];
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA, classB, classC];
expect(
classC.lookUpInheritedConcreteMethod(methodName, library),
same(inheritedMethod));
}
void test_lookUpInheritedConcreteMethod_inherited() {
// class A {
// m() {}
// }
// class B extends A {
// }
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
ClassElementImpl classA = ElementFactory.classElement2("A");
String methodName = "m";
MethodElement inheritedMethod =
ElementFactory.methodElement(methodName, null);
classA.methods = <MethodElement>[inheritedMethod];
ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA, classB];
expect(
classB.lookUpInheritedConcreteMethod(methodName, library),
same(inheritedMethod));
}
void test_lookUpInheritedConcreteMethod_undeclared() {
// class A {
// }
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
ClassElementImpl classA = ElementFactory.classElement2("A");
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA];
expect(classA.lookUpInheritedConcreteMethod("m", library), isNull);
}
void test_lookUpInheritedConcreteSetter_declared() {
// class A {
// set g(x) {}
// }
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
ClassElementImpl classA = ElementFactory.classElement2("A");
String setterName = "s";
PropertyAccessorElement setter =
ElementFactory.setterElement(setterName, false, null);
classA.accessors = <PropertyAccessorElement>[setter];
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA];
expect(classA.lookUpInheritedConcreteSetter(setterName, library), isNull);
}
void test_lookUpInheritedConcreteSetter_inherited() {
// class A {
// set g(x) {}
// }
// class B extends A {
// }
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
ClassElementImpl classA = ElementFactory.classElement2("A");
String setterName = "s";
PropertyAccessorElement setter =
ElementFactory.setterElement(setterName, false, null);
classA.accessors = <PropertyAccessorElement>[setter];
ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA, classB];
expect(
classB.lookUpInheritedConcreteSetter(setterName, library),
same(setter));
}
void test_lookUpInheritedConcreteSetter_undeclared() {
// class A {
// }
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
ClassElementImpl classA = ElementFactory.classElement2("A");
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA];
expect(classA.lookUpInheritedConcreteSetter("s", library), isNull);
}
void test_lookUpInheritedConcreteSetter_undeclared_recursive() {
// class A extends B {
// }
// class B extends A {
// }
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
ClassElementImpl classA = ElementFactory.classElement2("A");
ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
classA.supertype = classB.type;
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA, classB];
expect(classA.lookUpInheritedConcreteSetter("s", library), isNull);
}
void test_lookUpInheritedMethod_declared() {
// class A {
// m() {}
// }
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
ClassElementImpl classA = ElementFactory.classElement2("A");
String methodName = "m";
MethodElement method = ElementFactory.methodElement(methodName, null);
classA.methods = <MethodElement>[method];
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA];
expect(classA.lookUpInheritedMethod(methodName, library), isNull);
}
void test_lookUpInheritedMethod_declaredAndInherited() {
// class A {
// m() {}
// }
// class B extends A {
// m() {}
// }
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
ClassElementImpl classA = ElementFactory.classElement2("A");
String methodName = "m";
MethodElement inheritedMethod =
ElementFactory.methodElement(methodName, null);
classA.methods = <MethodElement>[inheritedMethod];
ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
MethodElement method = ElementFactory.methodElement(methodName, null);
classB.methods = <MethodElement>[method];
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA, classB];
expect(
classB.lookUpInheritedMethod(methodName, library),
same(inheritedMethod));
}
void test_lookUpInheritedMethod_inherited() {
// class A {
// m() {}
// }
// class B extends A {
// }
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
ClassElementImpl classA = ElementFactory.classElement2("A");
String methodName = "m";
MethodElement inheritedMethod =
ElementFactory.methodElement(methodName, null);
classA.methods = <MethodElement>[inheritedMethod];
ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA, classB];
expect(
classB.lookUpInheritedMethod(methodName, library),
same(inheritedMethod));
}
void test_lookUpInheritedMethod_undeclared() {
// class A {
// }
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
ClassElementImpl classA = ElementFactory.classElement2("A");
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA];
expect(classA.lookUpInheritedMethod("m", library), isNull);
}
void test_lookUpMethod_declared() {
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
ClassElementImpl classA = ElementFactory.classElement2("A");
String methodName = "m";
MethodElement method = ElementFactory.methodElement(methodName, null);
classA.methods = <MethodElement>[method];
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA];
expect(classA.lookUpMethod(methodName, library), same(method));
}
void test_lookUpMethod_inherited() {
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
ClassElementImpl classA = ElementFactory.classElement2("A");
String methodName = "m";
MethodElement method = ElementFactory.methodElement(methodName, null);
classA.methods = <MethodElement>[method];
ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA, classB];
expect(classB.lookUpMethod(methodName, library), same(method));
}
void test_lookUpMethod_undeclared() {
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
ClassElementImpl classA = ElementFactory.classElement2("A");
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA];
expect(classA.lookUpMethod("m", library), isNull);
}
void test_lookUpMethod_undeclared_recursive() {
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
ClassElementImpl classA = ElementFactory.classElement2("A");
ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
classA.supertype = classB.type;
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA, classB];
expect(classA.lookUpMethod("m", library), isNull);
}
void test_lookUpSetter_declared() {
// class A {
// set g(x) {}
// }
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
ClassElementImpl classA = ElementFactory.classElement2("A");
String setterName = "s";
PropertyAccessorElement setter =
ElementFactory.setterElement(setterName, false, null);
classA.accessors = <PropertyAccessorElement>[setter];
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA];
expect(classA.lookUpSetter(setterName, library), same(setter));
}
void test_lookUpSetter_inherited() {
// class A {
// set g(x) {}
// }
// class B extends A {
// }
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
ClassElementImpl classA = ElementFactory.classElement2("A");
String setterName = "s";
PropertyAccessorElement setter =
ElementFactory.setterElement(setterName, false, null);
classA.accessors = <PropertyAccessorElement>[setter];
ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA, classB];
expect(classB.lookUpSetter(setterName, library), same(setter));
}
void test_lookUpSetter_undeclared() {
// class A {
// }
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
ClassElementImpl classA = ElementFactory.classElement2("A");
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA];
expect(classA.lookUpSetter("s", library), isNull);
}
void test_lookUpSetter_undeclared_recursive() {
// class A extends B {
// }
// class B extends A {
// }
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
ClassElementImpl classA = ElementFactory.classElement2("A");
ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
classA.supertype = classB.type;
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA, classB];
expect(classA.lookUpSetter("s", library), isNull);
}
}
@reflectiveTest
class CompilationUnitElementImplTest extends EngineTestCase {
void test_getEnum_declared() {
TestTypeProvider typeProvider = new TestTypeProvider();
CompilationUnitElementImpl unit =
ElementFactory.compilationUnit("/lib.dart");
String enumName = "E";
ClassElement enumElement =
ElementFactory.enumElement(typeProvider, enumName);
unit.enums = <ClassElement>[enumElement];
expect(unit.getEnum(enumName), same(enumElement));
}
void test_getEnum_undeclared() {
TestTypeProvider typeProvider = new TestTypeProvider();
CompilationUnitElementImpl unit =
ElementFactory.compilationUnit("/lib.dart");
String enumName = "E";
ClassElement enumElement =
ElementFactory.enumElement(typeProvider, enumName);
unit.enums = <ClassElement>[enumElement];
expect(unit.getEnum("${enumName}x"), isNull);
}
void test_getType_declared() {
CompilationUnitElementImpl unit =
ElementFactory.compilationUnit("/lib.dart");
String className = "C";
ClassElement classElement = ElementFactory.classElement2(className);
unit.types = <ClassElement>[classElement];
expect(unit.getType(className), same(classElement));
}
void test_getType_undeclared() {
CompilationUnitElementImpl unit =
ElementFactory.compilationUnit("/lib.dart");
String className = "C";
ClassElement classElement = ElementFactory.classElement2(className);
unit.types = <ClassElement>[classElement];
expect(unit.getType("${className}x"), isNull);
}
}
@reflectiveTest
class ElementImplTest extends EngineTestCase {
void test_equals() {
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
ClassElementImpl classElement = ElementFactory.classElement2("C");
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classElement];
FieldElement field =
ElementFactory.fieldElement("next", false, false, false, classElement.type);
classElement.fields = <FieldElement>[field];
expect(field == field, isTrue);
expect(field == field.getter, isFalse);
expect(field == field.setter, isFalse);
expect(field.getter == field.setter, isFalse);
}
void test_isAccessibleIn_private_differentLibrary() {
AnalysisContextImpl context = createAnalysisContext();
LibraryElementImpl library1 = ElementFactory.library(context, "lib1");
ClassElement classElement = ElementFactory.classElement2("_C");
(library1.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classElement];
LibraryElementImpl library2 = ElementFactory.library(context, "lib2");
expect(classElement.isAccessibleIn(library2), isFalse);
}
void test_isAccessibleIn_private_sameLibrary() {
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
ClassElement classElement = ElementFactory.classElement2("_C");
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classElement];
expect(classElement.isAccessibleIn(library), isTrue);
}
void test_isAccessibleIn_public_differentLibrary() {
AnalysisContextImpl context = createAnalysisContext();
LibraryElementImpl library1 = ElementFactory.library(context, "lib1");
ClassElement classElement = ElementFactory.classElement2("C");
(library1.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classElement];
LibraryElementImpl library2 = ElementFactory.library(context, "lib2");
expect(classElement.isAccessibleIn(library2), isTrue);
}
void test_isAccessibleIn_public_sameLibrary() {
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
ClassElement classElement = ElementFactory.classElement2("C");
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classElement];
expect(classElement.isAccessibleIn(library), isTrue);
}
void test_isPrivate_false() {
Element element = ElementFactory.classElement2("C");
expect(element.isPrivate, isFalse);
}
void test_isPrivate_null() {
Element element = ElementFactory.classElement2(null);
expect(element.isPrivate, isTrue);
}
void test_isPrivate_true() {
Element element = ElementFactory.classElement2("_C");
expect(element.isPrivate, isTrue);
}
void test_isPublic_false() {
Element element = ElementFactory.classElement2("_C");
expect(element.isPublic, isFalse);
}
void test_isPublic_null() {
Element element = ElementFactory.classElement2(null);
expect(element.isPublic, isFalse);
}
void test_isPublic_true() {
Element element = ElementFactory.classElement2("C");
expect(element.isPublic, isTrue);
}
void test_SORT_BY_OFFSET() {
ClassElementImpl classElementA = ElementFactory.classElement2("A");
classElementA.nameOffset = 1;
ClassElementImpl classElementB = ElementFactory.classElement2("B");
classElementB.nameOffset = 2;
expect(Element.SORT_BY_OFFSET(classElementA, classElementA), 0);
expect(Element.SORT_BY_OFFSET(classElementA, classElementB) < 0, isTrue);
expect(Element.SORT_BY_OFFSET(classElementB, classElementA) > 0, isTrue);
}
}
@reflectiveTest
class ElementKindTest extends EngineTestCase {
void test_of_nonNull() {
expect(
ElementKind.of(ElementFactory.classElement2("A")),
same(ElementKind.CLASS));
}
void test_of_null() {
expect(ElementKind.of(null), same(ElementKind.ERROR));
}
}
@reflectiveTest
class ElementLocationImplTest extends EngineTestCase {
void test_create_encoding() {
String encoding = "a;b;c";
ElementLocationImpl location = new ElementLocationImpl.con2(encoding);
expect(location.encoding, encoding);
}
/**
* For example unnamed constructor.
*/
void test_create_encoding_emptyLast() {
String encoding = "a;b;c;";
ElementLocationImpl location = new ElementLocationImpl.con2(encoding);
expect(location.encoding, encoding);
}
void test_equals_equal() {
String encoding = "a;b;c";
ElementLocationImpl first = new ElementLocationImpl.con2(encoding);
ElementLocationImpl second = new ElementLocationImpl.con2(encoding);
expect(first == second, isTrue);
}
void test_equals_notEqual_differentLengths() {
ElementLocationImpl first = new ElementLocationImpl.con2("a;b;c");
ElementLocationImpl second = new ElementLocationImpl.con2("a;b;c;d");
expect(first == second, isFalse);
}
void test_equals_notEqual_notLocation() {
ElementLocationImpl first = new ElementLocationImpl.con2("a;b;c");
expect(first == "a;b;d", isFalse);
}
void test_equals_notEqual_sameLengths() {
ElementLocationImpl first = new ElementLocationImpl.con2("a;b;c");
ElementLocationImpl second = new ElementLocationImpl.con2("a;b;d");
expect(first == second, isFalse);
}
void test_getComponents() {
String encoding = "a;b;c";
ElementLocationImpl location = new ElementLocationImpl.con2(encoding);
List<String> components = location.components;
expect(components, hasLength(3));
expect(components[0], "a");
expect(components[1], "b");
expect(components[2], "c");
}
void test_getEncoding() {
String encoding = "a;b;c;;d";
ElementLocationImpl location = new ElementLocationImpl.con2(encoding);
expect(location.encoding, encoding);
}
void test_hashCode_equal() {
String encoding = "a;b;c";
ElementLocationImpl first = new ElementLocationImpl.con2(encoding);
ElementLocationImpl second = new ElementLocationImpl.con2(encoding);
expect(first.hashCode == second.hashCode, isTrue);
}
}
@reflectiveTest
class FunctionTypeImplTest extends EngineTestCase {
void test_creation() {
expect(
new FunctionTypeImpl.con1(
new FunctionElementImpl.forNode(AstFactory.identifier3("f"))),
isNotNull);
}
void test_getElement() {
FunctionElementImpl typeElement =
new FunctionElementImpl.forNode(AstFactory.identifier3("f"));
FunctionTypeImpl type = new FunctionTypeImpl.con1(typeElement);
expect(type.element, typeElement);
}
void test_getNamedParameterTypes() {
FunctionTypeImpl type = new FunctionTypeImpl.con1(
new FunctionElementImpl.forNode(AstFactory.identifier3("f")));
Map<String, DartType> types = type.namedParameterTypes;
expect(types, hasLength(0));
}
void test_getNormalParameterTypes() {
FunctionTypeImpl type = new FunctionTypeImpl.con1(
new FunctionElementImpl.forNode(AstFactory.identifier3("f")));
List<DartType> types = type.normalParameterTypes;
expect(types, hasLength(0));
}
void test_getReturnType() {
DartType expectedReturnType = VoidTypeImpl.instance;
FunctionElementImpl functionElement =
new FunctionElementImpl.forNode(AstFactory.identifier3("f"));
functionElement.returnType = expectedReturnType;
FunctionTypeImpl type = new FunctionTypeImpl.con1(functionElement);
DartType returnType = type.returnType;
expect(returnType, expectedReturnType);
}
void test_getTypeArguments() {
FunctionTypeImpl type = new FunctionTypeImpl.con1(
new FunctionElementImpl.forNode(AstFactory.identifier3("f")));
List<DartType> types = type.typeArguments;
expect(types, hasLength(0));
}
void test_hashCode_element() {
FunctionTypeImpl type = new FunctionTypeImpl.con1(
new FunctionElementImpl.forNode(AstFactory.identifier3("f")));
type.hashCode;
}
void test_hashCode_noElement() {
FunctionTypeImpl type = new FunctionTypeImpl.con1(null);
type.hashCode;
}
void test_isAssignableTo_normalAndPositionalArgs() {
// ([a]) -> void <: (a) -> void
ClassElement a = ElementFactory.classElement2("A");
FunctionType t =
ElementFactory.functionElement6("t", null, <ClassElement>[a]).type;
FunctionType s =
ElementFactory.functionElement5("s", <ClassElement>[a]).type;
expect(t.isSubtypeOf(s), isTrue);
expect(s.isSubtypeOf(t), isFalse);
// assignable iff subtype
expect(t.isAssignableTo(s), isTrue);
expect(s.isAssignableTo(t), isFalse);
}
void test_isSubtypeOf_baseCase_classFunction() {
// () -> void <: Function
ClassElementImpl functionElement = ElementFactory.classElement2("Function");
InterfaceTypeImpl functionType =
new _FunctionTypeImplTest_isSubtypeOf_baseCase_classFunction(functionElement);
FunctionType f = ElementFactory.functionElement("f").type;
expect(f.isSubtypeOf(functionType), isTrue);
}
void test_isSubtypeOf_baseCase_notFunctionType() {
// class C
// ! () -> void <: C
FunctionType f = ElementFactory.functionElement("f").type;
InterfaceType t = ElementFactory.classElement2("C").type;
expect(f.isSubtypeOf(t), isFalse);
}
void test_isSubtypeOf_baseCase_null() {
// ! () -> void <: null
FunctionType f = ElementFactory.functionElement("f").type;
expect(f.isSubtypeOf(null), isFalse);
}
void test_isSubtypeOf_baseCase_self() {
// () -> void <: () -> void
FunctionType f = ElementFactory.functionElement("f").type;
expect(f.isSubtypeOf(f), isTrue);
}
void test_isSubtypeOf_namedParameters_isAssignable() {
// B extends A
// ({name: A}) -> void <: ({name: B}) -> void
// ({name: B}) -> void <: ({name: A}) -> void
ClassElement a = ElementFactory.classElement2("A");
ClassElement b = ElementFactory.classElement("B", a.type);
FunctionType t = ElementFactory.functionElement4(
"t",
null,
null,
<String>["name"],
<ClassElement>[a]).type;
FunctionType s = ElementFactory.functionElement4(
"s",
null,
null,
<String>["name"],
<ClassElement>[b]).type;
expect(t.isSubtypeOf(s), isTrue);
expect(s.isSubtypeOf(t), isTrue);
}
void test_isSubtypeOf_namedParameters_isNotAssignable() {
// ! ({name: A}) -> void <: ({name: B}) -> void
FunctionType t = ElementFactory.functionElement4(
"t",
null,
null,
<String>["name"],
<ClassElement>[ElementFactory.classElement2("A")]).type;
FunctionType s = ElementFactory.functionElement4(
"s",
null,
null,
<String>["name"],
<ClassElement>[ElementFactory.classElement2("B")]).type;
expect(t.isSubtypeOf(s), isFalse);
}
void test_isSubtypeOf_namedParameters_namesDifferent() {
// B extends A
// void t({A name}) {}
// void s({A diff}) {}
// ! t <: s
// ! s <: t
ClassElement a = ElementFactory.classElement2("A");
ClassElement b = ElementFactory.classElement("B", a.type);
FunctionType t = ElementFactory.functionElement4(
"t",
null,
null,
<String>["name"],
<ClassElement>[a]).type;
FunctionType s = ElementFactory.functionElement4(
"s",
null,
null,
<String>["diff"],
<ClassElement>[b]).type;
expect(t.isSubtypeOf(s), isFalse);
expect(s.isSubtypeOf(t), isFalse);
}
void test_isSubtypeOf_namedParameters_orderOfParams() {
// B extends A
// ({A: A, B: B}) -> void <: ({B: B, A: A}) -> void
ClassElement a = ElementFactory.classElement2("A");
ClassElement b = ElementFactory.classElement("B", a.type);
FunctionType t = ElementFactory.functionElement4(
"t",
null,
null,
<String>["A", "B"],
<ClassElement>[a, b]).type;
FunctionType s = ElementFactory.functionElement4(
"s",
null,
null,
<String>["B", "A"],
<ClassElement>[b, a]).type;
expect(t.isSubtypeOf(s), isTrue);
}
void test_isSubtypeOf_namedParameters_orderOfParams2() {
// B extends A
// ! ({B: B}) -> void <: ({B: B, A: A}) -> void
ClassElement a = ElementFactory.classElement2("A");
ClassElement b = ElementFactory.classElement("B", a.type);
FunctionType t = ElementFactory.functionElement4(
"t",
null,
null,
<String>["B"],
<ClassElement>[b]).type;
FunctionType s = ElementFactory.functionElement4(
"s",
null,
null,
<String>["B", "A"],
<ClassElement>[b, a]).type;
expect(t.isSubtypeOf(s), isFalse);
}
void test_isSubtypeOf_namedParameters_orderOfParams3() {
// B extends A
// ({A: A, B: B}) -> void <: ({A: A}) -> void
ClassElement a = ElementFactory.classElement2("A");
ClassElement b = ElementFactory.classElement("B", a.type);
FunctionType t = ElementFactory.functionElement4(
"t",
null,
null,
<String>["A", "B"],
<ClassElement>[a, b]).type;
FunctionType s = ElementFactory.functionElement4(
"s",
null,
null,
<String>["B"],
<ClassElement>[b]).type;
expect(t.isSubtypeOf(s), isTrue);
}
void test_isSubtypeOf_namedParameters_sHasMoreParams() {
// B extends A
// ! ({name: A}) -> void <: ({name: B, name2: B}) -> void
ClassElement a = ElementFactory.classElement2("A");
ClassElement b = ElementFactory.classElement("B", a.type);
FunctionType t = ElementFactory.functionElement4(
"t",
null,
null,
<String>["name"],
<ClassElement>[a]).type;
FunctionType s = ElementFactory.functionElement4(
"s",
null,
null,
<String>["name", "name2"],
<ClassElement>[b, b]).type;
expect(t.isSubtypeOf(s), isFalse);
}
void test_isSubtypeOf_namedParameters_tHasMoreParams() {
// B extends A
// ({name: A, name2: A}) -> void <: ({name: B}) -> void
ClassElement a = ElementFactory.classElement2("A");
ClassElement b = ElementFactory.classElement("B", a.type);
FunctionType t = ElementFactory.functionElement4(
"t",
null,
null,
<String>["name", "name2"],
<ClassElement>[a, a]).type;
FunctionType s = ElementFactory.functionElement4(
"s",
null,
null,
<String>["name"],
<ClassElement>[b]).type;
expect(t.isSubtypeOf(s), isTrue);
}
void test_isSubtypeOf_normalAndPositionalArgs_1() {
// ([a]) -> void <: (a) -> void
ClassElement a = ElementFactory.classElement2("A");
FunctionType t =
ElementFactory.functionElement6("t", null, <ClassElement>[a]).type;
FunctionType s =
ElementFactory.functionElement5("s", <ClassElement>[a]).type;
expect(t.isSubtypeOf(s), isTrue);
expect(s.isSubtypeOf(t), isFalse);
}
void test_isSubtypeOf_normalAndPositionalArgs_2() {
// (a, [a]) -> void <: (a) -> void
ClassElement a = ElementFactory.classElement2("A");
FunctionType t = ElementFactory.functionElement6(
"t",
<ClassElement>[a],
<ClassElement>[a]).type;
FunctionType s =
ElementFactory.functionElement5("s", <ClassElement>[a]).type;
expect(t.isSubtypeOf(s), isTrue);
expect(s.isSubtypeOf(t), isFalse);
}
void test_isSubtypeOf_normalAndPositionalArgs_3() {
// ([a]) -> void <: () -> void
ClassElement a = ElementFactory.classElement2("A");
FunctionType t =
ElementFactory.functionElement6("t", null, <ClassElement>[a]).type;
FunctionType s = ElementFactory.functionElement("s").type;
expect(t.isSubtypeOf(s), isTrue);
expect(s.isSubtypeOf(t), isFalse);
}
void test_isSubtypeOf_normalAndPositionalArgs_4() {
// (a, b, [c, d, e]) -> void <: (a, b, c, [d]) -> void
ClassElement a = ElementFactory.classElement2("A");
ClassElement b = ElementFactory.classElement2("B");
ClassElement c = ElementFactory.classElement2("C");
ClassElement d = ElementFactory.classElement2("D");
ClassElement e = ElementFactory.classElement2("E");
FunctionType t = ElementFactory.functionElement6(
"t",
<ClassElement>[a, b],
<ClassElement>[c, d, e]).type;
FunctionType s = ElementFactory.functionElement6(
"s",
<ClassElement>[a, b, c],
<ClassElement>[d]).type;
expect(t.isSubtypeOf(s), isTrue);
expect(s.isSubtypeOf(t), isFalse);
}
void test_isSubtypeOf_normalParameters_isAssignable() {
// B extends A
// (a) -> void <: (b) -> void
// (b) -> void <: (a) -> void
ClassElement a = ElementFactory.classElement2("A");
ClassElement b = ElementFactory.classElement("B", a.type);
FunctionType t =
ElementFactory.functionElement5("t", <ClassElement>[a]).type;
FunctionType s =
ElementFactory.functionElement5("s", <ClassElement>[b]).type;
expect(t.isSubtypeOf(s), isTrue);
expect(s.isSubtypeOf(t), isTrue);
}
void test_isSubtypeOf_normalParameters_isNotAssignable() {
// ! (a) -> void <: (b) -> void
FunctionType t = ElementFactory.functionElement5(
"t",
<ClassElement>[ElementFactory.classElement2("A")]).type;
FunctionType s = ElementFactory.functionElement5(
"s",
<ClassElement>[ElementFactory.classElement2("B")]).type;
expect(t.isSubtypeOf(s), isFalse);
}
void test_isSubtypeOf_normalParameters_sHasMoreParams() {
// B extends A
// ! (a) -> void <: (b, b) -> void
ClassElement a = ElementFactory.classElement2("A");
ClassElement b = ElementFactory.classElement("B", a.type);
FunctionType t =
ElementFactory.functionElement5("t", <ClassElement>[a]).type;
FunctionType s =
ElementFactory.functionElement5("s", <ClassElement>[b, b]).type;
expect(t.isSubtypeOf(s), isFalse);
}
void test_isSubtypeOf_normalParameters_tHasMoreParams() {
// B extends A
// ! (a, a) -> void <: (a) -> void
ClassElement a = ElementFactory.classElement2("A");
ClassElement b = ElementFactory.classElement("B", a.type);
FunctionType t =
ElementFactory.functionElement5("t", <ClassElement>[a, a]).type;
FunctionType s =
ElementFactory.functionElement5("s", <ClassElement>[b]).type;
// note, this is a different assertion from the other "tHasMoreParams"
// tests, this is intentional as it is a difference of the "normal
// parameters"
expect(t.isSubtypeOf(s), isFalse);
}
void test_isSubtypeOf_Object() {
// () -> void <: Object
FunctionType f = ElementFactory.functionElement("f").type;
InterfaceType t = ElementFactory.object.type;
expect(f.isSubtypeOf(t), isTrue);
}
void test_isSubtypeOf_positionalParameters_isAssignable() {
// B extends A
// ([a]) -> void <: ([b]) -> void
// ([b]) -> void <: ([a]) -> void
ClassElement a = ElementFactory.classElement2("A");
ClassElement b = ElementFactory.classElement("B", a.type);
FunctionType t =
ElementFactory.functionElement6("t", null, <ClassElement>[a]).type;
FunctionType s =
ElementFactory.functionElement6("s", null, <ClassElement>[b]).type;
expect(t.isSubtypeOf(s), isTrue);
expect(s.isSubtypeOf(t), isTrue);
}
void test_isSubtypeOf_positionalParameters_isNotAssignable() {
// ! ([a]) -> void <: ([b]) -> void
FunctionType t = ElementFactory.functionElement6(
"t",
null,
<ClassElement>[ElementFactory.classElement2("A")]).type;
FunctionType s = ElementFactory.functionElement6(
"s",
null,
<ClassElement>[ElementFactory.classElement2("B")]).type;
expect(t.isSubtypeOf(s), isFalse);
}
void test_isSubtypeOf_positionalParameters_sHasMoreParams() {
// B extends A
// ! ([a]) -> void <: ([b, b]) -> void
ClassElement a = ElementFactory.classElement2("A");
ClassElement b = ElementFactory.classElement("B", a.type);
FunctionType t =
ElementFactory.functionElement6("t", null, <ClassElement>[a]).type;
FunctionType s =
ElementFactory.functionElement6("s", null, <ClassElement>[b, b]).type;
expect(t.isSubtypeOf(s), isFalse);
}
void test_isSubtypeOf_positionalParameters_tHasMoreParams() {
// B extends A
// ([a, a]) -> void <: ([b]) -> void
ClassElement a = ElementFactory.classElement2("A");
ClassElement b = ElementFactory.classElement("B", a.type);
FunctionType t =
ElementFactory.functionElement6("t", null, <ClassElement>[a, a]).type;
FunctionType s =
ElementFactory.functionElement6("s", null, <ClassElement>[b]).type;
expect(t.isSubtypeOf(s), isTrue);
}
void test_isSubtypeOf_returnType_sIsVoid() {
// () -> void <: void
FunctionType t = ElementFactory.functionElement("t").type;
FunctionType s = ElementFactory.functionElement("s").type;
// function s has the implicit return type of void, we assert it here
expect(VoidTypeImpl.instance == s.returnType, isTrue);
expect(t.isSubtypeOf(s), isTrue);
}
void test_isSubtypeOf_returnType_tAssignableToS() {
// B extends A
// () -> A <: () -> B
// () -> B <: () -> A
ClassElement a = ElementFactory.classElement2("A");
ClassElement b = ElementFactory.classElement("B", a.type);
FunctionType t = ElementFactory.functionElement2("t", a).type;
FunctionType s = ElementFactory.functionElement2("s", b).type;
expect(t.isSubtypeOf(s), isTrue);
expect(s.isSubtypeOf(t), isTrue);
}
void test_isSubtypeOf_returnType_tNotAssignableToS() {
// ! () -> A <: () -> B
FunctionType t =
ElementFactory.functionElement2("t", ElementFactory.classElement2("A")).type;
FunctionType s =
ElementFactory.functionElement2("s", ElementFactory.classElement2("B")).type;
expect(t.isSubtypeOf(s), isFalse);
}
void test_isSubtypeOf_typeParameters_matchesBounds() {
TestTypeProvider provider = new TestTypeProvider();
InterfaceType boolType = provider.boolType;
InterfaceType stringType = provider.stringType;
TypeParameterElementImpl parameterB =
new TypeParameterElementImpl.forNode(AstFactory.identifier3("B"));
parameterB.bound = boolType;
TypeParameterTypeImpl typeB = new TypeParameterTypeImpl(parameterB);
TypeParameterElementImpl parameterS =
new TypeParameterElementImpl.forNode(AstFactory.identifier3("S"));
parameterS.bound = stringType;
TypeParameterTypeImpl typeS = new TypeParameterTypeImpl(parameterS);
FunctionElementImpl functionAliasElement =
new FunctionElementImpl.forNode(AstFactory.identifier3("func"));
functionAliasElement.parameters = <ParameterElement>[
ElementFactory.requiredParameter2("a", typeB),
ElementFactory.positionalParameter2("b", typeS)];
functionAliasElement.returnType = stringType;
FunctionTypeImpl functionAliasType =
new FunctionTypeImpl.con1(functionAliasElement);
functionAliasElement.type = functionAliasType;
FunctionElementImpl functionElement =
new FunctionElementImpl.forNode(AstFactory.identifier3("f"));
functionElement.parameters = <ParameterElement>[
ElementFactory.requiredParameter2("c", boolType),
ElementFactory.positionalParameter2("d", stringType)];
functionElement.returnType = provider.dynamicType;
FunctionTypeImpl functionType = new FunctionTypeImpl.con1(functionElement);
functionElement.type = functionType;
expect(functionType.isAssignableTo(functionAliasType), isTrue);
}
void test_isSubtypeOf_wrongFunctionType_normal_named() {
// ! (a) -> void <: ({name: A}) -> void
// ! ({name: A}) -> void <: (a) -> void
ClassElement a = ElementFactory.classElement2("A");
FunctionType t =
ElementFactory.functionElement5("t", <ClassElement>[a]).type;
FunctionType s = ElementFactory.functionElement7(
"s",
null,
<String>["name"],
<ClassElement>[a]).type;
expect(t.isSubtypeOf(s), isFalse);
expect(s.isSubtypeOf(t), isFalse);
}
void test_isSubtypeOf_wrongFunctionType_optional_named() {
// ! ([a]) -> void <: ({name: A}) -> void
// ! ({name: A}) -> void <: ([a]) -> void
ClassElement a = ElementFactory.classElement2("A");
FunctionType t =
ElementFactory.functionElement6("t", null, <ClassElement>[a]).type;
FunctionType s = ElementFactory.functionElement7(
"s",
null,
<String>["name"],
<ClassElement>[a]).type;
expect(t.isSubtypeOf(s), isFalse);
expect(s.isSubtypeOf(t), isFalse);
}
void test_setTypeArguments() {
ClassElementImpl enclosingClass = ElementFactory.classElement2("C", ["E"]);
MethodElementImpl methodElement =
new MethodElementImpl.forNode(AstFactory.identifier3("m"));
enclosingClass.methods = <MethodElement>[methodElement];
FunctionTypeImpl type = new FunctionTypeImpl.con1(methodElement);
DartType expectedType = enclosingClass.typeParameters[0].type;
type.typeArguments = <DartType>[expectedType];
List<DartType> arguments = type.typeArguments;
expect(arguments, hasLength(1));
expect(arguments[0], expectedType);
}
void test_substitute2_equal() {
ClassElementImpl definingClass = ElementFactory.classElement2("C", ["E"]);
TypeParameterType parameterType = definingClass.typeParameters[0].type;
MethodElementImpl functionElement =
new MethodElementImpl.forNode(AstFactory.identifier3("m"));
String namedParameterName = "c";
functionElement.parameters = <ParameterElement>[
ElementFactory.requiredParameter2("a", parameterType),
ElementFactory.positionalParameter2("b", parameterType),
ElementFactory.namedParameter2(namedParameterName, parameterType)];
functionElement.returnType = parameterType;
definingClass.methods = <MethodElement>[functionElement];
FunctionTypeImpl functionType = new FunctionTypeImpl.con1(functionElement);
functionType.typeArguments = <DartType>[parameterType];
InterfaceTypeImpl argumentType = new InterfaceTypeImpl.con1(
new ClassElementImpl.forNode(AstFactory.identifier3("D")));
FunctionType result =
functionType.substitute2(<DartType>[argumentType], <DartType>[parameterType]);
expect(result.returnType, argumentType);
List<DartType> normalParameters = result.normalParameterTypes;
expect(normalParameters, hasLength(1));
expect(normalParameters[0], argumentType);
List<DartType> optionalParameters = result.optionalParameterTypes;
expect(optionalParameters, hasLength(1));
expect(optionalParameters[0], argumentType);
Map<String, DartType> namedParameters = result.namedParameterTypes;
expect(namedParameters, hasLength(1));
expect(namedParameters[namedParameterName], argumentType);
}
void test_substitute2_notEqual() {
DartType returnType = new InterfaceTypeImpl.con1(
new ClassElementImpl.forNode(AstFactory.identifier3("R")));
DartType normalParameterType = new InterfaceTypeImpl.con1(
new ClassElementImpl.forNode(AstFactory.identifier3("A")));
DartType optionalParameterType = new InterfaceTypeImpl.con1(
new ClassElementImpl.forNode(AstFactory.identifier3("B")));
DartType namedParameterType = new InterfaceTypeImpl.con1(
new ClassElementImpl.forNode(AstFactory.identifier3("C")));
FunctionElementImpl functionElement =
new FunctionElementImpl.forNode(AstFactory.identifier3("f"));
String namedParameterName = "c";
functionElement.parameters = <ParameterElement>[
ElementFactory.requiredParameter2("a", normalParameterType),
ElementFactory.positionalParameter2("b", optionalParameterType),
ElementFactory.namedParameter2(namedParameterName, namedParameterType)];
functionElement.returnType = returnType;
FunctionTypeImpl functionType = new FunctionTypeImpl.con1(functionElement);
InterfaceTypeImpl argumentType = new InterfaceTypeImpl.con1(
new ClassElementImpl.forNode(AstFactory.identifier3("D")));
TypeParameterTypeImpl parameterType = new TypeParameterTypeImpl(
new TypeParameterElementImpl.forNode(AstFactory.identifier3("E")));
FunctionType result =
functionType.substitute2(<DartType>[argumentType], <DartType>[parameterType]);
expect(result.returnType, returnType);
List<DartType> normalParameters = result.normalParameterTypes;
expect(normalParameters, hasLength(1));
expect(normalParameters[0], normalParameterType);
List<DartType> optionalParameters = result.optionalParameterTypes;
expect(optionalParameters, hasLength(1));
expect(optionalParameters[0], optionalParameterType);
Map<String, DartType> namedParameters = result.namedParameterTypes;
expect(namedParameters, hasLength(1));
expect(namedParameters[namedParameterName], namedParameterType);
}
}
@reflectiveTest
class HtmlElementImplTest extends EngineTestCase {
void test_equals_differentSource() {
AnalysisContextImpl context = createAnalysisContext();
HtmlElementImpl elementA = ElementFactory.htmlUnit(context, "indexA.html");
HtmlElementImpl elementB = ElementFactory.htmlUnit(context, "indexB.html");
expect(elementA == elementB, isFalse);
}
void test_equals_null() {
AnalysisContextImpl context = createAnalysisContext();
HtmlElementImpl element = ElementFactory.htmlUnit(context, "index.html");
expect(element == null, isFalse);
}
void test_equals_sameSource() {
AnalysisContextImpl context = createAnalysisContext();
HtmlElementImpl elementA = ElementFactory.htmlUnit(context, "index.html");
HtmlElementImpl elementB = ElementFactory.htmlUnit(context, "index.html");
expect(elementA == elementB, isTrue);
}
void test_equals_self() {
AnalysisContextImpl context = createAnalysisContext();
HtmlElementImpl element = ElementFactory.htmlUnit(context, "index.html");
expect(element == element, isTrue);
}
}
@reflectiveTest
class InterfaceTypeImplTest extends EngineTestCase {
/**
* The type provider used to access the types.
*/
TestTypeProvider _typeProvider;
@override
void setUp() {
_typeProvider = new TestTypeProvider();
}
void test_computeLongestInheritancePathToObject_multipleInterfacePaths() {
//
// Object
// |
// A
// / \
// B C
// | |
// | D
// \ /
// E
//
ClassElementImpl classA = ElementFactory.classElement2("A");
ClassElementImpl classB = ElementFactory.classElement2("B");
ClassElementImpl classC = ElementFactory.classElement2("C");
ClassElementImpl classD = ElementFactory.classElement2("D");
ClassElementImpl classE = ElementFactory.classElement2("E");
classB.interfaces = <InterfaceType>[classA.type];
classC.interfaces = <InterfaceType>[classA.type];
classD.interfaces = <InterfaceType>[classC.type];
classE.interfaces = <InterfaceType>[classB.type, classD.type];
// assertion: even though the longest path to Object for typeB is 2, and
// typeE implements typeB, the longest path for typeE is 4 since it also
// implements typeD
expect(
InterfaceTypeImpl.computeLongestInheritancePathToObject(classB.type),
2);
expect(
InterfaceTypeImpl.computeLongestInheritancePathToObject(classE.type),
4);
}
void test_computeLongestInheritancePathToObject_multipleSuperclassPaths() {
//
// Object
// |
// A
// / \
// B C
// | |
// | D
// \ /
// E
//
ClassElement classA = ElementFactory.classElement2("A");
ClassElement classB = ElementFactory.classElement("B", classA.type);
ClassElement classC = ElementFactory.classElement("C", classA.type);
ClassElement classD = ElementFactory.classElement("D", classC.type);
ClassElementImpl classE = ElementFactory.classElement("E", classB.type);
classE.interfaces = <InterfaceType>[classD.type];
// assertion: even though the longest path to Object for typeB is 2, and
// typeE extends typeB, the longest path for typeE is 4 since it also
// implements typeD
expect(
InterfaceTypeImpl.computeLongestInheritancePathToObject(classB.type),
2);
expect(
InterfaceTypeImpl.computeLongestInheritancePathToObject(classE.type),
4);
}
void test_computeLongestInheritancePathToObject_object() {
//
// Object
// |
// A
//
ClassElement classA = ElementFactory.classElement2("A");
InterfaceType object = classA.supertype;
expect(InterfaceTypeImpl.computeLongestInheritancePathToObject(object), 0);
}
void test_computeLongestInheritancePathToObject_recursion() {
ClassElementImpl classA = ElementFactory.classElement2("A");
ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
classA.supertype = classB.type;
expect(
InterfaceTypeImpl.computeLongestInheritancePathToObject(classA.type),
2);
}
void test_computeLongestInheritancePathToObject_singleInterfacePath() {
//
// Object
// |
// A
// |
// B
// |
// C
//
ClassElementImpl classA = ElementFactory.classElement2("A");
ClassElementImpl classB = ElementFactory.classElement2("B");
ClassElementImpl classC = ElementFactory.classElement2("C");
classB.interfaces = <InterfaceType>[classA.type];
classC.interfaces = <InterfaceType>[classB.type];
expect(
InterfaceTypeImpl.computeLongestInheritancePathToObject(classA.type),
1);
expect(
InterfaceTypeImpl.computeLongestInheritancePathToObject(classB.type),
2);
expect(
InterfaceTypeImpl.computeLongestInheritancePathToObject(classC.type),
3);
}
void test_computeLongestInheritancePathToObject_singleSuperclassPath() {
//
// Object
// |
// A
// |
// B
// |
// C
//
ClassElement classA = ElementFactory.classElement2("A");
ClassElement classB = ElementFactory.classElement("B", classA.type);
ClassElement classC = ElementFactory.classElement("C", classB.type);
expect(
InterfaceTypeImpl.computeLongestInheritancePathToObject(classA.type),
1);
expect(
InterfaceTypeImpl.computeLongestInheritancePathToObject(classB.type),
2);
expect(
InterfaceTypeImpl.computeLongestInheritancePathToObject(classC.type),
3);
}
void test_computeSuperinterfaceSet_genericInterfacePath() {
//
// A
// | implements
// B<T>
// | implements
// C<T>
//
// D
//
ClassElementImpl classA = ElementFactory.classElement2("A");
ClassElementImpl classB = ElementFactory.classElement2("B", ["T"]);
ClassElementImpl classC = ElementFactory.classElement2("C", ["T"]);
ClassElement classD = ElementFactory.classElement2("D");
InterfaceType typeA = classA.type;
classB.interfaces = <InterfaceType>[typeA];
InterfaceTypeImpl typeBT = new InterfaceTypeImpl.con1(classB);
DartType typeT = classC.type.typeArguments[0];
typeBT.typeArguments = <DartType>[typeT];
classC.interfaces = <InterfaceType>[typeBT];
// A
Set<InterfaceType> superinterfacesOfA =
InterfaceTypeImpl.computeSuperinterfaceSet(typeA);
expect(superinterfacesOfA, hasLength(1));
InterfaceType typeObject = ElementFactory.object.type;
expect(superinterfacesOfA.contains(typeObject), isTrue);
// B<D>
InterfaceTypeImpl typeBD = new InterfaceTypeImpl.con1(classB);
typeBD.typeArguments = <DartType>[classD.type];
Set<InterfaceType> superinterfacesOfBD =
InterfaceTypeImpl.computeSuperinterfaceSet(typeBD);
expect(superinterfacesOfBD, hasLength(2));
expect(superinterfacesOfBD.contains(typeObject), isTrue);
expect(superinterfacesOfBD.contains(typeA), isTrue);
// C<D>
InterfaceTypeImpl typeCD = new InterfaceTypeImpl.con1(classC);
typeCD.typeArguments = <DartType>[classD.type];
Set<InterfaceType> superinterfacesOfCD =
InterfaceTypeImpl.computeSuperinterfaceSet(typeCD);
expect(superinterfacesOfCD, hasLength(3));
expect(superinterfacesOfCD.contains(typeObject), isTrue);
expect(superinterfacesOfCD.contains(typeA), isTrue);
expect(superinterfacesOfCD.contains(typeBD), isTrue);
}
void test_computeSuperinterfaceSet_genericSuperclassPath() {
//
// A
// |
// B<T>
// |
// C<T>
//
// D
//
ClassElement classA = ElementFactory.classElement2("A");
InterfaceType typeA = classA.type;
ClassElement classB = ElementFactory.classElement("B", typeA, ["T"]);
ClassElementImpl classC = ElementFactory.classElement2("C", ["T"]);
InterfaceTypeImpl typeBT = new InterfaceTypeImpl.con1(classB);
DartType typeT = classC.type.typeArguments[0];
typeBT.typeArguments = <DartType>[typeT];
classC.supertype = typeBT;
ClassElement classD = ElementFactory.classElement2("D");
// A
Set<InterfaceType> superinterfacesOfA =
InterfaceTypeImpl.computeSuperinterfaceSet(typeA);
expect(superinterfacesOfA, hasLength(1));
InterfaceType typeObject = ElementFactory.object.type;
expect(superinterfacesOfA.contains(typeObject), isTrue);
// B<D>
InterfaceTypeImpl typeBD = new InterfaceTypeImpl.con1(classB);
typeBD.typeArguments = <DartType>[classD.type];
Set<InterfaceType> superinterfacesOfBD =
InterfaceTypeImpl.computeSuperinterfaceSet(typeBD);
expect(superinterfacesOfBD, hasLength(2));
expect(superinterfacesOfBD.contains(typeObject), isTrue);
expect(superinterfacesOfBD.contains(typeA), isTrue);
// C<D>
InterfaceTypeImpl typeCD = new InterfaceTypeImpl.con1(classC);
typeCD.typeArguments = <DartType>[classD.type];
Set<InterfaceType> superinterfacesOfCD =
InterfaceTypeImpl.computeSuperinterfaceSet(typeCD);
expect(superinterfacesOfCD, hasLength(3));
expect(superinterfacesOfCD.contains(typeObject), isTrue);
expect(superinterfacesOfCD.contains(typeA), isTrue);
expect(superinterfacesOfCD.contains(typeBD), isTrue);
}
void test_computeSuperinterfaceSet_multipleInterfacePaths() {
ClassElementImpl classA = ElementFactory.classElement2("A");
ClassElementImpl classB = ElementFactory.classElement2("B");
ClassElementImpl classC = ElementFactory.classElement2("C");
ClassElementImpl classD = ElementFactory.classElement2("D");
ClassElementImpl classE = ElementFactory.classElement2("E");
classB.interfaces = <InterfaceType>[classA.type];
classC.interfaces = <InterfaceType>[classA.type];
classD.interfaces = <InterfaceType>[classC.type];
classE.interfaces = <InterfaceType>[classB.type, classD.type];
// D
Set<InterfaceType> superinterfacesOfD =
InterfaceTypeImpl.computeSuperinterfaceSet(classD.type);
expect(superinterfacesOfD, hasLength(3));
expect(superinterfacesOfD.contains(ElementFactory.object.type), isTrue);
expect(superinterfacesOfD.contains(classA.type), isTrue);
expect(superinterfacesOfD.contains(classC.type), isTrue);
// E
Set<InterfaceType> superinterfacesOfE =
InterfaceTypeImpl.computeSuperinterfaceSet(classE.type);
expect(superinterfacesOfE, hasLength(5));
expect(superinterfacesOfE.contains(ElementFactory.object.type), isTrue);
expect(superinterfacesOfE.contains(classA.type), isTrue);
expect(superinterfacesOfE.contains(classB.type), isTrue);
expect(superinterfacesOfE.contains(classC.type), isTrue);
expect(superinterfacesOfE.contains(classD.type), isTrue);
}
void test_computeSuperinterfaceSet_multipleSuperclassPaths() {
ClassElement classA = ElementFactory.classElement2("A");
ClassElement classB = ElementFactory.classElement("B", classA.type);
ClassElement classC = ElementFactory.classElement("C", classA.type);
ClassElement classD = ElementFactory.classElement("D", classC.type);
ClassElementImpl classE = ElementFactory.classElement("E", classB.type);
classE.interfaces = <InterfaceType>[classD.type];
// D
Set<InterfaceType> superinterfacesOfD =
InterfaceTypeImpl.computeSuperinterfaceSet(classD.type);
expect(superinterfacesOfD, hasLength(3));
expect(superinterfacesOfD.contains(ElementFactory.object.type), isTrue);
expect(superinterfacesOfD.contains(classA.type), isTrue);
expect(superinterfacesOfD.contains(classC.type), isTrue);
// E
Set<InterfaceType> superinterfacesOfE =
InterfaceTypeImpl.computeSuperinterfaceSet(classE.type);
expect(superinterfacesOfE, hasLength(5));
expect(superinterfacesOfE.contains(ElementFactory.object.type), isTrue);
expect(superinterfacesOfE.contains(classA.type), isTrue);
expect(superinterfacesOfE.contains(classB.type), isTrue);
expect(superinterfacesOfE.contains(classC.type), isTrue);
expect(superinterfacesOfE.contains(classD.type), isTrue);
}
void test_computeSuperinterfaceSet_recursion() {
ClassElementImpl classA = ElementFactory.classElement2("A");
ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
classA.supertype = classB.type;
Set<InterfaceType> superinterfacesOfB =
InterfaceTypeImpl.computeSuperinterfaceSet(classB.type);
expect(superinterfacesOfB, hasLength(2));
}
void test_computeSuperinterfaceSet_singleInterfacePath() {
ClassElementImpl classA = ElementFactory.classElement2("A");
ClassElementImpl classB = ElementFactory.classElement2("B");
ClassElementImpl classC = ElementFactory.classElement2("C");
classB.interfaces = <InterfaceType>[classA.type];
classC.interfaces = <InterfaceType>[classB.type];
// A
Set<InterfaceType> superinterfacesOfA =
InterfaceTypeImpl.computeSuperinterfaceSet(classA.type);
expect(superinterfacesOfA, hasLength(1));
expect(superinterfacesOfA.contains(ElementFactory.object.type), isTrue);
// B
Set<InterfaceType> superinterfacesOfB =
InterfaceTypeImpl.computeSuperinterfaceSet(classB.type);
expect(superinterfacesOfB, hasLength(2));
expect(superinterfacesOfB.contains(ElementFactory.object.type), isTrue);
expect(superinterfacesOfB.contains(classA.type), isTrue);
// C
Set<InterfaceType> superinterfacesOfC =
InterfaceTypeImpl.computeSuperinterfaceSet(classC.type);
expect(superinterfacesOfC, hasLength(3));
expect(superinterfacesOfC.contains(ElementFactory.object.type), isTrue);
expect(superinterfacesOfC.contains(classA.type), isTrue);
expect(superinterfacesOfC.contains(classB.type), isTrue);
}
void test_computeSuperinterfaceSet_singleSuperclassPath() {
//
// A
// |
// B
// |
// C
//
ClassElement classA = ElementFactory.classElement2("A");
ClassElement classB = ElementFactory.classElement("B", classA.type);
ClassElement classC = ElementFactory.classElement("C", classB.type);
// A
Set<InterfaceType> superinterfacesOfA =
InterfaceTypeImpl.computeSuperinterfaceSet(classA.type);
expect(superinterfacesOfA, hasLength(1));
expect(superinterfacesOfA.contains(ElementFactory.object.type), isTrue);
// B
Set<InterfaceType> superinterfacesOfB =
InterfaceTypeImpl.computeSuperinterfaceSet(classB.type);
expect(superinterfacesOfB, hasLength(2));
expect(superinterfacesOfB.contains(ElementFactory.object.type), isTrue);
expect(superinterfacesOfB.contains(classA.type), isTrue);
// C
Set<InterfaceType> superinterfacesOfC =
InterfaceTypeImpl.computeSuperinterfaceSet(classC.type);
expect(superinterfacesOfC, hasLength(3));
expect(superinterfacesOfC.contains(ElementFactory.object.type), isTrue);
expect(superinterfacesOfC.contains(classA.type), isTrue);
expect(superinterfacesOfC.contains(classB.type), isTrue);
}
void test_creation() {
expect(
new InterfaceTypeImpl.con1(ElementFactory.classElement2("A")),
isNotNull);
}
void test_getAccessors() {
ClassElementImpl typeElement = ElementFactory.classElement2("A");
PropertyAccessorElement getterG =
ElementFactory.getterElement("g", false, null);
PropertyAccessorElement getterH =
ElementFactory.getterElement("h", false, null);
typeElement.accessors = <PropertyAccessorElement>[getterG, getterH];
InterfaceTypeImpl type = new InterfaceTypeImpl.con1(typeElement);
expect(type.accessors.length, 2);
}
void test_getAccessors_empty() {
ClassElementImpl typeElement = ElementFactory.classElement2("A");
InterfaceTypeImpl type = new InterfaceTypeImpl.con1(typeElement);
expect(type.accessors.length, 0);
}
void test_getElement() {
ClassElementImpl typeElement = ElementFactory.classElement2("A");
InterfaceTypeImpl type = new InterfaceTypeImpl.con1(typeElement);
expect(type.element, typeElement);
}
void test_getGetter_implemented() {
//
// class A { g {} }
//
ClassElementImpl classA = ElementFactory.classElement2("A");
String getterName = "g";
PropertyAccessorElement getterG =
ElementFactory.getterElement(getterName, false, null);
classA.accessors = <PropertyAccessorElement>[getterG];
InterfaceType typeA = classA.type;
expect(typeA.getGetter(getterName), same(getterG));
}
void test_getGetter_parameterized() {
//
// class A<E> { E get g {} }
//
ClassElementImpl classA = ElementFactory.classElement2("A", ["E"]);
DartType typeE = classA.type.typeArguments[0];
String getterName = "g";
PropertyAccessorElement getterG =
ElementFactory.getterElement(getterName, false, typeE);
classA.accessors = <PropertyAccessorElement>[getterG];
(getterG.type as FunctionTypeImpl).typeArguments =
classA.type.typeArguments;
//
// A<I>
//
InterfaceType typeI = ElementFactory.classElement2("I").type;
InterfaceTypeImpl typeAI = new InterfaceTypeImpl.con1(classA);
typeAI.typeArguments = <DartType>[typeI];
PropertyAccessorElement getter = typeAI.getGetter(getterName);
expect(getter, isNotNull);
FunctionType getterType = getter.type;
expect(getterType.returnType, same(typeI));
}
void test_getGetter_unimplemented() {
//
// class A {}
//
ClassElementImpl classA = ElementFactory.classElement2("A");
InterfaceType typeA = classA.type;
expect(typeA.getGetter("g"), isNull);
}
void test_getInterfaces_nonParameterized() {
//
// class C implements A, B
//
ClassElementImpl classA = ElementFactory.classElement2("A");
InterfaceType typeA = classA.type;
ClassElementImpl classB = ElementFactory.classElement2("B");
InterfaceType typeB = classB.type;
ClassElementImpl classC = ElementFactory.classElement2("C");
classC.interfaces = <InterfaceType>[typeA, typeB];
List<InterfaceType> interfaces = classC.type.interfaces;
expect(interfaces, hasLength(2));
if (identical(interfaces[0], typeA)) {
expect(interfaces[1], same(typeB));
} else {
expect(interfaces[0], same(typeB));
expect(interfaces[1], same(typeA));
}
}
void test_getInterfaces_parameterized() {
//
// class A<E>
// class B<F> implements A<F>
//
ClassElementImpl classA = ElementFactory.classElement2("A", ["E"]);
ClassElementImpl classB = ElementFactory.classElement2("B", ["F"]);
InterfaceType typeB = classB.type;
InterfaceTypeImpl typeAF = new InterfaceTypeImpl.con1(classA);
typeAF.typeArguments = <DartType>[typeB.typeArguments[0]];
classB.interfaces = <InterfaceType>[typeAF];
//
// B<I>
//
InterfaceType typeI = ElementFactory.classElement2("I").type;
InterfaceTypeImpl typeBI = new InterfaceTypeImpl.con1(classB);
typeBI.typeArguments = <DartType>[typeI];
List<InterfaceType> interfaces = typeBI.interfaces;
expect(interfaces, hasLength(1));
InterfaceType result = interfaces[0];
expect(result.element, same(classA));
expect(result.typeArguments[0], same(typeI));
}
void test_getLeastUpperBound_directInterfaceCase() {
//
// class A
// class B implements A
// class C implements B
//
ClassElementImpl classA = ElementFactory.classElement2("A");
ClassElementImpl classB = ElementFactory.classElement2("B");
ClassElementImpl classC = ElementFactory.classElement2("C");
InterfaceType typeA = classA.type;
InterfaceType typeB = classB.type;
InterfaceType typeC = classC.type;
classB.interfaces = <InterfaceType>[typeA];
classC.interfaces = <InterfaceType>[typeB];
expect(typeB.getLeastUpperBound(typeC), typeB);
expect(typeC.getLeastUpperBound(typeB), typeB);
}
void test_getLeastUpperBound_directSubclassCase() {
//
// class A
// class B extends A
// class C extends B
//
ClassElementImpl classA = ElementFactory.classElement2("A");
ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
ClassElementImpl classC = ElementFactory.classElement("C", classB.type);
InterfaceType typeB = classB.type;
InterfaceType typeC = classC.type;
expect(typeB.getLeastUpperBound(typeC), typeB);
expect(typeC.getLeastUpperBound(typeB), typeB);
}
void test_getLeastUpperBound_functionType() {
DartType interfaceType = ElementFactory.classElement2("A").type;
FunctionTypeImpl functionType = new FunctionTypeImpl.con1(
new FunctionElementImpl.forNode(AstFactory.identifier3("f")));
expect(interfaceType.getLeastUpperBound(functionType), isNull);
}
void test_getLeastUpperBound_mixinCase() {
//
// class A
// class B extends A
// class C extends A
// class D extends B with M, N, O, P
//
ClassElement classA = ElementFactory.classElement2("A");
ClassElement classB = ElementFactory.classElement("B", classA.type);
ClassElement classC = ElementFactory.classElement("C", classA.type);
ClassElementImpl classD = ElementFactory.classElement("D", classB.type);
InterfaceType typeA = classA.type;
InterfaceType typeC = classC.type;
InterfaceType typeD = classD.type;
classD.mixins = <InterfaceType>[
ElementFactory.classElement2("M").type,
ElementFactory.classElement2("N").type,
ElementFactory.classElement2("O").type,
ElementFactory.classElement2("P").type];
expect(typeD.getLeastUpperBound(typeC), typeA);
expect(typeC.getLeastUpperBound(typeD), typeA);
}
void test_getLeastUpperBound_null() {
DartType interfaceType = ElementFactory.classElement2("A").type;
expect(interfaceType.getLeastUpperBound(null), isNull);
}
void test_getLeastUpperBound_object() {
ClassElementImpl classA = ElementFactory.classElement2("A");
ClassElementImpl classB = ElementFactory.classElement2("B");
InterfaceType typeA = classA.type;
InterfaceType typeB = classB.type;
DartType typeObject = typeA.element.supertype;
// assert that object does not have a super type
expect((typeObject.element as ClassElement).supertype, isNull);
// assert that both A and B have the same super type of Object
expect(typeB.element.supertype, typeObject);
// finally, assert that the only least upper bound of A and B is Object
expect(typeA.getLeastUpperBound(typeB), typeObject);
}
void test_getLeastUpperBound_self() {
ClassElement classA = ElementFactory.classElement2("A");
InterfaceType typeA = classA.type;
expect(typeA.getLeastUpperBound(typeA), typeA);
}
void test_getLeastUpperBound_sharedSuperclass1() {
ClassElementImpl classA = ElementFactory.classElement2("A");
ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
ClassElementImpl classC = ElementFactory.classElement("C", classA.type);
InterfaceType typeA = classA.type;
InterfaceType typeB = classB.type;
InterfaceType typeC = classC.type;
expect(typeB.getLeastUpperBound(typeC), typeA);
expect(typeC.getLeastUpperBound(typeB), typeA);
}
void test_getLeastUpperBound_sharedSuperclass2() {
ClassElementImpl classA = ElementFactory.classElement2("A");
ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
ClassElementImpl classC = ElementFactory.classElement("C", classA.type);
ClassElementImpl classD = ElementFactory.classElement("D", classC.type);
InterfaceType typeA = classA.type;
InterfaceType typeB = classB.type;
InterfaceType typeD = classD.type;
expect(typeB.getLeastUpperBound(typeD), typeA);
expect(typeD.getLeastUpperBound(typeB), typeA);
}
void test_getLeastUpperBound_sharedSuperclass3() {
ClassElementImpl classA = ElementFactory.classElement2("A");
ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
ClassElementImpl classC = ElementFactory.classElement("C", classB.type);
ClassElementImpl classD = ElementFactory.classElement("D", classB.type);
InterfaceType typeB = classB.type;
InterfaceType typeC = classC.type;
InterfaceType typeD = classD.type;
expect(typeC.getLeastUpperBound(typeD), typeB);
expect(typeD.getLeastUpperBound(typeC), typeB);
}
void test_getLeastUpperBound_sharedSuperclass4() {
ClassElement classA = ElementFactory.classElement2("A");
ClassElement classA2 = ElementFactory.classElement2("A2");
ClassElement classA3 = ElementFactory.classElement2("A3");
ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
ClassElementImpl classC = ElementFactory.classElement("C", classA.type);
InterfaceType typeA = classA.type;
InterfaceType typeA2 = classA2.type;
InterfaceType typeA3 = classA3.type;
InterfaceType typeB = classB.type;
InterfaceType typeC = classC.type;
classB.interfaces = <InterfaceType>[typeA2];
classC.interfaces = <InterfaceType>[typeA3];
expect(typeB.getLeastUpperBound(typeC), typeA);
expect(typeC.getLeastUpperBound(typeB), typeA);
}
void test_getLeastUpperBound_sharedSuperinterface1() {
ClassElementImpl classA = ElementFactory.classElement2("A");
ClassElementImpl classB = ElementFactory.classElement2("B");
ClassElementImpl classC = ElementFactory.classElement2("C");
InterfaceType typeA = classA.type;
InterfaceType typeB = classB.type;
InterfaceType typeC = classC.type;
classB.interfaces = <InterfaceType>[typeA];
classC.interfaces = <InterfaceType>[typeA];
expect(typeB.getLeastUpperBound(typeC), typeA);
expect(typeC.getLeastUpperBound(typeB), typeA);
}
void test_getLeastUpperBound_sharedSuperinterface2() {
ClassElementImpl classA = ElementFactory.classElement2("A");
ClassElementImpl classB = ElementFactory.classElement2("B");
ClassElementImpl classC = ElementFactory.classElement2("C");
ClassElementImpl classD = ElementFactory.classElement2("D");
InterfaceType typeA = classA.type;
InterfaceType typeB = classB.type;
InterfaceType typeC = classC.type;
InterfaceType typeD = classD.type;
classB.interfaces = <InterfaceType>[typeA];
classC.interfaces = <InterfaceType>[typeA];
classD.interfaces = <InterfaceType>[typeC];
expect(typeB.getLeastUpperBound(typeD), typeA);
expect(typeD.getLeastUpperBound(typeB), typeA);
}
void test_getLeastUpperBound_sharedSuperinterface3() {
ClassElementImpl classA = ElementFactory.classElement2("A");
ClassElementImpl classB = ElementFactory.classElement2("B");
ClassElementImpl classC = ElementFactory.classElement2("C");
ClassElementImpl classD = ElementFactory.classElement2("D");
InterfaceType typeA = classA.type;
InterfaceType typeB = classB.type;
InterfaceType typeC = classC.type;
InterfaceType typeD = classD.type;
classB.interfaces = <InterfaceType>[typeA];
classC.interfaces = <InterfaceType>[typeB];
classD.interfaces = <InterfaceType>[typeB];
expect(typeC.getLeastUpperBound(typeD), typeB);
expect(typeD.getLeastUpperBound(typeC), typeB);
}
void test_getLeastUpperBound_sharedSuperinterface4() {
ClassElement classA = ElementFactory.classElement2("A");
ClassElement classA2 = ElementFactory.classElement2("A2");
ClassElement classA3 = ElementFactory.classElement2("A3");
ClassElementImpl classB = ElementFactory.classElement2("B");
ClassElementImpl classC = ElementFactory.classElement2("C");
InterfaceType typeA = classA.type;
InterfaceType typeA2 = classA2.type;
InterfaceType typeA3 = classA3.type;
InterfaceType typeB = classB.type;
InterfaceType typeC = classC.type;
classB.interfaces = <InterfaceType>[typeA, typeA2];
classC.interfaces = <InterfaceType>[typeA, typeA3];
expect(typeB.getLeastUpperBound(typeC), typeA);
expect(typeC.getLeastUpperBound(typeB), typeA);
}
void test_getLeastUpperBound_twoComparables() {
InterfaceType string = _typeProvider.stringType;
InterfaceType num = _typeProvider.numType;
expect(string.getLeastUpperBound(num), _typeProvider.objectType);
}
void test_getLeastUpperBound_typeParameters_different() {
//
// class List<int>
// class List<double>
//
InterfaceType listType = _typeProvider.listType;
InterfaceType intType = _typeProvider.intType;
InterfaceType doubleType = _typeProvider.doubleType;
InterfaceType listOfIntType = listType.substitute4(<DartType>[intType]);
InterfaceType listOfDoubleType =
listType.substitute4(<DartType>[doubleType]);
expect(
listOfIntType.getLeastUpperBound(listOfDoubleType),
_typeProvider.objectType);
}
void test_getLeastUpperBound_typeParameters_same() {
//
// List<int>
// List<int>
//
InterfaceType listType = _typeProvider.listType;
InterfaceType intType = _typeProvider.intType;
InterfaceType listOfIntType = listType.substitute4(<DartType>[intType]);
expect(listOfIntType.getLeastUpperBound(listOfIntType), listOfIntType);
}
void test_getMethod_implemented() {
//
// class A { m() {} }
//
ClassElementImpl classA = ElementFactory.classElement2("A");
String methodName = "m";
MethodElementImpl methodM = ElementFactory.methodElement(methodName, null);
classA.methods = <MethodElement>[methodM];
InterfaceType typeA = classA.type;
expect(typeA.getMethod(methodName), same(methodM));
}
void test_getMethod_parameterized() {
//
// class A<E> { E m(E p) {} }
//
ClassElementImpl classA = ElementFactory.classElement2("A", ["E"]);
DartType typeE = classA.type.typeArguments[0];
String methodName = "m";
MethodElementImpl methodM =
ElementFactory.methodElement(methodName, typeE, [typeE]);
classA.methods = <MethodElement>[methodM];
(methodM.type as FunctionTypeImpl).typeArguments =
classA.type.typeArguments;
//
// A<I>
//
InterfaceType typeI = ElementFactory.classElement2("I").type;
InterfaceTypeImpl typeAI = new InterfaceTypeImpl.con1(classA);
typeAI.typeArguments = <DartType>[typeI];
MethodElement method = typeAI.getMethod(methodName);
expect(method, isNotNull);
FunctionType methodType = method.type;
expect(methodType.returnType, same(typeI));
List<DartType> parameterTypes = methodType.normalParameterTypes;
expect(parameterTypes, hasLength(1));
expect(parameterTypes[0], same(typeI));
}
void test_getMethod_unimplemented() {
//
// class A {}
//
ClassElementImpl classA = ElementFactory.classElement2("A");
InterfaceType typeA = classA.type;
expect(typeA.getMethod("m"), isNull);
}
void test_getMethods() {
ClassElementImpl typeElement = ElementFactory.classElement2("A");
MethodElementImpl methodOne = ElementFactory.methodElement("one", null);
MethodElementImpl methodTwo = ElementFactory.methodElement("two", null);
typeElement.methods = <MethodElement>[methodOne, methodTwo];
InterfaceTypeImpl type = new InterfaceTypeImpl.con1(typeElement);
expect(type.methods.length, 2);
}
void test_getMethods_empty() {
ClassElementImpl typeElement = ElementFactory.classElement2("A");
InterfaceTypeImpl type = new InterfaceTypeImpl.con1(typeElement);
expect(type.methods.length, 0);
}
void test_getMixins_nonParameterized() {
//
// class C extends Object with A, B
//
ClassElementImpl classA = ElementFactory.classElement2("A");
InterfaceType typeA = classA.type;
ClassElementImpl classB = ElementFactory.classElement2("B");
InterfaceType typeB = classB.type;
ClassElementImpl classC = ElementFactory.classElement2("C");
classC.mixins = <InterfaceType>[typeA, typeB];
List<InterfaceType> interfaces = classC.type.mixins;
expect(interfaces, hasLength(2));
if (identical(interfaces[0], typeA)) {
expect(interfaces[1], same(typeB));
} else {
expect(interfaces[0], same(typeB));
expect(interfaces[1], same(typeA));
}
}
void test_getMixins_parameterized() {
//
// class A<E>
// class B<F> extends Object with A<F>
//
ClassElementImpl classA = ElementFactory.classElement2("A", ["E"]);
ClassElementImpl classB = ElementFactory.classElement2("B", ["F"]);
InterfaceType typeB = classB.type;
InterfaceTypeImpl typeAF = new InterfaceTypeImpl.con1(classA);
typeAF.typeArguments = <DartType>[typeB.typeArguments[0]];
classB.mixins = <InterfaceType>[typeAF];
//
// B<I>
//
InterfaceType typeI = ElementFactory.classElement2("I").type;
InterfaceTypeImpl typeBI = new InterfaceTypeImpl.con1(classB);
typeBI.typeArguments = <DartType>[typeI];
List<InterfaceType> interfaces = typeBI.mixins;
expect(interfaces, hasLength(1));
InterfaceType result = interfaces[0];
expect(result.element, same(classA));
expect(result.typeArguments[0], same(typeI));
}
void test_getSetter_implemented() {
//
// class A { s() {} }
//
ClassElementImpl classA = ElementFactory.classElement2("A");
String setterName = "s";
PropertyAccessorElement setterS =
ElementFactory.setterElement(setterName, false, null);
classA.accessors = <PropertyAccessorElement>[setterS];
InterfaceType typeA = classA.type;
expect(typeA.getSetter(setterName), same(setterS));
}
void test_getSetter_parameterized() {
//
// class A<E> { set s(E p) {} }
//
ClassElementImpl classA = ElementFactory.classElement2("A", ["E"]);
DartType typeE = classA.type.typeArguments[0];
String setterName = "s";
PropertyAccessorElement setterS =
ElementFactory.setterElement(setterName, false, typeE);
classA.accessors = <PropertyAccessorElement>[setterS];
(setterS.type as FunctionTypeImpl).typeArguments =
classA.type.typeArguments;
//
// A<I>
//
InterfaceType typeI = ElementFactory.classElement2("I").type;
InterfaceTypeImpl typeAI = new InterfaceTypeImpl.con1(classA);
typeAI.typeArguments = <DartType>[typeI];
PropertyAccessorElement setter = typeAI.getSetter(setterName);
expect(setter, isNotNull);
FunctionType setterType = setter.type;
List<DartType> parameterTypes = setterType.normalParameterTypes;
expect(parameterTypes, hasLength(1));
expect(parameterTypes[0], same(typeI));
}
void test_getSetter_unimplemented() {
//
// class A {}
//
ClassElementImpl classA = ElementFactory.classElement2("A");
InterfaceType typeA = classA.type;
expect(typeA.getSetter("s"), isNull);
}
void test_getSuperclass_nonParameterized() {
//
// class B extends A
//
ClassElementImpl classA = ElementFactory.classElement2("A");
InterfaceType typeA = classA.type;
ClassElementImpl classB = ElementFactory.classElement("B", typeA);
InterfaceType typeB = classB.type;
expect(typeB.superclass, same(typeA));
}
void test_getSuperclass_parameterized() {
//
// class A<E>
// class B<F> extends A<F>
//
ClassElementImpl classA = ElementFactory.classElement2("A", ["E"]);
ClassElementImpl classB = ElementFactory.classElement2("B", ["F"]);
InterfaceType typeB = classB.type;
InterfaceTypeImpl typeAF = new InterfaceTypeImpl.con1(classA);
typeAF.typeArguments = <DartType>[typeB.typeArguments[0]];
classB.supertype = typeAF;
//
// B<I>
//
InterfaceType typeI = ElementFactory.classElement2("I").type;
InterfaceTypeImpl typeBI = new InterfaceTypeImpl.con1(classB);
typeBI.typeArguments = <DartType>[typeI];
InterfaceType superclass = typeBI.superclass;
expect(superclass.element, same(classA));
expect(superclass.typeArguments[0], same(typeI));
}
void test_getTypeArguments_empty() {
InterfaceType type = ElementFactory.classElement2("A").type;
expect(type.typeArguments, hasLength(0));
}
void test_hashCode() {
ClassElement classA = ElementFactory.classElement2("A");
InterfaceType typeA = classA.type;
expect(0 == typeA.hashCode, isFalse);
}
void test_isAssignableTo_typeVariables() {
//
// class A<E> {}
// class B<F, G> {
// A<F> af;
// f (A<G> ag) {
// af = ag;
// }
// }
//
ClassElement classA = ElementFactory.classElement2("A", ["E"]);
ClassElement classB = ElementFactory.classElement2("B", ["F", "G"]);
InterfaceTypeImpl typeAF = new InterfaceTypeImpl.con1(classA);
typeAF.typeArguments = <DartType>[classB.typeParameters[0].type];
InterfaceTypeImpl typeAG = new InterfaceTypeImpl.con1(classA);
typeAG.typeArguments = <DartType>[classB.typeParameters[1].type];
expect(typeAG.isAssignableTo(typeAF), isFalse);
}
void test_isAssignableTo_void() {
expect(
VoidTypeImpl.instance.isAssignableTo(_typeProvider.intType),
isFalse);
}
void test_isDirectSupertypeOf_extends() {
ClassElement classA = ElementFactory.classElement2("A");
ClassElement classB = ElementFactory.classElement("B", classA.type);
InterfaceType typeA = classA.type;
InterfaceType typeB = classB.type;
expect(typeA.isDirectSupertypeOf(typeB), isTrue);
}
void test_isDirectSupertypeOf_false() {
ClassElement classA = ElementFactory.classElement2("A");
ClassElement classB = ElementFactory.classElement2("B");
ClassElement classC = ElementFactory.classElement("C", classB.type);
InterfaceType typeA = classA.type;
InterfaceType typeC = classC.type;
expect(typeA.isDirectSupertypeOf(typeC), isFalse);
}
void test_isDirectSupertypeOf_implements() {
ClassElementImpl classA = ElementFactory.classElement2("A");
ClassElementImpl classB = ElementFactory.classElement2("B");
InterfaceType typeA = classA.type;
InterfaceType typeB = classB.type;
classB.interfaces = <InterfaceType>[typeA];
expect(typeA.isDirectSupertypeOf(typeB), isTrue);
}
void test_isDirectSupertypeOf_with() {
ClassElementImpl classA = ElementFactory.classElement2("A");
ClassElementImpl classB = ElementFactory.classElement2("B");
InterfaceType typeA = classA.type;
InterfaceType typeB = classB.type;
classB.mixins = <InterfaceType>[typeA];
expect(typeA.isDirectSupertypeOf(typeB), isTrue);
}
void test_isMoreSpecificThan_bottom() {
DartType type = ElementFactory.classElement2("A").type;
expect(BottomTypeImpl.instance.isMoreSpecificThan(type), isTrue);
}
void test_isMoreSpecificThan_covariance() {
ClassElement classA = ElementFactory.classElement2("A", ["E"]);
ClassElement classI = ElementFactory.classElement2("I");
ClassElement classJ = ElementFactory.classElement("J", classI.type);
InterfaceTypeImpl typeAI = new InterfaceTypeImpl.con1(classA);
InterfaceTypeImpl typeAJ = new InterfaceTypeImpl.con1(classA);
typeAI.typeArguments = <DartType>[classI.type];
typeAJ.typeArguments = <DartType>[classJ.type];
expect(typeAJ.isMoreSpecificThan(typeAI), isTrue);
expect(typeAI.isMoreSpecificThan(typeAJ), isFalse);
}
void test_isMoreSpecificThan_directSupertype() {
ClassElement classA = ElementFactory.classElement2("A");
ClassElement classB = ElementFactory.classElement("B", classA.type);
InterfaceType typeA = classA.type;
InterfaceType typeB = classB.type;
expect(typeB.isMoreSpecificThan(typeA), isTrue);
// the opposite test tests a different branch in isMoreSpecificThan()
expect(typeA.isMoreSpecificThan(typeB), isFalse);
}
void test_isMoreSpecificThan_dynamic() {
InterfaceType type = ElementFactory.classElement2("A").type;
expect(type.isMoreSpecificThan(DynamicTypeImpl.instance), isTrue);
}
void test_isMoreSpecificThan_generic() {
ClassElement classA = ElementFactory.classElement2("A", ["E"]);
ClassElement classB = ElementFactory.classElement2("B");
DartType dynamicType = DynamicTypeImpl.instance;
InterfaceType typeAOfDynamic =
classA.type.substitute4(<DartType>[dynamicType]);
InterfaceType typeAOfB = classA.type.substitute4(<DartType>[classB.type]);
expect(typeAOfDynamic.isMoreSpecificThan(typeAOfB), isFalse);
expect(typeAOfB.isMoreSpecificThan(typeAOfDynamic), isTrue);
}
void test_isMoreSpecificThan_self() {
InterfaceType type = ElementFactory.classElement2("A").type;
expect(type.isMoreSpecificThan(type), isTrue);
}
void test_isMoreSpecificThan_transitive_interface() {
//
// class A {}
// class B extends A {}
// class C implements B {}
//
ClassElementImpl classA = ElementFactory.classElement2("A");
ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
ClassElementImpl classC = ElementFactory.classElement2("C");
classC.interfaces = <InterfaceType>[classB.type];
InterfaceType typeA = classA.type;
InterfaceType typeC = classC.type;
expect(typeC.isMoreSpecificThan(typeA), isTrue);
}
void test_isMoreSpecificThan_transitive_mixin() {
//
// class A {}
// class B extends A {}
// class C with B {}
//
ClassElementImpl classA = ElementFactory.classElement2("A");
ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
ClassElementImpl classC = ElementFactory.classElement2("C");
classC.mixins = <InterfaceType>[classB.type];
InterfaceType typeA = classA.type;
InterfaceType typeC = classC.type;
expect(typeC.isMoreSpecificThan(typeA), isTrue);
}
void test_isMoreSpecificThan_transitive_recursive() {
//
// class A extends B {}
// class B extends A {}
// class C {}
//
ClassElementImpl classA = ElementFactory.classElement2("A");
ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
ClassElementImpl classC = ElementFactory.classElement2("C");
InterfaceType typeA = classA.type;
InterfaceType typeC = classC.type;
classA.supertype = classB.type;
expect(typeA.isMoreSpecificThan(typeC), isFalse);
}
void test_isMoreSpecificThan_transitive_superclass() {
//
// class A {}
// class B extends A {}
// class C extends B {}
//
ClassElement classA = ElementFactory.classElement2("A");
ClassElement classB = ElementFactory.classElement("B", classA.type);
ClassElement classC = ElementFactory.classElement("C", classB.type);
InterfaceType typeA = classA.type;
InterfaceType typeC = classC.type;
expect(typeC.isMoreSpecificThan(typeA), isTrue);
}
void test_isMoreSpecificThan_typeParameterType() {
//
// class A<E> {}
//
ClassElement classA = ElementFactory.classElement2("A", ["E"]);
InterfaceType typeA = classA.type;
TypeParameterType parameterType = classA.typeParameters[0].type;
DartType objectType = _typeProvider.objectType;
expect(parameterType.isMoreSpecificThan(objectType), isTrue);
expect(parameterType.isMoreSpecificThan(typeA), isFalse);
}
void test_isMoreSpecificThan_typeParameterType_withBound() {
//
// class A {}
// class B<E extends A> {}
//
ClassElement classA = ElementFactory.classElement2("A");
InterfaceType typeA = classA.type;
ClassElementImpl classB = ElementFactory.classElement2("B");
TypeParameterElementImpl parameterEA =
new TypeParameterElementImpl.forNode(AstFactory.identifier3("E"));
TypeParameterType parameterAEType = new TypeParameterTypeImpl(parameterEA);
parameterEA.bound = typeA;
parameterEA.type = parameterAEType;
classB.typeParameters = <TypeParameterElementImpl>[parameterEA];
expect(parameterAEType.isMoreSpecificThan(typeA), isTrue);
}
void test_isSubtypeOf_directSubtype() {
ClassElement classA = ElementFactory.classElement2("A");
ClassElement classB = ElementFactory.classElement("B", classA.type);
InterfaceType typeA = classA.type;
InterfaceType typeB = classB.type;
expect(typeB.isSubtypeOf(typeA), isTrue);
expect(typeA.isSubtypeOf(typeB), isFalse);
}
void test_isSubtypeOf_dynamic() {
ClassElement classA = ElementFactory.classElement2("A");
InterfaceType typeA = classA.type;
DartType dynamicType = DynamicTypeImpl.instance;
expect(dynamicType.isSubtypeOf(typeA), isTrue);
expect(typeA.isSubtypeOf(dynamicType), isTrue);
}
void test_isSubtypeOf_function() {
//
// void f(String s) {}
// class A {
// void call(String s) {}
// }
//
InterfaceType stringType = _typeProvider.stringType;
ClassElementImpl classA = ElementFactory.classElement2("A");
classA.methods = <MethodElement>[
ElementFactory.methodElement("call", VoidTypeImpl.instance, [stringType])];
FunctionType functionType =
ElementFactory.functionElement5("f", <ClassElement>[stringType.element]).type;
expect(classA.type.isSubtypeOf(functionType), isTrue);
}
void test_isSubtypeOf_generic() {
ClassElement classA = ElementFactory.classElement2("A", ["E"]);
ClassElement classB = ElementFactory.classElement2("B");
DartType dynamicType = DynamicTypeImpl.instance;
InterfaceType typeAOfDynamic =
classA.type.substitute4(<DartType>[dynamicType]);
InterfaceType typeAOfB = classA.type.substitute4(<DartType>[classB.type]);
expect(typeAOfDynamic.isSubtypeOf(typeAOfB), isTrue);
expect(typeAOfB.isSubtypeOf(typeAOfDynamic), isTrue);
}
void test_isSubtypeOf_interface() {
ClassElement classA = ElementFactory.classElement2("A");
ClassElement classB = ElementFactory.classElement("B", classA.type);
ClassElementImpl classC = ElementFactory.classElement2("C");
InterfaceType typeObject = classA.supertype;
InterfaceType typeA = classA.type;
InterfaceType typeB = classB.type;
InterfaceType typeC = classC.type;
classC.interfaces = <InterfaceType>[typeB];
expect(typeC.isSubtypeOf(typeB), isTrue);
expect(typeC.isSubtypeOf(typeObject), isTrue);
expect(typeC.isSubtypeOf(typeA), isTrue);
expect(typeA.isSubtypeOf(typeC), isFalse);
}
void test_isSubtypeOf_mixins() {
//
// class A {}
// class B extends A {}
// class C with B {}
//
ClassElement classA = ElementFactory.classElement2("A");
ClassElement classB = ElementFactory.classElement("B", classA.type);
ClassElementImpl classC = ElementFactory.classElement2("C");
InterfaceType typeObject = classA.supertype;
InterfaceType typeA = classA.type;
InterfaceType typeB = classB.type;
InterfaceType typeC = classC.type;
classC.mixins = <InterfaceType>[typeB];
expect(typeC.isSubtypeOf(typeB), isTrue);
expect(typeC.isSubtypeOf(typeObject), isTrue);
expect(typeC.isSubtypeOf(typeA), isTrue);
expect(typeA.isSubtypeOf(typeC), isFalse);
}
void test_isSubtypeOf_object() {
ClassElement classA = ElementFactory.classElement2("A");
InterfaceType typeA = classA.type;
InterfaceType typeObject = classA.supertype;
expect(typeA.isSubtypeOf(typeObject), isTrue);
expect(typeObject.isSubtypeOf(typeA), isFalse);
}
void test_isSubtypeOf_self() {
ClassElement classA = ElementFactory.classElement2("A");
InterfaceType typeA = classA.type;
expect(typeA.isSubtypeOf(typeA), isTrue);
}
void test_isSubtypeOf_transitive_recursive() {
//
// class A extends B {}
// class B extends A {}
// class C {}
//
ClassElementImpl classA = ElementFactory.classElement2("A");
ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
ClassElementImpl classC = ElementFactory.classElement2("C");
InterfaceType typeA = classA.type;
InterfaceType typeC = classC.type;
classA.supertype = classB.type;
expect(typeA.isSubtypeOf(typeC), isFalse);
}
void test_isSubtypeOf_transitive_superclass() {
ClassElement classA = ElementFactory.classElement2("A");
ClassElement classB = ElementFactory.classElement("B", classA.type);
ClassElement classC = ElementFactory.classElement("C", classB.type);
InterfaceType typeA = classA.type;
InterfaceType typeC = classC.type;
expect(typeC.isSubtypeOf(typeA), isTrue);
expect(typeA.isSubtypeOf(typeC), isFalse);
}
void test_isSubtypeOf_typeArguments() {
DartType dynamicType = DynamicTypeImpl.instance;
ClassElement classA = ElementFactory.classElement2("A", ["E"]);
ClassElement classI = ElementFactory.classElement2("I");
ClassElement classJ = ElementFactory.classElement("J", classI.type);
ClassElement classK = ElementFactory.classElement2("K");
InterfaceType typeA = classA.type;
InterfaceType typeA_dynamic = typeA.substitute4(<DartType>[dynamicType]);
InterfaceTypeImpl typeAI = new InterfaceTypeImpl.con1(classA);
InterfaceTypeImpl typeAJ = new InterfaceTypeImpl.con1(classA);
InterfaceTypeImpl typeAK = new InterfaceTypeImpl.con1(classA);
typeAI.typeArguments = <DartType>[classI.type];
typeAJ.typeArguments = <DartType>[classJ.type];
typeAK.typeArguments = <DartType>[classK.type];
// A<J> <: A<I> since J <: I
expect(typeAJ.isSubtypeOf(typeAI), isTrue);
expect(typeAI.isSubtypeOf(typeAJ), isFalse);
// A<I> <: A<I> since I <: I
expect(typeAI.isSubtypeOf(typeAI), isTrue);
// A <: A<I> and A <: A<J>
expect(typeA_dynamic.isSubtypeOf(typeAI), isTrue);
expect(typeA_dynamic.isSubtypeOf(typeAJ), isTrue);
// A<I> <: A and A<J> <: A
expect(typeAI.isSubtypeOf(typeA_dynamic), isTrue);
expect(typeAJ.isSubtypeOf(typeA_dynamic), isTrue);
// A<I> !<: A<K> and A<K> !<: A<I>
expect(typeAI.isSubtypeOf(typeAK), isFalse);
expect(typeAK.isSubtypeOf(typeAI), isFalse);
}
void test_isSubtypeOf_typeParameter() {
//
// class A<E> {}
//
ClassElement classA = ElementFactory.classElement2("A", ["E"]);
InterfaceType typeA = classA.type;
TypeParameterType parameterType = classA.typeParameters[0].type;
expect(typeA.isSubtypeOf(parameterType), isFalse);
}
void test_isSupertypeOf_directSupertype() {
ClassElement classA = ElementFactory.classElement2("A");
ClassElement classB = ElementFactory.classElement("B", classA.type);
InterfaceType typeA = classA.type;
InterfaceType typeB = classB.type;
expect(typeB.isSupertypeOf(typeA), isFalse);
expect(typeA.isSupertypeOf(typeB), isTrue);
}
void test_isSupertypeOf_dynamic() {
ClassElement classA = ElementFactory.classElement2("A");
InterfaceType typeA = classA.type;
DartType dynamicType = DynamicTypeImpl.instance;
expect(dynamicType.isSupertypeOf(typeA), isTrue);
expect(typeA.isSupertypeOf(dynamicType), isTrue);
}
void test_isSupertypeOf_indirectSupertype() {
ClassElement classA = ElementFactory.classElement2("A");
ClassElement classB = ElementFactory.classElement("B", classA.type);
ClassElement classC = ElementFactory.classElement("C", classB.type);
InterfaceType typeA = classA.type;
InterfaceType typeC = classC.type;
expect(typeC.isSupertypeOf(typeA), isFalse);
expect(typeA.isSupertypeOf(typeC), isTrue);
}
void test_isSupertypeOf_interface() {
ClassElement classA = ElementFactory.classElement2("A");
ClassElement classB = ElementFactory.classElement("B", classA.type);
ClassElementImpl classC = ElementFactory.classElement2("C");
InterfaceType typeObject = classA.supertype;
InterfaceType typeA = classA.type;
InterfaceType typeB = classB.type;
InterfaceType typeC = classC.type;
classC.interfaces = <InterfaceType>[typeB];
expect(typeB.isSupertypeOf(typeC), isTrue);
expect(typeObject.isSupertypeOf(typeC), isTrue);
expect(typeA.isSupertypeOf(typeC), isTrue);
expect(typeC.isSupertypeOf(typeA), isFalse);
}
void test_isSupertypeOf_mixins() {
//
// class A {}
// class B extends A {}
// class C with B {}
//
ClassElement classA = ElementFactory.classElement2("A");
ClassElement classB = ElementFactory.classElement("B", classA.type);
ClassElementImpl classC = ElementFactory.classElement2("C");
InterfaceType typeObject = classA.supertype;
InterfaceType typeA = classA.type;
InterfaceType typeB = classB.type;
InterfaceType typeC = classC.type;
classC.mixins = <InterfaceType>[typeB];
expect(typeB.isSupertypeOf(typeC), isTrue);
expect(typeObject.isSupertypeOf(typeC), isTrue);
expect(typeA.isSupertypeOf(typeC), isTrue);
expect(typeC.isSupertypeOf(typeA), isFalse);
}
void test_isSupertypeOf_object() {
ClassElement classA = ElementFactory.classElement2("A");
InterfaceType typeA = classA.type;
InterfaceType typeObject = classA.supertype;
expect(typeA.isSupertypeOf(typeObject), isFalse);
expect(typeObject.isSupertypeOf(typeA), isTrue);
}
void test_isSupertypeOf_self() {
ClassElement classA = ElementFactory.classElement2("A");
InterfaceType typeA = classA.type;
expect(typeA.isSupertypeOf(typeA), isTrue);
}
void test_lookUpGetter_implemented() {
//
// class A { g {} }
//
ClassElementImpl classA = ElementFactory.classElement2("A");
String getterName = "g";
PropertyAccessorElement getterG =
ElementFactory.getterElement(getterName, false, null);
classA.accessors = <PropertyAccessorElement>[getterG];
InterfaceType typeA = classA.type;
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
CompilationUnitElement unit = library.definingCompilationUnit;
(unit as CompilationUnitElementImpl).types = <ClassElement>[classA];
expect(typeA.lookUpGetter(getterName, library), same(getterG));
}
void test_lookUpGetter_inherited() {
//
// class A { g {} }
// class B extends A {}
//
ClassElementImpl classA = ElementFactory.classElement2("A");
String getterName = "g";
PropertyAccessorElement getterG =
ElementFactory.getterElement(getterName, false, null);
classA.accessors = <PropertyAccessorElement>[getterG];
ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
InterfaceType typeB = classB.type;
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
CompilationUnitElement unit = library.definingCompilationUnit;
(unit as CompilationUnitElementImpl).types = <ClassElement>[classA, classB];
expect(typeB.lookUpGetter(getterName, library), same(getterG));
}
void test_lookUpGetter_mixin_shadowing() {
//
// class B {}
// class M1 { get g {} }
// class M2 { get g {} }
// class C extends B with M1, M2 {}
//
TestTypeProvider typeProvider = new TestTypeProvider();
String getterName = 'g';
ClassElementImpl classB = ElementFactory.classElement2('B');
ClassElementImpl classM1 = ElementFactory.classElement2('M1');
PropertyAccessorElementImpl getterM1g =
ElementFactory.getterElement(getterName, false, typeProvider.dynamicType);
classM1.accessors = <PropertyAccessorElement>[getterM1g];
ClassElementImpl classM2 = ElementFactory.classElement2('M2');
PropertyAccessorElementImpl getterM2g =
ElementFactory.getterElement(getterName, false, typeProvider.dynamicType);
classM2.accessors = <PropertyAccessorElement>[getterM2g];
ClassElementImpl classC = ElementFactory.classElement('C', classB.type);
classC.mixins = <InterfaceType>[classM1.type, classM2.type];
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
CompilationUnitElementImpl unit = library.definingCompilationUnit;
unit.types = <ClassElement>[classB, classM1, classM2, classC];
expect(classC.type.lookUpGetter(getterName, library), getterM2g);
}
void test_lookUpGetter_recursive() {
//
// class A extends B {}
// class B extends A {}
//
ClassElementImpl classA = ElementFactory.classElement2("A");
InterfaceType typeA = classA.type;
ClassElementImpl classB = ElementFactory.classElement("B", typeA);
classA.supertype = classB.type;
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
CompilationUnitElement unit = library.definingCompilationUnit;
(unit as CompilationUnitElementImpl).types = <ClassElement>[classA, classB];
expect(typeA.lookUpGetter("g", library), isNull);
}
void test_lookUpGetter_unimplemented() {
//
// class A {}
//
ClassElementImpl classA = ElementFactory.classElement2("A");
InterfaceType typeA = classA.type;
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
CompilationUnitElement unit = library.definingCompilationUnit;
(unit as CompilationUnitElementImpl).types = <ClassElement>[classA];
expect(typeA.lookUpGetter("g", library), isNull);
}
void test_lookUpMethod_implemented() {
//
// class A { m() {} }
//
ClassElementImpl classA = ElementFactory.classElement2("A");
String methodName = "m";
MethodElementImpl methodM = ElementFactory.methodElement(methodName, null);
classA.methods = <MethodElement>[methodM];
InterfaceType typeA = classA.type;
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
CompilationUnitElement unit = library.definingCompilationUnit;
(unit as CompilationUnitElementImpl).types = <ClassElement>[classA];
expect(typeA.lookUpMethod(methodName, library), same(methodM));
}
void test_lookUpMethod_inherited() {
//
// class A { m() {} }
// class B extends A {}
//
ClassElementImpl classA = ElementFactory.classElement2("A");
String methodName = "m";
MethodElementImpl methodM = ElementFactory.methodElement(methodName, null);
classA.methods = <MethodElement>[methodM];
ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
InterfaceType typeB = classB.type;
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
CompilationUnitElement unit = library.definingCompilationUnit;
(unit as CompilationUnitElementImpl).types = <ClassElement>[classA, classB];
expect(typeB.lookUpMethod(methodName, library), same(methodM));
}
void test_lookUpMethod_mixin_shadowing() {
//
// class B {}
// class M1 { m() {} }
// class M2 { m() {} }
// class C extends B with M1, M2 {}
//
String methodName = 'm';
ClassElementImpl classB = ElementFactory.classElement2('B');
ClassElementImpl classM1 = ElementFactory.classElement2('M1');
MethodElementImpl methodM1m =
ElementFactory.methodElement(methodName, null);
classM1.methods = <MethodElement>[methodM1m];
ClassElementImpl classM2 = ElementFactory.classElement2('M2');
MethodElementImpl methodM2m =
ElementFactory.methodElement(methodName, null);
classM2.methods = <MethodElement>[methodM2m];
ClassElementImpl classC = ElementFactory.classElement('C', classB.type);
classC.mixins = <InterfaceType>[classM1.type, classM2.type];
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
CompilationUnitElementImpl unit = library.definingCompilationUnit;
unit.types = <ClassElement>[classB, classM1, classM2, classC];
expect(classC.type.lookUpMethod(methodName, library), methodM2m);
}
void test_lookUpMethod_parameterized() {
//
// class A<E> { E m(E p) {} }
// class B<F> extends A<F> {}
//
ClassElementImpl classA = ElementFactory.classElement2("A", ["E"]);
DartType typeE = classA.type.typeArguments[0];
String methodName = "m";
MethodElementImpl methodM =
ElementFactory.methodElement(methodName, typeE, [typeE]);
classA.methods = <MethodElement>[methodM];
(methodM.type as FunctionTypeImpl).typeArguments =
classA.type.typeArguments;
ClassElementImpl classB = ElementFactory.classElement2("B", ["F"]);
InterfaceType typeB = classB.type;
InterfaceTypeImpl typeAF = new InterfaceTypeImpl.con1(classA);
typeAF.typeArguments = <DartType>[typeB.typeArguments[0]];
classB.supertype = typeAF;
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
CompilationUnitElement unit = library.definingCompilationUnit;
(unit as CompilationUnitElementImpl).types = <ClassElement>[classA];
//
// B<I>
//
InterfaceType typeI = ElementFactory.classElement2("I").type;
InterfaceTypeImpl typeBI = new InterfaceTypeImpl.con1(classB);
typeBI.typeArguments = <DartType>[typeI];
MethodElement method = typeBI.lookUpMethod(methodName, library);
expect(method, isNotNull);
FunctionType methodType = method.type;
expect(methodType.returnType, same(typeI));
List<DartType> parameterTypes = methodType.normalParameterTypes;
expect(parameterTypes, hasLength(1));
expect(parameterTypes[0], same(typeI));
}
void test_lookUpMethod_recursive() {
//
// class A extends B {}
// class B extends A {}
//
ClassElementImpl classA = ElementFactory.classElement2("A");
InterfaceType typeA = classA.type;
ClassElementImpl classB = ElementFactory.classElement("B", typeA);
classA.supertype = classB.type;
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
CompilationUnitElement unit = library.definingCompilationUnit;
(unit as CompilationUnitElementImpl).types = <ClassElement>[classA, classB];
expect(typeA.lookUpMethod("m", library), isNull);
}
void test_lookUpMethod_unimplemented() {
//
// class A {}
//
ClassElementImpl classA = ElementFactory.classElement2("A");
InterfaceType typeA = classA.type;
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
CompilationUnitElement unit = library.definingCompilationUnit;
(unit as CompilationUnitElementImpl).types = <ClassElement>[classA];
expect(typeA.lookUpMethod("m", library), isNull);
}
void test_lookUpSetter_implemented() {
//
// class A { s(x) {} }
//
ClassElementImpl classA = ElementFactory.classElement2("A");
String setterName = "s";
PropertyAccessorElement setterS =
ElementFactory.setterElement(setterName, false, null);
classA.accessors = <PropertyAccessorElement>[setterS];
InterfaceType typeA = classA.type;
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
CompilationUnitElement unit = library.definingCompilationUnit;
(unit as CompilationUnitElementImpl).types = <ClassElement>[classA];
expect(typeA.lookUpSetter(setterName, library), same(setterS));
}
void test_lookUpSetter_inherited() {
//
// class A { s(x) {} }
// class B extends A {}
//
ClassElementImpl classA = ElementFactory.classElement2("A");
String setterName = "g";
PropertyAccessorElement setterS =
ElementFactory.setterElement(setterName, false, null);
classA.accessors = <PropertyAccessorElement>[setterS];
ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
InterfaceType typeB = classB.type;
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
CompilationUnitElement unit = library.definingCompilationUnit;
(unit as CompilationUnitElementImpl).types = <ClassElement>[classA, classB];
expect(typeB.lookUpSetter(setterName, library), same(setterS));
}
void test_lookUpSetter_mixin_shadowing() {
//
// class B {}
// class M1 { set s() {} }
// class M2 { set s() {} }
// class C extends B with M1, M2 {}
//
TestTypeProvider typeProvider = new TestTypeProvider();
String setterName = 's';
ClassElementImpl classB = ElementFactory.classElement2('B');
ClassElementImpl classM1 = ElementFactory.classElement2('M1');
PropertyAccessorElementImpl setterM1g =
ElementFactory.setterElement(setterName, false, typeProvider.dynamicType);
classM1.accessors = <PropertyAccessorElement>[setterM1g];
ClassElementImpl classM2 = ElementFactory.classElement2('M2');
PropertyAccessorElementImpl setterM2g =
ElementFactory.getterElement(setterName, false, typeProvider.dynamicType);
classM2.accessors = <PropertyAccessorElement>[setterM2g];
ClassElementImpl classC = ElementFactory.classElement('C', classB.type);
classC.mixins = <InterfaceType>[classM1.type, classM2.type];
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
CompilationUnitElementImpl unit = library.definingCompilationUnit;
unit.types = <ClassElement>[classB, classM1, classM2, classC];
expect(classC.type.lookUpGetter(setterName, library), setterM2g);
}
void test_lookUpSetter_recursive() {
//
// class A extends B {}
// class B extends A {}
//
ClassElementImpl classA = ElementFactory.classElement2("A");
InterfaceType typeA = classA.type;
ClassElementImpl classB = ElementFactory.classElement("B", typeA);
classA.supertype = classB.type;
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
CompilationUnitElement unit = library.definingCompilationUnit;
(unit as CompilationUnitElementImpl).types = <ClassElement>[classA, classB];
expect(typeA.lookUpSetter("s", library), isNull);
}
void test_lookUpSetter_unimplemented() {
//
// class A {}
//
ClassElementImpl classA = ElementFactory.classElement2("A");
InterfaceType typeA = classA.type;
LibraryElementImpl library =
ElementFactory.library(createAnalysisContext(), "lib");
CompilationUnitElement unit = library.definingCompilationUnit;
(unit as CompilationUnitElementImpl).types = <ClassElement>[classA];
expect(typeA.lookUpSetter("s", library), isNull);
}
void test_setTypeArguments() {
InterfaceTypeImpl type =
ElementFactory.classElement2("A").type as InterfaceTypeImpl;
List<DartType> typeArguments = <DartType>[
ElementFactory.classElement2("B").type,
ElementFactory.classElement2("C").type];
type.typeArguments = typeArguments;
expect(type.typeArguments, typeArguments);
}
void test_substitute_equal() {
ClassElement classAE = ElementFactory.classElement2("A", ["E"]);
InterfaceType typeAE = classAE.type;
InterfaceType argumentType = ElementFactory.classElement2("B").type;
List<DartType> args = [argumentType];
List<DartType> params = [classAE.typeParameters[0].type];
InterfaceType typeAESubbed = typeAE.substitute2(args, params);
expect(typeAESubbed.element, classAE);
List<DartType> resultArguments = typeAESubbed.typeArguments;
expect(resultArguments, hasLength(1));
expect(resultArguments[0], argumentType);
}
void test_substitute_exception() {
try {
ClassElementImpl classA = ElementFactory.classElement2("A");
InterfaceTypeImpl type = new InterfaceTypeImpl.con1(classA);
InterfaceType argumentType = ElementFactory.classElement2("B").type;
type.substitute2(<DartType>[argumentType], <DartType>[]);
fail(
"Expected to encounter exception, argument and parameter type array lengths not equal.");
} catch (e) {
// Expected result
}
}
void test_substitute_notEqual() {
// The [test_substitute_equals] above has a slightly higher level
// implementation.
ClassElementImpl classA = ElementFactory.classElement2("A");
TypeParameterElementImpl parameterElement =
new TypeParameterElementImpl.forNode(AstFactory.identifier3("E"));
InterfaceTypeImpl type = new InterfaceTypeImpl.con1(classA);
TypeParameterTypeImpl parameter =
new TypeParameterTypeImpl(parameterElement);
type.typeArguments = <DartType>[parameter];
InterfaceType argumentType = ElementFactory.classElement2("B").type;
TypeParameterTypeImpl parameterType = new TypeParameterTypeImpl(
new TypeParameterElementImpl.forNode(AstFactory.identifier3("F")));
InterfaceType result =
type.substitute2(<DartType>[argumentType], <DartType>[parameterType]);
expect(result.element, classA);
List<DartType> resultArguments = result.typeArguments;
expect(resultArguments, hasLength(1));
expect(resultArguments[0], parameter);
}
}
@reflectiveTest
class LibraryElementImplTest extends EngineTestCase {
void test_creation() {
expect(
new LibraryElementImpl.forNode(
createAnalysisContext(),
AstFactory.libraryIdentifier2(["l"])),
isNotNull);
}
void test_getImportedLibraries() {
AnalysisContext context = createAnalysisContext();
LibraryElementImpl library1 = ElementFactory.library(context, "l1");
LibraryElementImpl library2 = ElementFactory.library(context, "l2");
LibraryElementImpl library3 = ElementFactory.library(context, "l3");
LibraryElementImpl library4 = ElementFactory.library(context, "l4");
PrefixElement prefixA =
new PrefixElementImpl.forNode(AstFactory.identifier3("a"));
PrefixElement prefixB =
new PrefixElementImpl.forNode(AstFactory.identifier3("b"));
List<ImportElementImpl> imports = [
ElementFactory.importFor(library2, null),
ElementFactory.importFor(library2, prefixB),
ElementFactory.importFor(library3, null),
ElementFactory.importFor(library3, prefixA),
ElementFactory.importFor(library3, prefixB),
ElementFactory.importFor(library4, prefixA)];
library1.imports = imports;
List<LibraryElement> libraries = library1.importedLibraries;
expect(
libraries,
unorderedEquals(<LibraryElement>[library2, library3, library4]));
}
void test_getPrefixes() {
AnalysisContext context = createAnalysisContext();
LibraryElementImpl library = ElementFactory.library(context, "l1");
PrefixElement prefixA =
new PrefixElementImpl.forNode(AstFactory.identifier3("a"));
PrefixElement prefixB =
new PrefixElementImpl.forNode(AstFactory.identifier3("b"));
List<ImportElementImpl> imports = [
ElementFactory.importFor(ElementFactory.library(context, "l2"), null),
ElementFactory.importFor(ElementFactory.library(context, "l3"), null),
ElementFactory.importFor(ElementFactory.library(context, "l4"), prefixA),
ElementFactory.importFor(ElementFactory.library(context, "l5"), prefixA),
ElementFactory.importFor(ElementFactory.library(context, "l6"), prefixB)];
library.imports = imports;
List<PrefixElement> prefixes = library.prefixes;
expect(prefixes, hasLength(2));
if (identical(prefixA, prefixes[0])) {
expect(prefixes[1], same(prefixB));
} else {
expect(prefixes[0], same(prefixB));
expect(prefixes[1], same(prefixA));
}
}
void test_getUnits() {
AnalysisContext context = createAnalysisContext();
LibraryElementImpl library = ElementFactory.library(context, "test");
CompilationUnitElement unitLib = library.definingCompilationUnit;
CompilationUnitElementImpl unitA =
ElementFactory.compilationUnit("unit_a.dart");
CompilationUnitElementImpl unitB =
ElementFactory.compilationUnit("unit_b.dart");
library.parts = <CompilationUnitElement>[unitA, unitB];
expect(
library.units,
unorderedEquals(<CompilationUnitElement>[unitLib, unitA, unitB]));
}
void test_getVisibleLibraries_cycle() {
AnalysisContext context = createAnalysisContext();
LibraryElementImpl library = ElementFactory.library(context, "app");
LibraryElementImpl libraryA = ElementFactory.library(context, "A");
libraryA.imports =
<ImportElementImpl>[ElementFactory.importFor(library, null)];
library.imports =
<ImportElementImpl>[ElementFactory.importFor(libraryA, null)];
List<LibraryElement> libraries = library.visibleLibraries;
expect(libraries, unorderedEquals(<LibraryElement>[library, libraryA]));
}
void test_getVisibleLibraries_directExports() {
AnalysisContext context = createAnalysisContext();
LibraryElementImpl library = ElementFactory.library(context, "app");
LibraryElementImpl libraryA = ElementFactory.library(context, "A");
library.exports = <ExportElementImpl>[ElementFactory.exportFor(libraryA)];
List<LibraryElement> libraries = library.visibleLibraries;
expect(libraries, unorderedEquals(<LibraryElement>[library]));
}
void test_getVisibleLibraries_directImports() {
AnalysisContext context = createAnalysisContext();
LibraryElementImpl library = ElementFactory.library(context, "app");
LibraryElementImpl libraryA = ElementFactory.library(context, "A");
library.imports =
<ImportElementImpl>[ElementFactory.importFor(libraryA, null)];
List<LibraryElement> libraries = library.visibleLibraries;
expect(libraries, unorderedEquals(<LibraryElement>[library, libraryA]));
}
void test_getVisibleLibraries_indirectExports() {
AnalysisContext context = createAnalysisContext();
LibraryElementImpl library = ElementFactory.library(context, "app");
LibraryElementImpl libraryA = ElementFactory.library(context, "A");
LibraryElementImpl libraryAA = ElementFactory.library(context, "AA");
libraryA.exports = <ExportElementImpl>[ElementFactory.exportFor(libraryAA)];
library.imports =
<ImportElementImpl>[ElementFactory.importFor(libraryA, null)];
List<LibraryElement> libraries = library.visibleLibraries;
expect(
libraries,
unorderedEquals(<LibraryElement>[library, libraryA, libraryAA]));
}
void test_getVisibleLibraries_indirectImports() {
AnalysisContext context = createAnalysisContext();
LibraryElementImpl library = ElementFactory.library(context, "app");
LibraryElementImpl libraryA = ElementFactory.library(context, "A");
LibraryElementImpl libraryAA = ElementFactory.library(context, "AA");
LibraryElementImpl libraryB = ElementFactory.library(context, "B");
libraryA.imports =
<ImportElementImpl>[ElementFactory.importFor(libraryAA, null)];
library.imports = <ImportElementImpl>[
ElementFactory.importFor(libraryA, null),
ElementFactory.importFor(libraryB, null)];
List<LibraryElement> libraries = library.visibleLibraries;
expect(
libraries,
unorderedEquals(<LibraryElement>[library, libraryA, libraryAA, libraryB]));
}
void test_getVisibleLibraries_noImports() {
AnalysisContext context = createAnalysisContext();
LibraryElementImpl library = ElementFactory.library(context, "app");
expect(
library.visibleLibraries,
unorderedEquals(<LibraryElement>[library]));
}
void test_isUpToDate() {
AnalysisContext context = createAnalysisContext();
context.sourceFactory = new SourceFactory([]);
LibraryElement library = ElementFactory.library(context, "foo");
context.setContents(library.definingCompilationUnit.source, "sdfsdff");
// Assert that we are not up to date if the target has an old time stamp.
expect(library.isUpToDate(0), isFalse);
// Assert that we are up to date with a target modification time in the
// future.
expect(library.isUpToDate(JavaSystem.currentTimeMillis() + 1000), isTrue);
}
void test_setImports() {
AnalysisContext context = createAnalysisContext();
LibraryElementImpl library =
new LibraryElementImpl.forNode(context, AstFactory.libraryIdentifier2(["l1"]));
List<ImportElementImpl> expectedImports = [
ElementFactory.importFor(ElementFactory.library(context, "l2"), null),
ElementFactory.importFor(ElementFactory.library(context, "l3"), null)];
library.imports = expectedImports;
List<ImportElement> actualImports = library.imports;
expect(actualImports, hasLength(expectedImports.length));
for (int i = 0; i < actualImports.length; i++) {
expect(actualImports[i], same(expectedImports[i]));
}
}
}
@reflectiveTest
class MultiplyDefinedElementImplTest extends EngineTestCase {
void test_fromElements_conflicting() {
Element firstElement = ElementFactory.localVariableElement2("xx");
Element secondElement = ElementFactory.localVariableElement2("yy");
Element result =
MultiplyDefinedElementImpl.fromElements(null, firstElement, secondElement);
EngineTestCase.assertInstanceOf(
(obj) => obj is MultiplyDefinedElement,
MultiplyDefinedElement,
result);
List<Element> elements =
(result as MultiplyDefinedElement).conflictingElements;
expect(elements, hasLength(2));
for (int i = 0; i < elements.length; i++) {
EngineTestCase.assertInstanceOf(
(obj) => obj is LocalVariableElement,
LocalVariableElement,
elements[i]);
}
}
void test_fromElements_multiple() {
Element firstElement = ElementFactory.localVariableElement2("xx");
Element secondElement = ElementFactory.localVariableElement2("yy");
Element thirdElement = ElementFactory.localVariableElement2("zz");
Element result = MultiplyDefinedElementImpl.fromElements(
null,
MultiplyDefinedElementImpl.fromElements(null, firstElement, secondElement),
thirdElement);
EngineTestCase.assertInstanceOf(
(obj) => obj is MultiplyDefinedElement,
MultiplyDefinedElement,
result);
List<Element> elements =
(result as MultiplyDefinedElement).conflictingElements;
expect(elements, hasLength(3));
for (int i = 0; i < elements.length; i++) {
EngineTestCase.assertInstanceOf(
(obj) => obj is LocalVariableElement,
LocalVariableElement,
elements[i]);
}
}
void test_fromElements_nonConflicting() {
Element element = ElementFactory.localVariableElement2("xx");
expect(
MultiplyDefinedElementImpl.fromElements(null, element, element),
same(element));
}
}
@reflectiveTest
class TypeParameterTypeImplTest extends EngineTestCase {
void test_creation() {
expect(
new TypeParameterTypeImpl(
new TypeParameterElementImpl.forNode(AstFactory.identifier3("E"))),
isNotNull);
}
void test_getElement() {
TypeParameterElementImpl element =
new TypeParameterElementImpl.forNode(AstFactory.identifier3("E"));
TypeParameterTypeImpl type = new TypeParameterTypeImpl(element);
expect(type.element, element);
}
void test_isMoreSpecificThan_typeArguments_dynamic() {
TypeParameterElementImpl element =
new TypeParameterElementImpl.forNode(AstFactory.identifier3("E"));
TypeParameterTypeImpl type = new TypeParameterTypeImpl(element);
// E << dynamic
expect(type.isMoreSpecificThan(DynamicTypeImpl.instance), isTrue);
}
void test_isMoreSpecificThan_typeArguments_object() {
TypeParameterElementImpl element =
new TypeParameterElementImpl.forNode(AstFactory.identifier3("E"));
TypeParameterTypeImpl type = new TypeParameterTypeImpl(element);
// E << Object
expect(type.isMoreSpecificThan(ElementFactory.object.type), isTrue);
}
void test_isMoreSpecificThan_typeArguments_resursive() {
ClassElementImpl classS = ElementFactory.classElement2("A");
TypeParameterElementImpl typeParameterU =
new TypeParameterElementImpl.forNode(AstFactory.identifier3("U"));
TypeParameterTypeImpl typeParameterTypeU =
new TypeParameterTypeImpl(typeParameterU);
TypeParameterElementImpl typeParameterT =
new TypeParameterElementImpl.forNode(AstFactory.identifier3("T"));
TypeParameterTypeImpl typeParameterTypeT =
new TypeParameterTypeImpl(typeParameterT);
typeParameterT.bound = typeParameterTypeU;
typeParameterU.bound = typeParameterTypeU;
// <T extends U> and <U extends T>
// T << S
expect(typeParameterTypeT.isMoreSpecificThan(classS.type), isFalse);
}
void test_isMoreSpecificThan_typeArguments_self() {
TypeParameterElementImpl element =
new TypeParameterElementImpl.forNode(AstFactory.identifier3("E"));
TypeParameterTypeImpl type = new TypeParameterTypeImpl(element);
// E << E
expect(type.isMoreSpecificThan(type), isTrue);
}
void test_isMoreSpecificThan_typeArguments_transitivity_interfaceTypes() {
// class A {}
// class B extends A {}
//
ClassElement classA = ElementFactory.classElement2("A");
ClassElement classB = ElementFactory.classElement("B", classA.type);
InterfaceType typeA = classA.type;
InterfaceType typeB = classB.type;
TypeParameterElementImpl typeParameterT =
new TypeParameterElementImpl.forNode(AstFactory.identifier3("T"));
typeParameterT.bound = typeB;
TypeParameterTypeImpl typeParameterTypeT =
new TypeParameterTypeImpl(typeParameterT);
// <T extends B>
// T << A
expect(typeParameterTypeT.isMoreSpecificThan(typeA), isTrue);
}
void test_isMoreSpecificThan_typeArguments_transitivity_typeParameters() {
ClassElementImpl classS = ElementFactory.classElement2("A");
TypeParameterElementImpl typeParameterU =
new TypeParameterElementImpl.forNode(AstFactory.identifier3("U"));
typeParameterU.bound = classS.type;
TypeParameterTypeImpl typeParameterTypeU =
new TypeParameterTypeImpl(typeParameterU);
TypeParameterElementImpl typeParameterT =
new TypeParameterElementImpl.forNode(AstFactory.identifier3("T"));
typeParameterT.bound = typeParameterTypeU;
TypeParameterTypeImpl typeParameterTypeT =
new TypeParameterTypeImpl(typeParameterT);
// <T extends U> and <U extends S>
// T << S
expect(typeParameterTypeT.isMoreSpecificThan(classS.type), isTrue);
}
void test_isMoreSpecificThan_typeArguments_upperBound() {
ClassElementImpl classS = ElementFactory.classElement2("A");
TypeParameterElementImpl typeParameterT =
new TypeParameterElementImpl.forNode(AstFactory.identifier3("T"));
typeParameterT.bound = classS.type;
TypeParameterTypeImpl typeParameterTypeT =
new TypeParameterTypeImpl(typeParameterT);
// <T extends S>
// T << S
expect(typeParameterTypeT.isMoreSpecificThan(classS.type), isTrue);
}
void test_substitute_equal() {
TypeParameterElementImpl element =
new TypeParameterElementImpl.forNode(AstFactory.identifier3("E"));
TypeParameterTypeImpl type = new TypeParameterTypeImpl(element);
InterfaceTypeImpl argument = new InterfaceTypeImpl.con1(
new ClassElementImpl.forNode(AstFactory.identifier3("A")));
TypeParameterTypeImpl parameter = new TypeParameterTypeImpl(element);
expect(
type.substitute2(<DartType>[argument], <DartType>[parameter]),
same(argument));
}
void test_substitute_notEqual() {
TypeParameterTypeImpl type = new TypeParameterTypeImpl(
new TypeParameterElementImpl.forNode(AstFactory.identifier3("E")));
InterfaceTypeImpl argument = new InterfaceTypeImpl.con1(
new ClassElementImpl.forNode(AstFactory.identifier3("A")));
TypeParameterTypeImpl parameter = new TypeParameterTypeImpl(
new TypeParameterElementImpl.forNode(AstFactory.identifier3("F")));
expect(
type.substitute2(<DartType>[argument], <DartType>[parameter]),
same(type));
}
}
@reflectiveTest
class UnionTypeImplTest extends EngineTestCase {
ClassElement _classA;
InterfaceType _typeA;
ClassElement _classB;
InterfaceType _typeB;
DartType _uA;
DartType _uB;
DartType _uAB;
DartType _uBA;
List<DartType> _us;
@override
void setUp() {
super.setUp();
_classA = ElementFactory.classElement2("A");
_typeA = _classA.type;
_classB = ElementFactory.classElement("B", _typeA);
_typeB = _classB.type;
_uA = UnionTypeImpl.union([_typeA]);
_uB = UnionTypeImpl.union([_typeB]);
_uAB = UnionTypeImpl.union([_typeA, _typeB]);
_uBA = UnionTypeImpl.union([_typeB, _typeA]);
_us = <DartType>[_uA, _uB, _uAB, _uBA];
}
void test_emptyUnionsNotAllowed() {
try {
UnionTypeImpl.union([]);
} on IllegalArgumentException catch (e) {
return;
}
fail("Expected illegal argument exception.");
}
void test_equality_beingASubtypeOfAnElementIsNotSufficient() {
// Non-equal if some elements are different
expect(_uAB == _uA, isFalse);
}
void test_equality_insertionOrderDoesntMatter() {
// Insertion order doesn't matter, only sets of elements
expect(_uAB == _uBA, isTrue);
expect(_uBA == _uAB, isTrue);
}
void test_equality_reflexivity() {
for (DartType u in _us) {
expect(u == u, isTrue);
}
}
void test_equality_singletonsCollapse() {
expect(_typeA == _uA, isTrue);
expect(_uA == _typeA, isTrue);
}
void test_isMoreSpecificThan_allElementsOnLHSAreSubtypesOfSomeElementOnRHS() {
// Unions are subtypes when all elements are subtypes
expect(_uAB.isMoreSpecificThan(_uA), isTrue);
expect(_uAB.isMoreSpecificThan(_typeA), isTrue);
}
void test_isMoreSpecificThan_element() {
// Elements of union are sub types
expect(_typeA.isMoreSpecificThan(_uAB), isTrue);
expect(_typeB.isMoreSpecificThan(_uAB), isTrue);
}
void test_isMoreSpecificThan_notSubtypeOfAnyElement() {
// Types that are not subtypes of elements are not subtypes
expect(_typeA.isMoreSpecificThan(_uB), isFalse);
}
void test_isMoreSpecificThan_reflexivity() {
for (DartType u in _us) {
expect(u.isMoreSpecificThan(u), isTrue);
}
}
void
test_isMoreSpecificThan_someElementOnLHSIsNotASubtypeOfAnyElementOnRHS() {
// Unions are subtypes when some element is a subtype
expect(_uAB.isMoreSpecificThan(_uB), isTrue);
expect(_uAB.isMoreSpecificThan(_typeB), isTrue);
}
void test_isMoreSpecificThan_subtypeOfSomeElement() {
// Subtypes of elements are sub types
expect(_typeB.isMoreSpecificThan(_uA), isTrue);
}
void test_isSubtypeOf_allElementsOnLHSAreSubtypesOfSomeElementOnRHS() {
// Unions are subtypes when all elements are subtypes
expect(_uAB.isSubtypeOf(_uA), isTrue);
expect(_uAB.isSubtypeOf(_typeA), isTrue);
}
void test_isSubtypeOf_element() {
// Elements of union are sub types
expect(_typeA.isSubtypeOf(_uAB), isTrue);
expect(_typeB.isSubtypeOf(_uAB), isTrue);
}
void test_isSubtypeOf_notSubtypeOfAnyElement() {
// Types that are not subtypes of elements are not subtypes
expect(_typeA.isSubtypeOf(_uB), isFalse);
}
void test_isSubtypeOf_reflexivity() {
for (DartType u in _us) {
expect(u.isSubtypeOf(u), isTrue);
}
}
void test_isSubtypeOf_someElementOnLHSIsNotASubtypeOfAnyElementOnRHS() {
// Unions are subtypes when some element is a subtype
expect(_uAB.isSubtypeOf(_uB), isTrue);
expect(_uAB.isSubtypeOf(_typeB), isTrue);
}
void test_isSubtypeOf_subtypeOfSomeElement() {
// Subtypes of elements are sub types
expect(_typeB.isSubtypeOf(_uA), isTrue);
}
void test_nestedUnionsCollapse() {
UnionType u = UnionTypeImpl.union([_uAB, _typeA]) as UnionType;
for (DartType t in u.elements) {
if (t is UnionType) {
fail("Expected only non-union types but found $t!");
}
}
}
void test_noLossage() {
UnionType u = UnionTypeImpl.union(
[_typeA, _typeB, _typeB, _typeA, _typeB, _typeB]) as UnionType;
Set<DartType> elements = u.elements;
expect(elements.contains(_typeA), isTrue);
expect(elements.contains(_typeB), isTrue);
expect(elements.length == 2, isTrue);
}
void test_substitute() {
// Based on [InterfaceTypeImplTest.test_substitute_equal].
ClassElement classAE = ElementFactory.classElement2("A", ["E"]);
InterfaceType typeAE = classAE.type;
List<DartType> args = [_typeB];
List<DartType> params = [classAE.typeParameters[0].type];
DartType typeAESubbed = typeAE.substitute2(args, params);
expect(typeAE == typeAESubbed, isFalse);
expect(
UnionTypeImpl.union([_typeA, typeAESubbed]),
UnionTypeImpl.union([_typeA, typeAE]).substitute2(args, params));
}
void test_toString_pair() {
String s = _uAB.toString();
expect(s == "{A,B}" || s == "{B,A}", isTrue);
expect(_uAB.displayName, s);
}
void test_toString_singleton() {
// Singleton unions collapse to the the single type.
expect(_uA.toString(), "A");
}
void test_unionTypeIsLessSpecificThan_function() {
// Based on
// [FunctionTypeImplTest.test_isAssignableTo_normalAndPositionalArgs].
ClassElement a = ElementFactory.classElement2("A");
FunctionType t =
ElementFactory.functionElement6("t", null, <ClassElement>[a]).type;
DartType uAT = UnionTypeImpl.union([_uA, t]);
expect(t.isMoreSpecificThan(uAT), isTrue);
expect(t.isMoreSpecificThan(_uAB), isFalse);
}
void test_unionTypeIsSuperTypeOf_function() {
// Based on
// [FunctionTypeImplTest.test_isAssignableTo_normalAndPositionalArgs].
ClassElement a = ElementFactory.classElement2("A");
FunctionType t =
ElementFactory.functionElement6("t", null, <ClassElement>[a]).type;
DartType uAT = UnionTypeImpl.union([_uA, t]);
expect(t.isSubtypeOf(uAT), isTrue);
expect(t.isSubtypeOf(_uAB), isFalse);
}
}
@reflectiveTest
class VoidTypeImplTest extends EngineTestCase {
/**
* Reference {code VoidTypeImpl.getInstance()}.
*/
DartType _voidType = VoidTypeImpl.instance;
void test_isMoreSpecificThan_void_A() {
ClassElement classA = ElementFactory.classElement2("A");
expect(_voidType.isMoreSpecificThan(classA.type), isFalse);
}
void test_isMoreSpecificThan_void_dynamic() {
expect(_voidType.isMoreSpecificThan(DynamicTypeImpl.instance), isTrue);
}
void test_isMoreSpecificThan_void_void() {
expect(_voidType.isMoreSpecificThan(_voidType), isTrue);
}
void test_isSubtypeOf_void_A() {
ClassElement classA = ElementFactory.classElement2("A");
expect(_voidType.isSubtypeOf(classA.type), isFalse);
}
void test_isSubtypeOf_void_dynamic() {
expect(_voidType.isSubtypeOf(DynamicTypeImpl.instance), isTrue);
}
void test_isSubtypeOf_void_void() {
expect(_voidType.isSubtypeOf(_voidType), isTrue);
}
void test_isVoid() {
expect(_voidType.isVoid, isTrue);
}
}
class _FunctionTypeImplTest_isSubtypeOf_baseCase_classFunction extends
InterfaceTypeImpl {
_FunctionTypeImplTest_isSubtypeOf_baseCase_classFunction(ClassElement arg0)
: super.con1(arg0);
@override
bool get isDartCoreFunction => true;
}