| OLD | NEW |
| (Empty) | |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 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. |
| 4 |
| 5 library engine.incremental_resolver_test; |
| 6 |
| 7 import 'package:analyzer/src/generated/ast.dart'; |
| 8 import 'package:analyzer/src/generated/element.dart'; |
| 9 import 'package:analyzer/src/generated/engine.dart'; |
| 10 import 'package:analyzer/src/generated/incremental_resolver.dart'; |
| 11 import 'package:analyzer/src/generated/java_engine.dart'; |
| 12 import 'package:analyzer/src/generated/resolver.dart'; |
| 13 import 'package:analyzer/src/generated/source_io.dart'; |
| 14 import 'package:analyzer/src/generated/testing/ast_factory.dart'; |
| 15 import 'package:analyzer/src/generated/testing/element_factory.dart'; |
| 16 import 'package:unittest/unittest.dart'; |
| 17 |
| 18 import '../reflective_tests.dart'; |
| 19 import 'parser_test.dart'; |
| 20 import 'resolver_test.dart'; |
| 21 import 'test_support.dart'; |
| 22 |
| 23 |
| 24 main() { |
| 25 groupSep = ' | '; |
| 26 runReflectiveTests(ScopeBuilderTest); |
| 27 runReflectiveTests(DeclarationMatcherTest); |
| 28 runReflectiveTests(IncrementalResolverTest); |
| 29 } |
| 30 |
| 31 |
| 32 class DeclarationMatcherTest extends ResolverTestCase { |
| 33 void test_compilationUnitMatches_false_topLevelVariable() { |
| 34 _assertCompilationUnitMatches(false, r''' |
| 35 class C { |
| 36 int m(int p) { |
| 37 return p + p; |
| 38 } |
| 39 }''', r''' |
| 40 const int ZERO = 0; |
| 41 class C { |
| 42 int m(int p) { |
| 43 return p + p; |
| 44 } |
| 45 }'''); |
| 46 } |
| 47 |
| 48 void test_compilationUnitMatches_true_different() { |
| 49 _assertCompilationUnitMatches(true, r''' |
| 50 class C { |
| 51 int m(int p) { |
| 52 return p + p; |
| 53 } |
| 54 }''', r''' |
| 55 class C { |
| 56 int m(int p) { |
| 57 return (p * p) + (p * p); |
| 58 } |
| 59 }'''); |
| 60 } |
| 61 |
| 62 void test_compilationUnitMatches_true_same() { |
| 63 String content = r''' |
| 64 class C { |
| 65 int m(int p) { |
| 66 return p + p; |
| 67 } |
| 68 }'''; |
| 69 _assertCompilationUnitMatches(true, content, content); |
| 70 } |
| 71 |
| 72 void test_methodDeclarationMatches_false_localVariable() { |
| 73 _assertMethodMatches(false, r''' |
| 74 class C { |
| 75 int m(int p) { |
| 76 return p + p; |
| 77 } |
| 78 }''', r''' |
| 79 class C { |
| 80 int m(int p) { |
| 81 int product = p * p; |
| 82 return product + product; |
| 83 } |
| 84 }'''); |
| 85 } |
| 86 |
| 87 void test_methodDeclarationMatches_false_parameter() { |
| 88 _assertMethodMatches(false, r''' |
| 89 class C { |
| 90 int m(int p) { |
| 91 return p + p; |
| 92 } |
| 93 }''', r''' |
| 94 class C { |
| 95 int m(int p, int q) { |
| 96 return (p * q) + (q * p); |
| 97 } |
| 98 }'''); |
| 99 } |
| 100 |
| 101 void test_methodDeclarationMatches_true_different() { |
| 102 _assertMethodMatches(true, r''' |
| 103 class C { |
| 104 int m(int p) { |
| 105 return p + p; |
| 106 } |
| 107 }''', r''' |
| 108 class C { |
| 109 int m(int p) { |
| 110 return (p * p) + (p * p); |
| 111 } |
| 112 }'''); |
| 113 } |
| 114 |
| 115 void test_methodDeclarationMatches_true_same() { |
| 116 String content = r''' |
| 117 class C { |
| 118 int m(int p) { |
| 119 return p + p; |
| 120 } |
| 121 }'''; |
| 122 _assertMethodMatches(true, content, content); |
| 123 } |
| 124 |
| 125 void _assertCompilationUnitMatches(bool expectMatch, String oldContent, |
| 126 String newContent) { |
| 127 Source source = addSource(oldContent); |
| 128 LibraryElement library = resolve(source); |
| 129 CompilationUnit oldUnit = resolveCompilationUnit(source, library); |
| 130 CompilationUnit newUnit = ParserTestCase.parseCompilationUnit(newContent); |
| 131 DeclarationMatcher matcher = new DeclarationMatcher(); |
| 132 expect(matcher.matches(newUnit, oldUnit.element), expectMatch); |
| 133 } |
| 134 |
| 135 void _assertMethodMatches(bool expectMatch, String oldContent, |
| 136 String newContent) { |
| 137 Source source = addSource(oldContent); |
| 138 LibraryElement library = resolve(source); |
| 139 CompilationUnit oldUnit = resolveCompilationUnit(source, library); |
| 140 MethodElement element = _getFirstMethod(oldUnit).element as MethodElement; |
| 141 AnalysisContext context = analysisContext; |
| 142 context.setContents(source, newContent); |
| 143 CompilationUnit newUnit = context.parseCompilationUnit(source); |
| 144 MethodDeclaration newMethod = _getFirstMethod(newUnit); |
| 145 DeclarationMatcher matcher = new DeclarationMatcher(); |
| 146 expect(matcher.matches(newMethod, element), expectMatch); |
| 147 } |
| 148 |
| 149 MethodDeclaration _getFirstMethod(CompilationUnit unit) { |
| 150 ClassDeclaration classNode = unit.declarations[0] as ClassDeclaration; |
| 151 return classNode.members[0] as MethodDeclaration; |
| 152 } |
| 153 } |
| 154 |
| 155 class IncrementalResolverTest extends ResolverTestCase { |
| 156 void test_resolve() { |
| 157 MethodDeclaration method = _resolveMethod(r''' |
| 158 class C { |
| 159 int m(int a) { |
| 160 return a + a; |
| 161 } |
| 162 }'''); |
| 163 BlockFunctionBody body = method.body as BlockFunctionBody; |
| 164 ReturnStatement statement = body.block.statements[0] as ReturnStatement; |
| 165 BinaryExpression expression = statement.expression as BinaryExpression; |
| 166 SimpleIdentifier left = expression.leftOperand as SimpleIdentifier; |
| 167 Element leftElement = left.staticElement; |
| 168 SimpleIdentifier right = expression.rightOperand as SimpleIdentifier; |
| 169 Element rightElement = right.staticElement; |
| 170 expect(leftElement, isNotNull); |
| 171 expect(rightElement, same(leftElement)); |
| 172 } |
| 173 |
| 174 MethodDeclaration _resolveMethod(String content) { |
| 175 Source source = addSource(content); |
| 176 LibraryElement library = resolve(source); |
| 177 CompilationUnit unit = resolveCompilationUnit(source, library); |
| 178 ClassDeclaration classNode = unit.declarations[0] as ClassDeclaration; |
| 179 MethodDeclaration method = classNode.members[0] as MethodDeclaration; |
| 180 method.body.accept(new ResolutionEraser()); |
| 181 GatheringErrorListener errorListener = new GatheringErrorListener(); |
| 182 IncrementalResolver resolver = |
| 183 new IncrementalResolver(library, source, typeProvider, errorListener); |
| 184 resolver.resolve(method.body); |
| 185 return method; |
| 186 } |
| 187 } |
| 188 |
| 189 class ScopeBuilderTest extends EngineTestCase { |
| 190 void test_scopeFor_ClassDeclaration() { |
| 191 GatheringErrorListener listener = new GatheringErrorListener(); |
| 192 Scope scope = |
| 193 ScopeBuilder.scopeFor(_createResolvedClassDeclaration(), listener); |
| 194 EngineTestCase.assertInstanceOf( |
| 195 (obj) => obj is LibraryScope, |
| 196 LibraryScope, |
| 197 scope); |
| 198 } |
| 199 |
| 200 void test_scopeFor_ClassTypeAlias() { |
| 201 GatheringErrorListener listener = new GatheringErrorListener(); |
| 202 Scope scope = |
| 203 ScopeBuilder.scopeFor(_createResolvedClassTypeAlias(), listener); |
| 204 EngineTestCase.assertInstanceOf( |
| 205 (obj) => obj is LibraryScope, |
| 206 LibraryScope, |
| 207 scope); |
| 208 } |
| 209 |
| 210 void test_scopeFor_CompilationUnit() { |
| 211 GatheringErrorListener listener = new GatheringErrorListener(); |
| 212 Scope scope = |
| 213 ScopeBuilder.scopeFor(_createResolvedCompilationUnit(), listener); |
| 214 EngineTestCase.assertInstanceOf( |
| 215 (obj) => obj is LibraryScope, |
| 216 LibraryScope, |
| 217 scope); |
| 218 } |
| 219 |
| 220 void test_scopeFor_ConstructorDeclaration() { |
| 221 GatheringErrorListener listener = new GatheringErrorListener(); |
| 222 Scope scope = |
| 223 ScopeBuilder.scopeFor(_createResolvedConstructorDeclaration(), listener)
; |
| 224 EngineTestCase.assertInstanceOf( |
| 225 (obj) => obj is ClassScope, |
| 226 ClassScope, |
| 227 scope); |
| 228 } |
| 229 |
| 230 void test_scopeFor_ConstructorDeclaration_parameters() { |
| 231 GatheringErrorListener listener = new GatheringErrorListener(); |
| 232 Scope scope = ScopeBuilder.scopeFor( |
| 233 _createResolvedConstructorDeclaration().parameters, |
| 234 listener); |
| 235 EngineTestCase.assertInstanceOf( |
| 236 (obj) => obj is FunctionScope, |
| 237 FunctionScope, |
| 238 scope); |
| 239 } |
| 240 |
| 241 void test_scopeFor_FunctionDeclaration() { |
| 242 GatheringErrorListener listener = new GatheringErrorListener(); |
| 243 Scope scope = |
| 244 ScopeBuilder.scopeFor(_createResolvedFunctionDeclaration(), listener); |
| 245 EngineTestCase.assertInstanceOf( |
| 246 (obj) => obj is LibraryScope, |
| 247 LibraryScope, |
| 248 scope); |
| 249 } |
| 250 |
| 251 void test_scopeFor_FunctionDeclaration_parameters() { |
| 252 GatheringErrorListener listener = new GatheringErrorListener(); |
| 253 Scope scope = ScopeBuilder.scopeFor( |
| 254 _createResolvedFunctionDeclaration().functionExpression.parameters, |
| 255 listener); |
| 256 EngineTestCase.assertInstanceOf( |
| 257 (obj) => obj is FunctionScope, |
| 258 FunctionScope, |
| 259 scope); |
| 260 } |
| 261 |
| 262 void test_scopeFor_FunctionTypeAlias() { |
| 263 GatheringErrorListener listener = new GatheringErrorListener(); |
| 264 Scope scope = |
| 265 ScopeBuilder.scopeFor(_createResolvedFunctionTypeAlias(), listener); |
| 266 EngineTestCase.assertInstanceOf( |
| 267 (obj) => obj is LibraryScope, |
| 268 LibraryScope, |
| 269 scope); |
| 270 } |
| 271 |
| 272 void test_scopeFor_FunctionTypeAlias_parameters() { |
| 273 GatheringErrorListener listener = new GatheringErrorListener(); |
| 274 Scope scope = |
| 275 ScopeBuilder.scopeFor(_createResolvedFunctionTypeAlias().parameters, lis
tener); |
| 276 EngineTestCase.assertInstanceOf( |
| 277 (obj) => obj is FunctionTypeScope, |
| 278 FunctionTypeScope, |
| 279 scope); |
| 280 } |
| 281 |
| 282 void test_scopeFor_MethodDeclaration() { |
| 283 GatheringErrorListener listener = new GatheringErrorListener(); |
| 284 Scope scope = |
| 285 ScopeBuilder.scopeFor(_createResolvedMethodDeclaration(), listener); |
| 286 EngineTestCase.assertInstanceOf( |
| 287 (obj) => obj is ClassScope, |
| 288 ClassScope, |
| 289 scope); |
| 290 } |
| 291 |
| 292 void test_scopeFor_MethodDeclaration_body() { |
| 293 GatheringErrorListener listener = new GatheringErrorListener(); |
| 294 Scope scope = |
| 295 ScopeBuilder.scopeFor(_createResolvedMethodDeclaration().body, listener)
; |
| 296 EngineTestCase.assertInstanceOf( |
| 297 (obj) => obj is FunctionScope, |
| 298 FunctionScope, |
| 299 scope); |
| 300 } |
| 301 |
| 302 void test_scopeFor_notInCompilationUnit() { |
| 303 GatheringErrorListener listener = new GatheringErrorListener(); |
| 304 try { |
| 305 ScopeBuilder.scopeFor(AstFactory.identifier3("x"), listener); |
| 306 fail("Expected AnalysisException"); |
| 307 } on AnalysisException catch (exception) { |
| 308 // Expected |
| 309 } |
| 310 } |
| 311 |
| 312 void test_scopeFor_null() { |
| 313 GatheringErrorListener listener = new GatheringErrorListener(); |
| 314 try { |
| 315 ScopeBuilder.scopeFor(null, listener); |
| 316 fail("Expected AnalysisException"); |
| 317 } on AnalysisException catch (exception) { |
| 318 // Expected |
| 319 } |
| 320 } |
| 321 |
| 322 void test_scopeFor_unresolved() { |
| 323 GatheringErrorListener listener = new GatheringErrorListener(); |
| 324 try { |
| 325 ScopeBuilder.scopeFor(AstFactory.compilationUnit(), listener); |
| 326 fail("Expected AnalysisException"); |
| 327 } on AnalysisException catch (exception) { |
| 328 // Expected |
| 329 } |
| 330 } |
| 331 |
| 332 ClassDeclaration _createResolvedClassDeclaration() { |
| 333 CompilationUnit unit = _createResolvedCompilationUnit(); |
| 334 String className = "C"; |
| 335 ClassDeclaration classNode = AstFactory.classDeclaration( |
| 336 null, |
| 337 className, |
| 338 AstFactory.typeParameterList(), |
| 339 null, |
| 340 null, |
| 341 null); |
| 342 unit.declarations.add(classNode); |
| 343 ClassElement classElement = ElementFactory.classElement2(className); |
| 344 classNode.name.staticElement = classElement; |
| 345 (unit.element as CompilationUnitElementImpl).types = |
| 346 <ClassElement>[classElement]; |
| 347 return classNode; |
| 348 } |
| 349 |
| 350 ClassTypeAlias _createResolvedClassTypeAlias() { |
| 351 CompilationUnit unit = _createResolvedCompilationUnit(); |
| 352 String className = "C"; |
| 353 ClassTypeAlias classNode = AstFactory.classTypeAlias( |
| 354 className, |
| 355 AstFactory.typeParameterList(), |
| 356 null, |
| 357 null, |
| 358 null, |
| 359 null); |
| 360 unit.declarations.add(classNode); |
| 361 ClassElement classElement = ElementFactory.classElement2(className); |
| 362 classNode.name.staticElement = classElement; |
| 363 (unit.element as CompilationUnitElementImpl).types = |
| 364 <ClassElement>[classElement]; |
| 365 return classNode; |
| 366 } |
| 367 |
| 368 CompilationUnit _createResolvedCompilationUnit() { |
| 369 CompilationUnit unit = AstFactory.compilationUnit(); |
| 370 LibraryElementImpl library = |
| 371 ElementFactory.library(AnalysisContextFactory.contextWithCore(), "lib"); |
| 372 unit.element = library.definingCompilationUnit; |
| 373 return unit; |
| 374 } |
| 375 |
| 376 ConstructorDeclaration _createResolvedConstructorDeclaration() { |
| 377 ClassDeclaration classNode = _createResolvedClassDeclaration(); |
| 378 String constructorName = "f"; |
| 379 ConstructorDeclaration constructorNode = AstFactory.constructorDeclaration( |
| 380 AstFactory.identifier3(constructorName), |
| 381 null, |
| 382 AstFactory.formalParameterList(), |
| 383 null); |
| 384 classNode.members.add(constructorNode); |
| 385 ConstructorElement constructorElement = |
| 386 ElementFactory.constructorElement2(classNode.element, null); |
| 387 constructorNode.element = constructorElement; |
| 388 (classNode.element as ClassElementImpl).constructors = |
| 389 <ConstructorElement>[constructorElement]; |
| 390 return constructorNode; |
| 391 } |
| 392 |
| 393 FunctionDeclaration _createResolvedFunctionDeclaration() { |
| 394 CompilationUnit unit = _createResolvedCompilationUnit(); |
| 395 String functionName = "f"; |
| 396 FunctionDeclaration functionNode = AstFactory.functionDeclaration( |
| 397 null, |
| 398 null, |
| 399 functionName, |
| 400 AstFactory.functionExpression()); |
| 401 unit.declarations.add(functionNode); |
| 402 FunctionElement functionElement = |
| 403 ElementFactory.functionElement(functionName); |
| 404 functionNode.name.staticElement = functionElement; |
| 405 (unit.element as CompilationUnitElementImpl).functions = |
| 406 <FunctionElement>[functionElement]; |
| 407 return functionNode; |
| 408 } |
| 409 |
| 410 FunctionTypeAlias _createResolvedFunctionTypeAlias() { |
| 411 CompilationUnit unit = _createResolvedCompilationUnit(); |
| 412 FunctionTypeAlias aliasNode = AstFactory.typeAlias( |
| 413 AstFactory.typeName4("A"), |
| 414 "F", |
| 415 AstFactory.typeParameterList(), |
| 416 AstFactory.formalParameterList()); |
| 417 unit.declarations.add(aliasNode); |
| 418 SimpleIdentifier aliasName = aliasNode.name; |
| 419 FunctionTypeAliasElement aliasElement = |
| 420 new FunctionTypeAliasElementImpl.forNode(aliasName); |
| 421 aliasName.staticElement = aliasElement; |
| 422 (unit.element as CompilationUnitElementImpl).typeAliases = |
| 423 <FunctionTypeAliasElement>[aliasElement]; |
| 424 return aliasNode; |
| 425 } |
| 426 |
| 427 MethodDeclaration _createResolvedMethodDeclaration() { |
| 428 ClassDeclaration classNode = _createResolvedClassDeclaration(); |
| 429 String methodName = "f"; |
| 430 MethodDeclaration methodNode = AstFactory.methodDeclaration( |
| 431 null, |
| 432 null, |
| 433 null, |
| 434 null, |
| 435 AstFactory.identifier3(methodName), |
| 436 AstFactory.formalParameterList()); |
| 437 classNode.members.add(methodNode); |
| 438 MethodElement methodElement = |
| 439 ElementFactory.methodElement(methodName, null); |
| 440 methodNode.name.staticElement = methodElement; |
| 441 (classNode.element as ClassElementImpl).methods = |
| 442 <MethodElement>[methodElement]; |
| 443 return methodNode; |
| 444 } |
| 445 } |
| OLD | NEW |