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

Unified Diff: pkg/analyzer/test/utils.dart

Issue 1462133005: Downwards inference. This adds support to the resolver for downwards (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Address comments 2 Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: pkg/analyzer/test/utils.dart
diff --git a/pkg/analyzer/test/utils.dart b/pkg/analyzer/test/utils.dart
index 7c9fbe01d274542be37c6747da69fa145036ff6b..d5d28794240a775ba2d62ee8933460bd60615d7f 100644
--- a/pkg/analyzer/test/utils.dart
+++ b/pkg/analyzer/test/utils.dart
@@ -4,7 +4,10 @@
library analyzer.test.utils;
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/element.dart';
import 'package:analyzer/src/generated/java_io.dart';
+import 'package:analyzer/src/generated/resolver.dart' show TypeProvider;
import 'package:path/path.dart' as path;
import 'package:unittest/unittest.dart';
@@ -12,3 +15,289 @@ void initializeTestEnvironment() {
groupSep = ' | ';
JavaFile.pathContext = path.posix;
}
+
+/**
+ * The type of an assertion which asserts properties of [T]s.
+ */
+typedef void Asserter<T>(T type);
+
+/**
+ * The type of a function which given an [S], builds an assertion over [T]s.
+ */
+typedef Asserter<T> AsserterBuilder<S, T>(S arg);
+
+/**
+ * The type of a function which given an [S0] and an S1, builds an assertion
+ * over [T]s.
+ */
+typedef Asserter<T> AsserterBuilder2<S0, S1, T>(S0 arg0, S1 arg1);
+
+/**
+ * The type of a function which given an [R] returns an [AsserterBuilder] over
+ * [S]s and [T]s. That is, it returns a function which given an [S], returns
+ * a function over [T]s.
+ */
+typedef AsserterBuilder<S, T> AsserterBuilderBuilder<R, S, T>(R arg);
+
+class AstFinder {
+ /**
+ * Return the declaration of the class with the given [className] in the given
+ * compilation [unit].
+ */
+ static ClassDeclaration getClass(CompilationUnit unit, String className) {
+ NodeList<CompilationUnitMember> unitMembers = unit.declarations;
+ for (CompilationUnitMember unitMember in unitMembers) {
+ if (unitMember is ClassDeclaration && unitMember.name.name == className) {
+ return unitMember;
+ }
+ }
+ fail('No class named $className in ${unit.element.source}');
+ return null;
+ }
+
+ /**
+ * Return the declaration of the constructor with the given [constructorName] in
+ * the class with the given [className] in the given compilation [unit]. If
+ * constructorName is null, return the default constructor;
+ */
+ static ConstructorDeclaration getConstructorInClass(
+ CompilationUnit unit, String className, String constructorName) {
+ ClassDeclaration unitMember = getClass(unit, className);
+ NodeList<ClassMember> classMembers = unitMember.members;
+ for (ClassMember classMember in classMembers) {
+ if (classMember is ConstructorDeclaration) {
+ if (classMember.name?.name == constructorName) {
+ return classMember;
+ }
+ }
+ }
+ fail('No constructor named $constructorName in $className');
+ return null;
+ }
+
+ /**
+ * Return the declaration of the field with the given [fieldName] in the class
+ * with the given [className] in the given compilation [unit].
+ */
+ static VariableDeclaration getFieldInClass(
+ CompilationUnit unit, String className, String fieldName) {
+ ClassDeclaration unitMember = getClass(unit, className);
+ NodeList<ClassMember> classMembers = unitMember.members;
+ for (ClassMember classMember in classMembers) {
+ if (classMember is FieldDeclaration) {
+ NodeList<VariableDeclaration> fields = classMember.fields.variables;
+ for (VariableDeclaration field in fields) {
+ if (field.name.name == fieldName) {
+ return field;
+ }
+ }
+ }
+ }
+ fail('No field named $fieldName in $className');
+ return null;
+ }
+
+ /**
+ * Return the element of the field with the given [fieldName] in the class
+ * with the given [className] in the given compilation [unit].
+ */
+ static FieldElement getFieldInClassElement(
+ CompilationUnit unit, String className, String fieldName) {
+ return getFieldInClass(unit, className, fieldName)?.name?.staticElement;
+ }
+
+ /**
+ * Return the declaration of the method with the given [methodName] in the
+ * class with the given [className] in the given compilation [unit].
+ */
+ static MethodDeclaration getMethodInClass(
+ CompilationUnit unit, String className, String methodName) {
+ ClassDeclaration unitMember = getClass(unit, className);
+ NodeList<ClassMember> classMembers = unitMember.members;
+ for (ClassMember classMember in classMembers) {
+ if (classMember is MethodDeclaration) {
+ if (classMember.name.name == methodName) {
+ return classMember;
+ }
+ }
+ }
+ fail('No method named $methodName in $className');
+ return null;
+ }
+
+ /**
+ * Return the statements in the body of a the method with the given
+ * [methodName] in the class with the given [className] in the given
+ * compilation [unit].
+ */
+ static List<Statement> getStatementsInMethod(
+ CompilationUnit unit, String className, String methodName) {
+ MethodDeclaration method = getMethodInClass(unit, className, methodName);
+ BlockFunctionBody body = method.body;
+ return body.block.statements;
+ }
+
+ /**
+ * Return the statements in the body of the top-level function with the given
+ * [functionName] in the given compilation [unit].
+ */
+ static List<Statement> getStatementsInTopLevelFunction(
+ CompilationUnit unit, String functionName) {
+ FunctionDeclaration function = getTopLevelFunction(unit, functionName);
+ BlockFunctionBody body = function.functionExpression.body;
+ return body.block.statements;
+ }
+
+ /**
+ * Return the declaration of the top-level function with the given
+ * [functionName] in the given compilation [unit].
+ */
+ static FunctionDeclaration getTopLevelFunction(
+ CompilationUnit unit, String functionName) {
+ NodeList<CompilationUnitMember> unitMembers = unit.declarations;
+ for (CompilationUnitMember unitMember in unitMembers) {
+ if (unitMember is FunctionDeclaration) {
+ if (unitMember.name.name == functionName) {
+ return unitMember;
+ }
+ }
+ }
+ fail('No toplevel function named $functionName found');
+ return null;
+ }
+
+ /**
+ * Return the declaration of the top-level variable with the given
+ * [variableName] in the given compilation [unit].
+ */
+ static VariableDeclaration getTopLevelVariable(
+ CompilationUnit unit, String variableName) {
+ NodeList<CompilationUnitMember> unitMembers = unit.declarations;
+ for (CompilationUnitMember unitMember in unitMembers) {
+ if (unitMember is TopLevelVariableDeclaration) {
+ NodeList<VariableDeclaration> variables =
+ unitMember.variables.variables;
+ for (VariableDeclaration variable in variables) {
+ if (variable.name.name == variableName) {
+ return variable;
+ }
+ }
+ }
+ }
+ fail('No toplevel variable named $variableName found');
+ return null;
+ }
+
+ /**
+ * Return the top-level variable element with the given [name].
+ */
+ static TopLevelVariableElement getTopLevelVariableElement(
+ CompilationUnit unit, String name) {
+ return getTopLevelVariable(unit, name)?.name?.staticElement;
+ }
+}
+
+/**
+ * Class for compositionally building up assertions on types
+ */
+class TypeAssertions {
+ // TODO(leafp): Make these matchers.
+ // https://www.dartdocs.org/documentation/matcher/0.12.0%2B1/matcher/Matcher-class.html
+
+ /* Provides primitive types for basic type assertions */
+ final TypeProvider _typeProvider;
+
+ TypeAssertions(this._typeProvider);
+
+ /**
+ * Primitive assertion for the dynamic type
+ */
+ Asserter<DartType> get isDynamic => isType(_typeProvider.dynamicType);
+
+ /**
+ * Primitive assertion for the int type
+ */
+ Asserter<DartType> get isInt => isType(_typeProvider.intType);
+
+ /**
+ * Primitive assertion for the list type
+ */
+ Asserter<DartType> get isList => sameElement(_typeProvider.listType);
+
+ /**
+ * Primitive assertion for the map type
+ */
+ Asserter<DartType> get isMap => sameElement(_typeProvider.mapType);
+
+ /**
+ * Primitive assertion for the num type
+ */
+ Asserter<DartType> get isNum => isType(_typeProvider.numType);
+
+ /**
+ * Primitive assertion for the string type
+ */
+ Asserter<DartType> get isString => isType(_typeProvider.stringType);
+
+ /**
+ * Given a type, produce an assertion that a type has the same element.
+ */
+ Asserter<DartType> hasElement(Element element) =>
+ (DartType type) => expect(element, same(type.element));
+
+ /**
+ * Given assertions for the argument and return types, produce an
+ * assertion over unary function types.
+ */
+ Asserter<DartType> isFunction2Of(
+ Asserter<DartType> argType, Asserter<DartType> returnType) =>
+ (DartType type) {
+ FunctionType fType = (type as FunctionType);
+ argType(fType.normalParameterTypes[0]);
+ returnType(fType.returnType);
+ };
+
+ /**
+ * Given an assertion for the base type and assertions over the type
+ * parameters, produce an assertion over instantations.
+ */
+ AsserterBuilder<List<Asserter<DartType>>, DartType> isInstantiationOf(
+ Asserter<DartType> baseAssert) =>
+ (List<Asserter<DartType>> argAsserts) => (DartType type) {
+ InterfaceType t = (type as InterfaceType);
+ baseAssert(t);
+ List<DartType> typeArguments = t.typeArguments;
+ expect(typeArguments, hasLength(argAsserts.length));
+ for (int i = 0; i < typeArguments.length; i++) {
+ argAsserts[i](typeArguments[i]);
+ }
+ };
+
+ /**
+ * Assert that a type is the List type, and that the given assertion holds
+ * over the type parameter.
+ */
+ Asserter<InterfaceType> isListOf(Asserter<DartType> argAssert) =>
+ isInstantiationOf(isList)([argAssert]);
+
+ /**
+ * Assert that a type is the Map type, and that the given assertions hold
+ * over the type parameters.
+ */
+ Asserter<InterfaceType> isMapOf(
+ Asserter<DartType> argAssert0, Asserter<DartType> argAssert1) =>
+ isInstantiationOf(isMap)([argAssert0, argAssert1]);
+
+ /**
+ * Assert that one type is the same as another
+ */
+ Asserter<DartType> isType(DartType argument) => (DartType t) {
+ expect(t, same(argument));
+ };
+
+ /**
+ * Given a type, produce an assertion that a type has the same element.
+ */
+ Asserter<DartType> sameElement(DartType elementType) =>
+ hasElement(elementType.element);
+}

Powered by Google App Engine
This is Rietveld 408576698