1 /* 2 * Copyright (C) 2020 The Dagger Authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package dagger.internal.codegen; 18 19 import androidx.room.compiler.processing.util.Source; 20 import com.google.common.collect.ImmutableCollection; 21 import dagger.testing.compile.CompilerTests; 22 import org.junit.Test; 23 import org.junit.runner.RunWith; 24 import org.junit.runners.Parameterized; 25 import org.junit.runners.Parameterized.Parameters; 26 27 @RunWith(Parameterized.class) 28 public class AssistedFactoryErrorsTest { 29 @Parameters(name = "{0}") parameters()30 public static ImmutableCollection<Object[]> parameters() { 31 return CompilerMode.TEST_PARAMETERS; 32 } 33 34 private final CompilerMode compilerMode; 35 AssistedFactoryErrorsTest(CompilerMode compilerMode)36 public AssistedFactoryErrorsTest(CompilerMode compilerMode) { 37 this.compilerMode = compilerMode; 38 } 39 40 @Test testFactoryNotAbstract()41 public void testFactoryNotAbstract() { 42 Source foo = 43 CompilerTests.javaSource( 44 "test.Factory", 45 "package test;", 46 "", 47 "import dagger.assisted.AssistedFactory;", 48 "", 49 "@AssistedFactory class Factory {}"); 50 51 CompilerTests.daggerCompiler(foo) 52 .withProcessingOptions(compilerMode.processorOptions()) 53 .compile( 54 subject -> { 55 subject.hasErrorCount(1); 56 subject.hasErrorContaining( 57 "The @AssistedFactory-annotated type must be either an abstract class or " 58 + "interface."); 59 }); 60 } 61 62 @Test testNestedFactoryNotStatic()63 public void testNestedFactoryNotStatic() { 64 Source foo = 65 CompilerTests.javaSource( 66 "test.Foo", 67 "package test;", 68 "", 69 "import dagger.assisted.Assisted;", 70 "import dagger.assisted.AssistedInject;", 71 "import dagger.assisted.AssistedFactory;", 72 "", 73 "class Foo {", 74 " @AssistedInject", 75 " Foo(@Assisted int i) {}", 76 "", 77 " @AssistedFactory", 78 " abstract class Factory {", 79 " abstract Foo create(int i);", 80 " }", 81 "}"); 82 83 CompilerTests.daggerCompiler(foo) 84 .withProcessingOptions(compilerMode.processorOptions()) 85 .compile( 86 subject -> { 87 subject.hasErrorCount(1); 88 subject.hasErrorContaining("Nested @AssistedFactory-annotated types must be static."); 89 }); 90 } 91 92 @Test testFactoryMissingAbstractMethod()93 public void testFactoryMissingAbstractMethod() { 94 Source factory = 95 CompilerTests.javaSource( 96 "test.Factory", 97 "package test;", 98 "", 99 "import dagger.assisted.AssistedFactory;", 100 "", 101 "@AssistedFactory interface Factory {}"); 102 103 CompilerTests.daggerCompiler(factory) 104 .withProcessingOptions(compilerMode.processorOptions()) 105 .compile( 106 subject -> { 107 subject.hasErrorCount(1); 108 subject.hasErrorContaining( 109 "The @AssistedFactory-annotated type is missing an abstract, non-default method " 110 + "whose return type matches the assisted injection type."); 111 }); 112 } 113 114 @Test testFactoryReturnsNonDeclaredType()115 public void testFactoryReturnsNonDeclaredType() { 116 Source noInject = 117 CompilerTests.javaSource( 118 "test.NoInject", 119 "package test;", 120 "", 121 "final class NoInject {}"); 122 123 Source noAssistedParam = 124 CompilerTests.javaSource( 125 "test.NoAssistedParam", 126 "package test;", 127 "", 128 "import dagger.assisted.AssistedInject;", 129 "", 130 "final class NoAssistedParam {", 131 " @AssistedInject NoAssistedParam() {}", 132 "}"); 133 134 Source factory = 135 CompilerTests.javaSource( 136 "test.Factory", 137 "package test;", 138 "", 139 "import dagger.assisted.AssistedFactory;", 140 "", 141 "@AssistedFactory", 142 "interface Factory<T> {", 143 " int createInt();", // Fails return type not @AssistedInject 144 "", 145 " NoInject createNoInject();", // Fails return type not @AssistedInject 146 "", 147 " NoAssistedParam createNoAssistedParam();", // Succeeds 148 "", 149 " T createT();", // Fails return type not @AssistedInject 150 "}"); 151 152 CompilerTests.daggerCompiler(factory, noInject, noAssistedParam) 153 .withProcessingOptions(compilerMode.processorOptions()) 154 .compile( 155 subject -> { 156 subject.hasErrorCount(4); 157 subject.hasErrorContaining( 158 "The @AssistedFactory-annotated type should contain a single abstract, " 159 + "non-default method but found multiple: [" 160 + "test.Factory.createInt(), " 161 + "test.Factory.createNoInject(), " 162 + "test.Factory.createNoAssistedParam(), " 163 + "test.Factory.createT()" 164 + "]") 165 .onSource(factory) 166 .onLine(6); 167 subject.hasErrorContaining( 168 "Invalid return type: int. " 169 + "An assisted factory's abstract method must return a type with an " 170 + "@AssistedInject-annotated constructor.") 171 .onSource(factory) 172 .onLine(7); 173 subject.hasErrorContaining( 174 "Invalid return type: test.NoInject. " 175 + "An assisted factory's abstract method must return a type with an " 176 + "@AssistedInject-annotated constructor.") 177 .onSource(factory) 178 .onLine(9); 179 subject.hasErrorContaining( 180 "Invalid return type: T. " 181 + "An assisted factory's abstract method must return a type with an " 182 + "@AssistedInject-annotated constructor.") 183 .onSource(factory) 184 .onLine(13); 185 }); 186 } 187 188 @Test testFactoryMultipleAbstractMethods()189 public void testFactoryMultipleAbstractMethods() { 190 Source foo = 191 CompilerTests.javaSource( 192 "test.Foo", 193 "package test;", 194 "", 195 "import dagger.assisted.Assisted;", 196 "import dagger.assisted.AssistedInject;", 197 "", 198 "class Foo {", 199 " @AssistedInject Foo(@Assisted int i) {}", 200 "}"); 201 202 Source fooFactoryInterface = 203 CompilerTests.javaSource( 204 "test.FooFactoryInterface", 205 "package test;", 206 "", 207 "interface FooFactoryInterface {", 208 " Foo createFoo1(int i);", 209 "}"); 210 211 Source fooFactory = 212 CompilerTests.javaSource( 213 "test.FooFactory", 214 "package test;", 215 "", 216 "import dagger.assisted.AssistedFactory;", 217 "", 218 "@AssistedFactory", 219 "interface FooFactory extends FooFactoryInterface {", 220 " Foo createFoo2(int i);", 221 "", 222 " Foo createFoo3(int i);", 223 "}"); 224 225 CompilerTests.daggerCompiler(foo, fooFactory, fooFactoryInterface) 226 .withProcessingOptions(compilerMode.processorOptions()) 227 .compile( 228 subject -> { 229 subject.hasErrorCount(1); 230 subject.hasErrorContaining( 231 "The @AssistedFactory-annotated type should contain a single abstract, " 232 + "non-default method but found multiple: [" 233 + "test.FooFactoryInterface.createFoo1(int), " 234 + "test.FooFactory.createFoo2(int), " 235 + "test.FooFactory.createFoo3(int)" 236 + "]"); 237 }); 238 } 239 240 @Test testFactoryMismatchingParameter()241 public void testFactoryMismatchingParameter() { 242 Source foo = 243 CompilerTests.javaSource( 244 "test.Foo", 245 "package test;", 246 "", 247 "import dagger.assisted.Assisted;", 248 "import dagger.assisted.AssistedInject;", 249 "", 250 "class Foo {", 251 " @AssistedInject Foo(@Assisted int i) {}", 252 "}"); 253 254 Source fooFactory = 255 CompilerTests.javaSource( 256 "test.FooFactory", 257 "package test;", 258 "", 259 "import dagger.assisted.AssistedFactory;", 260 "", 261 "@AssistedFactory", 262 "interface FooFactory {", 263 " Foo create(String i);", 264 "}"); 265 266 CompilerTests.daggerCompiler(foo, fooFactory) 267 .withProcessingOptions(compilerMode.processorOptions()) 268 .compile( 269 subject -> { 270 subject.hasErrorCount(1); 271 subject.hasErrorContaining( 272 "The parameters in the factory method must match the @Assisted parameters in " 273 + "test.Foo."); 274 subject.hasErrorContaining(" Actual: test.FooFactory#create(java.lang.String)"); 275 subject.hasErrorContaining("Expected: test.FooFactory#create(int)"); 276 }); 277 } 278 279 @Test testFactoryMismatchingGenericParameter()280 public void testFactoryMismatchingGenericParameter() { 281 Source foo = 282 CompilerTests.javaSource( 283 "test.Foo", 284 "package test;", 285 "", 286 "import dagger.assisted.Assisted;", 287 "import dagger.assisted.AssistedInject;", 288 "", 289 "class Foo<T> {", 290 " @AssistedInject Foo(@Assisted T t) {}", 291 "}"); 292 293 Source fooFactory = 294 CompilerTests.javaSource( 295 "test.FooFactory", 296 "package test;", 297 "", 298 "import dagger.assisted.AssistedFactory;", 299 "", 300 "@AssistedFactory", 301 "interface FooFactory<T> {", 302 " Foo<T> create(String str);", 303 "}"); 304 305 CompilerTests.daggerCompiler(foo, fooFactory) 306 .withProcessingOptions(compilerMode.processorOptions()) 307 .compile( 308 subject -> { 309 subject.hasErrorCount(1); 310 subject.hasErrorContaining( 311 "The parameters in the factory method must match the @Assisted parameters in " 312 + "test.Foo<T>."); 313 subject.hasErrorContaining(" Actual: test.FooFactory#create(java.lang.String)"); 314 subject.hasErrorContaining("Expected: test.FooFactory#create(T)"); 315 }); 316 } 317 318 @Test testFactoryDuplicateGenericParameter()319 public void testFactoryDuplicateGenericParameter() { 320 Source foo = 321 CompilerTests.javaSource( 322 "test.Foo", 323 "package test;", 324 "", 325 "import dagger.assisted.Assisted;", 326 "import dagger.assisted.AssistedInject;", 327 "", 328 "class Foo<T> {", 329 " @AssistedInject Foo(@Assisted String str, @Assisted T t) {}", 330 "}"); 331 332 Source fooFactory = 333 CompilerTests.javaSource( 334 "test.FooFactory", 335 "package test;", 336 "", 337 "import dagger.assisted.AssistedFactory;", 338 "", 339 "@AssistedFactory", 340 "interface FooFactory {", 341 " Foo<String> create(String str1, String str2);", 342 "}"); 343 344 CompilerTests.daggerCompiler(foo, fooFactory) 345 .withProcessingOptions(compilerMode.processorOptions()) 346 .compile( 347 subject -> { 348 subject.hasErrorCount(1); 349 subject.hasErrorContaining( 350 "@AssistedFactory method has duplicate @Assisted types: " 351 + "@Assisted java.lang.String"); 352 }); 353 } 354 355 @Test testAssistedInjectionRequest()356 public void testAssistedInjectionRequest() { 357 Source foo = 358 CompilerTests.javaSource( 359 "test.Foo", 360 "package test;", 361 "", 362 "import dagger.assisted.Assisted;", 363 "import dagger.assisted.AssistedInject;", 364 "", 365 "class Foo {", 366 " @AssistedInject Foo(@Assisted String str) {}", 367 "}"); 368 369 Source bar = 370 CompilerTests.javaSource( 371 "test.Bar", 372 "package test;", 373 "", 374 "import javax.inject.Inject;", 375 "import javax.inject.Provider;", 376 "", 377 "class Bar {", 378 " @Inject", 379 " Bar(Foo foo, Provider<Foo> fooProvider) {}", 380 "}"); 381 382 Source module = 383 CompilerTests.javaSource( 384 "test.FooModule", 385 "package test;", 386 "", 387 "import dagger.Module;", 388 "import dagger.Provides;", 389 "import javax.inject.Provider;", 390 "", 391 "@Module", 392 "class FooModule {", 393 " @Provides", 394 " static int provideInt(Foo foo, Provider<Foo> fooProvider) {", 395 " return 0;", 396 " }", 397 "}"); 398 399 Source component = 400 CompilerTests.javaSource( 401 "test.FooComponent", 402 "package test;", 403 "", 404 "import dagger.Component;", 405 "import javax.inject.Provider;", 406 "", 407 "@Component", 408 "interface FooComponent {", 409 " Foo foo();", 410 "", 411 " Provider<Foo> fooProvider();", 412 "}"); 413 414 CompilerTests.daggerCompiler(foo, bar, module, component) 415 .withProcessingOptions(compilerMode.processorOptions()) 416 .compile( 417 subject -> { 418 subject.hasErrorCount(6); 419 420 String fooError = 421 "Dagger does not support injecting @AssistedInject type, test.Foo. " 422 + "Did you mean to inject its assisted factory type instead?"; 423 subject.hasErrorContaining(fooError).onSource(bar).onLine(8); 424 subject.hasErrorContaining(fooError).onSource(module).onLine(10); 425 subject.hasErrorContaining(fooError).onSource(component).onLine(8); 426 427 String fooProviderError = 428 "Dagger does not support injecting @AssistedInject type, " 429 + "javax.inject.Provider<test.Foo>. " 430 + "Did you mean to inject its assisted factory type instead?"; 431 subject.hasErrorContaining(fooProviderError).onSource(bar).onLine(8); 432 subject.hasErrorContaining(fooProviderError).onSource(module).onLine(10); 433 subject.hasErrorContaining(fooProviderError).onSource(component).onLine(10); 434 }); 435 } 436 437 @Test testProvidesAssistedBindings()438 public void testProvidesAssistedBindings() { 439 Source foo = 440 CompilerTests.javaSource( 441 "test.Foo", 442 "package test;", 443 "", 444 "import dagger.assisted.Assisted;", 445 "import dagger.assisted.AssistedInject;", 446 "import dagger.assisted.AssistedFactory;", 447 "", 448 "class Foo {", 449 " @AssistedInject Foo(@Assisted int i) {}", 450 "", 451 " @AssistedFactory", 452 " interface Factory {", 453 " Foo create(int i);", 454 " }", 455 "}"); 456 457 Source module = 458 CompilerTests.javaSource( 459 "test.FooModule", 460 "package test;", 461 "", 462 "import dagger.Module;", 463 "import dagger.Provides;", 464 "import javax.inject.Provider;", 465 "", 466 "@Module", 467 "class FooModule {", 468 " @Provides", 469 " static Foo provideFoo() {", 470 " return null;", 471 " }", 472 "", 473 " @Provides", 474 " static Foo.Factory provideFooFactory() {", 475 " return null;", 476 " }", 477 "}"); 478 479 CompilerTests.daggerCompiler(foo, module) 480 .withProcessingOptions(compilerMode.processorOptions()) 481 .compile( 482 subject -> { 483 subject.hasErrorCount(2); 484 subject.hasErrorContaining( 485 "[test.Foo] Dagger does not support providing @AssistedInject types.") 486 .onSource(module) 487 .onLine(10); 488 subject.hasErrorContaining( 489 "[test.Foo.Factory] Dagger does not support providing @AssistedFactory " 490 + "types.") 491 .onSource(module) 492 .onLine(15); 493 }); 494 } 495 496 @Test testProvidesAssistedBindingsAsFactoryBindsInstance()497 public void testProvidesAssistedBindingsAsFactoryBindsInstance() { 498 Source foo = 499 CompilerTests.javaSource( 500 "test.Foo", 501 "package test;", 502 "", 503 "import dagger.assisted.Assisted;", 504 "import dagger.assisted.AssistedInject;", 505 "import dagger.assisted.AssistedFactory;", 506 "", 507 "class Foo {", 508 " @AssistedInject Foo(@Assisted int i) {}", 509 "", 510 " @AssistedFactory", 511 " interface Factory {", 512 " Foo create(int i);", 513 " }", 514 "}"); 515 516 Source component = 517 CompilerTests.javaSource( 518 "test.FooComponent", 519 "package test;", 520 "", 521 "import dagger.Component;", 522 "import dagger.BindsInstance;", 523 "", 524 "@Component", 525 "interface FooComponent {", 526 " @Component.Factory", 527 " interface Factory {", 528 " FooComponent create(", 529 " @BindsInstance Foo foo,", 530 " @BindsInstance Foo.Factory fooFactory);", 531 " }", 532 "}"); 533 534 CompilerTests.daggerCompiler(foo, component) 535 .withProcessingOptions(compilerMode.processorOptions()) 536 .compile( 537 subject -> { 538 subject.hasErrorCount(2); 539 subject.hasErrorContaining( 540 "[test.Foo] Dagger does not support providing @AssistedInject types.") 541 .onSource(component) 542 .onLine(11); 543 subject.hasErrorContaining( 544 "[test.Foo.Factory] Dagger does not support providing @AssistedFactory " 545 + "types.") 546 .onSource(component) 547 .onLine(12); 548 }); 549 } 550 551 @Test testProvidesAssistedBindingsAsBuilderBindsInstance()552 public void testProvidesAssistedBindingsAsBuilderBindsInstance() { 553 Source foo = 554 CompilerTests.javaSource( 555 "test.Foo", 556 "package test;", 557 "", 558 "import dagger.assisted.Assisted;", 559 "import dagger.assisted.AssistedInject;", 560 "import dagger.assisted.AssistedFactory;", 561 "", 562 "class Foo {", 563 " @AssistedInject Foo(@Assisted int i) {}", 564 "", 565 " @AssistedFactory", 566 " interface Factory {", 567 " Foo create(int i);", 568 " }", 569 "}"); 570 571 Source component = 572 CompilerTests.javaSource( 573 "test.FooComponent", 574 "package test;", 575 "", 576 "import dagger.Component;", 577 "import dagger.BindsInstance;", 578 "", 579 "@Component", 580 "interface FooComponent {", 581 " @Component.Builder", 582 " interface Builder {", 583 " @BindsInstance Builder foo(Foo foo);", 584 " @BindsInstance Builder fooFactory(Foo.Factory fooFactory);", 585 " FooComponent build();", 586 " }", 587 "}"); 588 589 CompilerTests.daggerCompiler(foo, component) 590 .withProcessingOptions(compilerMode.processorOptions()) 591 .compile( 592 subject -> { 593 subject.hasErrorCount(2); 594 subject.hasErrorContaining( 595 "[test.Foo] Dagger does not support providing @AssistedInject types.") 596 .onSource(component) 597 .onLine(10); 598 subject.hasErrorContaining( 599 "[test.Foo.Factory] Dagger does not support providing @AssistedFactory " 600 + "types.") 601 .onSource(component) 602 .onLine(11); 603 }); 604 } 605 606 @Test testProvidesAssistedBindingsAsOptional()607 public void testProvidesAssistedBindingsAsOptional() { 608 Source foo = 609 CompilerTests.javaSource( 610 "test.Foo", 611 "package test;", 612 "", 613 "import dagger.assisted.Assisted;", 614 "import dagger.assisted.AssistedInject;", 615 "import dagger.assisted.AssistedFactory;", 616 "", 617 "class Foo {", 618 " @AssistedInject Foo() {}", 619 "", 620 " @AssistedFactory", 621 " interface Factory {", 622 " Foo create();", 623 " }", 624 "}"); 625 626 Source module = 627 CompilerTests.javaSource( 628 "test.FooModule", 629 "package test;", 630 "", 631 "import dagger.BindsOptionalOf;", 632 "import dagger.Module;", 633 "import dagger.Provides;", 634 "", 635 "@Module", 636 "interface FooModule {", 637 " @BindsOptionalOf Foo optionalFoo();", 638 "", 639 " @BindsOptionalOf Foo.Factory optionalFooFactory();", 640 "}"); 641 642 CompilerTests.daggerCompiler(foo, module) 643 .withProcessingOptions(compilerMode.processorOptions()) 644 .compile( 645 subject -> { 646 subject.hasErrorCount(2); 647 subject.hasErrorContaining( 648 "[test.Foo] Dagger does not support providing @AssistedInject types.") 649 .onSource(module) 650 .onLine(9); 651 subject.hasErrorContaining( 652 "[test.Foo.Factory] Dagger does not support providing @AssistedFactory " 653 + "types.") 654 .onSource(module) 655 .onLine(11); 656 }); 657 } 658 659 @Test testInjectsLazyOfAssistedFactory()660 public void testInjectsLazyOfAssistedFactory() { 661 Source foo = 662 CompilerTests.javaSource( 663 "test.Foo", 664 "package test;", 665 "", 666 "import dagger.assisted.Assisted;", 667 "import dagger.assisted.AssistedInject;", 668 "import dagger.assisted.AssistedFactory;", 669 "", 670 "class Foo {", 671 " @AssistedInject Foo(@Assisted int i) {}", 672 "", 673 " @AssistedFactory", 674 " interface Factory {", 675 " Foo create(int i);", 676 " }", 677 "}"); 678 679 Source bar = 680 CompilerTests.javaSource( 681 "test.Bar", 682 "package test;", 683 "", 684 "import dagger.Lazy;", 685 "import javax.inject.Inject;", 686 "", 687 "class Bar {", 688 " @Inject", 689 " Bar(Foo.Factory fooFactory, Lazy<Foo.Factory> fooFactoryLazy) {}", 690 "}"); 691 692 693 CompilerTests.daggerCompiler(foo, bar) 694 .withProcessingOptions(compilerMode.processorOptions()) 695 .compile( 696 subject -> { 697 subject.hasErrorCount(1); 698 subject.hasErrorContaining( 699 "Dagger does not support injecting Lazy<T>, Producer<T>, or Produced<T> " 700 + "when T is an @AssistedFactory-annotated type such as test.Foo.Factory") 701 .onSource(bar) 702 .onLine(8); 703 }); 704 } 705 706 @Test testScopedAssistedInjection()707 public void testScopedAssistedInjection() { 708 Source foo = 709 CompilerTests.javaSource( 710 "test.Foo", 711 "package test;", 712 "", 713 "import dagger.assisted.Assisted;", 714 "import dagger.assisted.AssistedInject;", 715 "import dagger.assisted.AssistedFactory;", 716 "import javax.inject.Singleton;", 717 "", 718 "@Singleton", 719 "class Foo {", 720 " @AssistedInject", 721 " Foo(@Assisted int i) {}", 722 "", 723 " @AssistedFactory", 724 " interface Factory {", 725 " Foo create(int i);", 726 " }", 727 "}"); 728 729 CompilerTests.daggerCompiler(foo) 730 .withProcessingOptions(compilerMode.processorOptions()) 731 .compile( 732 subject -> 733 // Don't assert on the number of errors as Foo_Factory_Impl can also be created 734 // and have errors from the missing Foo_Factory. 735 // TODO(erichang): don't generate the factory impls if there are errors with the 736 // assisted type 737 subject 738 .hasErrorContaining( 739 "A type with an @AssistedInject-annotated constructor cannot be scoped") 740 .onSource(foo) 741 .onLine(8)); 742 } 743 744 @Test testMultipleInjectAnnotations()745 public void testMultipleInjectAnnotations() { 746 Source foo = 747 CompilerTests.javaSource( 748 "test.Foo", 749 "package test;", 750 "", 751 "import dagger.assisted.Assisted;", 752 "import dagger.assisted.AssistedInject;", 753 "import javax.inject.Inject;", 754 "", 755 "class Foo {", 756 " @Inject", 757 " @AssistedInject", 758 " Foo(@Assisted int i) {}", 759 "}"); 760 761 CompilerTests.daggerCompiler(foo) 762 .withProcessingOptions(compilerMode.processorOptions()) 763 .compile( 764 subject -> { 765 subject.hasErrorCount(1); 766 subject.hasErrorContaining( 767 "Constructors cannot be annotated with both @Inject and @AssistedInject"); 768 }); 769 } 770 771 @Test testAssistedInjectWithNoAssistedParametersIsNotInjectable()772 public void testAssistedInjectWithNoAssistedParametersIsNotInjectable() { 773 Source foo = 774 CompilerTests.javaSource( 775 "test.Foo", 776 "package test;", 777 "", 778 "import javax.inject.Inject;", 779 "", 780 "class Foo {", 781 " @Inject", 782 " Foo(Bar bar) {}", 783 "}"); 784 785 Source bar = 786 CompilerTests.javaSource( 787 "test.Bar", 788 "package test;", 789 "", 790 "import dagger.assisted.AssistedInject;", 791 "import javax.inject.Inject;", 792 "", 793 "class Bar {", 794 " @AssistedInject", 795 " Bar() {}", 796 "}"); 797 798 Source component = 799 CompilerTests.javaSource( 800 "test.FooComponent", 801 "package test;", 802 "", 803 "import dagger.Component;", 804 "", 805 "@Component", 806 "interface FooComponent {", 807 " Foo foo();", 808 "}"); 809 810 811 CompilerTests.daggerCompiler(foo, bar, component) 812 .withProcessingOptions(compilerMode.processorOptions()) 813 .compile( 814 subject -> { 815 subject.hasErrorCount(2); 816 subject.hasErrorContaining( 817 "Dagger does not support injecting @AssistedInject type, test.Bar. " 818 + "Did you mean to inject its assisted factory type instead?") 819 .onSource(foo) 820 .onLine(7); 821 subject.hasErrorContaining( 822 "\033[1;31m[Dagger/MissingBinding]\033[0m " 823 + "Foo cannot be provided without an @Inject constructor or an " 824 + "@Provides-annotated method."); 825 }); 826 } 827 828 @Test testInaccessibleFoo()829 public void testInaccessibleFoo() { 830 Source foo = 831 CompilerTests.javaSource( 832 "test.subpackage.InaccessibleFoo", 833 "package test.subpackage;", 834 "", 835 "import dagger.assisted.Assisted;", 836 "import dagger.assisted.AssistedInject;", 837 "", 838 "class InaccessibleFoo {", 839 " @AssistedInject InaccessibleFoo(@Assisted int i) {}", 840 "}"); 841 842 Source fooFactory = 843 CompilerTests.javaSource( 844 "test.subpackage.InaccessibleFooFactory", 845 "package test.subpackage;", 846 "", 847 "import dagger.assisted.AssistedFactory;", 848 "", 849 "@AssistedFactory", 850 "public interface InaccessibleFooFactory {", 851 " InaccessibleFoo create(int i);", 852 "}"); 853 854 Source component = 855 CompilerTests.javaSource( 856 "test.FooFactoryComponent", 857 "package test;", 858 "", 859 "import dagger.Component;", 860 "import test.subpackage.InaccessibleFooFactory;", 861 "", 862 "@Component", 863 "interface FooFactoryComponent {", 864 " InaccessibleFooFactory inaccessibleFooFactory();", 865 "}"); 866 867 CompilerTests.DaggerCompiler daggerCompiler = 868 CompilerTests.daggerCompiler(foo, fooFactory, component) 869 .withProcessingOptions(compilerMode.processorOptions()); 870 871 if (compilerMode == CompilerMode.FAST_INIT_MODE) { 872 // TODO(bcorso): Remove once we fix inaccessible assisted factory imlementation for fastInit. 873 daggerCompiler.compile( 874 subject -> { 875 // TODO(bcorso): We don't report the error count here because javac reports 876 // the error once, whereas ksp reports the error twice. 877 subject 878 .hasErrorContaining( 879 "test.subpackage.InaccessibleFoo is not public in test.subpackage; cannot be " 880 + "accessed from outside package"); 881 }); 882 } else { 883 daggerCompiler.compile(subject -> subject.hasErrorCount(0)); 884 } 885 } 886 887 @Test testAssistedFactoryMethodWithTypeParametersFails()888 public void testAssistedFactoryMethodWithTypeParametersFails() { 889 Source foo = 890 CompilerTests.javaSource( 891 "test.Foo", 892 "package test;", 893 "", 894 "import dagger.assisted.AssistedInject;", 895 "import dagger.assisted.AssistedFactory;", 896 "", 897 "class Foo<T> {", 898 " @AssistedInject", 899 " Foo() {}", 900 "", 901 " @AssistedFactory", 902 " interface FooFactory {", 903 " <T> Foo<T> create();", 904 " }", 905 "}"); 906 907 CompilerTests.daggerCompiler(foo) 908 .withProcessingOptions(compilerMode.processorOptions()) 909 .compile( 910 subject -> { 911 subject.hasErrorCount(1); 912 subject.hasErrorContaining( 913 "@AssistedFactory does not currently support type parameters in the creator " 914 + "method.") 915 .onSource(foo) 916 .onLine(12); 917 }); 918 } 919 } 920