1*f585d8a3SJacky Wang /*
2*f585d8a3SJacky Wang  * Copyright (C) 2016 The Dagger Authors.
3*f585d8a3SJacky Wang  *
4*f585d8a3SJacky Wang  * Licensed under the Apache License, Version 2.0 (the "License");
5*f585d8a3SJacky Wang  * you may not use this file except in compliance with the License.
6*f585d8a3SJacky Wang  * You may obtain a copy of the License at
7*f585d8a3SJacky Wang  *
8*f585d8a3SJacky Wang  * http://www.apache.org/licenses/LICENSE-2.0
9*f585d8a3SJacky Wang  *
10*f585d8a3SJacky Wang  * Unless required by applicable law or agreed to in writing, software
11*f585d8a3SJacky Wang  * distributed under the License is distributed on an "AS IS" BASIS,
12*f585d8a3SJacky Wang  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*f585d8a3SJacky Wang  * See the License for the specific language governing permissions and
14*f585d8a3SJacky Wang  * limitations under the License.
15*f585d8a3SJacky Wang  */
16*f585d8a3SJacky Wang 
17*f585d8a3SJacky Wang package dagger.internal.codegen;
18*f585d8a3SJacky Wang 
19*f585d8a3SJacky Wang import androidx.room.compiler.processing.util.Source;
20*f585d8a3SJacky Wang import com.google.common.collect.ImmutableList;
21*f585d8a3SJacky Wang import com.google.common.collect.ImmutableMap;
22*f585d8a3SJacky Wang import dagger.testing.compile.CompilerTests;
23*f585d8a3SJacky Wang import org.junit.Test;
24*f585d8a3SJacky Wang import org.junit.runner.RunWith;
25*f585d8a3SJacky Wang import org.junit.runners.Parameterized;
26*f585d8a3SJacky Wang import org.junit.runners.Parameterized.Parameters;
27*f585d8a3SJacky Wang 
28*f585d8a3SJacky Wang /** Tests for {ComponentHierarchyValidator}. */
29*f585d8a3SJacky Wang @RunWith(Parameterized.class)
30*f585d8a3SJacky Wang public class ComponentHierarchyValidationTest {
31*f585d8a3SJacky Wang   @Parameters(name = "{0}")
parameters()32*f585d8a3SJacky Wang   public static ImmutableList<Object[]> parameters() {
33*f585d8a3SJacky Wang     return CompilerMode.TEST_PARAMETERS;
34*f585d8a3SJacky Wang   }
35*f585d8a3SJacky Wang 
36*f585d8a3SJacky Wang   private final CompilerMode compilerMode;
37*f585d8a3SJacky Wang 
ComponentHierarchyValidationTest(CompilerMode compilerMode)38*f585d8a3SJacky Wang   public ComponentHierarchyValidationTest(CompilerMode compilerMode) {
39*f585d8a3SJacky Wang     this.compilerMode = compilerMode;
40*f585d8a3SJacky Wang   }
41*f585d8a3SJacky Wang 
42*f585d8a3SJacky Wang   @Test
singletonSubcomponent()43*f585d8a3SJacky Wang   public void singletonSubcomponent() {
44*f585d8a3SJacky Wang     Source component =
45*f585d8a3SJacky Wang         CompilerTests.javaSource(
46*f585d8a3SJacky Wang             "test.Parent",
47*f585d8a3SJacky Wang             "package test;",
48*f585d8a3SJacky Wang             "",
49*f585d8a3SJacky Wang             "import dagger.Component;",
50*f585d8a3SJacky Wang             "import javax.inject.Singleton;",
51*f585d8a3SJacky Wang             "",
52*f585d8a3SJacky Wang             "@Singleton",
53*f585d8a3SJacky Wang             "@Component",
54*f585d8a3SJacky Wang             "interface Parent {",
55*f585d8a3SJacky Wang             "  Child child();",
56*f585d8a3SJacky Wang             "}");
57*f585d8a3SJacky Wang     Source subcomponent =
58*f585d8a3SJacky Wang         CompilerTests.javaSource(
59*f585d8a3SJacky Wang             "test.Child",
60*f585d8a3SJacky Wang             "package test;",
61*f585d8a3SJacky Wang             "",
62*f585d8a3SJacky Wang             "import dagger.Subcomponent;",
63*f585d8a3SJacky Wang             "import javax.inject.Singleton;",
64*f585d8a3SJacky Wang             "",
65*f585d8a3SJacky Wang             "@Singleton",
66*f585d8a3SJacky Wang             "@Subcomponent",
67*f585d8a3SJacky Wang             "interface Child {}");
68*f585d8a3SJacky Wang 
69*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(component, subcomponent)
70*f585d8a3SJacky Wang         .withProcessingOptions(compilerMode.processorOptions())
71*f585d8a3SJacky Wang         .compile(
72*f585d8a3SJacky Wang             subject -> {
73*f585d8a3SJacky Wang               subject.hasErrorCount(1);
74*f585d8a3SJacky Wang               subject.hasErrorContaining(
75*f585d8a3SJacky Wang                   String.join(
76*f585d8a3SJacky Wang                       "\n",
77*f585d8a3SJacky Wang                       "test.Child has conflicting scopes:",
78*f585d8a3SJacky Wang                       "    test.Parent also has @Singleton"));
79*f585d8a3SJacky Wang             });
80*f585d8a3SJacky Wang 
81*f585d8a3SJacky Wang     // Check that compiling with disableInterComponentScopeValidation=none flag succeeds.
82*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(component, subcomponent)
83*f585d8a3SJacky Wang         .withProcessingOptions(
84*f585d8a3SJacky Wang             ImmutableMap.<String, String>builder()
85*f585d8a3SJacky Wang                 .putAll(compilerMode.processorOptions())
86*f585d8a3SJacky Wang                 .put("dagger.disableInterComponentScopeValidation", "none")
87*f585d8a3SJacky Wang                 .buildOrThrow())
88*f585d8a3SJacky Wang         .compile(subject -> subject.hasErrorCount(0));
89*f585d8a3SJacky Wang   }
90*f585d8a3SJacky Wang 
91*f585d8a3SJacky Wang   @Test
productionComponents_productionScopeImplicitOnBoth()92*f585d8a3SJacky Wang   public void productionComponents_productionScopeImplicitOnBoth() {
93*f585d8a3SJacky Wang     Source component =
94*f585d8a3SJacky Wang         CompilerTests.javaSource(
95*f585d8a3SJacky Wang             "test.Parent",
96*f585d8a3SJacky Wang             "package test;",
97*f585d8a3SJacky Wang             "",
98*f585d8a3SJacky Wang             "import dagger.producers.ProductionComponent;",
99*f585d8a3SJacky Wang             "",
100*f585d8a3SJacky Wang             "@ProductionComponent(modules = ParentModule.class)",
101*f585d8a3SJacky Wang             "interface Parent {",
102*f585d8a3SJacky Wang             "  Child child();",
103*f585d8a3SJacky Wang             "  Object productionScopedObject();",
104*f585d8a3SJacky Wang             "}");
105*f585d8a3SJacky Wang     Source parentModule =
106*f585d8a3SJacky Wang         CompilerTests.javaSource(
107*f585d8a3SJacky Wang             "test.ParentModule",
108*f585d8a3SJacky Wang             "package test;",
109*f585d8a3SJacky Wang             "",
110*f585d8a3SJacky Wang             "import dagger.Provides;",
111*f585d8a3SJacky Wang             "import dagger.producers.ProducerModule;",
112*f585d8a3SJacky Wang             "import dagger.producers.ProductionScope;",
113*f585d8a3SJacky Wang             "",
114*f585d8a3SJacky Wang             "@ProducerModule",
115*f585d8a3SJacky Wang             "class ParentModule {",
116*f585d8a3SJacky Wang             "  @Provides @ProductionScope Object parentScopedObject() { return new Object(); }",
117*f585d8a3SJacky Wang             "}");
118*f585d8a3SJacky Wang     Source subcomponent =
119*f585d8a3SJacky Wang         CompilerTests.javaSource(
120*f585d8a3SJacky Wang             "test.Child",
121*f585d8a3SJacky Wang             "package test;",
122*f585d8a3SJacky Wang             "",
123*f585d8a3SJacky Wang             "import dagger.producers.ProductionSubcomponent;",
124*f585d8a3SJacky Wang             "",
125*f585d8a3SJacky Wang             "@ProductionSubcomponent(modules = ChildModule.class)",
126*f585d8a3SJacky Wang             "interface Child {",
127*f585d8a3SJacky Wang             "  String productionScopedString();",
128*f585d8a3SJacky Wang             "}");
129*f585d8a3SJacky Wang     Source childModule =
130*f585d8a3SJacky Wang         CompilerTests.javaSource(
131*f585d8a3SJacky Wang             "test.ChildModule",
132*f585d8a3SJacky Wang             "package test;",
133*f585d8a3SJacky Wang             "",
134*f585d8a3SJacky Wang             "import dagger.Provides;",
135*f585d8a3SJacky Wang             "import dagger.producers.ProducerModule;",
136*f585d8a3SJacky Wang             "import dagger.producers.ProductionScope;",
137*f585d8a3SJacky Wang             "",
138*f585d8a3SJacky Wang             "@ProducerModule",
139*f585d8a3SJacky Wang             "class ChildModule {",
140*f585d8a3SJacky Wang             "  @Provides @ProductionScope String childScopedString() { return new String(); }",
141*f585d8a3SJacky Wang             "}");
142*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(component, subcomponent, parentModule, childModule)
143*f585d8a3SJacky Wang         .withProcessingOptions(compilerMode.processorOptions())
144*f585d8a3SJacky Wang         .compile(subject -> subject.hasErrorCount(0));
145*f585d8a3SJacky Wang   }
146*f585d8a3SJacky Wang 
147*f585d8a3SJacky Wang   @Test
producerModuleRepeated()148*f585d8a3SJacky Wang   public void producerModuleRepeated() {
149*f585d8a3SJacky Wang     Source component =
150*f585d8a3SJacky Wang         CompilerTests.javaSource(
151*f585d8a3SJacky Wang             "test.Parent",
152*f585d8a3SJacky Wang             "package test;",
153*f585d8a3SJacky Wang             "",
154*f585d8a3SJacky Wang             "import dagger.producers.ProductionComponent;",
155*f585d8a3SJacky Wang             "",
156*f585d8a3SJacky Wang             "@ProductionComponent(modules = RepeatedProducerModule.class)",
157*f585d8a3SJacky Wang             "interface Parent {",
158*f585d8a3SJacky Wang             "  Child child();",
159*f585d8a3SJacky Wang             "}");
160*f585d8a3SJacky Wang     Source repeatedModule =
161*f585d8a3SJacky Wang         CompilerTests.javaSource(
162*f585d8a3SJacky Wang             "test.RepeatedProducerModule",
163*f585d8a3SJacky Wang             "package test;",
164*f585d8a3SJacky Wang             "",
165*f585d8a3SJacky Wang             "import dagger.producers.ProducerModule;",
166*f585d8a3SJacky Wang             "",
167*f585d8a3SJacky Wang             "@ProducerModule",
168*f585d8a3SJacky Wang             "interface RepeatedProducerModule {}");
169*f585d8a3SJacky Wang     Source subcomponent =
170*f585d8a3SJacky Wang         CompilerTests.javaSource(
171*f585d8a3SJacky Wang             "test.Child",
172*f585d8a3SJacky Wang             "package test;",
173*f585d8a3SJacky Wang             "",
174*f585d8a3SJacky Wang             "import dagger.producers.ProductionSubcomponent;",
175*f585d8a3SJacky Wang             "",
176*f585d8a3SJacky Wang             "@ProductionSubcomponent(modules = RepeatedProducerModule.class)",
177*f585d8a3SJacky Wang             "interface Child {}");
178*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(component, subcomponent, repeatedModule)
179*f585d8a3SJacky Wang         .withProcessingOptions(compilerMode.processorOptions())
180*f585d8a3SJacky Wang         .compile(
181*f585d8a3SJacky Wang             subject -> {
182*f585d8a3SJacky Wang               subject.hasErrorCount(1);
183*f585d8a3SJacky Wang               subject.hasErrorContaining(
184*f585d8a3SJacky Wang                       String.join(
185*f585d8a3SJacky Wang                           "\n",
186*f585d8a3SJacky Wang                           "test.Child repeats @ProducerModules:",
187*f585d8a3SJacky Wang                           "test.Parent also installs: test.RepeatedProducerModule"))
188*f585d8a3SJacky Wang                   .onSource(component)
189*f585d8a3SJacky Wang                   .onLineContaining("interface Parent");
190*f585d8a3SJacky Wang             });
191*f585d8a3SJacky Wang   }
192*f585d8a3SJacky Wang 
193*f585d8a3SJacky Wang   @Test
factoryMethodForSubcomponentWithBuilder_isNotAllowed()194*f585d8a3SJacky Wang   public void factoryMethodForSubcomponentWithBuilder_isNotAllowed() {
195*f585d8a3SJacky Wang     Source module =
196*f585d8a3SJacky Wang         CompilerTests.javaSource(
197*f585d8a3SJacky Wang             "test.TestModule",
198*f585d8a3SJacky Wang             "package test;",
199*f585d8a3SJacky Wang             "",
200*f585d8a3SJacky Wang             "import dagger.Module;",
201*f585d8a3SJacky Wang             "import dagger.Provides;",
202*f585d8a3SJacky Wang             "",
203*f585d8a3SJacky Wang             "@Module(subcomponents = Sub.class)",
204*f585d8a3SJacky Wang             "class TestModule {",
205*f585d8a3SJacky Wang             "}");
206*f585d8a3SJacky Wang 
207*f585d8a3SJacky Wang     Source subcomponent =
208*f585d8a3SJacky Wang         CompilerTests.javaSource(
209*f585d8a3SJacky Wang             "test.Sub",
210*f585d8a3SJacky Wang             "package test;",
211*f585d8a3SJacky Wang             "",
212*f585d8a3SJacky Wang             "import dagger.Subcomponent;",
213*f585d8a3SJacky Wang             "",
214*f585d8a3SJacky Wang             "@Subcomponent",
215*f585d8a3SJacky Wang             "interface Sub {",
216*f585d8a3SJacky Wang             "  @Subcomponent.Builder",
217*f585d8a3SJacky Wang             "  interface Builder {",
218*f585d8a3SJacky Wang             "    Sub build();",
219*f585d8a3SJacky Wang             "  }",
220*f585d8a3SJacky Wang             "}");
221*f585d8a3SJacky Wang 
222*f585d8a3SJacky Wang     Source component =
223*f585d8a3SJacky Wang         CompilerTests.javaSource(
224*f585d8a3SJacky Wang             "test.C",
225*f585d8a3SJacky Wang             "package test;",
226*f585d8a3SJacky Wang             "",
227*f585d8a3SJacky Wang             "import dagger.Component;",
228*f585d8a3SJacky Wang             "",
229*f585d8a3SJacky Wang             "@Component(modules = TestModule.class)",
230*f585d8a3SJacky Wang             "interface C {",
231*f585d8a3SJacky Wang             "  Sub newSub();",
232*f585d8a3SJacky Wang             "}");
233*f585d8a3SJacky Wang 
234*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(module, component, subcomponent)
235*f585d8a3SJacky Wang         .withProcessingOptions(compilerMode.processorOptions())
236*f585d8a3SJacky Wang         .compile(
237*f585d8a3SJacky Wang             subject -> {
238*f585d8a3SJacky Wang               subject.hasErrorCount(1);
239*f585d8a3SJacky Wang               subject.hasErrorContaining(
240*f585d8a3SJacky Wang                   "Components may not have factory methods for subcomponents that define a "
241*f585d8a3SJacky Wang                       + "builder.");
242*f585d8a3SJacky Wang             });
243*f585d8a3SJacky Wang   }
244*f585d8a3SJacky Wang 
245*f585d8a3SJacky Wang   @Test
repeatedModulesWithScopes()246*f585d8a3SJacky Wang   public void repeatedModulesWithScopes() {
247*f585d8a3SJacky Wang     Source testScope =
248*f585d8a3SJacky Wang         CompilerTests.javaSource(
249*f585d8a3SJacky Wang             "test.TestScope",
250*f585d8a3SJacky Wang             "package test;",
251*f585d8a3SJacky Wang             "",
252*f585d8a3SJacky Wang             "import javax.inject.Scope;",
253*f585d8a3SJacky Wang             "",
254*f585d8a3SJacky Wang             "@Scope",
255*f585d8a3SJacky Wang             "@interface TestScope {}");
256*f585d8a3SJacky Wang     Source moduleWithScopedProvides =
257*f585d8a3SJacky Wang         CompilerTests.javaSource(
258*f585d8a3SJacky Wang             "test.ModuleWithScopedProvides",
259*f585d8a3SJacky Wang             "package test;",
260*f585d8a3SJacky Wang             "",
261*f585d8a3SJacky Wang             "import dagger.Module;",
262*f585d8a3SJacky Wang             "import dagger.Provides;",
263*f585d8a3SJacky Wang             "",
264*f585d8a3SJacky Wang             "@Module",
265*f585d8a3SJacky Wang             "class ModuleWithScopedProvides {",
266*f585d8a3SJacky Wang             "  @Provides",
267*f585d8a3SJacky Wang             "  @TestScope",
268*f585d8a3SJacky Wang             "  static Object o() { return new Object(); }",
269*f585d8a3SJacky Wang             "}");
270*f585d8a3SJacky Wang     Source moduleWithScopedBinds =
271*f585d8a3SJacky Wang         CompilerTests.javaSource(
272*f585d8a3SJacky Wang             "test.ModuleWithScopedBinds",
273*f585d8a3SJacky Wang             "package test;",
274*f585d8a3SJacky Wang             "",
275*f585d8a3SJacky Wang             "import dagger.Binds;",
276*f585d8a3SJacky Wang             "import dagger.Module;",
277*f585d8a3SJacky Wang             "",
278*f585d8a3SJacky Wang             "@Module",
279*f585d8a3SJacky Wang             "interface ModuleWithScopedBinds {",
280*f585d8a3SJacky Wang             "  @Binds",
281*f585d8a3SJacky Wang             "  @TestScope",
282*f585d8a3SJacky Wang             "  Object o(String s);",
283*f585d8a3SJacky Wang             "}");
284*f585d8a3SJacky Wang     Source parent =
285*f585d8a3SJacky Wang         CompilerTests.javaSource(
286*f585d8a3SJacky Wang             "test.Parent",
287*f585d8a3SJacky Wang             "package test;",
288*f585d8a3SJacky Wang             "",
289*f585d8a3SJacky Wang             "import dagger.Component;",
290*f585d8a3SJacky Wang             "",
291*f585d8a3SJacky Wang             "@Component(modules = {ModuleWithScopedProvides.class, ModuleWithScopedBinds.class})",
292*f585d8a3SJacky Wang             "interface Parent {",
293*f585d8a3SJacky Wang             "  Child child();",
294*f585d8a3SJacky Wang             "}");
295*f585d8a3SJacky Wang     Source child =
296*f585d8a3SJacky Wang         CompilerTests.javaSource(
297*f585d8a3SJacky Wang             "test.Child",
298*f585d8a3SJacky Wang             "package test;",
299*f585d8a3SJacky Wang             "",
300*f585d8a3SJacky Wang             "import dagger.Subcomponent;",
301*f585d8a3SJacky Wang             "",
302*f585d8a3SJacky Wang             "@Subcomponent(",
303*f585d8a3SJacky Wang             "    modules = {ModuleWithScopedProvides.class, ModuleWithScopedBinds.class})",
304*f585d8a3SJacky Wang             "interface Child {}");
305*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(
306*f585d8a3SJacky Wang             testScope, moduleWithScopedProvides, moduleWithScopedBinds, parent, child)
307*f585d8a3SJacky Wang         .withProcessingOptions(compilerMode.processorOptions())
308*f585d8a3SJacky Wang         .compile(
309*f585d8a3SJacky Wang             subject -> {
310*f585d8a3SJacky Wang               subject.hasErrorCount(1);
311*f585d8a3SJacky Wang               subject.hasErrorContaining(
312*f585d8a3SJacky Wang                   String.join(
313*f585d8a3SJacky Wang                       "\n",
314*f585d8a3SJacky Wang                       "test.Child repeats modules with scoped bindings or declarations:",
315*f585d8a3SJacky Wang                       "- test.Parent also includes:",
316*f585d8a3SJacky Wang                       "    - test.ModuleWithScopedProvides with scopes: @test.TestScope",
317*f585d8a3SJacky Wang                       "    - test.ModuleWithScopedBinds with scopes: @test.TestScope"));
318*f585d8a3SJacky Wang             });
319*f585d8a3SJacky Wang   }
320*f585d8a3SJacky Wang 
321*f585d8a3SJacky Wang   @Test
repeatedModulesWithReusableScope()322*f585d8a3SJacky Wang   public void repeatedModulesWithReusableScope() {
323*f585d8a3SJacky Wang     Source moduleWithScopedProvides =
324*f585d8a3SJacky Wang         CompilerTests.javaSource(
325*f585d8a3SJacky Wang             "test.ModuleWithScopedProvides",
326*f585d8a3SJacky Wang             "package test;",
327*f585d8a3SJacky Wang             "",
328*f585d8a3SJacky Wang             "import dagger.Module;",
329*f585d8a3SJacky Wang             "import dagger.Provides;",
330*f585d8a3SJacky Wang             "import dagger.Reusable;",
331*f585d8a3SJacky Wang             "",
332*f585d8a3SJacky Wang             "@Module",
333*f585d8a3SJacky Wang             "class ModuleWithScopedProvides {",
334*f585d8a3SJacky Wang             "  @Provides",
335*f585d8a3SJacky Wang             "  @Reusable",
336*f585d8a3SJacky Wang             "  static Object o() { return new Object(); }",
337*f585d8a3SJacky Wang             "}");
338*f585d8a3SJacky Wang     Source moduleWithScopedBinds =
339*f585d8a3SJacky Wang         CompilerTests.javaSource(
340*f585d8a3SJacky Wang             "test.ModuleWithScopedBinds",
341*f585d8a3SJacky Wang             "package test;",
342*f585d8a3SJacky Wang             "",
343*f585d8a3SJacky Wang             "import dagger.Binds;",
344*f585d8a3SJacky Wang             "import dagger.Module;",
345*f585d8a3SJacky Wang             "import dagger.Reusable;",
346*f585d8a3SJacky Wang             "",
347*f585d8a3SJacky Wang             "@Module",
348*f585d8a3SJacky Wang             "interface ModuleWithScopedBinds {",
349*f585d8a3SJacky Wang             "  @Binds",
350*f585d8a3SJacky Wang             "  @Reusable",
351*f585d8a3SJacky Wang             "  Object o(String s);",
352*f585d8a3SJacky Wang             "}");
353*f585d8a3SJacky Wang     Source parent =
354*f585d8a3SJacky Wang         CompilerTests.javaSource(
355*f585d8a3SJacky Wang             "test.Parent",
356*f585d8a3SJacky Wang             "package test;",
357*f585d8a3SJacky Wang             "",
358*f585d8a3SJacky Wang             "import dagger.Component;",
359*f585d8a3SJacky Wang             "",
360*f585d8a3SJacky Wang             "@Component(modules = {ModuleWithScopedProvides.class, ModuleWithScopedBinds.class})",
361*f585d8a3SJacky Wang             "interface Parent {",
362*f585d8a3SJacky Wang             "  Child child();",
363*f585d8a3SJacky Wang             "}");
364*f585d8a3SJacky Wang     Source child =
365*f585d8a3SJacky Wang         CompilerTests.javaSource(
366*f585d8a3SJacky Wang             "test.Child",
367*f585d8a3SJacky Wang             "package test;",
368*f585d8a3SJacky Wang             "",
369*f585d8a3SJacky Wang             "import dagger.Subcomponent;",
370*f585d8a3SJacky Wang             "",
371*f585d8a3SJacky Wang             "@Subcomponent(",
372*f585d8a3SJacky Wang             "    modules = {ModuleWithScopedProvides.class, ModuleWithScopedBinds.class})",
373*f585d8a3SJacky Wang             "interface Child {}");
374*f585d8a3SJacky Wang     CompilerTests.daggerCompiler(moduleWithScopedProvides, moduleWithScopedBinds, parent, child)
375*f585d8a3SJacky Wang         .withProcessingOptions(compilerMode.processorOptions())
376*f585d8a3SJacky Wang         .compile(
377*f585d8a3SJacky Wang             subject -> {
378*f585d8a3SJacky Wang               subject.hasErrorCount(0);
379*f585d8a3SJacky Wang               subject.hasWarningCount(0);
380*f585d8a3SJacky Wang             });
381*f585d8a3SJacky Wang   }
382*f585d8a3SJacky Wang }
383