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

Side by Side 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library analyzer.test.utils; 5 library analyzer.test.utils;
6 6
7 import 'package:analyzer/src/generated/ast.dart';
8 import 'package:analyzer/src/generated/element.dart';
7 import 'package:analyzer/src/generated/java_io.dart'; 9 import 'package:analyzer/src/generated/java_io.dart';
10 import 'package:analyzer/src/generated/resolver.dart' show TypeProvider;
8 import 'package:path/path.dart' as path; 11 import 'package:path/path.dart' as path;
9 import 'package:unittest/unittest.dart'; 12 import 'package:unittest/unittest.dart';
10 13
11 void initializeTestEnvironment() { 14 void initializeTestEnvironment() {
12 groupSep = ' | '; 15 groupSep = ' | ';
13 JavaFile.pathContext = path.posix; 16 JavaFile.pathContext = path.posix;
14 } 17 }
18
19 /**
20 * The type of an assertion which asserts properties of [T]s.
21 */
22 typedef void Asserter<T>(T type);
23
24 /**
25 * The type of a function which given an [S], builds an assertion over [T]s.
26 */
27 typedef Asserter<T> AsserterBuilder<S, T>(S arg);
28
29 /**
30 * The type of a function which given an [S0] and an S1, builds an assertion
31 * over [T]s.
32 */
33 typedef Asserter<T> AsserterBuilder2<S0, S1, T>(S0 arg0, S1 arg1);
34
35 /**
36 * The type of a function which given an [R] returns an [AsserterBuilder] over
37 * [S]s and [T]s. That is, it returns a function which given an [S], returns
38 * a function over [T]s.
39 */
40 typedef AsserterBuilder<S, T> AsserterBuilderBuilder<R, S, T>(R arg);
41
42 class AstFinder {
43 /**
44 * Return the declaration of the class with the given [className] in the given
45 * compilation [unit].
46 */
47 static ClassDeclaration getClass(CompilationUnit unit, String className) {
48 NodeList<CompilationUnitMember> unitMembers = unit.declarations;
49 for (CompilationUnitMember unitMember in unitMembers) {
50 if (unitMember is ClassDeclaration && unitMember.name.name == className) {
51 return unitMember;
52 }
53 }
54 fail('No class named $className in ${unit.element.source}');
55 return null;
56 }
57
58 /**
59 * Return the declaration of the constructor with the given [constructorName] in
60 * the class with the given [className] in the given compilation [unit]. If
61 * constructorName is null, return the default constructor;
62 */
63 static ConstructorDeclaration getConstructorInClass(
64 CompilationUnit unit, String className, String constructorName) {
65 ClassDeclaration unitMember = getClass(unit, className);
66 NodeList<ClassMember> classMembers = unitMember.members;
67 for (ClassMember classMember in classMembers) {
68 if (classMember is ConstructorDeclaration) {
69 if (classMember.name?.name == constructorName) {
70 return classMember;
71 }
72 }
73 }
74 fail('No constructor named $constructorName in $className');
75 return null;
76 }
77
78 /**
79 * Return the declaration of the field with the given [fieldName] in the class
80 * with the given [className] in the given compilation [unit].
81 */
82 static VariableDeclaration getFieldInClass(
83 CompilationUnit unit, String className, String fieldName) {
84 ClassDeclaration unitMember = getClass(unit, className);
85 NodeList<ClassMember> classMembers = unitMember.members;
86 for (ClassMember classMember in classMembers) {
87 if (classMember is FieldDeclaration) {
88 NodeList<VariableDeclaration> fields = classMember.fields.variables;
89 for (VariableDeclaration field in fields) {
90 if (field.name.name == fieldName) {
91 return field;
92 }
93 }
94 }
95 }
96 fail('No field named $fieldName in $className');
97 return null;
98 }
99
100 /**
101 * Return the element of the field with the given [fieldName] in the class
102 * with the given [className] in the given compilation [unit].
103 */
104 static FieldElement getFieldInClassElement(
105 CompilationUnit unit, String className, String fieldName) {
106 return getFieldInClass(unit, className, fieldName)?.name?.staticElement;
107 }
108
109 /**
110 * Return the declaration of the method with the given [methodName] in the
111 * class with the given [className] in the given compilation [unit].
112 */
113 static MethodDeclaration getMethodInClass(
114 CompilationUnit unit, String className, String methodName) {
115 ClassDeclaration unitMember = getClass(unit, className);
116 NodeList<ClassMember> classMembers = unitMember.members;
117 for (ClassMember classMember in classMembers) {
118 if (classMember is MethodDeclaration) {
119 if (classMember.name.name == methodName) {
120 return classMember;
121 }
122 }
123 }
124 fail('No method named $methodName in $className');
125 return null;
126 }
127
128 /**
129 * Return the statements in the body of a the method with the given
130 * [methodName] in the class with the given [className] in the given
131 * compilation [unit].
132 */
133 static List<Statement> getStatementsInMethod(
134 CompilationUnit unit, String className, String methodName) {
135 MethodDeclaration method = getMethodInClass(unit, className, methodName);
136 BlockFunctionBody body = method.body;
137 return body.block.statements;
138 }
139
140 /**
141 * Return the statements in the body of the top-level function with the given
142 * [functionName] in the given compilation [unit].
143 */
144 static List<Statement> getStatementsInTopLevelFunction(
145 CompilationUnit unit, String functionName) {
146 FunctionDeclaration function = getTopLevelFunction(unit, functionName);
147 BlockFunctionBody body = function.functionExpression.body;
148 return body.block.statements;
149 }
150
151 /**
152 * Return the declaration of the top-level function with the given
153 * [functionName] in the given compilation [unit].
154 */
155 static FunctionDeclaration getTopLevelFunction(
156 CompilationUnit unit, String functionName) {
157 NodeList<CompilationUnitMember> unitMembers = unit.declarations;
158 for (CompilationUnitMember unitMember in unitMembers) {
159 if (unitMember is FunctionDeclaration) {
160 if (unitMember.name.name == functionName) {
161 return unitMember;
162 }
163 }
164 }
165 fail('No toplevel function named $functionName found');
166 return null;
167 }
168
169 /**
170 * Return the declaration of the top-level variable with the given
171 * [variableName] in the given compilation [unit].
172 */
173 static VariableDeclaration getTopLevelVariable(
174 CompilationUnit unit, String variableName) {
175 NodeList<CompilationUnitMember> unitMembers = unit.declarations;
176 for (CompilationUnitMember unitMember in unitMembers) {
177 if (unitMember is TopLevelVariableDeclaration) {
178 NodeList<VariableDeclaration> variables =
179 unitMember.variables.variables;
180 for (VariableDeclaration variable in variables) {
181 if (variable.name.name == variableName) {
182 return variable;
183 }
184 }
185 }
186 }
187 fail('No toplevel variable named $variableName found');
188 return null;
189 }
190
191 /**
192 * Return the top-level variable element with the given [name].
193 */
194 static TopLevelVariableElement getTopLevelVariableElement(
195 CompilationUnit unit, String name) {
196 return getTopLevelVariable(unit, name)?.name?.staticElement;
197 }
198 }
199
200 /**
201 * Class for compositionally building up assertions on types
202 */
203 class TypeAssertions {
204 // TODO(leafp): Make these matchers.
205 // https://www.dartdocs.org/documentation/matcher/0.12.0%2B1/matcher/Matcher-c lass.html
206
207 /* Provides primitive types for basic type assertions */
208 final TypeProvider _typeProvider;
209
210 TypeAssertions(this._typeProvider);
211
212 /**
213 * Primitive assertion for the dynamic type
214 */
215 Asserter<DartType> get isDynamic => isType(_typeProvider.dynamicType);
216
217 /**
218 * Primitive assertion for the int type
219 */
220 Asserter<DartType> get isInt => isType(_typeProvider.intType);
221
222 /**
223 * Primitive assertion for the list type
224 */
225 Asserter<DartType> get isList => sameElement(_typeProvider.listType);
226
227 /**
228 * Primitive assertion for the map type
229 */
230 Asserter<DartType> get isMap => sameElement(_typeProvider.mapType);
231
232 /**
233 * Primitive assertion for the num type
234 */
235 Asserter<DartType> get isNum => isType(_typeProvider.numType);
236
237 /**
238 * Primitive assertion for the string type
239 */
240 Asserter<DartType> get isString => isType(_typeProvider.stringType);
241
242 /**
243 * Given a type, produce an assertion that a type has the same element.
244 */
245 Asserter<DartType> hasElement(Element element) =>
246 (DartType type) => expect(element, same(type.element));
247
248 /**
249 * Given assertions for the argument and return types, produce an
250 * assertion over unary function types.
251 */
252 Asserter<DartType> isFunction2Of(
253 Asserter<DartType> argType, Asserter<DartType> returnType) =>
254 (DartType type) {
255 FunctionType fType = (type as FunctionType);
256 argType(fType.normalParameterTypes[0]);
257 returnType(fType.returnType);
258 };
259
260 /**
261 * Given an assertion for the base type and assertions over the type
262 * parameters, produce an assertion over instantations.
263 */
264 AsserterBuilder<List<Asserter<DartType>>, DartType> isInstantiationOf(
265 Asserter<DartType> baseAssert) =>
266 (List<Asserter<DartType>> argAsserts) => (DartType type) {
267 InterfaceType t = (type as InterfaceType);
268 baseAssert(t);
269 List<DartType> typeArguments = t.typeArguments;
270 expect(typeArguments, hasLength(argAsserts.length));
271 for (int i = 0; i < typeArguments.length; i++) {
272 argAsserts[i](typeArguments[i]);
273 }
274 };
275
276 /**
277 * Assert that a type is the List type, and that the given assertion holds
278 * over the type parameter.
279 */
280 Asserter<InterfaceType> isListOf(Asserter<DartType> argAssert) =>
281 isInstantiationOf(isList)([argAssert]);
282
283 /**
284 * Assert that a type is the Map type, and that the given assertions hold
285 * over the type parameters.
286 */
287 Asserter<InterfaceType> isMapOf(
288 Asserter<DartType> argAssert0, Asserter<DartType> argAssert1) =>
289 isInstantiationOf(isMap)([argAssert0, argAssert1]);
290
291 /**
292 * Assert that one type is the same as another
293 */
294 Asserter<DartType> isType(DartType argument) => (DartType t) {
295 expect(t, same(argument));
296 };
297
298 /**
299 * Given a type, produce an assertion that a type has the same element.
300 */
301 Asserter<DartType> sameElement(DartType elementType) =>
302 hasElement(elementType.element);
303 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698