@@ -35,6 +35,24 @@ public static Collection<Object[]> parameters() {
35
35
return CompilerMode .TEST_PARAMETERS ;
36
36
}
37
37
38
+ private static final Source EXECUTOR_MODULE =
39
+ CompilerTests .javaSource (
40
+ "test.ExecutorModule" ,
41
+ "package test;" ,
42
+ "" ,
43
+ "import com.google.common.util.concurrent.MoreExecutors;" ,
44
+ "import dagger.Module;" ,
45
+ "import dagger.Provides;" ,
46
+ "import dagger.producers.Production;" ,
47
+ "import java.util.concurrent.Executor;" ,
48
+ "" ,
49
+ "@Module" ,
50
+ "final class ExecutorModule {" ,
51
+ " @Provides @Production Executor executor() {" ,
52
+ " return MoreExecutors.directExecutor();" ,
53
+ " }" ,
54
+ "}" );
55
+
38
56
@ Rule public GoldenFileRule goldenFileRule = new GoldenFileRule ();
39
57
40
58
private final CompilerMode compilerMode ;
@@ -122,23 +140,6 @@ public ProductionComponentProcessorTest(CompilerMode compilerMode) {
122
140
123
141
@ Test
124
142
public void dependsOnProductionExecutor () throws Exception {
125
- Source moduleFile =
126
- CompilerTests .javaSource (
127
- "test.ExecutorModule" ,
128
- "package test;" ,
129
- "" ,
130
- "import com.google.common.util.concurrent.MoreExecutors;" ,
131
- "import dagger.Module;" ,
132
- "import dagger.Provides;" ,
133
- "import dagger.producers.Production;" ,
134
- "import java.util.concurrent.Executor;" ,
135
- "" ,
136
- "@Module" ,
137
- "final class ExecutorModule {" ,
138
- " @Provides @Production Executor executor() {" ,
139
- " return MoreExecutors.directExecutor();" ,
140
- " }" ,
141
- "}" );
142
143
Source producerModuleFile =
143
144
CompilerTests .javaSource (
144
145
"test.SimpleModule" ,
@@ -175,7 +176,7 @@ public void dependsOnProductionExecutor() throws Exception {
175
176
"}" );
176
177
177
178
String errorMessage = "String may not depend on the production executor" ;
178
- CompilerTests .daggerCompiler (moduleFile , producerModuleFile , componentFile )
179
+ CompilerTests .daggerCompiler (EXECUTOR_MODULE , producerModuleFile , componentFile )
179
180
.withProcessingOptions (compilerMode .processorOptions ())
180
181
.compile (
181
182
subject -> {
@@ -419,23 +420,6 @@ public void productionScope_injectConstructor() throws Exception {
419
420
420
421
@ Test
421
422
public void requestProducerNodeWithProvider_failsWithNotSupportedError () {
422
- Source moduleFile =
423
- CompilerTests .javaSource (
424
- "test.ExecutorModule" ,
425
- "package test;" ,
426
- "" ,
427
- "import com.google.common.util.concurrent.MoreExecutors;" ,
428
- "import dagger.Module;" ,
429
- "import dagger.Provides;" ,
430
- "import dagger.producers.Production;" ,
431
- "import java.util.concurrent.Executor;" ,
432
- "" ,
433
- "@Module" ,
434
- "final class ExecutorModule {" ,
435
- " @Provides @Production Executor executor() {" ,
436
- " return MoreExecutors.directExecutor();" ,
437
- " }" ,
438
- "}" );
439
423
Source producerModuleFile =
440
424
CompilerTests .javaSource (
441
425
"test.SimpleModule" ,
@@ -472,7 +456,7 @@ public void requestProducerNodeWithProvider_failsWithNotSupportedError() {
472
456
" }" ,
473
457
"}" );
474
458
475
- CompilerTests .daggerCompiler (moduleFile , producerModuleFile , componentFile )
459
+ CompilerTests .daggerCompiler (EXECUTOR_MODULE , producerModuleFile , componentFile )
476
460
.withProcessingOptions (compilerMode .processorOptions ())
477
461
.compile (
478
462
subject -> {
@@ -481,4 +465,175 @@ public void requestProducerNodeWithProvider_failsWithNotSupportedError() {
481
465
"request kind PROVIDER cannot be satisfied by production binding" );
482
466
});
483
467
}
468
+
469
+ @ Test
470
+ public void productionBindingKind_failsIfScoped () {
471
+ Source component =
472
+ CompilerTests .javaSource (
473
+ "test.TestComponent" ,
474
+ "package test;" ,
475
+ "" ,
476
+ "import com.google.common.util.concurrent.ListenableFuture;" ,
477
+ "import dagger.producers.ProductionComponent;" ,
478
+ "" ,
479
+ "@ProductionComponent(modules = {ExecutorModule.class, TestModule.class})" ,
480
+ "interface TestComponent {" ,
481
+ " ListenableFuture<String> str();" ,
482
+ "}" );
483
+ Source module =
484
+ CompilerTests .javaSource (
485
+ "test.TestModule" ,
486
+ "package test;" ,
487
+ "" ,
488
+ "import dagger.producers.ProducerModule;" ,
489
+ "import dagger.producers.Produces;" ,
490
+ "import dagger.producers.ProductionScope;" ,
491
+ "import javax.inject.Provider;" ,
492
+ "import java.util.concurrent.Executor;" ,
493
+ "import dagger.producers.Production;" ,
494
+ "" ,
495
+ "@ProducerModule" ,
496
+ "interface TestModule {" ,
497
+ " @ProductionScope" ,
498
+ " @Produces" ,
499
+ " static String provideString() { return \" \" ; }" ,
500
+ "}" );
501
+
502
+ CompilerTests .daggerCompiler (component , module , EXECUTOR_MODULE )
503
+ .withProcessingOptions (compilerMode .processorOptions ())
504
+ .compile (
505
+ subject -> {
506
+ subject .hasErrorCount (1 );
507
+ subject .hasErrorContaining ("@Produces methods cannot be scoped" );
508
+ });
509
+ }
510
+
511
+ @ Test
512
+ public void delegateToProductionBindingKind_failsIfScoped () {
513
+ Source component =
514
+ CompilerTests .javaSource (
515
+ "test.TestComponent" ,
516
+ "package test;" ,
517
+ "" ,
518
+ "import com.google.common.util.concurrent.ListenableFuture;" ,
519
+ "import dagger.producers.ProductionComponent;" ,
520
+ "" ,
521
+ "@ProductionComponent(modules = {ExecutorModule.class, TestModule.class})" ,
522
+ "interface TestComponent {" ,
523
+ " ListenableFuture<Foo> foo();" ,
524
+ "}" );
525
+ Source module =
526
+ CompilerTests .javaSource (
527
+ "test.TestModule" ,
528
+ "package test;" ,
529
+ "" ,
530
+ "import dagger.Binds;" ,
531
+ "import dagger.producers.ProducerModule;" ,
532
+ "import dagger.producers.Produces;" ,
533
+ "import dagger.producers.ProductionScope;" ,
534
+ "import javax.inject.Provider;" ,
535
+ "import java.util.concurrent.Executor;" ,
536
+ "import dagger.producers.Production;" ,
537
+ "" ,
538
+ "@ProducerModule" ,
539
+ "interface TestModule {" ,
540
+ " @ProductionScope" ,
541
+ " @Binds" ,
542
+ " Foo bind(FooImpl impl);" ,
543
+ "" ,
544
+ " @Produces" ,
545
+ " static FooImpl fooImpl() { return new FooImpl(); }" ,
546
+ "}" );
547
+ Source foo =
548
+ CompilerTests .javaSource (
549
+ "test.Foo" ,
550
+ "package test;" ,
551
+ "" ,
552
+ "interface Foo {}" );
553
+ Source fooImpl =
554
+ CompilerTests .javaSource (
555
+ "test.FooImpl" ,
556
+ "package test;" ,
557
+ "" ,
558
+ "final class FooImpl implements Foo {}" );
559
+
560
+ CompilerTests .daggerCompiler (component , module , foo , fooImpl , EXECUTOR_MODULE )
561
+ .withProcessingOptions (compilerMode .processorOptions ())
562
+ .compile (
563
+ subject -> {
564
+ subject .hasErrorCount (1 );
565
+ subject .hasErrorContaining (
566
+ "@ProductionScope @Binds Foo TestModule.bind(FooImpl) cannot be scoped "
567
+ + "because it delegates to an @Produces method" );
568
+ });
569
+ }
570
+
571
+ @ Test
572
+ public void multipleDelegatesToProductionBindingKind_failsIfScoped () {
573
+ Source component =
574
+ CompilerTests .javaSource (
575
+ "test.TestComponent" ,
576
+ "package test;" ,
577
+ "" ,
578
+ "import com.google.common.util.concurrent.ListenableFuture;" ,
579
+ "import dagger.producers.ProductionComponent;" ,
580
+ "" ,
581
+ "@ProductionComponent(modules = {ExecutorModule.class, TestModule.class})" ,
582
+ "interface TestComponent {" ,
583
+ " ListenableFuture<FooSuper> fooSuper();" ,
584
+ "}" );
585
+ Source module =
586
+ CompilerTests .javaSource (
587
+ "test.TestModule" ,
588
+ "package test;" ,
589
+ "" ,
590
+ "import dagger.Binds;" ,
591
+ "import dagger.producers.ProducerModule;" ,
592
+ "import dagger.producers.Produces;" ,
593
+ "import dagger.producers.ProductionScope;" ,
594
+ "import javax.inject.Provider;" ,
595
+ "import java.util.concurrent.Executor;" ,
596
+ "import dagger.producers.Production;" ,
597
+ "" ,
598
+ "@ProducerModule" ,
599
+ "interface TestModule {" ,
600
+ " @ProductionScope" ,
601
+ " @Binds" ,
602
+ " FooSuper bindFooSuper(Foo impl);" ,
603
+ "" ,
604
+ " @Binds" ,
605
+ " Foo bindFoo(FooImpl impl);" ,
606
+ "" ,
607
+ " @Produces" ,
608
+ " static FooImpl fooImpl() { return new FooImpl(); }" ,
609
+ "}" );
610
+ Source fooSuper =
611
+ CompilerTests .javaSource (
612
+ "test.FooSuper" ,
613
+ "package test;" ,
614
+ "" ,
615
+ "interface FooSuper {}" );
616
+ Source foo =
617
+ CompilerTests .javaSource (
618
+ "test.Foo" ,
619
+ "package test;" ,
620
+ "" ,
621
+ "interface Foo extends FooSuper {}" );
622
+ Source fooImpl =
623
+ CompilerTests .javaSource (
624
+ "test.FooImpl" ,
625
+ "package test;" ,
626
+ "" ,
627
+ "final class FooImpl implements Foo {}" );
628
+
629
+ CompilerTests .daggerCompiler (component , module , fooSuper , foo , fooImpl , EXECUTOR_MODULE )
630
+ .withProcessingOptions (compilerMode .processorOptions ())
631
+ .compile (
632
+ subject -> {
633
+ subject .hasErrorCount (1 );
634
+ subject .hasErrorContaining (
635
+ "@ProductionScope @Binds FooSuper TestModule.bindFooSuper(Foo) cannot be scoped "
636
+ + "because it delegates to an @Produces method" );
637
+ });
638
+ }
484
639
}
0 commit comments