| OLD | NEW |
| (Empty) | |
| 1 // Copyright (c) 2016, 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 analyzer.test.generated.simple_resolver_test; |
| 6 |
| 7 import 'package:analyzer/dart/ast/ast.dart'; |
| 8 import 'package:analyzer/dart/ast/visitor.dart'; |
| 9 import 'package:analyzer/dart/element/element.dart'; |
| 10 import 'package:analyzer/dart/element/type.dart'; |
| 11 import 'package:analyzer/exception/exception.dart'; |
| 12 import 'package:analyzer/src/error/codes.dart'; |
| 13 import 'package:analyzer/src/generated/engine.dart'; |
| 14 import 'package:analyzer/src/generated/source_io.dart'; |
| 15 import 'package:test_reflective_loader/test_reflective_loader.dart'; |
| 16 import 'package:unittest/unittest.dart'; |
| 17 |
| 18 import '../utils.dart'; |
| 19 import 'resolver_test_case.dart'; |
| 20 import 'test_support.dart'; |
| 21 |
| 22 main() { |
| 23 initializeTestEnvironment(); |
| 24 defineReflectiveTests(SimpleResolverTest); |
| 25 } |
| 26 |
| 27 @reflectiveTest |
| 28 class SimpleResolverTest extends ResolverTestCase { |
| 29 void test_argumentResolution_required_matching() { |
| 30 Source source = addSource(r''' |
| 31 class A { |
| 32 void f() { |
| 33 g(1, 2, 3); |
| 34 } |
| 35 void g(a, b, c) {} |
| 36 }'''); |
| 37 _validateArgumentResolution(source, [0, 1, 2]); |
| 38 } |
| 39 |
| 40 void test_argumentResolution_required_tooFew() { |
| 41 Source source = addSource(r''' |
| 42 class A { |
| 43 void f() { |
| 44 g(1, 2); |
| 45 } |
| 46 void g(a, b, c) {} |
| 47 }'''); |
| 48 _validateArgumentResolution(source, [0, 1]); |
| 49 } |
| 50 |
| 51 void test_argumentResolution_required_tooMany() { |
| 52 Source source = addSource(r''' |
| 53 class A { |
| 54 void f() { |
| 55 g(1, 2, 3); |
| 56 } |
| 57 void g(a, b) {} |
| 58 }'''); |
| 59 _validateArgumentResolution(source, [0, 1, -1]); |
| 60 } |
| 61 |
| 62 void test_argumentResolution_requiredAndNamed_extra() { |
| 63 Source source = addSource(r''' |
| 64 class A { |
| 65 void f() { |
| 66 g(1, 2, c: 3, d: 4); |
| 67 } |
| 68 void g(a, b, {c}) {} |
| 69 }'''); |
| 70 _validateArgumentResolution(source, [0, 1, 2, -1]); |
| 71 } |
| 72 |
| 73 void test_argumentResolution_requiredAndNamed_matching() { |
| 74 Source source = addSource(r''' |
| 75 class A { |
| 76 void f() { |
| 77 g(1, 2, c: 3); |
| 78 } |
| 79 void g(a, b, {c}) {} |
| 80 }'''); |
| 81 _validateArgumentResolution(source, [0, 1, 2]); |
| 82 } |
| 83 |
| 84 void test_argumentResolution_requiredAndNamed_missing() { |
| 85 Source source = addSource(r''' |
| 86 class A { |
| 87 void f() { |
| 88 g(1, 2, d: 3); |
| 89 } |
| 90 void g(a, b, {c, d}) {} |
| 91 }'''); |
| 92 _validateArgumentResolution(source, [0, 1, 3]); |
| 93 } |
| 94 |
| 95 void test_argumentResolution_requiredAndPositional_fewer() { |
| 96 Source source = addSource(r''' |
| 97 class A { |
| 98 void f() { |
| 99 g(1, 2, 3); |
| 100 } |
| 101 void g(a, b, [c, d]) {} |
| 102 }'''); |
| 103 _validateArgumentResolution(source, [0, 1, 2]); |
| 104 } |
| 105 |
| 106 void test_argumentResolution_requiredAndPositional_matching() { |
| 107 Source source = addSource(r''' |
| 108 class A { |
| 109 void f() { |
| 110 g(1, 2, 3, 4); |
| 111 } |
| 112 void g(a, b, [c, d]) {} |
| 113 }'''); |
| 114 _validateArgumentResolution(source, [0, 1, 2, 3]); |
| 115 } |
| 116 |
| 117 void test_argumentResolution_requiredAndPositional_more() { |
| 118 Source source = addSource(r''' |
| 119 class A { |
| 120 void f() { |
| 121 g(1, 2, 3, 4); |
| 122 } |
| 123 void g(a, b, [c]) {} |
| 124 }'''); |
| 125 _validateArgumentResolution(source, [0, 1, 2, -1]); |
| 126 } |
| 127 |
| 128 void test_argumentResolution_setter_propagated() { |
| 129 Source source = addSource(r''' |
| 130 main() { |
| 131 var a = new A(); |
| 132 a.sss = 0; |
| 133 } |
| 134 class A { |
| 135 set sss(x) {} |
| 136 }'''); |
| 137 LibraryElement library = resolve2(source); |
| 138 CompilationUnitElement unit = library.definingCompilationUnit; |
| 139 // find "a.sss = 0" |
| 140 AssignmentExpression assignment; |
| 141 { |
| 142 FunctionElement mainElement = unit.functions[0]; |
| 143 FunctionBody mainBody = mainElement.computeNode().functionExpression.body; |
| 144 Statement statement = (mainBody as BlockFunctionBody).block.statements[1]; |
| 145 ExpressionStatement expressionStatement = |
| 146 statement as ExpressionStatement; |
| 147 assignment = expressionStatement.expression as AssignmentExpression; |
| 148 } |
| 149 // get parameter |
| 150 Expression rhs = assignment.rightHandSide; |
| 151 expect(rhs.staticParameterElement, isNull); |
| 152 ParameterElement parameter = rhs.propagatedParameterElement; |
| 153 expect(parameter, isNotNull); |
| 154 expect(parameter.displayName, "x"); |
| 155 // validate |
| 156 ClassElement classA = unit.types[0]; |
| 157 PropertyAccessorElement setter = classA.accessors[0]; |
| 158 expect(setter.parameters[0], same(parameter)); |
| 159 } |
| 160 |
| 161 void test_argumentResolution_setter_propagated_propertyAccess() { |
| 162 Source source = addSource(r''' |
| 163 main() { |
| 164 var a = new A(); |
| 165 a.b.sss = 0; |
| 166 } |
| 167 class A { |
| 168 B b = new B(); |
| 169 } |
| 170 class B { |
| 171 set sss(x) {} |
| 172 }'''); |
| 173 LibraryElement library = resolve2(source); |
| 174 CompilationUnitElement unit = library.definingCompilationUnit; |
| 175 // find "a.b.sss = 0" |
| 176 AssignmentExpression assignment; |
| 177 { |
| 178 FunctionElement mainElement = unit.functions[0]; |
| 179 FunctionBody mainBody = mainElement.computeNode().functionExpression.body; |
| 180 Statement statement = (mainBody as BlockFunctionBody).block.statements[1]; |
| 181 ExpressionStatement expressionStatement = |
| 182 statement as ExpressionStatement; |
| 183 assignment = expressionStatement.expression as AssignmentExpression; |
| 184 } |
| 185 // get parameter |
| 186 Expression rhs = assignment.rightHandSide; |
| 187 expect(rhs.staticParameterElement, isNull); |
| 188 ParameterElement parameter = rhs.propagatedParameterElement; |
| 189 expect(parameter, isNotNull); |
| 190 expect(parameter.displayName, "x"); |
| 191 // validate |
| 192 ClassElement classB = unit.types[1]; |
| 193 PropertyAccessorElement setter = classB.accessors[0]; |
| 194 expect(setter.parameters[0], same(parameter)); |
| 195 } |
| 196 |
| 197 void test_argumentResolution_setter_static() { |
| 198 Source source = addSource(r''' |
| 199 main() { |
| 200 A a = new A(); |
| 201 a.sss = 0; |
| 202 } |
| 203 class A { |
| 204 set sss(x) {} |
| 205 }'''); |
| 206 LibraryElement library = resolve2(source); |
| 207 CompilationUnitElement unit = library.definingCompilationUnit; |
| 208 // find "a.sss = 0" |
| 209 AssignmentExpression assignment; |
| 210 { |
| 211 FunctionElement mainElement = unit.functions[0]; |
| 212 FunctionBody mainBody = mainElement.computeNode().functionExpression.body; |
| 213 Statement statement = (mainBody as BlockFunctionBody).block.statements[1]; |
| 214 ExpressionStatement expressionStatement = |
| 215 statement as ExpressionStatement; |
| 216 assignment = expressionStatement.expression as AssignmentExpression; |
| 217 } |
| 218 // get parameter |
| 219 Expression rhs = assignment.rightHandSide; |
| 220 ParameterElement parameter = rhs.staticParameterElement; |
| 221 expect(parameter, isNotNull); |
| 222 expect(parameter.displayName, "x"); |
| 223 // validate |
| 224 ClassElement classA = unit.types[0]; |
| 225 PropertyAccessorElement setter = classA.accessors[0]; |
| 226 expect(setter.parameters[0], same(parameter)); |
| 227 } |
| 228 |
| 229 void test_argumentResolution_setter_static_propertyAccess() { |
| 230 Source source = addSource(r''' |
| 231 main() { |
| 232 A a = new A(); |
| 233 a.b.sss = 0; |
| 234 } |
| 235 class A { |
| 236 B b = new B(); |
| 237 } |
| 238 class B { |
| 239 set sss(x) {} |
| 240 }'''); |
| 241 LibraryElement library = resolve2(source); |
| 242 CompilationUnitElement unit = library.definingCompilationUnit; |
| 243 // find "a.b.sss = 0" |
| 244 AssignmentExpression assignment; |
| 245 { |
| 246 FunctionElement mainElement = unit.functions[0]; |
| 247 FunctionBody mainBody = mainElement.computeNode().functionExpression.body; |
| 248 Statement statement = (mainBody as BlockFunctionBody).block.statements[1]; |
| 249 ExpressionStatement expressionStatement = |
| 250 statement as ExpressionStatement; |
| 251 assignment = expressionStatement.expression as AssignmentExpression; |
| 252 } |
| 253 // get parameter |
| 254 Expression rhs = assignment.rightHandSide; |
| 255 ParameterElement parameter = rhs.staticParameterElement; |
| 256 expect(parameter, isNotNull); |
| 257 expect(parameter.displayName, "x"); |
| 258 // validate |
| 259 ClassElement classB = unit.types[1]; |
| 260 PropertyAccessorElement setter = classB.accessors[0]; |
| 261 expect(setter.parameters[0], same(parameter)); |
| 262 } |
| 263 |
| 264 void test_breakTarget_labeled() { |
| 265 // Verify that the target of the label is correctly found and is recorded |
| 266 // as the unlabeled portion of the statement. |
| 267 String text = r''' |
| 268 void f() { |
| 269 loop1: while (true) { |
| 270 loop2: for (int i = 0; i < 10; i++) { |
| 271 break loop1; |
| 272 break loop2; |
| 273 } |
| 274 } |
| 275 } |
| 276 '''; |
| 277 CompilationUnit unit = resolveSource(text); |
| 278 WhileStatement whileStatement = EngineTestCase.findNode( |
| 279 unit, text, 'while (true)', (n) => n is WhileStatement); |
| 280 ForStatement forStatement = |
| 281 EngineTestCase.findNode(unit, text, 'for', (n) => n is ForStatement); |
| 282 BreakStatement break1 = EngineTestCase.findNode( |
| 283 unit, text, 'break loop1', (n) => n is BreakStatement); |
| 284 BreakStatement break2 = EngineTestCase.findNode( |
| 285 unit, text, 'break loop2', (n) => n is BreakStatement); |
| 286 expect(break1.target, same(whileStatement)); |
| 287 expect(break2.target, same(forStatement)); |
| 288 } |
| 289 |
| 290 void test_breakTarget_unlabeledBreakFromDo() { |
| 291 String text = r''' |
| 292 void f() { |
| 293 do { |
| 294 break; |
| 295 } while (true); |
| 296 } |
| 297 '''; |
| 298 CompilationUnit unit = resolveSource(text); |
| 299 DoStatement doStatement = |
| 300 EngineTestCase.findNode(unit, text, 'do', (n) => n is DoStatement); |
| 301 BreakStatement breakStatement = EngineTestCase.findNode( |
| 302 unit, text, 'break', (n) => n is BreakStatement); |
| 303 expect(breakStatement.target, same(doStatement)); |
| 304 } |
| 305 |
| 306 void test_breakTarget_unlabeledBreakFromFor() { |
| 307 String text = r''' |
| 308 void f() { |
| 309 for (int i = 0; i < 10; i++) { |
| 310 break; |
| 311 } |
| 312 } |
| 313 '''; |
| 314 CompilationUnit unit = resolveSource(text); |
| 315 ForStatement forStatement = |
| 316 EngineTestCase.findNode(unit, text, 'for', (n) => n is ForStatement); |
| 317 BreakStatement breakStatement = EngineTestCase.findNode( |
| 318 unit, text, 'break', (n) => n is BreakStatement); |
| 319 expect(breakStatement.target, same(forStatement)); |
| 320 } |
| 321 |
| 322 void test_breakTarget_unlabeledBreakFromForEach() { |
| 323 String text = r''' |
| 324 void f() { |
| 325 for (x in []) { |
| 326 break; |
| 327 } |
| 328 } |
| 329 '''; |
| 330 CompilationUnit unit = resolveSource(text); |
| 331 ForEachStatement forStatement = EngineTestCase.findNode( |
| 332 unit, text, 'for', (n) => n is ForEachStatement); |
| 333 BreakStatement breakStatement = EngineTestCase.findNode( |
| 334 unit, text, 'break', (n) => n is BreakStatement); |
| 335 expect(breakStatement.target, same(forStatement)); |
| 336 } |
| 337 |
| 338 void test_breakTarget_unlabeledBreakFromSwitch() { |
| 339 String text = r''' |
| 340 void f() { |
| 341 while (true) { |
| 342 switch (0) { |
| 343 case 0: |
| 344 break; |
| 345 } |
| 346 } |
| 347 } |
| 348 '''; |
| 349 CompilationUnit unit = resolveSource(text); |
| 350 SwitchStatement switchStatement = EngineTestCase.findNode( |
| 351 unit, text, 'switch', (n) => n is SwitchStatement); |
| 352 BreakStatement breakStatement = EngineTestCase.findNode( |
| 353 unit, text, 'break', (n) => n is BreakStatement); |
| 354 expect(breakStatement.target, same(switchStatement)); |
| 355 } |
| 356 |
| 357 void test_breakTarget_unlabeledBreakFromWhile() { |
| 358 String text = r''' |
| 359 void f() { |
| 360 while (true) { |
| 361 break; |
| 362 } |
| 363 } |
| 364 '''; |
| 365 CompilationUnit unit = resolveSource(text); |
| 366 WhileStatement whileStatement = EngineTestCase.findNode( |
| 367 unit, text, 'while', (n) => n is WhileStatement); |
| 368 BreakStatement breakStatement = EngineTestCase.findNode( |
| 369 unit, text, 'break', (n) => n is BreakStatement); |
| 370 expect(breakStatement.target, same(whileStatement)); |
| 371 } |
| 372 |
| 373 void test_breakTarget_unlabeledBreakToOuterFunction() { |
| 374 // Verify that unlabeled break statements can't resolve to loops in an |
| 375 // outer function. |
| 376 String text = r''' |
| 377 void f() { |
| 378 while (true) { |
| 379 void g() { |
| 380 break; |
| 381 } |
| 382 } |
| 383 } |
| 384 '''; |
| 385 CompilationUnit unit = resolveSource(text); |
| 386 BreakStatement breakStatement = EngineTestCase.findNode( |
| 387 unit, text, 'break', (n) => n is BreakStatement); |
| 388 expect(breakStatement.target, isNull); |
| 389 } |
| 390 |
| 391 void test_class_definesCall() { |
| 392 Source source = addSource(r''' |
| 393 class A { |
| 394 int call(int x) { return x; } |
| 395 } |
| 396 int f(A a) { |
| 397 return a(0); |
| 398 }'''); |
| 399 computeLibrarySourceErrors(source); |
| 400 assertNoErrors(source); |
| 401 verify([source]); |
| 402 } |
| 403 |
| 404 void test_class_extends_implements() { |
| 405 Source source = addSource(r''' |
| 406 class A extends B implements C {} |
| 407 class B {} |
| 408 class C {}'''); |
| 409 computeLibrarySourceErrors(source); |
| 410 assertNoErrors(source); |
| 411 verify([source]); |
| 412 } |
| 413 |
| 414 void test_commentReference_class() { |
| 415 Source source = addSource(r''' |
| 416 f() {} |
| 417 /** [A] [new A] [A.n] [new A.n] [m] [f] */ |
| 418 class A { |
| 419 A() {} |
| 420 A.n() {} |
| 421 m() {} |
| 422 }'''); |
| 423 computeLibrarySourceErrors(source); |
| 424 assertNoErrors(source); |
| 425 verify([source]); |
| 426 } |
| 427 |
| 428 void test_commentReference_parameter() { |
| 429 Source source = addSource(r''' |
| 430 class A { |
| 431 A() {} |
| 432 A.n() {} |
| 433 /** [e] [f] */ |
| 434 m(e, f()) {} |
| 435 }'''); |
| 436 computeLibrarySourceErrors(source); |
| 437 assertNoErrors(source); |
| 438 verify([source]); |
| 439 } |
| 440 |
| 441 void test_commentReference_singleLine() { |
| 442 Source source = addSource(r''' |
| 443 /// [A] |
| 444 class A {}'''); |
| 445 computeLibrarySourceErrors(source); |
| 446 assertNoErrors(source); |
| 447 verify([source]); |
| 448 } |
| 449 |
| 450 void test_continueTarget_labeled() { |
| 451 // Verify that the target of the label is correctly found and is recorded |
| 452 // as the unlabeled portion of the statement. |
| 453 String text = r''' |
| 454 void f() { |
| 455 loop1: while (true) { |
| 456 loop2: for (int i = 0; i < 10; i++) { |
| 457 continue loop1; |
| 458 continue loop2; |
| 459 } |
| 460 } |
| 461 } |
| 462 '''; |
| 463 CompilationUnit unit = resolveSource(text); |
| 464 WhileStatement whileStatement = EngineTestCase.findNode( |
| 465 unit, text, 'while (true)', (n) => n is WhileStatement); |
| 466 ForStatement forStatement = |
| 467 EngineTestCase.findNode(unit, text, 'for', (n) => n is ForStatement); |
| 468 ContinueStatement continue1 = EngineTestCase.findNode( |
| 469 unit, text, 'continue loop1', (n) => n is ContinueStatement); |
| 470 ContinueStatement continue2 = EngineTestCase.findNode( |
| 471 unit, text, 'continue loop2', (n) => n is ContinueStatement); |
| 472 expect(continue1.target, same(whileStatement)); |
| 473 expect(continue2.target, same(forStatement)); |
| 474 } |
| 475 |
| 476 void test_continueTarget_unlabeledContinueFromDo() { |
| 477 String text = r''' |
| 478 void f() { |
| 479 do { |
| 480 continue; |
| 481 } while (true); |
| 482 } |
| 483 '''; |
| 484 CompilationUnit unit = resolveSource(text); |
| 485 DoStatement doStatement = |
| 486 EngineTestCase.findNode(unit, text, 'do', (n) => n is DoStatement); |
| 487 ContinueStatement continueStatement = EngineTestCase.findNode( |
| 488 unit, text, 'continue', (n) => n is ContinueStatement); |
| 489 expect(continueStatement.target, same(doStatement)); |
| 490 } |
| 491 |
| 492 void test_continueTarget_unlabeledContinueFromFor() { |
| 493 String text = r''' |
| 494 void f() { |
| 495 for (int i = 0; i < 10; i++) { |
| 496 continue; |
| 497 } |
| 498 } |
| 499 '''; |
| 500 CompilationUnit unit = resolveSource(text); |
| 501 ForStatement forStatement = |
| 502 EngineTestCase.findNode(unit, text, 'for', (n) => n is ForStatement); |
| 503 ContinueStatement continueStatement = EngineTestCase.findNode( |
| 504 unit, text, 'continue', (n) => n is ContinueStatement); |
| 505 expect(continueStatement.target, same(forStatement)); |
| 506 } |
| 507 |
| 508 void test_continueTarget_unlabeledContinueFromForEach() { |
| 509 String text = r''' |
| 510 void f() { |
| 511 for (x in []) { |
| 512 continue; |
| 513 } |
| 514 } |
| 515 '''; |
| 516 CompilationUnit unit = resolveSource(text); |
| 517 ForEachStatement forStatement = EngineTestCase.findNode( |
| 518 unit, text, 'for', (n) => n is ForEachStatement); |
| 519 ContinueStatement continueStatement = EngineTestCase.findNode( |
| 520 unit, text, 'continue', (n) => n is ContinueStatement); |
| 521 expect(continueStatement.target, same(forStatement)); |
| 522 } |
| 523 |
| 524 void test_continueTarget_unlabeledContinueFromWhile() { |
| 525 String text = r''' |
| 526 void f() { |
| 527 while (true) { |
| 528 continue; |
| 529 } |
| 530 } |
| 531 '''; |
| 532 CompilationUnit unit = resolveSource(text); |
| 533 WhileStatement whileStatement = EngineTestCase.findNode( |
| 534 unit, text, 'while', (n) => n is WhileStatement); |
| 535 ContinueStatement continueStatement = EngineTestCase.findNode( |
| 536 unit, text, 'continue', (n) => n is ContinueStatement); |
| 537 expect(continueStatement.target, same(whileStatement)); |
| 538 } |
| 539 |
| 540 void test_continueTarget_unlabeledContinueSkipsSwitch() { |
| 541 String text = r''' |
| 542 void f() { |
| 543 while (true) { |
| 544 switch (0) { |
| 545 case 0: |
| 546 continue; |
| 547 } |
| 548 } |
| 549 } |
| 550 '''; |
| 551 CompilationUnit unit = resolveSource(text); |
| 552 WhileStatement whileStatement = EngineTestCase.findNode( |
| 553 unit, text, 'while', (n) => n is WhileStatement); |
| 554 ContinueStatement continueStatement = EngineTestCase.findNode( |
| 555 unit, text, 'continue', (n) => n is ContinueStatement); |
| 556 expect(continueStatement.target, same(whileStatement)); |
| 557 } |
| 558 |
| 559 void test_continueTarget_unlabeledContinueToOuterFunction() { |
| 560 // Verify that unlabeled continue statements can't resolve to loops in an |
| 561 // outer function. |
| 562 String text = r''' |
| 563 void f() { |
| 564 while (true) { |
| 565 void g() { |
| 566 continue; |
| 567 } |
| 568 } |
| 569 } |
| 570 '''; |
| 571 CompilationUnit unit = resolveSource(text); |
| 572 ContinueStatement continueStatement = EngineTestCase.findNode( |
| 573 unit, text, 'continue', (n) => n is ContinueStatement); |
| 574 expect(continueStatement.target, isNull); |
| 575 } |
| 576 |
| 577 void test_empty() { |
| 578 Source source = addSource(""); |
| 579 computeLibrarySourceErrors(source); |
| 580 assertNoErrors(source); |
| 581 verify([source]); |
| 582 } |
| 583 |
| 584 void test_entryPoint_exported() { |
| 585 addNamedSource( |
| 586 "/two.dart", |
| 587 r''' |
| 588 library two; |
| 589 main() {}'''); |
| 590 Source source = addNamedSource( |
| 591 "/one.dart", |
| 592 r''' |
| 593 library one; |
| 594 export 'two.dart';'''); |
| 595 LibraryElement library = resolve2(source); |
| 596 expect(library, isNotNull); |
| 597 FunctionElement main = library.entryPoint; |
| 598 expect(main, isNotNull); |
| 599 expect(main.library, isNot(same(library))); |
| 600 assertNoErrors(source); |
| 601 verify([source]); |
| 602 } |
| 603 |
| 604 void test_entryPoint_local() { |
| 605 Source source = addNamedSource( |
| 606 "/one.dart", |
| 607 r''' |
| 608 library one; |
| 609 main() {}'''); |
| 610 LibraryElement library = resolve2(source); |
| 611 expect(library, isNotNull); |
| 612 FunctionElement main = library.entryPoint; |
| 613 expect(main, isNotNull); |
| 614 expect(main.library, same(library)); |
| 615 assertNoErrors(source); |
| 616 verify([source]); |
| 617 } |
| 618 |
| 619 void test_entryPoint_none() { |
| 620 Source source = addNamedSource("/one.dart", "library one;"); |
| 621 LibraryElement library = resolve2(source); |
| 622 expect(library, isNotNull); |
| 623 expect(library.entryPoint, isNull); |
| 624 assertNoErrors(source); |
| 625 verify([source]); |
| 626 } |
| 627 |
| 628 void test_enum_externalLibrary() { |
| 629 addNamedSource( |
| 630 "/my_lib.dart", |
| 631 r''' |
| 632 library my_lib; |
| 633 enum EEE {A, B, C}'''); |
| 634 Source source = addSource(r''' |
| 635 import 'my_lib.dart'; |
| 636 main() { |
| 637 EEE e = null; |
| 638 }'''); |
| 639 computeLibrarySourceErrors(source); |
| 640 assertNoErrors(source); |
| 641 verify([source]); |
| 642 } |
| 643 |
| 644 void test_extractedMethodAsConstant() { |
| 645 Source source = addSource(r''' |
| 646 abstract class Comparable<T> { |
| 647 int compareTo(T other); |
| 648 static int compare(Comparable a, Comparable b) => a.compareTo(b); |
| 649 } |
| 650 class A { |
| 651 void sort([compare = Comparable.compare]) {} |
| 652 }'''); |
| 653 computeLibrarySourceErrors(source); |
| 654 assertNoErrors(source); |
| 655 verify([source]); |
| 656 } |
| 657 |
| 658 void test_fieldFormalParameter() { |
| 659 AnalysisOptionsImpl options = new AnalysisOptionsImpl(); |
| 660 options.enableInitializingFormalAccess = true; |
| 661 resetWithOptions(options); |
| 662 Source source = addSource(r''' |
| 663 class A { |
| 664 int x; |
| 665 int y; |
| 666 A(this.x) : y = x {} |
| 667 }'''); |
| 668 CompilationUnit unit = |
| 669 analysisContext2.resolveCompilationUnit2(source, source); |
| 670 ClassDeclaration classA = unit.declarations[0]; |
| 671 FieldDeclaration field = classA.members[0]; |
| 672 ConstructorDeclaration constructor = classA.members[2]; |
| 673 ParameterElement paramElement = |
| 674 constructor.parameters.parameters[0].element; |
| 675 expect(paramElement, new isInstanceOf<FieldFormalParameterElement>()); |
| 676 expect((paramElement as FieldFormalParameterElement).field, |
| 677 field.fields.variables[0].element); |
| 678 ConstructorFieldInitializer initializer = constructor.initializers[0]; |
| 679 SimpleIdentifier identifierX = initializer.expression; |
| 680 expect(identifierX.staticElement, paramElement); |
| 681 |
| 682 computeLibrarySourceErrors(source); |
| 683 assertNoErrors(source); |
| 684 verify([source]); |
| 685 } |
| 686 |
| 687 void test_forEachLoops_nonConflicting() { |
| 688 Source source = addSource(r''' |
| 689 f() { |
| 690 List list = [1,2,3]; |
| 691 for (int x in list) {} |
| 692 for (int x in list) {} |
| 693 }'''); |
| 694 computeLibrarySourceErrors(source); |
| 695 assertNoErrors(source); |
| 696 verify([source]); |
| 697 } |
| 698 |
| 699 void test_forLoops_nonConflicting() { |
| 700 Source source = addSource(r''' |
| 701 f() { |
| 702 for (int i = 0; i < 3; i++) { |
| 703 } |
| 704 for (int i = 0; i < 3; i++) { |
| 705 } |
| 706 }'''); |
| 707 computeLibrarySourceErrors(source); |
| 708 assertNoErrors(source); |
| 709 verify([source]); |
| 710 } |
| 711 |
| 712 void test_functionTypeAlias() { |
| 713 Source source = addSource(r''' |
| 714 typedef bool P(e); |
| 715 class A { |
| 716 P p; |
| 717 m(e) { |
| 718 if (p(e)) {} |
| 719 } |
| 720 }'''); |
| 721 computeLibrarySourceErrors(source); |
| 722 assertNoErrors(source); |
| 723 verify([source]); |
| 724 } |
| 725 |
| 726 void test_getter_and_setter_fromMixins_bare_identifier() { |
| 727 Source source = addSource(''' |
| 728 class B {} |
| 729 class M1 { |
| 730 get x => null; |
| 731 set x(value) {} |
| 732 } |
| 733 class M2 { |
| 734 get x => null; |
| 735 set x(value) {} |
| 736 } |
| 737 class C extends B with M1, M2 { |
| 738 void f() { |
| 739 x += 1; |
| 740 } |
| 741 } |
| 742 '''); |
| 743 LibraryElement library = resolve2(source); |
| 744 assertNoErrors(source); |
| 745 verify([source]); |
| 746 // Verify that both the getter and setter for "x" in C.f() refer to the |
| 747 // accessors defined in M2. |
| 748 ClassElement classC = library.definingCompilationUnit.types[3]; |
| 749 MethodDeclaration f = classC.getMethod('f').computeNode(); |
| 750 BlockFunctionBody body = f.body; |
| 751 ExpressionStatement stmt = body.block.statements[0]; |
| 752 AssignmentExpression assignment = stmt.expression; |
| 753 SimpleIdentifier leftHandSide = assignment.leftHandSide; |
| 754 expect(leftHandSide.staticElement.enclosingElement.name, 'M2'); |
| 755 expect(leftHandSide.auxiliaryElements.staticElement.enclosingElement.name, |
| 756 'M2'); |
| 757 } |
| 758 |
| 759 @failingTest |
| 760 void test_getter_and_setter_fromMixins_property_access() { |
| 761 // TODO(paulberry): it appears that auxiliaryElements isn't properly set on |
| 762 // a SimpleIdentifier that's inside a property access. This bug should be |
| 763 // fixed. |
| 764 Source source = addSource(''' |
| 765 class B {} |
| 766 class M1 { |
| 767 get x => null; |
| 768 set x(value) {} |
| 769 } |
| 770 class M2 { |
| 771 get x => null; |
| 772 set x(value) {} |
| 773 } |
| 774 class C extends B with M1, M2 {} |
| 775 void main() { |
| 776 new C().x += 1; |
| 777 } |
| 778 '''); |
| 779 LibraryElement library = resolve2(source); |
| 780 assertNoErrors(source); |
| 781 verify([source]); |
| 782 // Verify that both the getter and setter for "x" in "new C().x" refer to |
| 783 // the accessors defined in M2. |
| 784 FunctionDeclaration main = |
| 785 library.definingCompilationUnit.functions[0].computeNode(); |
| 786 BlockFunctionBody body = main.functionExpression.body; |
| 787 ExpressionStatement stmt = body.block.statements[0]; |
| 788 AssignmentExpression assignment = stmt.expression; |
| 789 PropertyAccess propertyAccess = assignment.leftHandSide; |
| 790 expect( |
| 791 propertyAccess.propertyName.staticElement.enclosingElement.name, 'M2'); |
| 792 expect( |
| 793 propertyAccess |
| 794 .propertyName.auxiliaryElements.staticElement.enclosingElement.name, |
| 795 'M2'); |
| 796 } |
| 797 |
| 798 void test_getter_fromMixins_bare_identifier() { |
| 799 Source source = addSource(''' |
| 800 class B {} |
| 801 class M1 { |
| 802 get x => null; |
| 803 } |
| 804 class M2 { |
| 805 get x => null; |
| 806 } |
| 807 class C extends B with M1, M2 { |
| 808 f() { |
| 809 return x; |
| 810 } |
| 811 } |
| 812 '''); |
| 813 LibraryElement library = resolve2(source); |
| 814 assertNoErrors(source); |
| 815 verify([source]); |
| 816 // Verify that the getter for "x" in C.f() refers to the getter defined in |
| 817 // M2. |
| 818 ClassElement classC = library.definingCompilationUnit.types[3]; |
| 819 MethodDeclaration f = classC.getMethod('f').computeNode(); |
| 820 BlockFunctionBody body = f.body; |
| 821 ReturnStatement stmt = body.block.statements[0]; |
| 822 SimpleIdentifier x = stmt.expression; |
| 823 expect(x.staticElement.enclosingElement.name, 'M2'); |
| 824 } |
| 825 |
| 826 void test_getter_fromMixins_property_access() { |
| 827 Source source = addSource(''' |
| 828 class B {} |
| 829 class M1 { |
| 830 get x => null; |
| 831 } |
| 832 class M2 { |
| 833 get x => null; |
| 834 } |
| 835 class C extends B with M1, M2 {} |
| 836 void main() { |
| 837 var y = new C().x; |
| 838 } |
| 839 '''); |
| 840 LibraryElement library = resolve2(source); |
| 841 assertNoErrors(source); |
| 842 verify([source]); |
| 843 // Verify that the getter for "x" in "new C().x" refers to the getter |
| 844 // defined in M2. |
| 845 FunctionDeclaration main = |
| 846 library.definingCompilationUnit.functions[0].computeNode(); |
| 847 BlockFunctionBody body = main.functionExpression.body; |
| 848 VariableDeclarationStatement stmt = body.block.statements[0]; |
| 849 PropertyAccess propertyAccess = stmt.variables.variables[0].initializer; |
| 850 expect( |
| 851 propertyAccess.propertyName.staticElement.enclosingElement.name, 'M2'); |
| 852 } |
| 853 |
| 854 void test_getterAndSetterWithDifferentTypes() { |
| 855 Source source = addSource(r''' |
| 856 class A { |
| 857 int get f => 0; |
| 858 void set f(String s) {} |
| 859 } |
| 860 g (A a) { |
| 861 a.f = a.f.toString(); |
| 862 }'''); |
| 863 computeLibrarySourceErrors(source); |
| 864 assertErrors( |
| 865 source, [StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES]); |
| 866 verify([source]); |
| 867 } |
| 868 |
| 869 void test_hasReferenceToSuper() { |
| 870 Source source = addSource(r''' |
| 871 class A {} |
| 872 class B {toString() => super.toString();}'''); |
| 873 LibraryElement library = resolve2(source); |
| 874 expect(library, isNotNull); |
| 875 CompilationUnitElement unit = library.definingCompilationUnit; |
| 876 expect(unit, isNotNull); |
| 877 List<ClassElement> classes = unit.types; |
| 878 expect(classes, hasLength(2)); |
| 879 expect(classes[0].hasReferenceToSuper, isFalse); |
| 880 expect(classes[1].hasReferenceToSuper, isTrue); |
| 881 assertNoErrors(source); |
| 882 verify([source]); |
| 883 } |
| 884 |
| 885 void test_import_hide() { |
| 886 addNamedSource( |
| 887 "/lib1.dart", |
| 888 r''' |
| 889 library lib1; |
| 890 set foo(value) {} |
| 891 class A {}'''); |
| 892 addNamedSource( |
| 893 "/lib2.dart", |
| 894 r''' |
| 895 library lib2; |
| 896 set foo(value) {}'''); |
| 897 Source source = addNamedSource( |
| 898 "/lib3.dart", |
| 899 r''' |
| 900 import 'lib1.dart' hide foo; |
| 901 import 'lib2.dart'; |
| 902 |
| 903 main() { |
| 904 foo = 0; |
| 905 } |
| 906 A a;'''); |
| 907 computeLibrarySourceErrors(source); |
| 908 assertNoErrors(source); |
| 909 verify([source]); |
| 910 } |
| 911 |
| 912 void test_import_prefix() { |
| 913 addNamedSource( |
| 914 "/two.dart", |
| 915 r''' |
| 916 library two; |
| 917 f(int x) { |
| 918 return x * x; |
| 919 }'''); |
| 920 Source source = addNamedSource( |
| 921 "/one.dart", |
| 922 r''' |
| 923 library one; |
| 924 import 'two.dart' as _two; |
| 925 main() { |
| 926 _two.f(0); |
| 927 }'''); |
| 928 computeLibrarySourceErrors(source); |
| 929 assertNoErrors(source); |
| 930 verify([source]); |
| 931 } |
| 932 |
| 933 void test_import_prefix_doesNotExist() { |
| 934 // |
| 935 // The primary purpose of this test is to ensure that we are only getting a |
| 936 // single error generated when the only problem is that an imported file |
| 937 // does not exist. |
| 938 // |
| 939 Source source = addNamedSource( |
| 940 "/a.dart", |
| 941 r''' |
| 942 import 'missing.dart' as p; |
| 943 int a = p.q + p.r.s; |
| 944 String b = p.t(a) + p.u(v: 0); |
| 945 p.T c = new p.T(); |
| 946 class D<E> extends p.T { |
| 947 D(int i) : super(i); |
| 948 p.U f = new p.V(); |
| 949 } |
| 950 class F implements p.T { |
| 951 p.T m(p.U u) => null; |
| 952 } |
| 953 class G extends Object with p.V {} |
| 954 class H extends D<p.W> { |
| 955 H(int i) : super(i); |
| 956 } |
| 957 '''); |
| 958 computeLibrarySourceErrors(source); |
| 959 assertErrors(source, [CompileTimeErrorCode.URI_DOES_NOT_EXIST]); |
| 960 verify([source]); |
| 961 } |
| 962 |
| 963 void test_import_show_doesNotExist() { |
| 964 // |
| 965 // The primary purpose of this test is to ensure that we are only getting a |
| 966 // single error generated when the only problem is that an imported file |
| 967 // does not exist. |
| 968 // |
| 969 Source source = addNamedSource( |
| 970 "/a.dart", |
| 971 r''' |
| 972 import 'missing.dart' show q, r, t, u, T, U, V, W; |
| 973 int a = q + r.s; |
| 974 String b = t(a) + u(v: 0); |
| 975 T c = new T(); |
| 976 class D<E> extends T { |
| 977 D(int i) : super(i); |
| 978 U f = new V(); |
| 979 } |
| 980 class F implements T { |
| 981 T m(U u) => null; |
| 982 } |
| 983 class G extends Object with V {} |
| 984 class H extends D<W> { |
| 985 H(int i) : super(i); |
| 986 } |
| 987 '''); |
| 988 computeLibrarySourceErrors(source); |
| 989 assertErrors(source, [CompileTimeErrorCode.URI_DOES_NOT_EXIST]); |
| 990 verify([source]); |
| 991 } |
| 992 |
| 993 void test_import_spaceInUri() { |
| 994 addNamedSource( |
| 995 "/sub folder/lib.dart", |
| 996 r''' |
| 997 library lib; |
| 998 foo() {}'''); |
| 999 Source source = addNamedSource( |
| 1000 "/app.dart", |
| 1001 r''' |
| 1002 import 'sub folder/lib.dart'; |
| 1003 |
| 1004 main() { |
| 1005 foo(); |
| 1006 }'''); |
| 1007 computeLibrarySourceErrors(source); |
| 1008 assertNoErrors(source); |
| 1009 verify([source]); |
| 1010 } |
| 1011 |
| 1012 void test_indexExpression_typeParameters() { |
| 1013 Source source = addSource(r''' |
| 1014 f() { |
| 1015 List<int> a; |
| 1016 a[0]; |
| 1017 List<List<int>> b; |
| 1018 b[0][0]; |
| 1019 List<List<List<int>>> c; |
| 1020 c[0][0][0]; |
| 1021 }'''); |
| 1022 computeLibrarySourceErrors(source); |
| 1023 assertNoErrors(source); |
| 1024 verify([source]); |
| 1025 } |
| 1026 |
| 1027 void test_indexExpression_typeParameters_invalidAssignmentWarning() { |
| 1028 Source source = addSource(r''' |
| 1029 f() { |
| 1030 List<List<int>> b; |
| 1031 b[0][0] = 'hi'; |
| 1032 }'''); |
| 1033 computeLibrarySourceErrors(source); |
| 1034 assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]); |
| 1035 verify([source]); |
| 1036 } |
| 1037 |
| 1038 void test_indirectOperatorThroughCall() { |
| 1039 Source source = addSource(r''' |
| 1040 class A { |
| 1041 B call() { return new B(); } |
| 1042 } |
| 1043 |
| 1044 class B { |
| 1045 int operator [](int i) { return i; } |
| 1046 } |
| 1047 |
| 1048 A f = new A(); |
| 1049 |
| 1050 g(int x) {} |
| 1051 |
| 1052 main() { |
| 1053 g(f()[0]); |
| 1054 }'''); |
| 1055 computeLibrarySourceErrors(source); |
| 1056 assertNoErrors(source); |
| 1057 verify([source]); |
| 1058 } |
| 1059 |
| 1060 void test_invoke_dynamicThroughGetter() { |
| 1061 Source source = addSource(r''' |
| 1062 class A { |
| 1063 List get X => [() => 0]; |
| 1064 m(A a) { |
| 1065 X.last; |
| 1066 } |
| 1067 }'''); |
| 1068 computeLibrarySourceErrors(source); |
| 1069 assertNoErrors(source); |
| 1070 verify([source]); |
| 1071 } |
| 1072 |
| 1073 void test_isValidMixin_badSuperclass() { |
| 1074 Source source = addSource(r''' |
| 1075 class A extends B {} |
| 1076 class B {} |
| 1077 class C = Object with A;'''); |
| 1078 LibraryElement library = resolve2(source); |
| 1079 expect(library, isNotNull); |
| 1080 CompilationUnitElement unit = library.definingCompilationUnit; |
| 1081 expect(unit, isNotNull); |
| 1082 ClassElement a = unit.getType('A'); |
| 1083 expect(a.isValidMixin, isFalse); |
| 1084 assertErrors(source, [CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT]); |
| 1085 verify([source]); |
| 1086 } |
| 1087 |
| 1088 void test_isValidMixin_badSuperclass_withSuperMixins() { |
| 1089 resetWithOptions(new AnalysisOptionsImpl()..enableSuperMixins = true); |
| 1090 Source source = addSource(r''' |
| 1091 class A extends B {} |
| 1092 class B {} |
| 1093 class C = Object with A;'''); |
| 1094 LibraryElement library = resolve2(source); |
| 1095 expect(library, isNotNull); |
| 1096 CompilationUnitElement unit = library.definingCompilationUnit; |
| 1097 expect(unit, isNotNull); |
| 1098 ClassElement a = unit.getType('A'); |
| 1099 expect(a.isValidMixin, isTrue); |
| 1100 assertNoErrors(source); |
| 1101 verify([source]); |
| 1102 } |
| 1103 |
| 1104 void test_isValidMixin_constructor() { |
| 1105 Source source = addSource(r''' |
| 1106 class A { |
| 1107 A() {} |
| 1108 } |
| 1109 class C = Object with A;'''); |
| 1110 LibraryElement library = resolve2(source); |
| 1111 expect(library, isNotNull); |
| 1112 CompilationUnitElement unit = library.definingCompilationUnit; |
| 1113 expect(unit, isNotNull); |
| 1114 ClassElement a = unit.getType('A'); |
| 1115 expect(a.isValidMixin, isFalse); |
| 1116 assertErrors(source, [CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR]); |
| 1117 verify([source]); |
| 1118 } |
| 1119 |
| 1120 void test_isValidMixin_constructor_withSuperMixins() { |
| 1121 resetWithOptions(new AnalysisOptionsImpl()..enableSuperMixins = true); |
| 1122 Source source = addSource(r''' |
| 1123 class A { |
| 1124 A() {} |
| 1125 } |
| 1126 class C = Object with A;'''); |
| 1127 LibraryElement library = resolve2(source); |
| 1128 expect(library, isNotNull); |
| 1129 CompilationUnitElement unit = library.definingCompilationUnit; |
| 1130 expect(unit, isNotNull); |
| 1131 ClassElement a = unit.getType('A'); |
| 1132 expect(a.isValidMixin, isFalse); |
| 1133 assertErrors(source, [CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR]); |
| 1134 verify([source]); |
| 1135 } |
| 1136 |
| 1137 void test_isValidMixin_factoryConstructor() { |
| 1138 Source source = addSource(r''' |
| 1139 class A { |
| 1140 factory A() => null; |
| 1141 } |
| 1142 class C = Object with A;'''); |
| 1143 LibraryElement library = resolve2(source); |
| 1144 expect(library, isNotNull); |
| 1145 CompilationUnitElement unit = library.definingCompilationUnit; |
| 1146 expect(unit, isNotNull); |
| 1147 ClassElement a = unit.getType('A'); |
| 1148 expect(a.isValidMixin, isTrue); |
| 1149 assertNoErrors(source); |
| 1150 verify([source]); |
| 1151 } |
| 1152 |
| 1153 void test_isValidMixin_factoryConstructor_withSuperMixins() { |
| 1154 resetWithOptions(new AnalysisOptionsImpl()..enableSuperMixins = true); |
| 1155 Source source = addSource(r''' |
| 1156 class A { |
| 1157 factory A() => null; |
| 1158 } |
| 1159 class C = Object with A;'''); |
| 1160 LibraryElement library = resolve2(source); |
| 1161 expect(library, isNotNull); |
| 1162 CompilationUnitElement unit = library.definingCompilationUnit; |
| 1163 expect(unit, isNotNull); |
| 1164 ClassElement a = unit.getType('A'); |
| 1165 expect(a.isValidMixin, isTrue); |
| 1166 assertNoErrors(source); |
| 1167 verify([source]); |
| 1168 } |
| 1169 |
| 1170 void test_isValidMixin_super() { |
| 1171 Source source = addSource(r''' |
| 1172 class A { |
| 1173 toString() { |
| 1174 return super.toString(); |
| 1175 } |
| 1176 } |
| 1177 class C = Object with A;'''); |
| 1178 LibraryElement library = resolve2(source); |
| 1179 expect(library, isNotNull); |
| 1180 CompilationUnitElement unit = library.definingCompilationUnit; |
| 1181 expect(unit, isNotNull); |
| 1182 ClassElement a = unit.getType('A'); |
| 1183 expect(a.isValidMixin, isFalse); |
| 1184 assertErrors(source, [CompileTimeErrorCode.MIXIN_REFERENCES_SUPER]); |
| 1185 verify([source]); |
| 1186 } |
| 1187 |
| 1188 void test_isValidMixin_super_withSuperMixins() { |
| 1189 resetWithOptions(new AnalysisOptionsImpl()..enableSuperMixins = true); |
| 1190 Source source = addSource(r''' |
| 1191 class A { |
| 1192 toString() { |
| 1193 return super.toString(); |
| 1194 } |
| 1195 } |
| 1196 class C = Object with A;'''); |
| 1197 LibraryElement library = resolve2(source); |
| 1198 expect(library, isNotNull); |
| 1199 CompilationUnitElement unit = library.definingCompilationUnit; |
| 1200 expect(unit, isNotNull); |
| 1201 ClassElement a = unit.getType('A'); |
| 1202 expect(a.isValidMixin, isTrue); |
| 1203 assertNoErrors(source); |
| 1204 verify([source]); |
| 1205 } |
| 1206 |
| 1207 void test_isValidMixin_valid() { |
| 1208 Source source = addSource(''' |
| 1209 class A {} |
| 1210 class C = Object with A;'''); |
| 1211 LibraryElement library = resolve2(source); |
| 1212 expect(library, isNotNull); |
| 1213 CompilationUnitElement unit = library.definingCompilationUnit; |
| 1214 expect(unit, isNotNull); |
| 1215 ClassElement a = unit.getType('A'); |
| 1216 expect(a.isValidMixin, isTrue); |
| 1217 assertNoErrors(source); |
| 1218 verify([source]); |
| 1219 } |
| 1220 |
| 1221 void test_isValidMixin_valid_withSuperMixins() { |
| 1222 resetWithOptions(new AnalysisOptionsImpl()..enableSuperMixins = true); |
| 1223 Source source = addSource(''' |
| 1224 class A {} |
| 1225 class C = Object with A;'''); |
| 1226 LibraryElement library = resolve2(source); |
| 1227 expect(library, isNotNull); |
| 1228 CompilationUnitElement unit = library.definingCompilationUnit; |
| 1229 expect(unit, isNotNull); |
| 1230 ClassElement a = unit.getType('A'); |
| 1231 expect(a.isValidMixin, isTrue); |
| 1232 assertNoErrors(source); |
| 1233 verify([source]); |
| 1234 } |
| 1235 |
| 1236 void test_labels_switch() { |
| 1237 Source source = addSource(r''' |
| 1238 void doSwitch(int target) { |
| 1239 switch (target) { |
| 1240 l0: case 0: |
| 1241 continue l1; |
| 1242 l1: case 1: |
| 1243 continue l0; |
| 1244 default: |
| 1245 continue l1; |
| 1246 } |
| 1247 }'''); |
| 1248 LibraryElement library = resolve2(source); |
| 1249 expect(library, isNotNull); |
| 1250 assertNoErrors(source); |
| 1251 verify([source]); |
| 1252 } |
| 1253 |
| 1254 void test_localVariable_types_invoked() { |
| 1255 Source source = addSource(r''' |
| 1256 const A = null; |
| 1257 main() { |
| 1258 var myVar = (int p) => 'foo'; |
| 1259 myVar(42); |
| 1260 }'''); |
| 1261 LibraryElement library = resolve2(source); |
| 1262 expect(library, isNotNull); |
| 1263 CompilationUnit unit = |
| 1264 analysisContext.resolveCompilationUnit(source, library); |
| 1265 expect(unit, isNotNull); |
| 1266 List<bool> found = [false]; |
| 1267 List<CaughtException> thrownException = new List<CaughtException>(1); |
| 1268 unit.accept(new _SimpleResolverTest_localVariable_types_invoked( |
| 1269 this, found, thrownException)); |
| 1270 if (thrownException[0] != null) { |
| 1271 throw new AnalysisException( |
| 1272 "Exception", new CaughtException(thrownException[0], null)); |
| 1273 } |
| 1274 expect(found[0], isTrue); |
| 1275 } |
| 1276 |
| 1277 void test_metadata_class() { |
| 1278 Source source = addSource(r''' |
| 1279 const A = null; |
| 1280 @A class C<A> {}'''); |
| 1281 LibraryElement library = resolve2(source); |
| 1282 expect(library, isNotNull); |
| 1283 CompilationUnitElement unitElement = library.definingCompilationUnit; |
| 1284 expect(unitElement, isNotNull); |
| 1285 List<ClassElement> classes = unitElement.types; |
| 1286 expect(classes, hasLength(1)); |
| 1287 List<ElementAnnotation> annotations = classes[0].metadata; |
| 1288 expect(annotations, hasLength(1)); |
| 1289 assertNoErrors(source); |
| 1290 verify([source]); |
| 1291 CompilationUnit unit = resolveCompilationUnit(source, library); |
| 1292 NodeList<CompilationUnitMember> declarations = unit.declarations; |
| 1293 expect(declarations, hasLength(2)); |
| 1294 Element expectedElement = (declarations[0] as TopLevelVariableDeclaration) |
| 1295 .variables |
| 1296 .variables[0] |
| 1297 .name |
| 1298 .staticElement; |
| 1299 EngineTestCase.assertInstanceOf((obj) => obj is PropertyInducingElement, |
| 1300 PropertyInducingElement, expectedElement); |
| 1301 expectedElement = (expectedElement as PropertyInducingElement).getter; |
| 1302 Element actualElement = |
| 1303 (declarations[1] as ClassDeclaration).metadata[0].name.staticElement; |
| 1304 expect(actualElement, same(expectedElement)); |
| 1305 } |
| 1306 |
| 1307 void test_metadata_field() { |
| 1308 Source source = addSource(r''' |
| 1309 const A = null; |
| 1310 class C { |
| 1311 @A int f; |
| 1312 }'''); |
| 1313 LibraryElement library = resolve2(source); |
| 1314 expect(library, isNotNull); |
| 1315 CompilationUnitElement unit = library.definingCompilationUnit; |
| 1316 expect(unit, isNotNull); |
| 1317 List<ClassElement> classes = unit.types; |
| 1318 expect(classes, hasLength(1)); |
| 1319 FieldElement field = classes[0].fields[0]; |
| 1320 List<ElementAnnotation> annotations = field.metadata; |
| 1321 expect(annotations, hasLength(1)); |
| 1322 assertNoErrors(source); |
| 1323 verify([source]); |
| 1324 } |
| 1325 |
| 1326 void test_metadata_fieldFormalParameter() { |
| 1327 Source source = addSource(r''' |
| 1328 const A = null; |
| 1329 class C { |
| 1330 int f; |
| 1331 C(@A this.f); |
| 1332 }'''); |
| 1333 LibraryElement library = resolve2(source); |
| 1334 expect(library, isNotNull); |
| 1335 CompilationUnitElement unit = library.definingCompilationUnit; |
| 1336 expect(unit, isNotNull); |
| 1337 List<ClassElement> classes = unit.types; |
| 1338 expect(classes, hasLength(1)); |
| 1339 List<ConstructorElement> constructors = classes[0].constructors; |
| 1340 expect(constructors, hasLength(1)); |
| 1341 List<ParameterElement> parameters = constructors[0].parameters; |
| 1342 expect(parameters, hasLength(1)); |
| 1343 List<ElementAnnotation> annotations = parameters[0].metadata; |
| 1344 expect(annotations, hasLength(1)); |
| 1345 assertNoErrors(source); |
| 1346 verify([source]); |
| 1347 } |
| 1348 |
| 1349 void test_metadata_function() { |
| 1350 Source source = addSource(r''' |
| 1351 const A = null; |
| 1352 @A f() {}'''); |
| 1353 LibraryElement library = resolve2(source); |
| 1354 expect(library, isNotNull); |
| 1355 CompilationUnitElement unit = library.definingCompilationUnit; |
| 1356 expect(unit, isNotNull); |
| 1357 List<FunctionElement> functions = unit.functions; |
| 1358 expect(functions, hasLength(1)); |
| 1359 List<ElementAnnotation> annotations = functions[0].metadata; |
| 1360 expect(annotations, hasLength(1)); |
| 1361 assertNoErrors(source); |
| 1362 verify([source]); |
| 1363 } |
| 1364 |
| 1365 void test_metadata_functionTypedParameter() { |
| 1366 Source source = addSource(r''' |
| 1367 const A = null; |
| 1368 f(@A int p(int x)) {}'''); |
| 1369 LibraryElement library = resolve2(source); |
| 1370 expect(library, isNotNull); |
| 1371 CompilationUnitElement unit = library.definingCompilationUnit; |
| 1372 expect(unit, isNotNull); |
| 1373 List<FunctionElement> functions = unit.functions; |
| 1374 expect(functions, hasLength(1)); |
| 1375 List<ParameterElement> parameters = functions[0].parameters; |
| 1376 expect(parameters, hasLength(1)); |
| 1377 List<ElementAnnotation> annotations1 = parameters[0].metadata; |
| 1378 expect(annotations1, hasLength(1)); |
| 1379 assertNoErrors(source); |
| 1380 verify([source]); |
| 1381 } |
| 1382 |
| 1383 void test_metadata_libraryDirective() { |
| 1384 Source source = addSource(r''' |
| 1385 @A library lib; |
| 1386 const A = null;'''); |
| 1387 LibraryElement library = resolve2(source); |
| 1388 expect(library, isNotNull); |
| 1389 List<ElementAnnotation> annotations = library.metadata; |
| 1390 expect(annotations, hasLength(1)); |
| 1391 assertNoErrors(source); |
| 1392 verify([source]); |
| 1393 } |
| 1394 |
| 1395 void test_metadata_method() { |
| 1396 Source source = addSource(r''' |
| 1397 const A = null; |
| 1398 class C { |
| 1399 @A void m() {} |
| 1400 }'''); |
| 1401 LibraryElement library = resolve2(source); |
| 1402 expect(library, isNotNull); |
| 1403 CompilationUnitElement unit = library.definingCompilationUnit; |
| 1404 expect(unit, isNotNull); |
| 1405 List<ClassElement> classes = unit.types; |
| 1406 expect(classes, hasLength(1)); |
| 1407 MethodElement method = classes[0].methods[0]; |
| 1408 List<ElementAnnotation> annotations = method.metadata; |
| 1409 expect(annotations, hasLength(1)); |
| 1410 assertNoErrors(source); |
| 1411 verify([source]); |
| 1412 } |
| 1413 |
| 1414 void test_metadata_namedParameter() { |
| 1415 Source source = addSource(r''' |
| 1416 const A = null; |
| 1417 f({@A int p : 0}) {}'''); |
| 1418 LibraryElement library = resolve2(source); |
| 1419 expect(library, isNotNull); |
| 1420 CompilationUnitElement unit = library.definingCompilationUnit; |
| 1421 expect(unit, isNotNull); |
| 1422 List<FunctionElement> functions = unit.functions; |
| 1423 expect(functions, hasLength(1)); |
| 1424 List<ParameterElement> parameters = functions[0].parameters; |
| 1425 expect(parameters, hasLength(1)); |
| 1426 List<ElementAnnotation> annotations1 = parameters[0].metadata; |
| 1427 expect(annotations1, hasLength(1)); |
| 1428 assertNoErrors(source); |
| 1429 verify([source]); |
| 1430 } |
| 1431 |
| 1432 void test_metadata_positionalParameter() { |
| 1433 Source source = addSource(r''' |
| 1434 const A = null; |
| 1435 f([@A int p = 0]) {}'''); |
| 1436 LibraryElement library = resolve2(source); |
| 1437 expect(library, isNotNull); |
| 1438 CompilationUnitElement unit = library.definingCompilationUnit; |
| 1439 expect(unit, isNotNull); |
| 1440 List<FunctionElement> functions = unit.functions; |
| 1441 expect(functions, hasLength(1)); |
| 1442 List<ParameterElement> parameters = functions[0].parameters; |
| 1443 expect(parameters, hasLength(1)); |
| 1444 List<ElementAnnotation> annotations1 = parameters[0].metadata; |
| 1445 expect(annotations1, hasLength(1)); |
| 1446 assertNoErrors(source); |
| 1447 verify([source]); |
| 1448 } |
| 1449 |
| 1450 void test_metadata_simpleParameter() { |
| 1451 Source source = addSource(r''' |
| 1452 const A = null; |
| 1453 f(@A p1, @A int p2) {}'''); |
| 1454 LibraryElement library = resolve2(source); |
| 1455 expect(library, isNotNull); |
| 1456 CompilationUnitElement unit = library.definingCompilationUnit; |
| 1457 expect(unit, isNotNull); |
| 1458 List<FunctionElement> functions = unit.functions; |
| 1459 expect(functions, hasLength(1)); |
| 1460 List<ParameterElement> parameters = functions[0].parameters; |
| 1461 expect(parameters, hasLength(2)); |
| 1462 List<ElementAnnotation> annotations1 = parameters[0].metadata; |
| 1463 expect(annotations1, hasLength(1)); |
| 1464 List<ElementAnnotation> annotations2 = parameters[1].metadata; |
| 1465 expect(annotations2, hasLength(1)); |
| 1466 assertNoErrors(source); |
| 1467 verify([source]); |
| 1468 } |
| 1469 |
| 1470 void test_metadata_typedef() { |
| 1471 Source source = addSource(r''' |
| 1472 const A = null; |
| 1473 @A typedef F<A>();'''); |
| 1474 LibraryElement library = resolve2(source); |
| 1475 expect(library, isNotNull); |
| 1476 CompilationUnitElement unitElement = library.definingCompilationUnit; |
| 1477 expect(unitElement, isNotNull); |
| 1478 List<FunctionTypeAliasElement> aliases = unitElement.functionTypeAliases; |
| 1479 expect(aliases, hasLength(1)); |
| 1480 List<ElementAnnotation> annotations = aliases[0].metadata; |
| 1481 expect(annotations, hasLength(1)); |
| 1482 assertNoErrors(source); |
| 1483 verify([source]); |
| 1484 CompilationUnit unit = resolveCompilationUnit(source, library); |
| 1485 NodeList<CompilationUnitMember> declarations = unit.declarations; |
| 1486 expect(declarations, hasLength(2)); |
| 1487 Element expectedElement = (declarations[0] as TopLevelVariableDeclaration) |
| 1488 .variables |
| 1489 .variables[0] |
| 1490 .name |
| 1491 .staticElement; |
| 1492 EngineTestCase.assertInstanceOf((obj) => obj is PropertyInducingElement, |
| 1493 PropertyInducingElement, expectedElement); |
| 1494 expectedElement = (expectedElement as PropertyInducingElement).getter; |
| 1495 Element actualElement = |
| 1496 (declarations[1] as FunctionTypeAlias).metadata[0].name.staticElement; |
| 1497 expect(actualElement, same(expectedElement)); |
| 1498 } |
| 1499 |
| 1500 void test_method_fromMixin() { |
| 1501 Source source = addSource(r''' |
| 1502 class B { |
| 1503 bar() => 1; |
| 1504 } |
| 1505 class A { |
| 1506 foo() => 2; |
| 1507 } |
| 1508 |
| 1509 class C extends B with A { |
| 1510 bar() => super.bar(); |
| 1511 foo() => super.foo(); |
| 1512 }'''); |
| 1513 computeLibrarySourceErrors(source); |
| 1514 assertNoErrors(source); |
| 1515 verify([source]); |
| 1516 } |
| 1517 |
| 1518 void test_method_fromMixins() { |
| 1519 Source source = addSource(''' |
| 1520 class B {} |
| 1521 class M1 { |
| 1522 void f() {} |
| 1523 } |
| 1524 class M2 { |
| 1525 void f() {} |
| 1526 } |
| 1527 class C extends B with M1, M2 {} |
| 1528 void main() { |
| 1529 new C().f(); |
| 1530 } |
| 1531 '''); |
| 1532 LibraryElement library = resolve2(source); |
| 1533 assertNoErrors(source); |
| 1534 verify([source]); |
| 1535 // Verify that the "f" in "new C().f()" refers to the "f" defined in M2. |
| 1536 FunctionDeclaration main = |
| 1537 library.definingCompilationUnit.functions[0].computeNode(); |
| 1538 BlockFunctionBody body = main.functionExpression.body; |
| 1539 ExpressionStatement stmt = body.block.statements[0]; |
| 1540 MethodInvocation expr = stmt.expression; |
| 1541 expect(expr.methodName.staticElement.enclosingElement.name, 'M2'); |
| 1542 } |
| 1543 |
| 1544 void test_method_fromMixins_bare_identifier() { |
| 1545 Source source = addSource(''' |
| 1546 class B {} |
| 1547 class M1 { |
| 1548 void f() {} |
| 1549 } |
| 1550 class M2 { |
| 1551 void f() {} |
| 1552 } |
| 1553 class C extends B with M1, M2 { |
| 1554 void g() { |
| 1555 f(); |
| 1556 } |
| 1557 } |
| 1558 '''); |
| 1559 LibraryElement library = resolve2(source); |
| 1560 assertNoErrors(source); |
| 1561 verify([source]); |
| 1562 // Verify that the call to f() in C.g() refers to the method defined in M2. |
| 1563 ClassElement classC = library.definingCompilationUnit.types[3]; |
| 1564 MethodDeclaration g = classC.getMethod('g').computeNode(); |
| 1565 BlockFunctionBody body = g.body; |
| 1566 ExpressionStatement stmt = body.block.statements[0]; |
| 1567 MethodInvocation invocation = stmt.expression; |
| 1568 SimpleIdentifier methodName = invocation.methodName; |
| 1569 expect(methodName.staticElement.enclosingElement.name, 'M2'); |
| 1570 } |
| 1571 |
| 1572 void test_method_fromMixins_invked_from_outside_class() { |
| 1573 Source source = addSource(''' |
| 1574 class B {} |
| 1575 class M1 { |
| 1576 void f() {} |
| 1577 } |
| 1578 class M2 { |
| 1579 void f() {} |
| 1580 } |
| 1581 class C extends B with M1, M2 {} |
| 1582 void main() { |
| 1583 new C().f(); |
| 1584 } |
| 1585 '''); |
| 1586 LibraryElement library = resolve2(source); |
| 1587 assertNoErrors(source); |
| 1588 verify([source]); |
| 1589 // Verify that the call to f() in "new C().f()" refers to the method |
| 1590 // defined in M2. |
| 1591 FunctionDeclaration main = |
| 1592 library.definingCompilationUnit.functions[0].computeNode(); |
| 1593 BlockFunctionBody body = main.functionExpression.body; |
| 1594 ExpressionStatement stmt = body.block.statements[0]; |
| 1595 MethodInvocation invocation = stmt.expression; |
| 1596 expect(invocation.methodName.staticElement.enclosingElement.name, 'M2'); |
| 1597 } |
| 1598 |
| 1599 void test_method_fromSuperclassMixin() { |
| 1600 Source source = addSource(r''' |
| 1601 class A { |
| 1602 void m1() {} |
| 1603 } |
| 1604 class B extends Object with A { |
| 1605 } |
| 1606 class C extends B { |
| 1607 } |
| 1608 f(C c) { |
| 1609 c.m1(); |
| 1610 }'''); |
| 1611 computeLibrarySourceErrors(source); |
| 1612 assertNoErrors(source); |
| 1613 verify([source]); |
| 1614 } |
| 1615 |
| 1616 void test_methodCascades() { |
| 1617 Source source = addSource(r''' |
| 1618 class A { |
| 1619 void m1() {} |
| 1620 void m2() {} |
| 1621 void m() { |
| 1622 A a = new A(); |
| 1623 a..m1() |
| 1624 ..m2(); |
| 1625 } |
| 1626 }'''); |
| 1627 computeLibrarySourceErrors(source); |
| 1628 assertNoErrors(source); |
| 1629 verify([source]); |
| 1630 } |
| 1631 |
| 1632 void test_methodCascades_withSetter() { |
| 1633 Source source = addSource(r''' |
| 1634 class A { |
| 1635 String name; |
| 1636 void m1() {} |
| 1637 void m2() {} |
| 1638 void m() { |
| 1639 A a = new A(); |
| 1640 a..m1() |
| 1641 ..name = 'name' |
| 1642 ..m2(); |
| 1643 } |
| 1644 }'''); |
| 1645 computeLibrarySourceErrors(source); |
| 1646 // failing with error code: INVOCATION_OF_NON_FUNCTION |
| 1647 assertNoErrors(source); |
| 1648 verify([source]); |
| 1649 } |
| 1650 |
| 1651 void test_resolveAgainstNull() { |
| 1652 Source source = addSource(r''' |
| 1653 f(var p) { |
| 1654 return null == p; |
| 1655 }'''); |
| 1656 computeLibrarySourceErrors(source); |
| 1657 assertNoErrors(source); |
| 1658 } |
| 1659 |
| 1660 void test_setter_fromMixins_bare_identifier() { |
| 1661 Source source = addSource(''' |
| 1662 class B {} |
| 1663 class M1 { |
| 1664 set x(value) {} |
| 1665 } |
| 1666 class M2 { |
| 1667 set x(value) {} |
| 1668 } |
| 1669 class C extends B with M1, M2 { |
| 1670 void f() { |
| 1671 x = 1; |
| 1672 } |
| 1673 } |
| 1674 '''); |
| 1675 LibraryElement library = resolve2(source); |
| 1676 assertNoErrors(source); |
| 1677 verify([source]); |
| 1678 // Verify that the setter for "x" in C.f() refers to the setter defined in |
| 1679 // M2. |
| 1680 ClassElement classC = library.definingCompilationUnit.types[3]; |
| 1681 MethodDeclaration f = classC.getMethod('f').computeNode(); |
| 1682 BlockFunctionBody body = f.body; |
| 1683 ExpressionStatement stmt = body.block.statements[0]; |
| 1684 AssignmentExpression assignment = stmt.expression; |
| 1685 SimpleIdentifier leftHandSide = assignment.leftHandSide; |
| 1686 expect(leftHandSide.staticElement.enclosingElement.name, 'M2'); |
| 1687 } |
| 1688 |
| 1689 void test_setter_fromMixins_property_access() { |
| 1690 Source source = addSource(''' |
| 1691 class B {} |
| 1692 class M1 { |
| 1693 set x(value) {} |
| 1694 } |
| 1695 class M2 { |
| 1696 set x(value) {} |
| 1697 } |
| 1698 class C extends B with M1, M2 {} |
| 1699 void main() { |
| 1700 new C().x = 1; |
| 1701 } |
| 1702 '''); |
| 1703 LibraryElement library = resolve2(source); |
| 1704 assertNoErrors(source); |
| 1705 verify([source]); |
| 1706 // Verify that the setter for "x" in "new C().x" refers to the setter |
| 1707 // defined in M2. |
| 1708 FunctionDeclaration main = |
| 1709 library.definingCompilationUnit.functions[0].computeNode(); |
| 1710 BlockFunctionBody body = main.functionExpression.body; |
| 1711 ExpressionStatement stmt = body.block.statements[0]; |
| 1712 AssignmentExpression assignment = stmt.expression; |
| 1713 PropertyAccess propertyAccess = assignment.leftHandSide; |
| 1714 expect( |
| 1715 propertyAccess.propertyName.staticElement.enclosingElement.name, 'M2'); |
| 1716 } |
| 1717 |
| 1718 void test_setter_inherited() { |
| 1719 Source source = addSource(r''' |
| 1720 class A { |
| 1721 int get x => 0; |
| 1722 set x(int p) {} |
| 1723 } |
| 1724 class B extends A { |
| 1725 int get x => super.x == null ? 0 : super.x; |
| 1726 int f() => x = 1; |
| 1727 }'''); |
| 1728 computeLibrarySourceErrors(source); |
| 1729 assertNoErrors(source); |
| 1730 verify([source]); |
| 1731 } |
| 1732 |
| 1733 void test_setter_static() { |
| 1734 Source source = addSource(r''' |
| 1735 set s(x) { |
| 1736 } |
| 1737 |
| 1738 main() { |
| 1739 s = 123; |
| 1740 }'''); |
| 1741 computeLibrarySourceErrors(source); |
| 1742 assertNoErrors(source); |
| 1743 verify([source]); |
| 1744 } |
| 1745 |
| 1746 @failingTest |
| 1747 void test_staticInvocation() { |
| 1748 Source source = addSource(r''' |
| 1749 class A { |
| 1750 static int get g => (a,b) => 0; |
| 1751 } |
| 1752 class B { |
| 1753 f() { |
| 1754 A.g(1,0); |
| 1755 } |
| 1756 }'''); |
| 1757 computeLibrarySourceErrors(source); |
| 1758 assertNoErrors(source); |
| 1759 verify([source]); |
| 1760 } |
| 1761 |
| 1762 /** |
| 1763 * Resolve the given source and verify that the arguments in a specific method
invocation were |
| 1764 * correctly resolved. |
| 1765 * |
| 1766 * The source is expected to be source for a compilation unit, the first decla
ration is expected |
| 1767 * to be a class, the first member of which is expected to be a method with a
block body, and the |
| 1768 * first statement in the body is expected to be an expression statement whose
expression is a |
| 1769 * method invocation. It is the arguments to that method invocation that are t
ested. The method |
| 1770 * invocation can contain errors. |
| 1771 * |
| 1772 * The arguments were resolved correctly if the number of expressions in the l
ist matches the |
| 1773 * length of the array of indices and if, for each index in the array of indic
es, the parameter to |
| 1774 * which the argument expression was resolved is the parameter in the invoked
method's list of |
| 1775 * parameters at that index. Arguments that should not be resolved to a parame
ter because of an |
| 1776 * error can be denoted by including a negative index in the array of indices. |
| 1777 * |
| 1778 * @param source the source to be resolved |
| 1779 * @param indices the array of indices used to associate arguments with parame
ters |
| 1780 * @throws Exception if the source could not be resolved or if the structure o
f the source is not |
| 1781 * valid |
| 1782 */ |
| 1783 void _validateArgumentResolution(Source source, List<int> indices) { |
| 1784 LibraryElement library = resolve2(source); |
| 1785 expect(library, isNotNull); |
| 1786 ClassElement classElement = library.definingCompilationUnit.types[0]; |
| 1787 List<ParameterElement> parameters = classElement.methods[1].parameters; |
| 1788 CompilationUnit unit = resolveCompilationUnit(source, library); |
| 1789 expect(unit, isNotNull); |
| 1790 ClassDeclaration classDeclaration = |
| 1791 unit.declarations[0] as ClassDeclaration; |
| 1792 MethodDeclaration methodDeclaration = |
| 1793 classDeclaration.members[0] as MethodDeclaration; |
| 1794 Block block = (methodDeclaration.body as BlockFunctionBody).block; |
| 1795 ExpressionStatement statement = block.statements[0] as ExpressionStatement; |
| 1796 MethodInvocation invocation = statement.expression as MethodInvocation; |
| 1797 NodeList<Expression> arguments = invocation.argumentList.arguments; |
| 1798 int argumentCount = arguments.length; |
| 1799 expect(argumentCount, indices.length); |
| 1800 for (int i = 0; i < argumentCount; i++) { |
| 1801 Expression argument = arguments[i]; |
| 1802 ParameterElement element = argument.staticParameterElement; |
| 1803 int index = indices[i]; |
| 1804 if (index < 0) { |
| 1805 expect(element, isNull); |
| 1806 } else { |
| 1807 expect(element, same(parameters[index])); |
| 1808 } |
| 1809 } |
| 1810 } |
| 1811 } |
| 1812 |
| 1813 class _SimpleResolverTest_localVariable_types_invoked |
| 1814 extends RecursiveAstVisitor<Object> { |
| 1815 final SimpleResolverTest test; |
| 1816 |
| 1817 List<bool> found; |
| 1818 |
| 1819 List<CaughtException> thrownException; |
| 1820 |
| 1821 _SimpleResolverTest_localVariable_types_invoked( |
| 1822 this.test, this.found, this.thrownException) |
| 1823 : super(); |
| 1824 |
| 1825 @override |
| 1826 Object visitSimpleIdentifier(SimpleIdentifier node) { |
| 1827 if (node.name == "myVar" && node.parent is MethodInvocation) { |
| 1828 try { |
| 1829 found[0] = true; |
| 1830 // check static type |
| 1831 DartType staticType = node.staticType; |
| 1832 expect(staticType, same(test.typeProvider.dynamicType)); |
| 1833 // check propagated type |
| 1834 FunctionType propagatedType = node.propagatedType as FunctionType; |
| 1835 expect(propagatedType.returnType, test.typeProvider.stringType); |
| 1836 } on AnalysisException catch (e, stackTrace) { |
| 1837 thrownException[0] = new CaughtException(e, stackTrace); |
| 1838 } |
| 1839 } |
| 1840 return null; |
| 1841 } |
| 1842 } |
| OLD | NEW |