Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 /** The type of an assertion which asserts properties of [T]s. | |
| 20 */ | |
| 21 typedef void Asserter<T>(T type); | |
| 22 | |
| 23 /** The type of a function which given an [S], builds an assertion over [T]s. | |
| 24 */ | |
| 25 typedef Asserter<T> AsserterBuilder<S, T>(S arg); | |
| 26 | |
| 27 /** The type of a function which given an [S0] and an S1, builds an assertion ov er [T]s. | |
|
Jennifer Messerly
2015/11/23 22:11:58
long line (& a few below)
unfortunately dartfmt w
Leaf
2015/12/01 21:49:12
Done.
| |
| 28 */ | |
| 29 typedef Asserter<T> AsserterBuilder2<S0, S1, T>(S0 arg0, S1 arg1); | |
| 30 | |
| 31 /** The type of a function which given an [R] returns an [AsserterBuilder] over | |
| 32 * [S]s and [T]s. That is, it returns a function which given an [S], returns | |
| 33 * a function over [T]s. | |
| 34 */ | |
| 35 typedef AsserterBuilder<S, T> AsserterBuilderBuilder<R, S, T>(R arg); | |
| 36 | |
| 37 class AstFinder { | |
|
scheglov
2015/11/21 06:31:35
Could you please move the methods of AstFinder int
Brian Wilkerson
2015/11/21 16:12:22
I'm not a fan of top-level functions; I'd actually
Leaf
2015/11/24 19:32:12
Hmm, I was really annoyed that moving these from l
Brian Wilkerson
2015/11/24 21:17:57
It isn't my favorite solution, but I'm not going t
Leaf
2015/12/01 21:49:12
Ok, leaving as is for now.
| |
| 38 /** | |
| 39 * Return the declaration of the class with the given [className] in the given | |
| 40 * compilation [unit]. | |
| 41 */ | |
| 42 static ClassDeclaration getClass(CompilationUnit unit, String className) { | |
| 43 NodeList<CompilationUnitMember> unitMembers = unit.declarations; | |
| 44 for (CompilationUnitMember unitMember in unitMembers) { | |
| 45 if (unitMember is ClassDeclaration && unitMember.name.name == className) { | |
| 46 return unitMember; | |
| 47 } | |
| 48 } | |
| 49 fail('No class named $className in ${unit.element.source}'); | |
| 50 return null; | |
| 51 } | |
| 52 | |
| 53 /** | |
| 54 * Return the declaration of the constructor with the given [constructorName] in | |
| 55 * the class with the given [className] in the given compilation [unit]. If | |
| 56 * constructorName is null, return the default constructor; | |
| 57 */ | |
| 58 static ConstructorDeclaration getConstructorInClass( | |
| 59 CompilationUnit unit, String className, String constructorName) { | |
| 60 ClassDeclaration unitMember = getClass(unit, className); | |
| 61 NodeList<ClassMember> classMembers = unitMember.members; | |
| 62 for (ClassMember classMember in classMembers) { | |
| 63 if (classMember is ConstructorDeclaration) { | |
| 64 if (classMember.name?.name == constructorName) { | |
| 65 return classMember; | |
| 66 } | |
| 67 } | |
| 68 } | |
| 69 fail('No constructor named $constructorName in $className'); | |
| 70 return null; | |
| 71 } | |
| 72 | |
| 73 /** | |
| 74 * Return the declaration of the field with the given [fieldName] in the class | |
| 75 * with the given [className] in the given compilation [unit]. | |
| 76 */ | |
| 77 static VariableDeclaration getFieldInClass( | |
| 78 CompilationUnit unit, String className, String fieldName) { | |
| 79 ClassDeclaration unitMember = getClass(unit, className); | |
| 80 NodeList<ClassMember> classMembers = unitMember.members; | |
| 81 for (ClassMember classMember in classMembers) { | |
| 82 if (classMember is FieldDeclaration) { | |
| 83 NodeList<VariableDeclaration> fields = classMember.fields.variables; | |
| 84 for (VariableDeclaration field in fields) { | |
| 85 if (field.name.name == fieldName) { | |
| 86 return field; | |
| 87 } | |
| 88 } | |
| 89 } | |
| 90 } | |
| 91 fail('No field named $fieldName in $className'); | |
| 92 return null; | |
| 93 } | |
| 94 | |
| 95 /** | |
| 96 * Return the declaration of the method with the given [methodName] in the | |
| 97 * class with the given [className] in the given compilation [unit]. | |
| 98 */ | |
| 99 static MethodDeclaration getMethodInClass( | |
| 100 CompilationUnit unit, String className, String methodName) { | |
| 101 ClassDeclaration unitMember = getClass(unit, className); | |
| 102 NodeList<ClassMember> classMembers = unitMember.members; | |
| 103 for (ClassMember classMember in classMembers) { | |
| 104 if (classMember is MethodDeclaration) { | |
| 105 if (classMember.name.name == methodName) { | |
| 106 return classMember; | |
| 107 } | |
| 108 } | |
| 109 } | |
| 110 fail('No method named $methodName in $className'); | |
| 111 return null; | |
| 112 } | |
| 113 | |
| 114 /** | |
| 115 * Return the statements in the body of a the method with the given | |
| 116 * [methodName] in the class with the given [className] in the given | |
| 117 * compilation [unit]. | |
| 118 */ | |
| 119 static List<Statement> getStatementsInMethod( | |
| 120 CompilationUnit unit, String className, String methodName) { | |
| 121 MethodDeclaration method = getMethodInClass(unit, className, methodName); | |
| 122 BlockFunctionBody body = method.body; | |
| 123 return body.block.statements; | |
| 124 } | |
| 125 | |
| 126 /** | |
| 127 * Return the statements in the body of the top-level function with the given | |
| 128 * [functionName] in the given compilation [unit]. | |
| 129 */ | |
| 130 static List<Statement> getStatementsInTopLevelFunction( | |
| 131 CompilationUnit unit, String functionName) { | |
| 132 FunctionDeclaration function = getTopLevelFunction(unit, functionName); | |
| 133 BlockFunctionBody body = function.functionExpression.body; | |
| 134 return body.block.statements; | |
| 135 } | |
| 136 | |
| 137 /** | |
| 138 * Return the declaration of the top-level function with the given | |
| 139 * [functionName] in the given compilation [unit]. | |
| 140 */ | |
| 141 static FunctionDeclaration getTopLevelFunction( | |
| 142 CompilationUnit unit, String functionName) { | |
| 143 NodeList<CompilationUnitMember> unitMembers = unit.declarations; | |
| 144 for (CompilationUnitMember unitMember in unitMembers) { | |
| 145 if (unitMember is FunctionDeclaration) { | |
| 146 if (unitMember.name.name == functionName) { | |
| 147 return unitMember; | |
| 148 } | |
| 149 } | |
| 150 } | |
| 151 fail('No toplevel function named $functionName found'); | |
| 152 return null; | |
| 153 } | |
| 154 | |
| 155 /** | |
| 156 * Return the declaration of the top-level variable with the given | |
| 157 * [variableName] in the given compilation [unit]. | |
| 158 */ | |
| 159 static VariableDeclaration getTopLevelVariable( | |
| 160 CompilationUnit unit, String variableName) { | |
| 161 NodeList<CompilationUnitMember> unitMembers = unit.declarations; | |
| 162 for (CompilationUnitMember unitMember in unitMembers) { | |
| 163 if (unitMember is TopLevelVariableDeclaration) { | |
| 164 NodeList<VariableDeclaration> variables = | |
| 165 unitMember.variables.variables; | |
| 166 for (VariableDeclaration variable in variables) { | |
| 167 if (variable.name.name == variableName) { | |
| 168 return variable; | |
| 169 } | |
| 170 } | |
| 171 } | |
| 172 } | |
| 173 fail('No toplevel variable named $variableName found'); | |
| 174 return null; | |
| 175 } | |
| 176 } | |
| 177 | |
| 178 /** Class for compositionally building up assertions on types | |
| 179 */ | |
| 180 class TypeAssertions { | |
|
Jennifer Messerly
2015/11/23 22:11:58
note: it'd be slightly nicer to make these be Matc
Leaf
2015/12/01 21:49:12
Added TODO. Nice to know
| |
| 181 /* Provides primitive types for basic type assertions */ | |
| 182 final TypeProvider _typeProvider; | |
| 183 | |
| 184 TypeAssertions(this._typeProvider); | |
| 185 | |
| 186 /** Primitive assertion for the dynamic type */ | |
| 187 Asserter<DartType> get isDynamic => isType(_typeProvider.dynamicType); | |
| 188 | |
| 189 /** Primitive assertion for the int type */ | |
| 190 Asserter<DartType> get isInt => isType(_typeProvider.intType); | |
| 191 | |
| 192 /** Primitive assertion for the list type | |
| 193 */ | |
| 194 Asserter<DartType> get isList => sameElement(_typeProvider.listType); | |
| 195 | |
| 196 /** Primitive assertion for the map type | |
| 197 */ | |
| 198 Asserter<DartType> get isMap => sameElement(_typeProvider.mapType); | |
| 199 | |
| 200 /** Primitive assertion for the num type */ | |
| 201 Asserter<DartType> get isNum => isType(_typeProvider.numType); | |
| 202 | |
| 203 /** Primitive assertion for the string type */ | |
| 204 Asserter<DartType> get isString => isType(_typeProvider.stringType); | |
| 205 | |
| 206 /** Given a type, produce an assertion that a type has the same element. | |
| 207 */ | |
| 208 Asserter<DartType> hasElement(Element element) => | |
| 209 (DartType type) => expect(element, same(type.element)); | |
| 210 | |
| 211 /** Given assertions for the argument and return types, produce an | |
|
Brian Wilkerson
2015/11/21 16:12:22
Format the file?
Leaf
2015/12/01 21:49:12
Filed https://github.com/dart-lang/dart_style/issu
| |
| 212 * assertion over unary function types. | |
| 213 */ | |
| 214 Asserter<DartType> isFunction2Of( | |
| 215 Asserter<DartType> argType, Asserter<DartType> returnType) => | |
| 216 (DartType type) { | |
| 217 FunctionType fType = (type as FunctionType); | |
| 218 argType(fType.normalParameterTypes[0]); | |
| 219 returnType(fType.returnType); | |
| 220 }; | |
| 221 | |
| 222 /** Given an assertion for the base type and assertions over the type | |
| 223 * parameters, produce an assertion over instantations. | |
| 224 */ | |
| 225 AsserterBuilder<List<Asserter<DartType>>, DartType> isInstantiationOf( | |
| 226 Asserter<DartType> baseAssert) => | |
| 227 (List<Asserter<DartType>> argAsserts) => (DartType type) { | |
| 228 InterfaceType t = (type as InterfaceType); | |
| 229 baseAssert(t); | |
| 230 List<DartType> typeArguments = t.typeArguments; | |
| 231 expect(typeArguments, hasLength(argAsserts.length)); | |
| 232 for (int i = 0; i < typeArguments.length; i++) { | |
| 233 argAsserts[i](typeArguments[i]); | |
| 234 } | |
| 235 }; | |
| 236 | |
| 237 /** Assert that a type is the List type, and that the given assertion holds | |
| 238 * over the type parameter. | |
| 239 */ | |
| 240 Asserter<InterfaceType> isListOf(Asserter<DartType> argAssert) => | |
| 241 isInstantiationOf(isList)([argAssert]); | |
| 242 | |
| 243 /** Assert that a type is the Map type, and that the given assertions hold | |
| 244 * over the type parameters. | |
| 245 */ | |
| 246 Asserter<InterfaceType> isMapOf( | |
| 247 Asserter<DartType> argAssert0, Asserter<DartType> argAssert1) => | |
| 248 isInstantiationOf(isMap)([argAssert0, argAssert1]); | |
| 249 | |
| 250 /** Assert that one type is the same as another | |
| 251 */ | |
| 252 Asserter<DartType> isType(DartType argument) => (DartType t) { | |
| 253 expect(t, same(argument)); | |
| 254 }; | |
| 255 | |
| 256 /** Given a type, produce an assertion that a type has the same element. | |
| 257 */ | |
| 258 Asserter<DartType> sameElement(DartType elementType) => | |
| 259 hasElement(elementType.element); | |
| 260 } | |
| OLD | NEW |