1 /* 2 * Copyright (C) 2018 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 static com.google.testing.compile.CompilationSubject.assertThat; 20 import static dagger.internal.codegen.CompilerMode.AHEAD_OF_TIME_SUBCOMPONENTS_MODE; 21 import static dagger.internal.codegen.CompilerMode.FAST_INIT_MODE; 22 import static dagger.internal.codegen.Compilers.CLASS_PATH_WITHOUT_GUAVA_OPTION; 23 import static dagger.internal.codegen.Compilers.compilerWithOptions; 24 import static dagger.internal.codegen.Compilers.daggerCompiler; 25 import static dagger.internal.codegen.GeneratedLines.GENERATED_ANNOTATION; 26 import static dagger.internal.codegen.GeneratedLines.GENERATION_OPTIONS_ANNOTATION; 27 import static dagger.internal.codegen.GeneratedLines.IMPORT_GENERATED_ANNOTATION; 28 29 import com.google.common.collect.ImmutableList; 30 import com.google.testing.compile.Compilation; 31 import com.google.testing.compile.JavaFileObjects; 32 import javax.tools.JavaFileObject; 33 import org.junit.Test; 34 import org.junit.runner.RunWith; 35 import org.junit.runners.JUnit4; 36 37 @RunWith(JUnit4.class) 38 public final class AheadOfTimeSubcomponentsMultibindingsTest { 39 @Test setMultibindings_contributionsInLeaf()40 public void setMultibindings_contributionsInLeaf() { 41 ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder(); 42 createSimplePackagePrivateClasses(filesToCompile, "InLeaf"); 43 filesToCompile.add( 44 JavaFileObjects.forSourceLines( 45 "test.Leaf", 46 "package test;", 47 "", 48 "import dagger.Subcomponent;", 49 "import java.util.Set;", 50 "", 51 "@Subcomponent(modules = LeafModule.class)", 52 "interface Leaf {", 53 " Set<InLeaf> contributionsInLeaf();", 54 "}"), 55 JavaFileObjects.forSourceLines( 56 "test.LeafModule", 57 "package test;", 58 "", 59 "import dagger.Module;", 60 "import dagger.Provides;", 61 "import dagger.multibindings.IntoSet;", 62 "", 63 "@Module", 64 "class LeafModule {", 65 " @Provides", 66 " @IntoSet", 67 " static InLeaf provideInLeaf() {", 68 " return new InLeaf();", 69 " }", 70 "}")); 71 JavaFileObject generatedLeaf = 72 JavaFileObjects.forSourceLines( 73 "test.DaggerLeaf", 74 "package test;", 75 "", 76 "import com.google.common.collect.ImmutableSet;", 77 "import dagger.internal.GenerationOptions;", 78 "import java.util.Set;", 79 IMPORT_GENERATED_ANNOTATION, 80 "", 81 GENERATION_OPTIONS_ANNOTATION, 82 GENERATED_ANNOTATION, 83 "public abstract class DaggerLeaf implements Leaf {", 84 " protected DaggerLeaf() {}", 85 "", 86 " @Override", 87 " public Set<InLeaf> contributionsInLeaf() {", 88 " return ImmutableSet.<InLeaf>of(", 89 " LeafModule_ProvideInLeafFactory.provideInLeaf());", 90 " }", 91 "}"); 92 Compilation compilation = compile(filesToCompile.build()); 93 assertThat(compilation).succeededWithoutWarnings(); 94 assertThat(compilation) 95 .generatedSourceFile("test.DaggerLeaf") 96 .hasSourceEquivalentTo(generatedLeaf); 97 } 98 99 @Test setMultibindings_contributionsInAncestorOnly()100 public void setMultibindings_contributionsInAncestorOnly() { 101 ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder(); 102 createSimplePackagePrivateClasses(filesToCompile, "InAncestor"); 103 filesToCompile.add( 104 JavaFileObjects.forSourceLines( 105 "test.Leaf", 106 "package test;", 107 "", 108 "import dagger.Subcomponent;", 109 "import java.util.Set;", 110 "", 111 "@Subcomponent", 112 "interface Leaf {", 113 " Set<InAncestor> contributionsInAncestor();", 114 "}")); 115 JavaFileObject generatedLeaf = 116 JavaFileObjects.forSourceLines( 117 "test.DaggerLeaf", 118 "package test;", 119 "", 120 "import dagger.internal.GenerationOptions;", 121 "import java.util.Set;", 122 IMPORT_GENERATED_ANNOTATION, 123 "", 124 GENERATION_OPTIONS_ANNOTATION, 125 GENERATED_ANNOTATION, 126 "public abstract class DaggerLeaf implements Leaf {", 127 " protected DaggerLeaf() {}", 128 "", 129 " @Override", 130 " public abstract Set<InAncestor> contributionsInAncestor();", 131 "}"); 132 Compilation compilation = compile(filesToCompile.build()); 133 assertThat(compilation).succeededWithoutWarnings(); 134 assertThat(compilation) 135 .generatedSourceFile("test.DaggerLeaf") 136 .hasSourceEquivalentTo(generatedLeaf); 137 138 filesToCompile.add( 139 JavaFileObjects.forSourceLines( 140 "test.Ancestor", 141 "package test;", 142 "", 143 "import dagger.Subcomponent;", 144 "import java.util.Set;", 145 "", 146 "@Subcomponent(modules = AncestorModule.class)", 147 "interface Ancestor {", 148 " Leaf leaf();", 149 "}"), 150 JavaFileObjects.forSourceLines( 151 "test.AncestorModule", 152 "package test;", 153 "", 154 "import com.google.common.collect.ImmutableSet;", 155 "import dagger.Module;", 156 "import dagger.Provides;", 157 "import dagger.multibindings.ElementsIntoSet;", 158 "import java.util.Set;", 159 "", 160 "@Module", 161 "class AncestorModule {", 162 " @Provides", 163 " @ElementsIntoSet", 164 " static Set<InAncestor> provideInAncestors() {", 165 " return ImmutableSet.of(new InAncestor(), new InAncestor());", 166 " }", 167 "}")); 168 JavaFileObject generatedAncestor = 169 JavaFileObjects.forSourceLines( 170 "test.DaggerAncestor", 171 "package test;", 172 "", 173 "import com.google.common.collect.ImmutableSet;", 174 "import dagger.internal.GenerationOptions;", 175 "import java.util.Set;", 176 IMPORT_GENERATED_ANNOTATION, 177 "", 178 GENERATION_OPTIONS_ANNOTATION, 179 GENERATED_ANNOTATION, 180 "public abstract class DaggerAncestor implements Ancestor {", 181 " protected DaggerAncestor() {}", 182 "", 183 " protected abstract class LeafImpl extends DaggerLeaf {", 184 " protected LeafImpl() {}", 185 "", 186 " @Override", 187 " public Set<InAncestor> contributionsInAncestor() {", 188 " return ImmutableSet.<InAncestor>copyOf(", 189 " AncestorModule_ProvideInAncestorsFactory.provideInAncestors());", 190 " }", 191 " }", 192 "}"); 193 compilation = compile(filesToCompile.build()); 194 assertThat(compilation).succeededWithoutWarnings(); 195 assertThat(compilation) 196 .generatedSourceFile("test.DaggerAncestor") 197 .hasSourceEquivalentTo(generatedAncestor); 198 } 199 200 @Test setMultibindings_contributionsInLeafAndAncestor()201 public void setMultibindings_contributionsInLeafAndAncestor() { 202 ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder(); 203 createSimplePackagePrivateClasses(filesToCompile, "InEachSubcomponent"); 204 filesToCompile.add( 205 JavaFileObjects.forSourceLines( 206 "test.Leaf", 207 "package test;", 208 "", 209 "import dagger.Subcomponent;", 210 "import java.util.Set;", 211 "", 212 "@Subcomponent(modules = LeafModule.class)", 213 "interface Leaf {", 214 " Set<InEachSubcomponent> contributionsInEachSubcomponent();", 215 "}"), 216 JavaFileObjects.forSourceLines( 217 "test.LeafModule", 218 "package test;", 219 "", 220 "import dagger.Module;", 221 "import dagger.Provides;", 222 "import dagger.multibindings.IntoSet;", 223 "", 224 "@Module", 225 "class LeafModule {", 226 " @Provides", 227 " @IntoSet", 228 " static InEachSubcomponent provideInLeaf() {", 229 " return new InEachSubcomponent();", 230 " }", 231 "", 232 " @Provides", 233 " @IntoSet", 234 " static InEachSubcomponent provideAnotherInLeaf() {", 235 " return new InEachSubcomponent();", 236 " }", 237 "}")); 238 JavaFileObject generatedLeaf = 239 JavaFileObjects.forSourceLines( 240 "test.DaggerLeaf", 241 "package test;", 242 "", 243 "import com.google.common.collect.ImmutableSet;", 244 "import dagger.internal.GenerationOptions;", 245 "import java.util.Set;", 246 IMPORT_GENERATED_ANNOTATION, 247 "", 248 GENERATION_OPTIONS_ANNOTATION, 249 GENERATED_ANNOTATION, 250 "public abstract class DaggerLeaf implements Leaf {", 251 " protected DaggerLeaf() {}", 252 "", 253 " @Override", 254 " public Set<InEachSubcomponent> contributionsInEachSubcomponent() {", 255 " return ImmutableSet.<InEachSubcomponent>of(", 256 " LeafModule_ProvideInLeafFactory.provideInLeaf(),", 257 " LeafModule_ProvideAnotherInLeafFactory.provideAnotherInLeaf());", 258 " }", 259 "}"); 260 Compilation compilation = compile(filesToCompile.build()); 261 assertThat(compilation).succeededWithoutWarnings(); 262 assertThat(compilation) 263 .generatedSourceFile("test.DaggerLeaf") 264 .hasSourceEquivalentTo(generatedLeaf); 265 266 filesToCompile.add( 267 JavaFileObjects.forSourceLines( 268 "test.Ancestor", 269 "package test;", 270 "", 271 "import dagger.Subcomponent;", 272 "import java.util.Set;", 273 "", 274 "@Subcomponent(modules = AncestorModule.class)", 275 "interface Ancestor {", 276 " Leaf leaf();", 277 "}"), 278 JavaFileObjects.forSourceLines( 279 "test.AncestorModule", 280 "package test;", 281 "", 282 "import com.google.common.collect.ImmutableSet;", 283 "import dagger.Module;", 284 "import dagger.Provides;", 285 "import dagger.multibindings.ElementsIntoSet;", 286 "import java.util.Set;", 287 "", 288 "@Module", 289 "class AncestorModule {", 290 " @Provides", 291 " @ElementsIntoSet", 292 " static Set<InEachSubcomponent> provideInAncestor() {", 293 " return ImmutableSet.of(new InEachSubcomponent(), new InEachSubcomponent());", 294 " }", 295 "}")); 296 JavaFileObject generatedAncestor = 297 JavaFileObjects.forSourceLines( 298 "test.DaggerAncestor", 299 "package test;", 300 "", 301 "import com.google.common.collect.ImmutableSet;", 302 "import dagger.internal.GenerationOptions;", 303 "import java.util.Set;", 304 IMPORT_GENERATED_ANNOTATION, 305 "", 306 GENERATION_OPTIONS_ANNOTATION, 307 GENERATED_ANNOTATION, 308 "public abstract class DaggerAncestor implements Ancestor {", 309 " protected DaggerAncestor() {}", 310 "", 311 " protected abstract class LeafImpl extends DaggerLeaf {", 312 " protected LeafImpl() {}", 313 "", 314 " @Override", 315 " public Set<InEachSubcomponent> contributionsInEachSubcomponent() {", 316 " return ImmutableSet.<InEachSubcomponent>builderWithExpectedSize(3)", 317 " .addAll(AncestorModule_ProvideInAncestorFactory.provideInAncestor())", 318 " .addAll(super.contributionsInEachSubcomponent())", 319 " .build();", 320 " }", 321 " }", 322 "}"); 323 compilation = compile(filesToCompile.build()); 324 assertThat(compilation).succeededWithoutWarnings(); 325 assertThat(compilation) 326 .generatedSourceFile("test.DaggerAncestor") 327 .hasSourceEquivalentTo(generatedAncestor); 328 } 329 330 @Test setMultibindings_contributionsInLeafAndGrandAncestor()331 public void setMultibindings_contributionsInLeafAndGrandAncestor() { 332 ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder(); 333 createSimplePackagePrivateClasses(filesToCompile, "InLeafAndGrandAncestor"); 334 filesToCompile.add( 335 JavaFileObjects.forSourceLines( 336 "test.Leaf", 337 "package test;", 338 "", 339 "import dagger.Subcomponent;", 340 "import java.util.Set;", 341 "", 342 "@Subcomponent(modules = LeafModule.class)", 343 "interface Leaf {", 344 " Set<InLeafAndGrandAncestor> contributionsInLeafAndGrandAncestor();", 345 "}"), 346 JavaFileObjects.forSourceLines( 347 "test.LeafModule", 348 "package test;", 349 "", 350 "import dagger.Module;", 351 "import dagger.Provides;", 352 "import dagger.multibindings.IntoSet;", 353 "", 354 "@Module", 355 "class LeafModule {", 356 " @Provides", 357 " @IntoSet", 358 " static InLeafAndGrandAncestor provideInLeaf() {", 359 " return new InLeafAndGrandAncestor();", 360 " }", 361 "", 362 " @Provides", 363 " @IntoSet", 364 " static InLeafAndGrandAncestor provideAnotherInLeaf() {", 365 " return new InLeafAndGrandAncestor();", 366 " }", 367 "}")); 368 JavaFileObject generatedLeaf = 369 JavaFileObjects.forSourceLines( 370 "test.DaggerLeaf", 371 "package test;", 372 "", 373 "import com.google.common.collect.ImmutableSet;", 374 "import dagger.internal.GenerationOptions;", 375 "import java.util.Set;", 376 IMPORT_GENERATED_ANNOTATION, 377 "", 378 GENERATION_OPTIONS_ANNOTATION, 379 GENERATED_ANNOTATION, 380 "public abstract class DaggerLeaf implements Leaf {", 381 " protected DaggerLeaf() {}", 382 "", 383 " @Override", 384 " public Set<InLeafAndGrandAncestor> contributionsInLeafAndGrandAncestor() {", 385 " return ImmutableSet.<InLeafAndGrandAncestor>of(", 386 " LeafModule_ProvideInLeafFactory.provideInLeaf(),", 387 " LeafModule_ProvideAnotherInLeafFactory.provideAnotherInLeaf());", 388 " }", 389 "}"); 390 Compilation compilation = compile(filesToCompile.build()); 391 assertThat(compilation).succeededWithoutWarnings(); 392 assertThat(compilation) 393 .generatedSourceFile("test.DaggerLeaf") 394 .hasSourceEquivalentTo(generatedLeaf); 395 396 filesToCompile.add( 397 JavaFileObjects.forSourceLines( 398 "test.Ancestor", 399 "package test;", 400 "", 401 "import dagger.Subcomponent;", 402 "import java.util.Set;", 403 "", 404 "@Subcomponent", 405 "interface Ancestor {", 406 " Leaf leaf();", 407 "}")); 408 JavaFileObject generatedAncestor = 409 JavaFileObjects.forSourceLines( 410 "test.DaggerAncestor", 411 "package test;", 412 "", 413 "import dagger.internal.GenerationOptions;", 414 IMPORT_GENERATED_ANNOTATION, 415 "", 416 GENERATION_OPTIONS_ANNOTATION, 417 GENERATED_ANNOTATION, 418 "public abstract class DaggerAncestor implements Ancestor {", 419 " protected DaggerAncestor() {}", 420 "", 421 " protected abstract class LeafImpl extends DaggerLeaf {", 422 " protected LeafImpl() {}", 423 " }", 424 "}"); 425 compilation = compile(filesToCompile.build()); 426 assertThat(compilation).succeededWithoutWarnings(); 427 assertThat(compilation) 428 .generatedSourceFile("test.DaggerAncestor") 429 .hasSourceEquivalentTo(generatedAncestor); 430 431 filesToCompile.add( 432 JavaFileObjects.forSourceLines( 433 "test.GrandAncestor", 434 "package test;", 435 "", 436 "import dagger.Subcomponent;", 437 "import java.util.Set;", 438 "", 439 "@Subcomponent(modules = GrandAncestorModule.class)", 440 "interface GrandAncestor {", 441 " Leaf leaf();", 442 "}"), 443 JavaFileObjects.forSourceLines( 444 "test.GrandAncestorModule", 445 "package test;", 446 "", 447 "import com.google.common.collect.ImmutableSet;", 448 "import dagger.Module;", 449 "import dagger.Provides;", 450 "import dagger.multibindings.ElementsIntoSet;", 451 "import java.util.Set;", 452 "", 453 "@Module", 454 "class GrandAncestorModule {", 455 " @Provides", 456 " @ElementsIntoSet", 457 " static Set<InLeafAndGrandAncestor> provideInGrandAncestor() {", 458 " return ImmutableSet.of(new InLeafAndGrandAncestor(),", 459 " new InLeafAndGrandAncestor());", 460 " }", 461 "}")); 462 JavaFileObject generatedGrandAncestor = 463 JavaFileObjects.forSourceLines( 464 "test.DaggerGrandAncestor", 465 "package test;", 466 "", 467 "import com.google.common.collect.ImmutableSet;", 468 "import dagger.internal.GenerationOptions;", 469 "import java.util.Set;", 470 IMPORT_GENERATED_ANNOTATION, 471 "", 472 GENERATION_OPTIONS_ANNOTATION, 473 GENERATED_ANNOTATION, 474 "public abstract class DaggerGrandAncestor implements GrandAncestor {", 475 " protected DaggerGrandAncestor() {}", 476 "", 477 " protected abstract class LeafImpl extends DaggerLeaf {", 478 " protected LeafImpl() {}", 479 "", 480 " @Override", 481 " public Set<InLeafAndGrandAncestor> contributionsInLeafAndGrandAncestor() {", 482 " return ImmutableSet.<InLeafAndGrandAncestor>builderWithExpectedSize(3)", 483 " .addAll(GrandAncestorModule_ProvideInGrandAncestorFactory", 484 " .provideInGrandAncestor())", 485 " .addAll(super.contributionsInLeafAndGrandAncestor())", 486 " .build();", 487 " }", 488 " }", 489 "}"); 490 compilation = compile(filesToCompile.build()); 491 assertThat(compilation).succeededWithoutWarnings(); 492 assertThat(compilation) 493 .generatedSourceFile("test.DaggerGrandAncestor") 494 .hasSourceEquivalentTo(generatedGrandAncestor); 495 } 496 497 @Test setMultibindings_nonComponentMethodDependency()498 public void setMultibindings_nonComponentMethodDependency() { 499 ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder(); 500 createSimplePackagePrivateClasses( 501 filesToCompile, "InAllSubcomponents", "RequresInAllSubcomponentsSet"); 502 filesToCompile.add( 503 JavaFileObjects.forSourceLines( 504 "test.Leaf", 505 "package test;", 506 "", 507 "import dagger.Subcomponent;", 508 "import java.util.Set;", 509 "", 510 "@Subcomponent(modules = LeafModule.class)", 511 "interface Leaf {", 512 " RequresInAllSubcomponentsSet requiresNonComponentMethod();", 513 "}"), 514 JavaFileObjects.forSourceLines( 515 "test.LeafModule", 516 "package test;", 517 "", 518 "import dagger.Module;", 519 "import dagger.Provides;", 520 "import dagger.multibindings.IntoSet;", 521 "import java.util.Set;", 522 "", 523 "@Module", 524 "class LeafModule {", 525 " @Provides", 526 " @IntoSet", 527 " static InAllSubcomponents provideInAllSubcomponents() {", 528 " return new InAllSubcomponents();", 529 " }", 530 "", 531 " @Provides", 532 " static RequresInAllSubcomponentsSet providesRequresInAllSubcomponentsSet(", 533 " Set<InAllSubcomponents> inAllSubcomponents) {", 534 " return new RequresInAllSubcomponentsSet();", 535 " }", 536 "}")); 537 JavaFileObject generatedLeaf = 538 JavaFileObjects.forSourceLines( 539 "test.DaggerLeaf", 540 "package test;", 541 "", 542 "import com.google.common.collect.ImmutableSet;", 543 "import dagger.internal.GenerationOptions;", 544 "import java.util.Set;", 545 IMPORT_GENERATED_ANNOTATION, 546 "", 547 GENERATION_OPTIONS_ANNOTATION, 548 GENERATED_ANNOTATION, 549 "public abstract class DaggerLeaf implements Leaf {", 550 " protected DaggerLeaf() {}", 551 "", 552 " @Override", 553 " public RequresInAllSubcomponentsSet requiresNonComponentMethod() {", 554 " return LeafModule_ProvidesRequresInAllSubcomponentsSetFactory", 555 " .providesRequresInAllSubcomponentsSet(getSetOfInAllSubcomponents());", 556 " }", 557 "", 558 " protected Set getSetOfInAllSubcomponents() {", 559 " return ImmutableSet.<InAllSubcomponents>of(", 560 " LeafModule_ProvideInAllSubcomponentsFactory", 561 " .provideInAllSubcomponents());", 562 " }", 563 "}"); 564 Compilation compilation = compile(filesToCompile.build()); 565 assertThat(compilation).succeededWithoutWarnings(); 566 assertThat(compilation) 567 .generatedSourceFile("test.DaggerLeaf") 568 .hasSourceEquivalentTo(generatedLeaf); 569 570 filesToCompile.add( 571 JavaFileObjects.forSourceLines( 572 "test.Ancestor", 573 "package test;", 574 "", 575 "import dagger.Subcomponent;", 576 "", 577 "@Subcomponent(modules = AncestorModule.class)", 578 "interface Ancestor {", 579 " Leaf leaf();", 580 "}"), 581 JavaFileObjects.forSourceLines( 582 "test.AncestorModule", 583 "package test;", 584 "", 585 "import dagger.Module;", 586 "import dagger.Provides;", 587 "import dagger.multibindings.IntoSet;", 588 "", 589 "@Module", 590 "class AncestorModule {", 591 " @Provides", 592 " @IntoSet", 593 " static InAllSubcomponents provideInAllSubcomponents() {", 594 " return new InAllSubcomponents();", 595 " }", 596 "}")); 597 JavaFileObject generatedAncestor = 598 JavaFileObjects.forSourceLines( 599 "test.DaggerAncestor", 600 "package test;", 601 "", 602 "import com.google.common.collect.ImmutableSet;", 603 "import dagger.internal.GenerationOptions;", 604 "import java.util.Set;", 605 IMPORT_GENERATED_ANNOTATION, 606 "", 607 GENERATION_OPTIONS_ANNOTATION, 608 GENERATED_ANNOTATION, 609 "public abstract class DaggerAncestor implements Ancestor {", 610 " protected DaggerAncestor() {}", 611 "", 612 " protected abstract class LeafImpl extends DaggerLeaf {", 613 " protected LeafImpl() {}", 614 "", 615 " @Override", 616 " protected Set getSetOfInAllSubcomponents() {", 617 " return ImmutableSet.<InAllSubcomponents>builderWithExpectedSize(2)", 618 " .add(AncestorModule_ProvideInAllSubcomponentsFactory", 619 " .provideInAllSubcomponents())", 620 " .addAll(super.getSetOfInAllSubcomponents())", 621 " .build();", 622 " }", 623 " }", 624 "}"); 625 compilation = compile(filesToCompile.build()); 626 assertThat(compilation).succeededWithoutWarnings(); 627 assertThat(compilation) 628 .generatedSourceFile("test.DaggerAncestor") 629 .hasSourceEquivalentTo(generatedAncestor); 630 } 631 632 @Test setMultibindings_newSubclass()633 public void setMultibindings_newSubclass() { 634 ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder(); 635 createSimplePackagePrivateClasses(filesToCompile, "InAncestor", "RequiresInAncestorSet"); 636 filesToCompile.add( 637 JavaFileObjects.forSourceLines( 638 "test.Leaf", 639 "package test;", 640 "", 641 "import dagger.Subcomponent;", 642 "", 643 "@Subcomponent", 644 "interface Leaf {", 645 " RequiresInAncestorSet missingWithSetDependency();", 646 "}")); 647 JavaFileObject generatedLeaf = 648 JavaFileObjects.forSourceLines( 649 "test.DaggerLeaf", 650 "package test;", 651 "", 652 "import dagger.internal.GenerationOptions;", 653 IMPORT_GENERATED_ANNOTATION, 654 "", 655 GENERATION_OPTIONS_ANNOTATION, 656 GENERATED_ANNOTATION, 657 "public abstract class DaggerLeaf implements Leaf {", 658 " protected DaggerLeaf() {}", 659 "", 660 " @Override", 661 " public abstract RequiresInAncestorSet missingWithSetDependency();", 662 "}"); 663 Compilation compilation = compile(filesToCompile.build()); 664 assertThat(compilation).succeededWithoutWarnings(); 665 assertThat(compilation) 666 .generatedSourceFile("test.DaggerLeaf") 667 .hasSourceEquivalentTo(generatedLeaf); 668 669 filesToCompile.add( 670 JavaFileObjects.forSourceLines( 671 "test.Ancestor", 672 "package test;", 673 "", 674 "import dagger.Subcomponent;", 675 "", 676 "@Subcomponent(modules = AncestorModule.class)", 677 "interface Ancestor {", 678 " Leaf leaf();", 679 "}"), 680 JavaFileObjects.forSourceLines( 681 "test.AncestorModule", 682 "package test;", 683 "", 684 "import dagger.Module;", 685 "import dagger.Provides;", 686 "import dagger.multibindings.IntoSet;", 687 "import java.util.Set;", 688 "", 689 "@Module", 690 "class AncestorModule {", 691 "", 692 " @Provides", 693 " static RequiresInAncestorSet provideRequiresInAncestorSet(", 694 " Set<InAncestor> inAncestors) {", 695 " return new RequiresInAncestorSet();", 696 " }", 697 "", 698 " @Provides", 699 " @IntoSet", 700 " static InAncestor provideInAncestor() {", 701 " return new InAncestor();", 702 " }", 703 "}")); 704 JavaFileObject generatedAncestor = 705 JavaFileObjects.forSourceLines( 706 "test.DaggerAncestor", 707 "package test;", 708 "", 709 "import com.google.common.collect.ImmutableSet;", 710 "import dagger.internal.GenerationOptions;", 711 "import java.util.Set;", 712 IMPORT_GENERATED_ANNOTATION, 713 "", 714 GENERATION_OPTIONS_ANNOTATION, 715 GENERATED_ANNOTATION, 716 "public abstract class DaggerAncestor implements Ancestor {", 717 " protected DaggerAncestor() {}", 718 "", 719 " private RequiresInAncestorSet getRequiresInAncestorSet() {", 720 " return AncestorModule_ProvideRequiresInAncestorSetFactory", 721 " .provideRequiresInAncestorSet(getSetOfInAncestor());", 722 " }", 723 "", 724 " protected Set getSetOfInAncestor() {", 725 " return ImmutableSet.<InAncestor>of(", 726 " AncestorModule_ProvideInAncestorFactory.provideInAncestor());", 727 " }", 728 "", 729 " protected abstract class LeafImpl extends DaggerLeaf {", 730 " protected LeafImpl() {}", 731 "", 732 " @Override", 733 " public final RequiresInAncestorSet missingWithSetDependency() {", 734 " return DaggerAncestor.this.getRequiresInAncestorSet();", 735 " }", 736 " }", 737 "}"); 738 compilation = compile(filesToCompile.build()); 739 assertThat(compilation).succeededWithoutWarnings(); 740 assertThat(compilation) 741 .generatedSourceFile("test.DaggerAncestor") 742 .hasSourceEquivalentTo(generatedAncestor); 743 } 744 745 @Test setMultibinding_requestedAsInstanceInLeaf_requestedAsFrameworkInstanceFromAncestor()746 public void setMultibinding_requestedAsInstanceInLeaf_requestedAsFrameworkInstanceFromAncestor() { 747 ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder(); 748 createSimplePackagePrivateClasses( 749 filesToCompile, "Multibound", "MissingInLeaf_WillDependOnFrameworkInstance"); 750 filesToCompile.add( 751 JavaFileObjects.forSourceLines( 752 "test.Leaf", 753 "package test;", 754 "", 755 "import dagger.Subcomponent;", 756 "import java.util.Set;", 757 "import javax.inject.Provider;", 758 "", 759 "@Subcomponent(modules = LeafModule.class)", 760 "interface Leaf {", 761 " Set<Multibound> instance();", 762 " MissingInLeaf_WillDependOnFrameworkInstance willDependOnFrameworkInstance();", 763 "}"), 764 JavaFileObjects.forSourceLines( 765 "test.LeafModule", 766 "package test;", 767 "", 768 "import dagger.Module;", 769 "import dagger.Provides;", 770 "import dagger.multibindings.IntoSet;", 771 "import java.util.Set;", 772 "", 773 "@Module", 774 "class LeafModule {", 775 " @Provides", 776 " @IntoSet", 777 " static Multibound contribution() {", 778 " return new Multibound();", 779 " }", 780 "}")); 781 JavaFileObject generatedLeaf = 782 JavaFileObjects.forSourceLines( 783 "test.DaggerLeaf", 784 "package test;", 785 "", 786 "import com.google.common.collect.ImmutableSet;", 787 "import dagger.internal.GenerationOptions;", 788 "import java.util.Set;", 789 IMPORT_GENERATED_ANNOTATION, 790 "", 791 GENERATION_OPTIONS_ANNOTATION, 792 GENERATED_ANNOTATION, 793 "public abstract class DaggerLeaf implements Leaf {", 794 " protected DaggerLeaf() {}", 795 "", 796 " @Override", 797 " public Set<Multibound> instance() {", 798 " return ImmutableSet.<Multibound>of(", 799 " LeafModule_ContributionFactory.contribution());", 800 " }", 801 "", 802 " @Override", 803 " public abstract MissingInLeaf_WillDependOnFrameworkInstance", 804 " willDependOnFrameworkInstance();", 805 "}"); 806 Compilation compilation = compile(filesToCompile.build()); 807 assertThat(compilation).succeededWithoutWarnings(); 808 assertThat(compilation) 809 .generatedSourceFile("test.DaggerLeaf") 810 .hasSourceEquivalentTo(generatedLeaf); 811 812 filesToCompile.add( 813 JavaFileObjects.forSourceLines( 814 "test.Ancestor", 815 "package test;", 816 "", 817 "import dagger.Subcomponent;", 818 "", 819 "@Subcomponent(modules = AncestorModule.class)", 820 "interface Ancestor {", 821 " Leaf leaf();", 822 "}"), 823 JavaFileObjects.forSourceLines( 824 "test.AncestorModule", 825 "package test;", 826 "", 827 "import dagger.Module;", 828 "import dagger.Provides;", 829 "import dagger.multibindings.Multibinds;", 830 "import java.util.Set;", 831 "import javax.inject.Provider;", 832 "", 833 "@Module", 834 "interface AncestorModule {", 835 " @Provides", 836 " static MissingInLeaf_WillDependOnFrameworkInstance providedInAncestor(", 837 " Provider<Set<Multibound>> frameworkInstance) {", 838 " return null;", 839 " }", 840 "", 841 " @Multibinds Set<Multibound> multibinds();", 842 "}")); 843 JavaFileObject generatedAncestor = 844 JavaFileObjects.forSourceLines( 845 "test.DaggerAncestor", 846 "package test;", 847 "", 848 "import dagger.internal.GenerationOptions;", 849 "import dagger.internal.SetFactory;", 850 "import java.util.Set;", 851 IMPORT_GENERATED_ANNOTATION, 852 "import javax.inject.Provider;", 853 "", 854 GENERATION_OPTIONS_ANNOTATION, 855 GENERATED_ANNOTATION, 856 "public abstract class DaggerAncestor implements Ancestor {", 857 " protected DaggerAncestor() {}", 858 "", 859 " protected abstract class LeafImpl extends DaggerLeaf {", 860 " private Provider<Set<Multibound>> setOfMultiboundProvider;", 861 "", 862 " protected LeafImpl() {}", 863 "", 864 " protected void configureInitialization() { ", 865 " initialize();", 866 " }", 867 "", 868 " @SuppressWarnings(\"unchecked\")", 869 " private void initialize() { ", 870 " this.setOfMultiboundProvider =", 871 " SetFactory.<Multibound>builder(1, 0)", 872 " .addProvider(LeafModule_ContributionFactory.create())", 873 " .build();", 874 " }", 875 "", 876 " protected Provider getSetOfMultiboundProvider() {", 877 " return setOfMultiboundProvider;", 878 " }", 879 "", 880 " @Override", 881 " public final MissingInLeaf_WillDependOnFrameworkInstance ", 882 " willDependOnFrameworkInstance() {", 883 " return AncestorModule_ProvidedInAncestorFactory.providedInAncestor(", 884 " getSetOfMultiboundProvider());", 885 " }", 886 " }", 887 "}"); 888 compilation = compile(filesToCompile.build()); 889 assertThat(compilation).succeededWithoutWarnings(); 890 assertThat(compilation) 891 .generatedSourceFile("test.DaggerAncestor") 892 .hasSourceEquivalentTo(generatedAncestor); 893 } 894 895 @Test missingMultibindingInLeaf_onlyContributionsInAncestor_notReModifiedInRoot()896 public void missingMultibindingInLeaf_onlyContributionsInAncestor_notReModifiedInRoot() { 897 ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder(); 898 filesToCompile.add( 899 JavaFileObjects.forSourceLines( 900 "test.Leaf", 901 "package test;", 902 "", 903 "import dagger.Subcomponent;", 904 "import java.util.Set;", 905 "import javax.inject.Provider;", 906 "", 907 "@Subcomponent", 908 "interface Leaf {", 909 " Set<Object> set();", 910 "}")); 911 JavaFileObject generatedLeaf = 912 JavaFileObjects.forSourceLines( 913 "test.DaggerLeaf", 914 "package test;", 915 "", 916 "import dagger.internal.GenerationOptions;", 917 "import java.util.Set;", 918 IMPORT_GENERATED_ANNOTATION, 919 "", 920 GENERATION_OPTIONS_ANNOTATION, 921 GENERATED_ANNOTATION, 922 "public abstract class DaggerLeaf implements Leaf {", 923 " protected DaggerLeaf() {}", 924 "", 925 " @Override", 926 " public abstract Set<Object> set();", 927 "}"); 928 Compilation compilation = compile(filesToCompile.build()); 929 assertThat(compilation).succeededWithoutWarnings(); 930 assertThat(compilation) 931 .generatedSourceFile("test.DaggerLeaf") 932 .hasSourceEquivalentTo(generatedLeaf); 933 934 filesToCompile.add( 935 JavaFileObjects.forSourceLines( 936 "test.Ancestor", 937 "package test;", 938 "", 939 "import dagger.Subcomponent;", 940 "import java.util.Set;", 941 "", 942 "@Subcomponent(modules = AncestorModule.class)", 943 "interface Ancestor {", 944 " Leaf leaf();", 945 "}"), 946 JavaFileObjects.forSourceLines( 947 "test.AncestorModule", 948 "package test;", 949 "", 950 "import dagger.Module;", 951 "import dagger.Provides;", 952 "import dagger.multibindings.IntoSet;", 953 "", 954 "@Module", 955 "class AncestorModule {", 956 " @Provides", 957 " @IntoSet", 958 " static Object onlyContribution() {", 959 " return new Object();", 960 " }", 961 "}")); 962 JavaFileObject generatedAncestor = 963 JavaFileObjects.forSourceLines( 964 "test.DaggerAncestor", 965 "package test;", 966 "", 967 "import com.google.common.collect.ImmutableSet;", 968 "import dagger.internal.GenerationOptions;", 969 "import java.util.Set;", 970 IMPORT_GENERATED_ANNOTATION, 971 "", 972 GENERATION_OPTIONS_ANNOTATION, 973 GENERATED_ANNOTATION, 974 "public abstract class DaggerAncestor implements Ancestor {", 975 " protected DaggerAncestor() {}", 976 "", 977 " protected abstract class LeafImpl extends DaggerLeaf {", 978 " protected LeafImpl() {}", 979 "", 980 " @Override", 981 " public Set<Object> set() {", 982 " return ImmutableSet.<Object>of(", 983 " AncestorModule_OnlyContributionFactory.onlyContribution());", 984 " }", 985 " }", 986 "}"); 987 compilation = compile(filesToCompile.build()); 988 assertThat(compilation).succeededWithoutWarnings(); 989 assertThat(compilation) 990 .generatedSourceFile("test.DaggerAncestor") 991 .hasSourceEquivalentTo(generatedAncestor); 992 993 filesToCompile.add( 994 JavaFileObjects.forSourceLines( 995 "test.Root", 996 "package test;", 997 "", 998 "import dagger.Component;", 999 "", 1000 "@Component", 1001 "interface Root {", 1002 " Ancestor ancestor();", 1003 "}")); 1004 JavaFileObject generatedRoot = 1005 JavaFileObjects.forSourceLines( 1006 "test.DaggerRoot", 1007 "package test;", 1008 "", 1009 IMPORT_GENERATED_ANNOTATION, 1010 "", 1011 GENERATED_ANNOTATION, 1012 "final class DaggerRoot implements Root {", 1013 " private DaggerRoot() {}", 1014 "", 1015 " public static Builder builder() {", 1016 " return new Builder();", 1017 " }", 1018 "", 1019 " public static Root create() {", 1020 " return new Builder().build();", 1021 " }", 1022 "", 1023 " @Override", 1024 " public Ancestor ancestor() {", 1025 " return new AncestorImpl();", 1026 " }", 1027 "", 1028 " static final class Builder {", 1029 " private Builder() {}", 1030 "", 1031 " public Root build() {", 1032 " return new DaggerRoot();", 1033 " }", 1034 " }", 1035 "", 1036 " protected final class AncestorImpl extends DaggerAncestor {", 1037 " private AncestorImpl() {}", 1038 "", 1039 " @Override", 1040 " public Leaf leaf() {", 1041 " return new LeafImpl();", 1042 " }", 1043 "", 1044 " protected final class LeafImpl extends DaggerAncestor.LeafImpl {", 1045 " private LeafImpl() {}", 1046 // This tests a regression case where Dagger used to reimplement Leaf.set(), even though 1047 // there were no new contributions, because the state change from missing -> 1048 // multibinding wasn't properly recorded 1049 " }", 1050 " }", 1051 "}"); 1052 compilation = compile(filesToCompile.build()); 1053 assertThat(compilation).succeededWithoutWarnings(); 1054 assertThat(compilation) 1055 .generatedSourceFile("test.DaggerRoot") 1056 .hasSourceEquivalentTo(generatedRoot); 1057 } 1058 1059 @Test setMultibindings_contributionsInLeafAndAncestor_frameworkInstances()1060 public void setMultibindings_contributionsInLeafAndAncestor_frameworkInstances() { 1061 ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder(); 1062 createSimplePackagePrivateClasses(filesToCompile, "InEachSubcomponent"); 1063 filesToCompile.add( 1064 JavaFileObjects.forSourceLines( 1065 "test.Leaf", 1066 "package test;", 1067 "", 1068 "import dagger.Subcomponent;", 1069 "import java.util.Set;", 1070 "import javax.inject.Provider;", 1071 "", 1072 "@Subcomponent(modules = LeafModule.class)", 1073 "interface Leaf {", 1074 " Provider<Set<InEachSubcomponent>> contributionsInEachSubcomponent();", 1075 "}"), 1076 JavaFileObjects.forSourceLines( 1077 "test.LeafModule", 1078 "package test;", 1079 "", 1080 "import dagger.Module;", 1081 "import dagger.Provides;", 1082 "import dagger.multibindings.IntoSet;", 1083 "", 1084 "@Module", 1085 "class LeafModule {", 1086 " @Provides", 1087 " @IntoSet", 1088 " static InEachSubcomponent provideInLeaf() {", 1089 " return new InEachSubcomponent();", 1090 " }", 1091 "", 1092 " @Provides", 1093 " @IntoSet", 1094 " static InEachSubcomponent provideAnotherInLeaf() {", 1095 " return new InEachSubcomponent();", 1096 " }", 1097 "}")); 1098 JavaFileObject generatedLeaf = 1099 JavaFileObjects.forSourceLines( 1100 "test.DaggerLeaf", 1101 "package test;", 1102 "", 1103 "import dagger.internal.GenerationOptions;", 1104 "import dagger.internal.SetFactory;", 1105 "import java.util.Set;", 1106 IMPORT_GENERATED_ANNOTATION, 1107 "import javax.inject.Provider;", 1108 "", 1109 GENERATION_OPTIONS_ANNOTATION, 1110 GENERATED_ANNOTATION, 1111 "public abstract class DaggerLeaf implements Leaf {", 1112 " private Provider<Set<InEachSubcomponent>> setOfInEachSubcomponentProvider;", 1113 "", 1114 " protected DaggerLeaf() {}", 1115 "", 1116 " protected void configureInitialization() {", 1117 " initialize();", 1118 " }", 1119 "", 1120 " @SuppressWarnings(\"unchecked\")", 1121 " private void initialize() {", 1122 " this.setOfInEachSubcomponentProvider =", 1123 " SetFactory.<InEachSubcomponent>builder(2, 0)", 1124 " .addProvider(LeafModule_ProvideInLeafFactory.create())", 1125 " .addProvider(LeafModule_ProvideAnotherInLeafFactory.create())", 1126 " .build();", 1127 " }", 1128 "", 1129 " @Override", 1130 " public Provider<Set<InEachSubcomponent>> contributionsInEachSubcomponent() {", 1131 " return setOfInEachSubcomponentProvider;", 1132 " }", 1133 "}"); 1134 Compilation compilation = compile(filesToCompile.build()); 1135 assertThat(compilation).succeededWithoutWarnings(); 1136 assertThat(compilation) 1137 .generatedSourceFile("test.DaggerLeaf") 1138 .hasSourceEquivalentTo(generatedLeaf); 1139 1140 filesToCompile.add( 1141 JavaFileObjects.forSourceLines( 1142 "test.Ancestor", 1143 "package test;", 1144 "", 1145 "import dagger.Subcomponent;", 1146 "import java.util.Set;", 1147 "", 1148 "@Subcomponent(modules = AncestorModule.class)", 1149 "interface Ancestor {", 1150 " Leaf leaf();", 1151 "}"), 1152 JavaFileObjects.forSourceLines( 1153 "test.AncestorModule", 1154 "package test;", 1155 "", 1156 "import com.google.common.collect.ImmutableSet;", 1157 "import dagger.Module;", 1158 "import dagger.Provides;", 1159 "import dagger.multibindings.ElementsIntoSet;", 1160 "import java.util.Set;", 1161 "", 1162 "@Module", 1163 "class AncestorModule {", 1164 " @Provides", 1165 " @ElementsIntoSet", 1166 " static Set<InEachSubcomponent> provideInAncestor() {", 1167 " return ImmutableSet.of(new InEachSubcomponent(), new InEachSubcomponent());", 1168 " }", 1169 "}")); 1170 JavaFileObject generatedAncestor = 1171 JavaFileObjects.forSourceLines( 1172 "test.DaggerAncestor", 1173 "package test;", 1174 "", 1175 "import dagger.internal.DelegateFactory;", 1176 "import dagger.internal.GenerationOptions;", 1177 "import dagger.internal.SetFactory;", 1178 "import java.util.Set;", 1179 IMPORT_GENERATED_ANNOTATION, 1180 "import javax.inject.Provider;", 1181 "", 1182 GENERATION_OPTIONS_ANNOTATION, 1183 GENERATED_ANNOTATION, 1184 "public abstract class DaggerAncestor implements Ancestor {", 1185 " protected DaggerAncestor() {}", 1186 "", 1187 " protected abstract class LeafImpl extends DaggerLeaf {", 1188 " private Provider<Set<InEachSubcomponent>> setOfInEachSubcomponentProvider = ", 1189 " new DelegateFactory<>();", 1190 "", 1191 " protected LeafImpl() {}", 1192 "", 1193 " @Override", 1194 " protected void configureInitialization() {", 1195 " super.configureInitialization();", 1196 " initialize();", 1197 " }", 1198 "", 1199 " @SuppressWarnings(\"unchecked\")", 1200 " private void initialize() {", 1201 " DelegateFactory.setDelegate(", 1202 " setOfInEachSubcomponentProvider,", 1203 " SetFactory.<InEachSubcomponent>builder(0, 2)", 1204 " .addCollectionProvider(super.contributionsInEachSubcomponent())", 1205 " .addCollectionProvider(", 1206 " AncestorModule_ProvideInAncestorFactory.create())", 1207 " .build());", 1208 " }", 1209 "", 1210 " @Override", 1211 " public Provider<Set<InEachSubcomponent>> contributionsInEachSubcomponent() {", 1212 " return setOfInEachSubcomponentProvider;", 1213 " }", 1214 " }", 1215 "}"); 1216 compilation = compile(filesToCompile.build()); 1217 assertThat(compilation).succeededWithoutWarnings(); 1218 assertThat(compilation) 1219 .generatedSourceFile("test.DaggerAncestor") 1220 .hasSourceEquivalentTo(generatedAncestor); 1221 } 1222 1223 @Test mapMultibindings_contributionsInLeaf()1224 public void mapMultibindings_contributionsInLeaf() { 1225 ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder(); 1226 createSimplePackagePrivateClasses(filesToCompile, "InLeaf"); 1227 filesToCompile.add( 1228 JavaFileObjects.forSourceLines( 1229 "test.Leaf", 1230 "package test;", 1231 "", 1232 "import dagger.Subcomponent;", 1233 "import java.util.Map;", 1234 "", 1235 "@Subcomponent(modules = LeafModule.class)", 1236 "interface Leaf {", 1237 " Map<String, InLeaf> contributionsInLeaf();", 1238 "}"), 1239 JavaFileObjects.forSourceLines( 1240 "test.LeafModule", 1241 "package test;", 1242 "", 1243 "import dagger.Module;", 1244 "import dagger.Provides;", 1245 "import dagger.multibindings.IntoMap;", 1246 "import dagger.multibindings.StringKey;", 1247 "import java.util.Map;", 1248 "", 1249 "@Module", 1250 "class LeafModule {", 1251 " @Provides", 1252 " @IntoMap", 1253 " @StringKey(\"leafmodule\")", 1254 " static InLeaf provideInLeaf() {", 1255 " return new InLeaf();", 1256 " }", 1257 "}")); 1258 JavaFileObject generatedLeaf = 1259 JavaFileObjects.forSourceLines( 1260 "test.DaggerLeaf", 1261 "package test;", 1262 "", 1263 "import com.google.common.collect.ImmutableMap;", 1264 "import dagger.internal.GenerationOptions;", 1265 "import java.util.Map;", 1266 IMPORT_GENERATED_ANNOTATION, 1267 "", 1268 GENERATION_OPTIONS_ANNOTATION, 1269 GENERATED_ANNOTATION, 1270 "public abstract class DaggerLeaf implements Leaf {", 1271 " protected DaggerLeaf() {}", 1272 "", 1273 " @Override", 1274 " public Map<String, InLeaf> contributionsInLeaf() {", 1275 " return ImmutableMap.<String, InLeaf>of(", 1276 " \"leafmodule\",", 1277 " LeafModule_ProvideInLeafFactory.provideInLeaf());", 1278 " }", 1279 "}"); 1280 Compilation compilation = compile(filesToCompile.build()); 1281 assertThat(compilation).succeededWithoutWarnings(); 1282 assertThat(compilation) 1283 .generatedSourceFile("test.DaggerLeaf") 1284 .hasSourceEquivalentTo(generatedLeaf); 1285 } 1286 1287 @Test mapMultibindings_contributionsInAncestorOnly()1288 public void mapMultibindings_contributionsInAncestorOnly() { 1289 ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder(); 1290 createSimplePackagePrivateClasses(filesToCompile, "InAncestor"); 1291 filesToCompile.add( 1292 JavaFileObjects.forSourceLines( 1293 "test.Leaf", 1294 "package test;", 1295 "", 1296 "import dagger.Subcomponent;", 1297 "import java.util.Map;", 1298 "", 1299 "@Subcomponent", 1300 "interface Leaf {", 1301 " Map<String, InAncestor> contributionsInAncestor();", 1302 "}")); 1303 JavaFileObject generatedLeaf = 1304 JavaFileObjects.forSourceLines( 1305 "test.DaggerLeaf", 1306 "package test;", 1307 "", 1308 "import dagger.internal.GenerationOptions;", 1309 "import java.util.Map;", 1310 IMPORT_GENERATED_ANNOTATION, 1311 "", 1312 GENERATION_OPTIONS_ANNOTATION, 1313 GENERATED_ANNOTATION, 1314 "public abstract class DaggerLeaf implements Leaf {", 1315 " protected DaggerLeaf() {}", 1316 "", 1317 " @Override", 1318 " public abstract Map<String, InAncestor> contributionsInAncestor();", 1319 "}"); 1320 Compilation compilation = compile(filesToCompile.build()); 1321 assertThat(compilation).succeededWithoutWarnings(); 1322 assertThat(compilation) 1323 .generatedSourceFile("test.DaggerLeaf") 1324 .hasSourceEquivalentTo(generatedLeaf); 1325 1326 filesToCompile.add( 1327 JavaFileObjects.forSourceLines( 1328 "test.Ancestor", 1329 "package test;", 1330 "", 1331 "import dagger.Subcomponent;", 1332 "", 1333 "@Subcomponent(modules = AncestorModule.class)", 1334 "interface Ancestor {", 1335 " Leaf leaf();", 1336 "}"), 1337 JavaFileObjects.forSourceLines( 1338 "test.AncestorModule", 1339 "package test;", 1340 "", 1341 "import dagger.Module;", 1342 "import dagger.Provides;", 1343 "import dagger.multibindings.IntoMap;", 1344 "import dagger.multibindings.StringKey;", 1345 "import java.util.Map;", 1346 "", 1347 "@Module", 1348 "class AncestorModule {", 1349 " @Provides", 1350 " @IntoMap", 1351 " @StringKey(\"ancestormodule\")", 1352 " static InAncestor provideInAncestor() {", 1353 " return new InAncestor();", 1354 " }", 1355 "}")); 1356 JavaFileObject generatedAncestor = 1357 JavaFileObjects.forSourceLines( 1358 "test.DaggerAncestor", 1359 "package test;", 1360 "", 1361 "import com.google.common.collect.ImmutableMap;", 1362 "import dagger.internal.GenerationOptions;", 1363 "import java.util.Map;", 1364 IMPORT_GENERATED_ANNOTATION, 1365 "", 1366 GENERATION_OPTIONS_ANNOTATION, 1367 GENERATED_ANNOTATION, 1368 "public abstract class DaggerAncestor implements Ancestor {", 1369 " protected DaggerAncestor() {}", 1370 "", 1371 " protected abstract class LeafImpl extends DaggerLeaf {", 1372 " protected LeafImpl() {}", 1373 "", 1374 " @Override", 1375 " public Map<String, InAncestor> contributionsInAncestor() {", 1376 " return ImmutableMap.<String, InAncestor>of(\"ancestormodule\",", 1377 " AncestorModule_ProvideInAncestorFactory.provideInAncestor());", 1378 " }", 1379 " }", 1380 "}"); 1381 compilation = compile(filesToCompile.build()); 1382 assertThat(compilation).succeededWithoutWarnings(); 1383 assertThat(compilation) 1384 .generatedSourceFile("test.DaggerAncestor") 1385 .hasSourceEquivalentTo(generatedAncestor); 1386 } 1387 1388 @Test mapMultibindings_contributionsInLeafAndAncestor()1389 public void mapMultibindings_contributionsInLeafAndAncestor() { 1390 ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder(); 1391 createSimplePackagePrivateClasses(filesToCompile, "InEachSubcomponent"); 1392 filesToCompile.add( 1393 JavaFileObjects.forSourceLines( 1394 "test.Leaf", 1395 "package test;", 1396 "", 1397 "import dagger.Subcomponent;", 1398 "import java.util.Map;", 1399 "", 1400 "@Subcomponent(modules = LeafModule.class)", 1401 "interface Leaf {", 1402 " Map<String, InEachSubcomponent> contributionsInEachSubcomponent();", 1403 "}"), 1404 JavaFileObjects.forSourceLines( 1405 "test.LeafModule", 1406 "package test;", 1407 "", 1408 "import dagger.Module;", 1409 "import dagger.Provides;", 1410 "import dagger.multibindings.IntoMap;", 1411 "import dagger.multibindings.StringKey;", 1412 "import java.util.Map;", 1413 "", 1414 "@Module", 1415 "class LeafModule {", 1416 " @Provides", 1417 " @IntoMap", 1418 " @StringKey(\"leafmodule\")", 1419 " static InEachSubcomponent provideInLeaf() {", 1420 " return new InEachSubcomponent();", 1421 " }", 1422 "}")); 1423 JavaFileObject generatedLeaf = 1424 JavaFileObjects.forSourceLines( 1425 "test.DaggerLeaf", 1426 "package test;", 1427 "", 1428 "import com.google.common.collect.ImmutableMap;", 1429 "import dagger.internal.GenerationOptions;", 1430 "import java.util.Map;", 1431 IMPORT_GENERATED_ANNOTATION, 1432 "", 1433 GENERATION_OPTIONS_ANNOTATION, 1434 GENERATED_ANNOTATION, 1435 "public abstract class DaggerLeaf implements Leaf {", 1436 " protected DaggerLeaf() {}", 1437 "", 1438 " @Override", 1439 " public Map<String, InEachSubcomponent> contributionsInEachSubcomponent() {", 1440 " return ImmutableMap.<String, InEachSubcomponent>of(", 1441 " \"leafmodule\", LeafModule_ProvideInLeafFactory.provideInLeaf());", 1442 " }", 1443 "}"); 1444 Compilation compilation = compile(filesToCompile.build()); 1445 assertThat(compilation).succeededWithoutWarnings(); 1446 assertThat(compilation) 1447 .generatedSourceFile("test.DaggerLeaf") 1448 .hasSourceEquivalentTo(generatedLeaf); 1449 1450 filesToCompile.add( 1451 JavaFileObjects.forSourceLines( 1452 "test.Ancestor", 1453 "package test;", 1454 "", 1455 "import dagger.Subcomponent;", 1456 "", 1457 "@Subcomponent(modules = AncestorModule.class)", 1458 "interface Ancestor {", 1459 " Leaf leaf();", 1460 "}"), 1461 JavaFileObjects.forSourceLines( 1462 "test.AncestorModule", 1463 "package test;", 1464 "", 1465 "import dagger.Module;", 1466 "import dagger.Provides;", 1467 "import dagger.multibindings.IntoMap;", 1468 "import dagger.multibindings.StringKey;", 1469 "import java.util.Map;", 1470 "", 1471 "@Module", 1472 "class AncestorModule {", 1473 " @Provides", 1474 " @IntoMap", 1475 " @StringKey(\"ancestormodule\")", 1476 " static InEachSubcomponent provideInAncestor() {", 1477 " return new InEachSubcomponent();", 1478 " }", 1479 "}")); 1480 JavaFileObject generatedAncestor = 1481 JavaFileObjects.forSourceLines( 1482 "test.DaggerAncestor", 1483 "package test;", 1484 "", 1485 "import com.google.common.collect.ImmutableMap;", 1486 "import dagger.internal.GenerationOptions;", 1487 "import java.util.Map;", 1488 IMPORT_GENERATED_ANNOTATION, 1489 "", 1490 GENERATION_OPTIONS_ANNOTATION, 1491 GENERATED_ANNOTATION, 1492 "public abstract class DaggerAncestor implements Ancestor {", 1493 " protected DaggerAncestor() {}", 1494 "", 1495 " protected abstract class LeafImpl extends DaggerLeaf {", 1496 " protected LeafImpl() {}", 1497 "", 1498 " @Override", 1499 " public Map<String, InEachSubcomponent> contributionsInEachSubcomponent() {", 1500 " return ImmutableMap.<String, InEachSubcomponent>builderWithExpectedSize(2)", 1501 " .put(\"ancestormodule\",", 1502 " AncestorModule_ProvideInAncestorFactory.provideInAncestor())", 1503 " .putAll(super.contributionsInEachSubcomponent())", 1504 " .build();", 1505 " }", 1506 " }", 1507 "}"); 1508 compilation = compile(filesToCompile.build()); 1509 assertThat(compilation).succeededWithoutWarnings(); 1510 assertThat(compilation) 1511 .generatedSourceFile("test.DaggerAncestor") 1512 .hasSourceEquivalentTo(generatedAncestor); 1513 } 1514 1515 @Test mapMultibindings_contributionsInLeafAndAncestor_frameworkInstance()1516 public void mapMultibindings_contributionsInLeafAndAncestor_frameworkInstance() { 1517 ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder(); 1518 createSimplePackagePrivateClasses(filesToCompile, "InEachSubcomponent"); 1519 filesToCompile.add( 1520 JavaFileObjects.forSourceLines( 1521 "test.Leaf", 1522 "package test;", 1523 "", 1524 "import dagger.Subcomponent;", 1525 "import java.util.Map;", 1526 "import javax.inject.Provider;", 1527 "", 1528 "@Subcomponent(modules = LeafModule.class)", 1529 "interface Leaf {", 1530 " Provider<Map<String, InEachSubcomponent>> contributionsInEachSubcomponent();", 1531 "}"), 1532 JavaFileObjects.forSourceLines( 1533 "test.LeafModule", 1534 "package test;", 1535 "", 1536 "import dagger.Module;", 1537 "import dagger.Provides;", 1538 "import dagger.multibindings.IntoMap;", 1539 "import dagger.multibindings.StringKey;", 1540 "import java.util.Map;", 1541 "", 1542 "@Module", 1543 "class LeafModule {", 1544 " @Provides", 1545 " @IntoMap", 1546 " @StringKey(\"leafmodule\")", 1547 " static InEachSubcomponent provideInLeaf() {", 1548 " return new InEachSubcomponent();", 1549 " }", 1550 "}")); 1551 JavaFileObject generatedLeaf = 1552 JavaFileObjects.forSourceLines( 1553 "test.DaggerLeaf", 1554 "package test;", 1555 "", 1556 "import dagger.internal.GenerationOptions;", 1557 "import dagger.internal.MapFactory;", 1558 "import java.util.Map;", 1559 IMPORT_GENERATED_ANNOTATION, 1560 "import javax.inject.Provider;", 1561 "", 1562 GENERATION_OPTIONS_ANNOTATION, 1563 GENERATED_ANNOTATION, 1564 "public abstract class DaggerLeaf implements Leaf {", 1565 " private Provider<Map<String, InEachSubcomponent>> ", 1566 " mapOfStringAndInEachSubcomponentProvider;", 1567 "", 1568 " protected DaggerLeaf() {}", 1569 "", 1570 " protected void configureInitialization() {", 1571 " initialize();", 1572 " }", 1573 "", 1574 " @SuppressWarnings(\"unchecked\")", 1575 " private void initialize() {", 1576 " this.mapOfStringAndInEachSubcomponentProvider =", 1577 " MapFactory.<String, InEachSubcomponent>builder(1)", 1578 " .put(\"leafmodule\", LeafModule_ProvideInLeafFactory.create())", 1579 " .build();", 1580 " }", 1581 "", 1582 " @Override", 1583 " public Provider<Map<String, InEachSubcomponent>> ", 1584 " contributionsInEachSubcomponent() {", 1585 " return mapOfStringAndInEachSubcomponentProvider;", 1586 " }", 1587 "}"); 1588 Compilation compilation = compile(filesToCompile.build()); 1589 assertThat(compilation).succeededWithoutWarnings(); 1590 assertThat(compilation) 1591 .generatedSourceFile("test.DaggerLeaf") 1592 .hasSourceEquivalentTo(generatedLeaf); 1593 1594 filesToCompile.add( 1595 JavaFileObjects.forSourceLines( 1596 "test.Ancestor", 1597 "package test;", 1598 "", 1599 "import dagger.Subcomponent;", 1600 "", 1601 "@Subcomponent(modules = AncestorModule.class)", 1602 "interface Ancestor {", 1603 " Leaf leaf();", 1604 "}"), 1605 JavaFileObjects.forSourceLines( 1606 "test.AncestorModule", 1607 "package test;", 1608 "", 1609 "import dagger.Module;", 1610 "import dagger.Provides;", 1611 "import dagger.multibindings.IntoMap;", 1612 "import dagger.multibindings.StringKey;", 1613 "import java.util.Map;", 1614 "", 1615 "@Module", 1616 "class AncestorModule {", 1617 " @Provides", 1618 " @IntoMap", 1619 " @StringKey(\"ancestormodule\")", 1620 " static InEachSubcomponent provideInAncestor() {", 1621 " return new InEachSubcomponent();", 1622 " }", 1623 "}")); 1624 JavaFileObject generatedAncestor = 1625 JavaFileObjects.forSourceLines( 1626 "test.DaggerAncestor", 1627 "package test;", 1628 "", 1629 "import dagger.internal.DelegateFactory;", 1630 "import dagger.internal.GenerationOptions;", 1631 "import dagger.internal.MapFactory;", 1632 "import java.util.Map;", 1633 IMPORT_GENERATED_ANNOTATION, 1634 "import javax.inject.Provider;", 1635 "", 1636 GENERATION_OPTIONS_ANNOTATION, 1637 GENERATED_ANNOTATION, 1638 "public abstract class DaggerAncestor implements Ancestor {", 1639 " protected DaggerAncestor() {}", 1640 "", 1641 " protected abstract class LeafImpl extends DaggerLeaf {", 1642 " private Provider<Map<String, InEachSubcomponent>> ", 1643 " mapOfStringAndInEachSubcomponentProvider = new DelegateFactory<>();", 1644 "", 1645 " protected LeafImpl() {}", 1646 "", 1647 " @Override", 1648 " protected void configureInitialization() { ", 1649 " super.configureInitialization();", 1650 " initialize();", 1651 " }", 1652 "", 1653 " @SuppressWarnings(\"unchecked\")", 1654 " private void initialize() { ", 1655 " DelegateFactory.setDelegate(", 1656 " mapOfStringAndInEachSubcomponentProvider,", 1657 " MapFactory.<String, InEachSubcomponent>builder(2)", 1658 " .putAll(super.contributionsInEachSubcomponent())", 1659 " .put(", 1660 " \"ancestormodule\",", 1661 " AncestorModule_ProvideInAncestorFactory.create())", 1662 " .build());", 1663 " }", 1664 "", 1665 " @Override", 1666 " public Provider<Map<String, InEachSubcomponent>> ", 1667 " contributionsInEachSubcomponent() {", 1668 " return mapOfStringAndInEachSubcomponentProvider;", 1669 " }", 1670 " }", 1671 "}"); 1672 compilation = compile(filesToCompile.build()); 1673 assertThat(compilation).succeededWithoutWarnings(); 1674 assertThat(compilation) 1675 .generatedSourceFile("test.DaggerAncestor") 1676 .hasSourceEquivalentTo(generatedAncestor); 1677 } 1678 1679 @Test mapMultibindings_contributionsInLeafAndGrandAncestor()1680 public void mapMultibindings_contributionsInLeafAndGrandAncestor() { 1681 ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder(); 1682 createSimplePackagePrivateClasses(filesToCompile, "InLeafAndGrandAncestor"); 1683 filesToCompile.add( 1684 JavaFileObjects.forSourceLines( 1685 "test.Leaf", 1686 "package test;", 1687 "", 1688 "import dagger.Subcomponent;", 1689 "import java.util.Map;", 1690 "", 1691 "@Subcomponent(modules = LeafModule.class)", 1692 "interface Leaf {", 1693 " Map<String, InLeafAndGrandAncestor> contributionsInLeafAndGrandAncestor();", 1694 "}"), 1695 JavaFileObjects.forSourceLines( 1696 "test.LeafModule", 1697 "package test;", 1698 "", 1699 "import dagger.Module;", 1700 "import dagger.Provides;", 1701 "import dagger.multibindings.IntoMap;", 1702 "import dagger.multibindings.StringKey;", 1703 "import java.util.Map;", 1704 "", 1705 "@Module", 1706 "class LeafModule {", 1707 " @Provides", 1708 " @IntoMap", 1709 " @StringKey(\"leafmodule\")", 1710 " static InLeafAndGrandAncestor provideInLeaf() {", 1711 " return new InLeafAndGrandAncestor();", 1712 " }", 1713 "}")); 1714 JavaFileObject generatedLeaf = 1715 JavaFileObjects.forSourceLines( 1716 "test.DaggerLeaf", 1717 "package test;", 1718 "", 1719 "import com.google.common.collect.ImmutableMap;", 1720 "import dagger.internal.GenerationOptions;", 1721 "import java.util.Map;", 1722 IMPORT_GENERATED_ANNOTATION, 1723 "", 1724 GENERATION_OPTIONS_ANNOTATION, 1725 GENERATED_ANNOTATION, 1726 "public abstract class DaggerLeaf implements Leaf {", 1727 " protected DaggerLeaf() {}", 1728 "", 1729 " @Override", 1730 " public Map<String, InLeafAndGrandAncestor> contributionsInLeafAndGrandAncestor() {", 1731 " return ImmutableMap.<String, InLeafAndGrandAncestor>of(", 1732 " \"leafmodule\", LeafModule_ProvideInLeafFactory.provideInLeaf());", 1733 " }", 1734 "}"); 1735 Compilation compilation = compile(filesToCompile.build()); 1736 assertThat(compilation).succeededWithoutWarnings(); 1737 assertThat(compilation) 1738 .generatedSourceFile("test.DaggerLeaf") 1739 .hasSourceEquivalentTo(generatedLeaf); 1740 1741 filesToCompile.add( 1742 JavaFileObjects.forSourceLines( 1743 "test.Ancestor", 1744 "package test;", 1745 "", 1746 "import dagger.Subcomponent;", 1747 "", 1748 "@Subcomponent", 1749 "interface Ancestor {", 1750 " Leaf leaf();", 1751 "}")); 1752 JavaFileObject generatedAncestor = 1753 JavaFileObjects.forSourceLines( 1754 "test.DaggerAncestor", 1755 "package test;", 1756 "", 1757 "import dagger.internal.GenerationOptions;", 1758 IMPORT_GENERATED_ANNOTATION, 1759 "", 1760 GENERATION_OPTIONS_ANNOTATION, 1761 GENERATED_ANNOTATION, 1762 "public abstract class DaggerAncestor implements Ancestor {", 1763 " protected DaggerAncestor() {}", 1764 "", 1765 " protected abstract class LeafImpl extends DaggerLeaf {", 1766 " protected LeafImpl() {}", 1767 " }", 1768 "}"); 1769 compilation = compile(filesToCompile.build()); 1770 assertThat(compilation).succeededWithoutWarnings(); 1771 assertThat(compilation) 1772 .generatedSourceFile("test.DaggerAncestor") 1773 .hasSourceEquivalentTo(generatedAncestor); 1774 1775 filesToCompile.add( 1776 JavaFileObjects.forSourceLines( 1777 "test.GrandAncestor", 1778 "package test;", 1779 "", 1780 "import dagger.Subcomponent;", 1781 "", 1782 "@Subcomponent(modules = GrandAncestorModule.class)", 1783 "interface GrandAncestor {", 1784 " Ancestor ancestor();", 1785 "}"), 1786 JavaFileObjects.forSourceLines( 1787 "test.GrandAncestorModule", 1788 "package test;", 1789 "", 1790 "import dagger.Module;", 1791 "import dagger.Provides;", 1792 "import dagger.multibindings.IntoMap;", 1793 "import dagger.multibindings.StringKey;", 1794 "import java.util.Map;", 1795 "", 1796 "@Module", 1797 "class GrandAncestorModule {", 1798 " @Provides", 1799 " @IntoMap", 1800 " @StringKey(\"grandancestormodule\")", 1801 " static InLeafAndGrandAncestor provideInGrandAncestor() {", 1802 " return new InLeafAndGrandAncestor();", 1803 " }", 1804 "}")); 1805 JavaFileObject generatedGrandAncestor = 1806 JavaFileObjects.forSourceLines( 1807 "test.DaggerGrandAncestor", 1808 "package test;", 1809 "", 1810 "import com.google.common.collect.ImmutableMap;", 1811 "import dagger.internal.GenerationOptions;", 1812 "import java.util.Map;", 1813 IMPORT_GENERATED_ANNOTATION, 1814 "", 1815 GENERATION_OPTIONS_ANNOTATION, 1816 GENERATED_ANNOTATION, 1817 "public abstract class DaggerGrandAncestor implements GrandAncestor {", 1818 " protected DaggerGrandAncestor() {}", 1819 "", 1820 " protected abstract class AncestorImpl extends DaggerAncestor {", 1821 " protected AncestorImpl() {}", 1822 "", 1823 " protected abstract class LeafImpl extends DaggerAncestor.LeafImpl {", 1824 " protected LeafImpl() {}", 1825 "", 1826 " @Override", 1827 " public Map<String, InLeafAndGrandAncestor>", 1828 " contributionsInLeafAndGrandAncestor() {", 1829 " return", 1830 " ImmutableMap.<String, InLeafAndGrandAncestor>builderWithExpectedSize(2)", 1831 " .put(\"grandancestormodule\",", 1832 " GrandAncestorModule_ProvideInGrandAncestorFactory", 1833 " .provideInGrandAncestor())", 1834 " .putAll(super.contributionsInLeafAndGrandAncestor())", 1835 " .build();", 1836 " }", 1837 " }", 1838 " }", 1839 "}"); 1840 compilation = compile(filesToCompile.build()); 1841 assertThat(compilation).succeededWithoutWarnings(); 1842 assertThat(compilation) 1843 .generatedSourceFile("test.DaggerGrandAncestor") 1844 .hasSourceEquivalentTo(generatedGrandAncestor); 1845 } 1846 1847 @Test mapMultibindings_contributionsInLeafAndAncestorWithoutGuava()1848 public void mapMultibindings_contributionsInLeafAndAncestorWithoutGuava() { 1849 ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder(); 1850 createSimplePackagePrivateClasses(filesToCompile, "InEachSubcomponent"); 1851 filesToCompile.add( 1852 JavaFileObjects.forSourceLines( 1853 "test.Leaf", 1854 "package test;", 1855 "", 1856 "import dagger.Subcomponent;", 1857 "import java.util.Map;", 1858 "", 1859 "@Subcomponent(modules = LeafModule.class)", 1860 "interface Leaf {", 1861 " Map<String, InEachSubcomponent> contributionsInEachSubcomponent();", 1862 "}"), 1863 JavaFileObjects.forSourceLines( 1864 "test.LeafModule", 1865 "package test;", 1866 "", 1867 "import dagger.Module;", 1868 "import dagger.Provides;", 1869 "import dagger.multibindings.IntoMap;", 1870 "import dagger.multibindings.StringKey;", 1871 "import java.util.Map;", 1872 "", 1873 "@Module", 1874 "class LeafModule {", 1875 " @Provides", 1876 " @IntoMap", 1877 " @StringKey(\"leafmodule\")", 1878 " static InEachSubcomponent provideInLeaf() {", 1879 " return new InEachSubcomponent();", 1880 " }", 1881 "}")); 1882 JavaFileObject generatedLeaf = 1883 JavaFileObjects.forSourceLines( 1884 "test.DaggerLeaf", 1885 "package test;", 1886 "", 1887 "import dagger.internal.GenerationOptions;", 1888 "import java.util.Collections;", 1889 "import java.util.Map", 1890 IMPORT_GENERATED_ANNOTATION, 1891 "", 1892 GENERATION_OPTIONS_ANNOTATION, 1893 GENERATED_ANNOTATION, 1894 "public abstract class DaggerLeaf implements Leaf {", 1895 " protected DaggerLeaf() {}", 1896 "", 1897 " @Override", 1898 " public Map<String, InEachSubcomponent> contributionsInEachSubcomponent() {", 1899 " return Collections.<String, InEachSubcomponent>singletonMap(", 1900 " \"leafmodule\", LeafModule_ProvideInLeafFactory.provideInLeaf());", 1901 " }", 1902 "}"); 1903 Compilation compilation = compileWithoutGuava(filesToCompile.build()); 1904 assertThat(compilation).succeededWithoutWarnings(); 1905 assertThat(compilation) 1906 .generatedSourceFile("test.DaggerLeaf") 1907 .hasSourceEquivalentTo(generatedLeaf); 1908 1909 filesToCompile.add( 1910 JavaFileObjects.forSourceLines( 1911 "test.Ancestor", 1912 "package test;", 1913 "", 1914 "import dagger.Subcomponent;", 1915 "", 1916 "@Subcomponent(modules = AncestorModule.class)", 1917 "interface Ancestor {", 1918 " Leaf leaf();", 1919 "}"), 1920 JavaFileObjects.forSourceLines( 1921 "test.AncestorModule", 1922 "package test;", 1923 "", 1924 "import dagger.Module;", 1925 "import dagger.Provides;", 1926 "import dagger.multibindings.IntoMap;", 1927 "import dagger.multibindings.StringKey;", 1928 "import java.util.Map;", 1929 "", 1930 "@Module", 1931 "class AncestorModule {", 1932 " @Provides", 1933 " @IntoMap", 1934 " @StringKey(\"ancestormodule\")", 1935 " static InEachSubcomponent provideInAncestor() {", 1936 " return new InEachSubcomponent();", 1937 " }", 1938 "}")); 1939 JavaFileObject generatedAncestor = 1940 JavaFileObjects.forSourceLines( 1941 "test.DaggerAncestor", 1942 "package test;", 1943 "", 1944 "import dagger.internal.GenerationOptions;", 1945 "import dagger.internal.MapBuilder;", 1946 "import java.util.Map;", 1947 IMPORT_GENERATED_ANNOTATION, 1948 "", 1949 GENERATION_OPTIONS_ANNOTATION, 1950 GENERATED_ANNOTATION, 1951 "public abstract class DaggerAncestor implements Ancestor {", 1952 " protected DaggerAncestor() {}", 1953 "", 1954 " protected abstract class LeafImpl extends DaggerLeaf {", 1955 " protected LeafImpl() {}", 1956 "", 1957 " @Override", 1958 " public Map<String, InEachSubcomponent> contributionsInEachSubcomponent() {", 1959 " return MapBuilder.<String, InEachSubcomponent>newMapBuilder(2)", 1960 " .put(\"ancestormodule\",", 1961 " AncestorModule_ProvideInAncestorFactory.provideInAncestor())", 1962 " .putAll(super.contributionsInEachSubcomponent())", 1963 " .build();", 1964 " }", 1965 " }", 1966 "}"); 1967 compilation = compileWithoutGuava(filesToCompile.build()); 1968 assertThat(compilation).succeededWithoutWarnings(); 1969 assertThat(compilation) 1970 .generatedSourceFile("test.DaggerAncestor") 1971 .hasSourceEquivalentTo(generatedAncestor); 1972 } 1973 1974 @Test mapMultibinding_requestedAsInstanceInLeaf_requestedAsFrameworkInstanceFromAncestor()1975 public void mapMultibinding_requestedAsInstanceInLeaf_requestedAsFrameworkInstanceFromAncestor() { 1976 ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder(); 1977 createSimplePackagePrivateClasses( 1978 filesToCompile, "Multibound", "MissingInLeaf_WillDependOnFrameworkInstance"); 1979 filesToCompile.add( 1980 JavaFileObjects.forSourceLines( 1981 "test.Leaf", 1982 "package test;", 1983 "", 1984 "import dagger.Subcomponent;", 1985 "import java.util.Map;", 1986 "import javax.inject.Provider;", 1987 "", 1988 "@Subcomponent(modules = LeafModule.class)", 1989 "interface Leaf {", 1990 " Map<Integer, Multibound> instance();", 1991 " MissingInLeaf_WillDependOnFrameworkInstance willDependOnFrameworkInstance();", 1992 "}"), 1993 JavaFileObjects.forSourceLines( 1994 "test.LeafModule", 1995 "package test;", 1996 "", 1997 "import dagger.Module;", 1998 "import dagger.Provides;", 1999 "import dagger.multibindings.IntKey;", 2000 "import dagger.multibindings.IntoMap;", 2001 "import java.util.Map;", 2002 "", 2003 "@Module", 2004 "class LeafModule {", 2005 " @Provides", 2006 " @IntoMap", 2007 " @IntKey(111)", 2008 " static Multibound contribution() {", 2009 " return new Multibound();", 2010 " }", 2011 "}")); 2012 JavaFileObject generatedLeaf = 2013 JavaFileObjects.forSourceLines( 2014 "test.DaggerLeaf", 2015 "package test;", 2016 "", 2017 "import com.google.common.collect.ImmutableMap;", 2018 "import dagger.internal.GenerationOptions;", 2019 "import java.util.Map;", 2020 IMPORT_GENERATED_ANNOTATION, 2021 "", 2022 GENERATION_OPTIONS_ANNOTATION, 2023 GENERATED_ANNOTATION, 2024 "public abstract class DaggerLeaf implements Leaf {", 2025 " protected DaggerLeaf() {}", 2026 "", 2027 " @Override", 2028 " public Map<Integer, Multibound> instance() {", 2029 " return ImmutableMap.<Integer, Multibound>of(", 2030 " 111, LeafModule_ContributionFactory.contribution());", 2031 " }", 2032 "", 2033 " @Override", 2034 " public abstract MissingInLeaf_WillDependOnFrameworkInstance", 2035 " willDependOnFrameworkInstance();", 2036 "}"); 2037 Compilation compilation = compile(filesToCompile.build()); 2038 assertThat(compilation).succeededWithoutWarnings(); 2039 assertThat(compilation) 2040 .generatedSourceFile("test.DaggerLeaf") 2041 .hasSourceEquivalentTo(generatedLeaf); 2042 2043 filesToCompile.add( 2044 JavaFileObjects.forSourceLines( 2045 "test.Ancestor", 2046 "package test;", 2047 "", 2048 "import dagger.Subcomponent;", 2049 "", 2050 "@Subcomponent(modules = AncestorModule.class)", 2051 "interface Ancestor {", 2052 " Leaf leaf();", 2053 "}"), 2054 JavaFileObjects.forSourceLines( 2055 "test.AncestorModule", 2056 "package test;", 2057 "", 2058 "import dagger.Module;", 2059 "import dagger.Provides;", 2060 "import dagger.multibindings.Multibinds;", 2061 "import java.util.Map;", 2062 "import javax.inject.Provider;", 2063 "", 2064 "@Module", 2065 "interface AncestorModule {", 2066 " @Provides", 2067 " static MissingInLeaf_WillDependOnFrameworkInstance providedInAncestor(", 2068 " Provider<Map<Integer, Multibound>> frameworkInstance) {", 2069 " return null;", 2070 " }", 2071 "", 2072 " @Multibinds Map<Integer, Multibound> multibinds();", 2073 "}")); 2074 JavaFileObject generatedAncestor = 2075 JavaFileObjects.forSourceLines( 2076 "test.DaggerAncestor", 2077 "package test;", 2078 "", 2079 "import dagger.internal.GenerationOptions;", 2080 "import dagger.internal.MapFactory;", 2081 "import java.util.Map;", 2082 IMPORT_GENERATED_ANNOTATION, 2083 "import javax.inject.Provider;", 2084 "", 2085 GENERATION_OPTIONS_ANNOTATION, 2086 GENERATED_ANNOTATION, 2087 "public abstract class DaggerAncestor implements Ancestor {", 2088 " protected DaggerAncestor() {}", 2089 "", 2090 " protected abstract class LeafImpl extends DaggerLeaf {", 2091 " private Provider<Map<Integer, Multibound>> mapOfIntegerAndMultiboundProvider;", 2092 "", 2093 " protected LeafImpl() {}", 2094 "", 2095 " protected void configureInitialization() { ", 2096 " initialize();", 2097 " }", 2098 "", 2099 " @SuppressWarnings(\"unchecked\")", 2100 " private void initialize() { ", 2101 " this.mapOfIntegerAndMultiboundProvider =", 2102 " MapFactory.<Integer, Multibound>builder(1)", 2103 " .put(111, LeafModule_ContributionFactory.create())", 2104 " .build();", 2105 " }", 2106 "", 2107 " protected Provider getMapOfIntegerAndMultiboundProvider() {", 2108 " return mapOfIntegerAndMultiboundProvider;", 2109 " }", 2110 "", 2111 " @Override", 2112 " public final MissingInLeaf_WillDependOnFrameworkInstance ", 2113 " willDependOnFrameworkInstance() {", 2114 " return AncestorModule_ProvidedInAncestorFactory.providedInAncestor(", 2115 " getMapOfIntegerAndMultiboundProvider());", 2116 " }", 2117 " }", 2118 "}"); 2119 compilation = compile(filesToCompile.build()); 2120 assertThat(compilation).succeededWithoutWarnings(); 2121 assertThat(compilation) 2122 .generatedSourceFile("test.DaggerAncestor") 2123 .hasSourceEquivalentTo(generatedAncestor); 2124 } 2125 2126 @Test emptyMultibinds_set()2127 public void emptyMultibinds_set() { 2128 ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder(); 2129 createSimplePackagePrivateClasses(filesToCompile, "Multibound"); 2130 filesToCompile.add( 2131 JavaFileObjects.forSourceLines( 2132 "test.LeafModule", 2133 "package test;", 2134 "", 2135 "import dagger.Module;", 2136 "import dagger.multibindings.Multibinds;", 2137 "import java.util.Set;", 2138 "", 2139 "@Module", 2140 "interface LeafModule {", 2141 " @Multibinds", 2142 " Set<Multibound> set();", 2143 "}"), 2144 JavaFileObjects.forSourceLines( 2145 "test.Leaf", 2146 "package test;", 2147 "", 2148 "import dagger.Subcomponent;", 2149 "import java.util.Set;", 2150 "", 2151 "@Subcomponent(modules = LeafModule.class)", 2152 "interface Leaf {", 2153 " Set<Multibound> set();", 2154 "}")); 2155 JavaFileObject generatedLeaf = 2156 JavaFileObjects.forSourceLines( 2157 "test.DaggerLeaf", 2158 "package test;", 2159 "", 2160 "import com.google.common.collect.ImmutableSet;", 2161 "import dagger.internal.GenerationOptions;", 2162 "import java.util.Set;", 2163 IMPORT_GENERATED_ANNOTATION, 2164 "", 2165 GENERATION_OPTIONS_ANNOTATION, 2166 GENERATED_ANNOTATION, 2167 "public abstract class DaggerLeaf implements Leaf {", 2168 " protected DaggerLeaf() {}", 2169 "", 2170 " @Override", 2171 " public Set<Multibound> set() {", 2172 " return ImmutableSet.<Multibound>of();", 2173 " }", 2174 "}"); 2175 Compilation compilation = compile(filesToCompile.build()); 2176 assertThat(compilation).succeededWithoutWarnings(); 2177 assertThat(compilation) 2178 .generatedSourceFile("test.DaggerLeaf") 2179 .hasSourceEquivalentTo(generatedLeaf); 2180 2181 filesToCompile.add( 2182 JavaFileObjects.forSourceLines( 2183 "test.Ancestor", 2184 "package test;", 2185 "", 2186 "import dagger.Subcomponent;", 2187 "", 2188 "@Subcomponent(modules = AncestorModule.class)", 2189 "interface Ancestor {", 2190 " Leaf leaf();", 2191 "}"), 2192 JavaFileObjects.forSourceLines( 2193 "test.AncestorModule", 2194 "package test;", 2195 "", 2196 "import dagger.Module;", 2197 "import dagger.Provides;", 2198 "import dagger.multibindings.IntoSet;", 2199 "", 2200 "@Module", 2201 "class AncestorModule {", 2202 " @Provides", 2203 " @IntoSet", 2204 " static Multibound fromAncestor() {", 2205 " return new Multibound();", 2206 " }", 2207 "}")); 2208 JavaFileObject generatedAncestor = 2209 JavaFileObjects.forSourceLines( 2210 "test.DaggerAncestor", 2211 "package test;", 2212 "", 2213 "import com.google.common.collect.ImmutableSet;", 2214 "import dagger.internal.GenerationOptions;", 2215 "import java.util.Set;", 2216 IMPORT_GENERATED_ANNOTATION, 2217 "", 2218 GENERATION_OPTIONS_ANNOTATION, 2219 GENERATED_ANNOTATION, 2220 "public abstract class DaggerAncestor implements Ancestor {", 2221 " protected DaggerAncestor() {}", 2222 "", 2223 " protected abstract class LeafImpl extends DaggerLeaf {", 2224 " protected LeafImpl() {}", 2225 "", 2226 " @Override", 2227 " public Set<Multibound> set() {", 2228 " return ImmutableSet.<Multibound>of(", 2229 " AncestorModule_FromAncestorFactory.fromAncestor());", 2230 " }", 2231 " }", 2232 "}"); 2233 compilation = compile(filesToCompile.build()); 2234 assertThat(compilation).succeededWithoutWarnings(); 2235 assertThat(compilation) 2236 .generatedSourceFile("test.DaggerAncestor") 2237 .hasSourceEquivalentTo(generatedAncestor); 2238 } 2239 2240 @Test emptyMultibinds_set_frameworkInstance()2241 public void emptyMultibinds_set_frameworkInstance() { 2242 ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder(); 2243 createSimplePackagePrivateClasses(filesToCompile, "Multibound"); 2244 filesToCompile.add( 2245 JavaFileObjects.forSourceLines( 2246 "test.LeafModule", 2247 "package test;", 2248 "", 2249 "import dagger.Module;", 2250 "import dagger.multibindings.Multibinds;", 2251 "import java.util.Set;", 2252 "", 2253 "@Module", 2254 "interface LeafModule {", 2255 " @Multibinds", 2256 " Set<Multibound> set();", 2257 "}"), 2258 JavaFileObjects.forSourceLines( 2259 "test.Leaf", 2260 "package test;", 2261 "", 2262 "import dagger.Subcomponent;", 2263 "import java.util.Set;", 2264 "import javax.inject.Provider;", 2265 "", 2266 "@Subcomponent(modules = LeafModule.class)", 2267 "interface Leaf {", 2268 " Provider<Set<Multibound>> set();", 2269 "}")); 2270 JavaFileObject generatedLeaf = 2271 JavaFileObjects.forSourceLines( 2272 "test.DaggerLeaf", 2273 "package test;", 2274 "", 2275 "import dagger.internal.GenerationOptions;", 2276 "import dagger.internal.SetFactory;", 2277 "import java.util.Set;", 2278 IMPORT_GENERATED_ANNOTATION, 2279 "import javax.inject.Provider;", 2280 "", 2281 GENERATION_OPTIONS_ANNOTATION, 2282 GENERATED_ANNOTATION, 2283 "public abstract class DaggerLeaf implements Leaf {", 2284 " protected DaggerLeaf() {}", 2285 "", 2286 " @Override", 2287 " public Provider<Set<Multibound>> set() {", 2288 " return SetFactory.<Multibound>empty();", 2289 " }", 2290 "}"); 2291 Compilation compilation = compile(filesToCompile.build()); 2292 assertThat(compilation).succeededWithoutWarnings(); 2293 assertThat(compilation) 2294 .generatedSourceFile("test.DaggerLeaf") 2295 .hasSourceEquivalentTo(generatedLeaf); 2296 2297 filesToCompile.add( 2298 JavaFileObjects.forSourceLines( 2299 "test.Ancestor", 2300 "package test;", 2301 "", 2302 "import dagger.Subcomponent;", 2303 "", 2304 "@Subcomponent(modules = AncestorModule.class)", 2305 "interface Ancestor {", 2306 " Leaf leaf();", 2307 "}"), 2308 JavaFileObjects.forSourceLines( 2309 "test.AncestorModule", 2310 "package test;", 2311 "", 2312 "import dagger.Module;", 2313 "import dagger.Provides;", 2314 "import dagger.multibindings.IntoSet;", 2315 "", 2316 "@Module", 2317 "class AncestorModule {", 2318 " @Provides", 2319 " @IntoSet", 2320 " static Multibound fromAncestor() {", 2321 " return new Multibound();", 2322 " }", 2323 "}")); 2324 JavaFileObject generatedAncestor = 2325 JavaFileObjects.forSourceLines( 2326 "test.DaggerAncestor", 2327 "package test;", 2328 "", 2329 "import dagger.internal.DelegateFactory;", 2330 "import dagger.internal.GenerationOptions;", 2331 "import dagger.internal.SetFactory;", 2332 "import java.util.Set;", 2333 IMPORT_GENERATED_ANNOTATION, 2334 "import javax.inject.Provider;", 2335 "", 2336 GENERATION_OPTIONS_ANNOTATION, 2337 GENERATED_ANNOTATION, 2338 "public abstract class DaggerAncestor implements Ancestor {", 2339 " protected DaggerAncestor() {}", 2340 "", 2341 " protected abstract class LeafImpl extends DaggerLeaf {", 2342 " private Provider<Set<Multibound>> setOfMultiboundProvider =", 2343 " new DelegateFactory<>();", 2344 "", 2345 " protected LeafImpl() {}", 2346 "", 2347 " protected void configureInitialization() {", 2348 " initialize();", 2349 " }", 2350 "", 2351 " @SuppressWarnings(\"unchecked\")", 2352 " private void initialize() {", 2353 " DelegateFactory.setDelegate(", 2354 " setOfMultiboundProvider,", 2355 " SetFactory.<Multibound>builder(1, 0)", 2356 " .addProvider(AncestorModule_FromAncestorFactory.create())", 2357 " .build());", 2358 " }", 2359 "", 2360 " @Override", 2361 " public Provider<Set<Multibound>> set() {", 2362 " return setOfMultiboundProvider;", 2363 " }", 2364 " }", 2365 "}"); 2366 compilation = compile(filesToCompile.build()); 2367 assertThat(compilation).succeededWithoutWarnings(); 2368 assertThat(compilation) 2369 .generatedSourceFile("test.DaggerAncestor") 2370 .hasSourceEquivalentTo(generatedAncestor); 2371 } 2372 2373 @Test emptyMultibinds_map()2374 public void emptyMultibinds_map() { 2375 ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder(); 2376 createSimplePackagePrivateClasses(filesToCompile, "Multibound"); 2377 filesToCompile.add( 2378 JavaFileObjects.forSourceLines( 2379 "test.LeafModule", 2380 "package test;", 2381 "", 2382 "import dagger.Module;", 2383 "import dagger.multibindings.Multibinds;", 2384 "import java.util.Map;", 2385 "", 2386 "@Module", 2387 "interface LeafModule {", 2388 " @Multibinds", 2389 " Map<Integer, Multibound> map();", 2390 "}"), 2391 JavaFileObjects.forSourceLines( 2392 "test.Leaf", 2393 "package test;", 2394 "", 2395 "import dagger.Subcomponent;", 2396 "import java.util.Map;", 2397 "", 2398 "@Subcomponent(modules = LeafModule.class)", 2399 "interface Leaf {", 2400 " Map<Integer, Multibound> map();", 2401 "}")); 2402 JavaFileObject generatedLeaf = 2403 JavaFileObjects.forSourceLines( 2404 "test.DaggerLeaf", 2405 "package test;", 2406 "", 2407 "import com.google.common.collect.ImmutableMap;", 2408 "import dagger.internal.GenerationOptions;", 2409 "import java.util.Map;", 2410 IMPORT_GENERATED_ANNOTATION, 2411 "", 2412 GENERATION_OPTIONS_ANNOTATION, 2413 GENERATED_ANNOTATION, 2414 "public abstract class DaggerLeaf implements Leaf {", 2415 " protected DaggerLeaf() {}", 2416 "", 2417 " @Override", 2418 " public Map<Integer, Multibound> map() {", 2419 " return ImmutableMap.<Integer, Multibound>of();", 2420 " }", 2421 "}"); 2422 Compilation compilation = compile(filesToCompile.build()); 2423 assertThat(compilation).succeededWithoutWarnings(); 2424 assertThat(compilation) 2425 .generatedSourceFile("test.DaggerLeaf") 2426 .hasSourceEquivalentTo(generatedLeaf); 2427 2428 filesToCompile.add( 2429 JavaFileObjects.forSourceLines( 2430 "test.Ancestor", 2431 "package test;", 2432 "", 2433 "import dagger.Subcomponent;", 2434 "", 2435 "@Subcomponent(modules = AncestorModule.class)", 2436 "interface Ancestor {", 2437 " Leaf leaf();", 2438 "}"), 2439 JavaFileObjects.forSourceLines( 2440 "test.AncestorModule", 2441 "package test;", 2442 "", 2443 "import dagger.Module;", 2444 "import dagger.Provides;", 2445 "import dagger.multibindings.IntKey;", 2446 "import dagger.multibindings.IntoMap;", 2447 "", 2448 "@Module", 2449 "class AncestorModule {", 2450 " @Provides", 2451 " @IntoMap", 2452 " @IntKey(111)", 2453 " static Multibound fromAncestor() {", 2454 " return new Multibound();", 2455 " }", 2456 "}")); 2457 JavaFileObject generatedAncestor = 2458 JavaFileObjects.forSourceLines( 2459 "test.DaggerAncestor", 2460 "package test;", 2461 "", 2462 "import com.google.common.collect.ImmutableMap;", 2463 "import dagger.internal.GenerationOptions;", 2464 "import java.util.Map;", 2465 IMPORT_GENERATED_ANNOTATION, 2466 "", 2467 GENERATION_OPTIONS_ANNOTATION, 2468 GENERATED_ANNOTATION, 2469 "public abstract class DaggerAncestor implements Ancestor {", 2470 " protected DaggerAncestor() {}", 2471 "", 2472 " protected abstract class LeafImpl extends DaggerLeaf {", 2473 " protected LeafImpl() {}", 2474 "", 2475 " @Override", 2476 " public Map<Integer, Multibound> map() {", 2477 " return ImmutableMap.<Integer, Multibound>of(", 2478 " 111, AncestorModule_FromAncestorFactory.fromAncestor());", 2479 " }", 2480 " }", 2481 "}"); 2482 compilation = compile(filesToCompile.build()); 2483 assertThat(compilation).succeededWithoutWarnings(); 2484 assertThat(compilation) 2485 .generatedSourceFile("test.DaggerAncestor") 2486 .hasSourceEquivalentTo(generatedAncestor); 2487 } 2488 2489 @Test emptyMultibinds_map_frameworkInstance()2490 public void emptyMultibinds_map_frameworkInstance() { 2491 ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder(); 2492 createSimplePackagePrivateClasses(filesToCompile, "Multibound"); 2493 filesToCompile.add( 2494 JavaFileObjects.forSourceLines( 2495 "test.LeafModule", 2496 "package test;", 2497 "", 2498 "import dagger.Module;", 2499 "import dagger.multibindings.Multibinds;", 2500 "import java.util.Map;", 2501 "", 2502 "@Module", 2503 "interface LeafModule {", 2504 " @Multibinds", 2505 " Map<Integer, Multibound> map();", 2506 "}"), 2507 JavaFileObjects.forSourceLines( 2508 "test.Leaf", 2509 "package test;", 2510 "", 2511 "import dagger.Subcomponent;", 2512 "import java.util.Map;", 2513 "import javax.inject.Provider;", 2514 "", 2515 "@Subcomponent(modules = LeafModule.class)", 2516 "interface Leaf {", 2517 " Provider<Map<Integer, Multibound>> map();", 2518 "}")); 2519 JavaFileObject generatedLeaf = 2520 JavaFileObjects.forSourceLines( 2521 "test.DaggerLeaf", 2522 "package test;", 2523 "", 2524 "import dagger.internal.GenerationOptions;", 2525 "import dagger.internal.MapFactory;", 2526 "import java.util.Map;", 2527 IMPORT_GENERATED_ANNOTATION, 2528 "import javax.inject.Provider;", 2529 "", 2530 GENERATION_OPTIONS_ANNOTATION, 2531 GENERATED_ANNOTATION, 2532 "public abstract class DaggerLeaf implements Leaf {", 2533 " protected DaggerLeaf() {}", 2534 "", 2535 " @Override", 2536 " public Provider<Map<Integer, Multibound>> map() {", 2537 " return MapFactory.<Integer, Multibound>emptyMapProvider();", 2538 " }", 2539 "}"); 2540 Compilation compilation = compile(filesToCompile.build()); 2541 assertThat(compilation).succeededWithoutWarnings(); 2542 assertThat(compilation) 2543 .generatedSourceFile("test.DaggerLeaf") 2544 .hasSourceEquivalentTo(generatedLeaf); 2545 2546 filesToCompile.add( 2547 JavaFileObjects.forSourceLines( 2548 "test.Ancestor", 2549 "package test;", 2550 "", 2551 "import dagger.Subcomponent;", 2552 "", 2553 "@Subcomponent(modules = AncestorModule.class)", 2554 "interface Ancestor {", 2555 " Leaf leaf();", 2556 "}"), 2557 JavaFileObjects.forSourceLines( 2558 "test.AncestorModule", 2559 "package test;", 2560 "", 2561 "import dagger.Module;", 2562 "import dagger.Provides;", 2563 "import dagger.multibindings.IntKey;", 2564 "import dagger.multibindings.IntoMap;", 2565 "", 2566 "@Module", 2567 "class AncestorModule {", 2568 " @Provides", 2569 " @IntoMap", 2570 " @IntKey(111)", 2571 " static Multibound fromAncestor() {", 2572 " return new Multibound();", 2573 " }", 2574 "}")); 2575 JavaFileObject generatedAncestor = 2576 JavaFileObjects.forSourceLines( 2577 "test.DaggerAncestor", 2578 "package test;", 2579 "", 2580 "import dagger.internal.DelegateFactory;", 2581 "import dagger.internal.GenerationOptions;", 2582 "import dagger.internal.MapFactory;", 2583 "import java.util.Map;", 2584 IMPORT_GENERATED_ANNOTATION, 2585 "import javax.inject.Provider;", 2586 "", 2587 GENERATION_OPTIONS_ANNOTATION, 2588 GENERATED_ANNOTATION, 2589 "public abstract class DaggerAncestor implements Ancestor {", 2590 " protected DaggerAncestor() {}", 2591 "", 2592 " protected abstract class LeafImpl extends DaggerLeaf {", 2593 " private Provider<Map<Integer, Multibound>> mapOfIntegerAndMultiboundProvider =", 2594 " new DelegateFactory<>()", 2595 "", 2596 " protected LeafImpl() {}", 2597 "", 2598 " protected void configureInitialization() {", 2599 " initialize();", 2600 " }", 2601 "", 2602 " @SuppressWarnings(\"unchecked\")", 2603 " private void initialize() {", 2604 " DelegateFactory.setDelegate(", 2605 " mapOfIntegerAndMultiboundProvider,", 2606 " MapFactory.<Integer, Multibound>builder(1)", 2607 " .put(111, AncestorModule_FromAncestorFactory.create())", 2608 " .build());", 2609 " }", 2610 "", 2611 " @Override", 2612 " public Provider<Map<Integer, Multibound>> map() {", 2613 " return mapOfIntegerAndMultiboundProvider;", 2614 " }", 2615 " }", 2616 "}"); 2617 compilation = compile(filesToCompile.build()); 2618 assertThat(compilation).succeededWithoutWarnings(); 2619 assertThat(compilation) 2620 .generatedSourceFile("test.DaggerAncestor") 2621 .hasSourceEquivalentTo(generatedAncestor); 2622 } 2623 2624 @Test bindsMissingDep_Multibindings()2625 public void bindsMissingDep_Multibindings() { 2626 ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder(); 2627 filesToCompile.add( 2628 JavaFileObjects.forSourceLines( 2629 "test.LeafModule", 2630 "package test;", 2631 "", 2632 "import dagger.Binds;", 2633 "import dagger.Module;", 2634 "import dagger.multibindings.IntoSet;", 2635 "", 2636 "@Module", 2637 "interface LeafModule {", 2638 " @Binds", 2639 " @IntoSet", 2640 " CharSequence bindsMultibindingWithMissingDep(String string);", 2641 "}"), 2642 JavaFileObjects.forSourceLines( 2643 "test.Leaf", 2644 "package test;", 2645 "", 2646 "import dagger.Subcomponent;", 2647 "import java.util.Set;", 2648 "", 2649 "@Subcomponent(modules = LeafModule.class)", 2650 "interface Leaf {", 2651 " Set<CharSequence> set();", 2652 "}")); 2653 2654 JavaFileObject generatedLeaf = 2655 JavaFileObjects.forSourceLines( 2656 "test.DaggerLeaf", 2657 "package test;", 2658 "", 2659 "import com.google.common.collect.ImmutableSet;", 2660 "import dagger.internal.GenerationOptions;", 2661 "import java.util.Set;", 2662 IMPORT_GENERATED_ANNOTATION, 2663 "", 2664 GENERATION_OPTIONS_ANNOTATION, 2665 GENERATED_ANNOTATION, 2666 "public abstract class DaggerLeaf implements Leaf {", 2667 " protected DaggerLeaf() {}", 2668 "", 2669 " @Override", 2670 " public Set<CharSequence> set() {", 2671 " return ImmutableSet.<CharSequence>of(getBindsMultibindingWithMissingDep());", 2672 " }", 2673 "", 2674 // The expected output here is subtle: the Key of 2675 // LeafModule.bindsMultibindingWithMissingDep() is Set<CharSequence>, but the binding 2676 // method should only be returning an individual CharSequence. Otherwise the 2677 // ImmutableSet factory method above will fail. 2678 " protected abstract CharSequence getBindsMultibindingWithMissingDep();", 2679 "}"); 2680 Compilation compilation = compile(filesToCompile.build()); 2681 assertThat(compilation).succeededWithoutWarnings(); 2682 assertThat(compilation) 2683 .generatedSourceFile("test.DaggerLeaf") 2684 .hasSourceEquivalentTo(generatedLeaf); 2685 } 2686 2687 @Test multibindingsAndFastInit()2688 public void multibindingsAndFastInit() { 2689 ImmutableList.Builder<JavaFileObject> filesToCompile = ImmutableList.builder(); 2690 createSimplePackagePrivateClasses(filesToCompile, "PackagePrivate"); 2691 filesToCompile.add( 2692 JavaFileObjects.forSourceLines( 2693 "test.MultibindingModule", 2694 "package test;", 2695 "", 2696 "import dagger.Module;", 2697 "import dagger.Provides;", 2698 "import dagger.multibindings.IntKey;", 2699 "import dagger.multibindings.IntoMap;", 2700 "import dagger.multibindings.IntoSet;", 2701 "", 2702 "@Module", 2703 "interface MultibindingModule {", 2704 " @Provides", 2705 " @IntoSet", 2706 " @LeafScope", 2707 " static PackagePrivate setContribution() {", 2708 " return new PackagePrivate();", 2709 " }", 2710 "", 2711 " @Provides", 2712 " @IntoMap", 2713 " @IntKey(1)", 2714 " @LeafScope", 2715 " static PackagePrivate mapContribution() {", 2716 " return new PackagePrivate();", 2717 " }", 2718 "}"), 2719 JavaFileObjects.forSourceLines( 2720 "test.LeafScope", 2721 "package test;", 2722 "", 2723 "import javax.inject.Scope;", 2724 "", 2725 "@Scope", 2726 "@interface LeafScope {}"), 2727 JavaFileObjects.forSourceLines( 2728 "test.UsesMultibindings", 2729 "package test;", 2730 "", 2731 "import java.util.Map;", 2732 "import java.util.Set;", 2733 "import javax.inject.Inject;", 2734 "", 2735 "class UsesMultibindings {", 2736 " @Inject", 2737 " UsesMultibindings(Set<PackagePrivate> set, Map<Integer, PackagePrivate> map) {}", 2738 "}"), 2739 JavaFileObjects.forSourceLines( 2740 "test.Leaf", 2741 "package test;", 2742 "", 2743 "import dagger.Subcomponent;", 2744 "import java.util.Map;", 2745 "import java.util.Set;", 2746 "", 2747 "@LeafScope", 2748 "@Subcomponent(modules = MultibindingModule.class)", 2749 "interface Leaf {", 2750 " UsesMultibindings entryPoint();", 2751 "}")); 2752 2753 Compilation compilation = 2754 compilerWithOptions(AHEAD_OF_TIME_SUBCOMPONENTS_MODE, FAST_INIT_MODE) 2755 .compile(filesToCompile.build()); 2756 assertThat(compilation).succeededWithoutWarnings(); 2757 2758 JavaFileObject generatedLeaf = 2759 JavaFileObjects.forSourceLines( 2760 "test.DaggerLeaf", 2761 "package test;", 2762 "", 2763 "@GenerationOptions(fastInit = true)", 2764 GENERATED_ANNOTATION, 2765 "public abstract class DaggerLeaf implements Leaf {", 2766 " protected DaggerLeaf() {}", 2767 "", 2768 " private PackagePrivate getSetContribution() {", 2769 " Object local = setContribution;", 2770 " if (local instanceof MemoizedSentinel) {", 2771 " synchronized (local) {", 2772 " local = setContribution;", 2773 " if (local instanceof MemoizedSentinel) {", 2774 " local = MultibindingModule_SetContributionFactory.setContribution();", 2775 " setContribution = DoubleCheck.reentrantCheck(setContribution, local);", 2776 " }", 2777 " }", 2778 " }", 2779 " return (PackagePrivate) local;", 2780 " }", 2781 "", 2782 " private PackagePrivate getMapContribution() {", 2783 " Object local = mapContribution;", 2784 " if (local instanceof MemoizedSentinel) {", 2785 " synchronized (local) {", 2786 " local = mapContribution;", 2787 " if (local instanceof MemoizedSentinel) {", 2788 " local = MultibindingModule_MapContributionFactory.mapContribution();", 2789 " mapContribution = DoubleCheck.reentrantCheck(mapContribution, local);", 2790 " }", 2791 " }", 2792 " }", 2793 " return (PackagePrivate) local;", 2794 " }", 2795 "", 2796 " @Override", 2797 " public UsesMultibindings entryPoint() {", 2798 " return new UsesMultibindings(", 2799 " getSetOfPackagePrivate(), getMapOfIntegerAndPackagePrivate());", 2800 " }", 2801 "", 2802 " protected Set getSetOfPackagePrivate() {", 2803 " return ImmutableSet.<PackagePrivate>of(getSetContribution());", 2804 " }", 2805 "", 2806 " protected Map getMapOfIntegerAndPackagePrivate() {", 2807 " return ImmutableMap.<Integer, PackagePrivate>of(1, getMapContribution());", 2808 " }", 2809 "}"); 2810 assertThat(compilation) 2811 .generatedSourceFile("test.DaggerLeaf") 2812 .containsElementsIn(generatedLeaf); 2813 } 2814 2815 // TODO(ronshapiro): remove copies from AheadOfTimeSubcomponents*Test classes createSimplePackagePrivateClasses( ImmutableList.Builder<JavaFileObject> filesBuilder, String... ancillaryClasses)2816 private void createSimplePackagePrivateClasses( 2817 ImmutableList.Builder<JavaFileObject> filesBuilder, String... ancillaryClasses) { 2818 for (String className : ancillaryClasses) { 2819 filesBuilder.add( 2820 JavaFileObjects.forSourceLines( 2821 String.format("test.%s", className), 2822 "package test;", 2823 "", 2824 String.format("class %s { }", className))); 2825 } 2826 } 2827 compile(Iterable<JavaFileObject> files)2828 private static Compilation compile(Iterable<JavaFileObject> files) { 2829 return compilerWithOptions(AHEAD_OF_TIME_SUBCOMPONENTS_MODE).compile(files); 2830 } 2831 compileWithoutGuava(Iterable<JavaFileObject> files)2832 private static Compilation compileWithoutGuava(Iterable<JavaFileObject> files) { 2833 return daggerCompiler() 2834 .withOptions( 2835 AHEAD_OF_TIME_SUBCOMPONENTS_MODE.javacopts().append(CLASS_PATH_WITHOUT_GUAVA_OPTION)) 2836 .compile(files); 2837 } 2838 } 2839