blob: 4b56cff1c716f7138e8b3fc138095d22b57e93f1 [file] [log] [blame]
Colin Cross21fc9bb2019-01-18 15:05:09 -08001// Copyright 2017 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package java
16
17import (
Colin Cross882d6002024-08-14 10:24:06 -070018 "slices"
Colin Crossafbb1732019-01-17 15:42:52 -080019 "strconv"
Colin Cross21fc9bb2019-01-18 15:05:09 -080020 "strings"
21 "testing"
Colin Cross0c66bc62021-07-20 09:47:41 -070022
23 "android/soong/android"
Colin Cross21fc9bb2019-01-18 15:05:09 -080024)
25
26func TestKotlin(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -080027 t.Parallel()
Colin Cross882d6002024-08-14 10:24:06 -070028 bp := `
Colin Cross21fc9bb2019-01-18 15:05:09 -080029 java_library {
30 name: "foo",
31 srcs: ["a.java", "b.kt"],
Colin Cross882d6002024-08-14 10:24:06 -070032 static_libs: ["quz"],
Colin Cross21fc9bb2019-01-18 15:05:09 -080033 }
34
35 java_library {
36 name: "bar",
37 srcs: ["b.kt"],
38 libs: ["foo"],
39 static_libs: ["baz"],
40 }
41
42 java_library {
43 name: "baz",
44 srcs: ["c.java"],
Colin Cross882d6002024-08-14 10:24:06 -070045 static_libs: ["quz"],
Colin Cross21fc9bb2019-01-18 15:05:09 -080046 }
Colin Cross21fc9bb2019-01-18 15:05:09 -080047
Colin Cross882d6002024-08-14 10:24:06 -070048 java_library {
49 name: "quz",
50 srcs: ["d.kt"],
51 }`
Colin Cross06354472022-05-03 14:20:24 -070052
Colin Crossc9b4f6b2024-07-26 15:25:46 -070053 kotlinStdlibTurbineJars := []string{
54 "out/soong/.intermediates/default/java/kotlin-stdlib/android_common/turbine/kotlin-stdlib.jar",
55 "out/soong/.intermediates/default/java/kotlin-stdlib-jdk7/android_common/turbine/kotlin-stdlib-jdk7.jar",
56 "out/soong/.intermediates/default/java/kotlin-stdlib-jdk8/android_common/turbine/kotlin-stdlib-jdk8.jar",
57 "out/soong/.intermediates/default/java/kotlin-annotations/android_common/turbine/kotlin-annotations.jar",
58 }
59
Colin Cross882d6002024-08-14 10:24:06 -070060 kotlinStdlibJavacJars := []string{
61 "out/soong/.intermediates/default/java/kotlin-stdlib/android_common/javac/kotlin-stdlib.jar",
62 "out/soong/.intermediates/default/java/kotlin-stdlib-jdk7/android_common/javac/kotlin-stdlib-jdk7.jar",
63 "out/soong/.intermediates/default/java/kotlin-stdlib-jdk8/android_common/javac/kotlin-stdlib-jdk8.jar",
64 "out/soong/.intermediates/default/java/kotlin-annotations/android_common/javac/kotlin-annotations.jar",
Colin Cross21fc9bb2019-01-18 15:05:09 -080065 }
66
Colin Crossc9b4f6b2024-07-26 15:25:46 -070067 bootclasspathTurbineJars := []string{
68 "out/soong/.intermediates/default/java/stable.core.platform.api.stubs/android_common/turbine/stable.core.platform.api.stubs.jar",
69 "out/soong/.intermediates/default/java/core-lambda-stubs/android_common/turbine/core-lambda-stubs.jar",
70 }
71
Colin Crossc9b4f6b2024-07-26 15:25:46 -070072 frameworkTurbineJars := []string{
73 "out/soong/.intermediates/default/java/ext/android_common/turbine/ext.jar",
74 "out/soong/.intermediates/default/java/framework/android_common/turbine/framework.jar",
75 }
76
Colin Cross882d6002024-08-14 10:24:06 -070077 testCases := []struct {
78 name string
79
80 preparer android.FixturePreparer
81
82 fooKotlincInputs []string
83 fooJavacInputs []string
84 fooKotlincClasspath []string
85 fooJavacClasspath []string
86 fooCombinedInputs []string
87 fooHeaderCombinedInputs []string
88
89 barKotlincInputs []string
90 barKotlincClasspath []string
91 barCombinedInputs []string
92 barHeaderCombinedInputs []string
93 }{
94 {
Colin Crossc9b4f6b2024-07-26 15:25:46 -070095 name: "transitive classpath",
Colin Cross8ff4af32025-02-19 15:17:02 -080096 preparer: android.NullFixturePreparer,
Colin Crossc9b4f6b2024-07-26 15:25:46 -070097 fooKotlincInputs: []string{"a.java", "b.kt"},
98 fooJavacInputs: []string{"a.java"},
99 fooKotlincClasspath: slices.Concat(
100 bootclasspathTurbineJars,
101 frameworkTurbineJars,
102 []string{"out/soong/.intermediates/quz/android_common/kotlin_headers/quz.jar"},
103 kotlinStdlibTurbineJars,
104 ),
105 fooJavacClasspath: slices.Concat(
106 []string{"out/soong/.intermediates/foo/android_common/kotlin_headers/foo.jar"},
107 frameworkTurbineJars,
108 []string{"out/soong/.intermediates/quz/android_common/kotlin_headers/quz.jar"},
109 kotlinStdlibTurbineJars,
110 ),
111 fooCombinedInputs: slices.Concat(
112 []string{
113 "out/soong/.intermediates/foo/android_common/kotlin/foo.jar",
114 "out/soong/.intermediates/foo/android_common/javac/foo.jar",
115 "out/soong/.intermediates/quz/android_common/kotlin/quz.jar",
116 },
117 kotlinStdlibJavacJars,
118 ),
119 fooHeaderCombinedInputs: slices.Concat(
120 []string{
121 "out/soong/.intermediates/foo/android_common/turbine/foo.jar",
122 "out/soong/.intermediates/foo/android_common/kotlin_headers/foo.jar",
123 "out/soong/.intermediates/quz/android_common/kotlin_headers/quz.jar",
124 },
125 kotlinStdlibTurbineJars,
126 ),
127
128 barKotlincInputs: []string{"b.kt"},
129 barKotlincClasspath: slices.Concat(
130 bootclasspathTurbineJars,
131 frameworkTurbineJars,
132 []string{
133 "out/soong/.intermediates/foo/android_common/turbine/foo.jar",
134 "out/soong/.intermediates/foo/android_common/kotlin_headers/foo.jar",
135 "out/soong/.intermediates/quz/android_common/kotlin_headers/quz.jar",
136 },
137 kotlinStdlibTurbineJars,
138 []string{"out/soong/.intermediates/baz/android_common/turbine/baz.jar"},
139 ),
140 barCombinedInputs: slices.Concat(
141 []string{
142 "out/soong/.intermediates/bar/android_common/kotlin/bar.jar",
143 "out/soong/.intermediates/baz/android_common/javac/baz.jar",
144 "out/soong/.intermediates/quz/android_common/kotlin/quz.jar",
145 },
146 kotlinStdlibJavacJars,
147 ),
148 barHeaderCombinedInputs: slices.Concat(
149 []string{
150 "out/soong/.intermediates/bar/android_common/kotlin_headers/bar.jar",
151 "out/soong/.intermediates/baz/android_common/turbine/baz.jar",
152 "out/soong/.intermediates/quz/android_common/kotlin_headers/quz.jar",
153 },
154 kotlinStdlibTurbineJars,
155 ),
156 },
Colin Cross06354472022-05-03 14:20:24 -0700157 }
158
Colin Cross882d6002024-08-14 10:24:06 -0700159 for _, tt := range testCases {
160 t.Run(tt.name, func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800161 t.Parallel()
Colin Cross882d6002024-08-14 10:24:06 -0700162 result := android.GroupFixturePreparers(
163 PrepareForTestWithJavaDefaultModules,
164 tt.preparer,
165 ).RunTestWithBp(t, bp)
Colin Cross90607e92025-02-11 14:58:07 -0800166 foo := result.ModuleForTests(t, "foo", "android_common")
Colin Cross882d6002024-08-14 10:24:06 -0700167 fooKotlinc := foo.Rule("kotlinc")
168 android.AssertPathsRelativeToTopEquals(t, "foo kotlinc inputs", tt.fooKotlincInputs, fooKotlinc.Inputs)
Sam Delmerico9f9c0a22022-11-29 11:19:37 -0500169
Colin Cross882d6002024-08-14 10:24:06 -0700170 fooKotlincClasspath := android.ContentFromFileRuleForTests(t, result.TestContext, foo.Output("kotlinc/classpath.rsp"))
171 android.AssertStringPathsRelativeToTopEquals(t, "foo kotlinc classpath", result.Config, tt.fooKotlincClasspath, strings.Fields(fooKotlincClasspath))
Sam Delmerico9f9c0a22022-11-29 11:19:37 -0500172
Colin Cross882d6002024-08-14 10:24:06 -0700173 fooJavac := foo.Rule("javac")
174 android.AssertPathsRelativeToTopEquals(t, "foo javac inputs", tt.fooJavacInputs, fooJavac.Inputs)
Colin Cross06354472022-05-03 14:20:24 -0700175
Colin Cross882d6002024-08-14 10:24:06 -0700176 fooJavacClasspath := fooJavac.Args["classpath"]
177 android.AssertStringPathsRelativeToTopEquals(t, "foo javac classpath", result.Config, tt.fooJavacClasspath,
178 strings.Split(strings.TrimPrefix(fooJavacClasspath, "-classpath "), ":"))
Colin Cross220a9a12022-03-28 17:08:01 -0700179
Colin Cross882d6002024-08-14 10:24:06 -0700180 fooCombinedJar := foo.Output("combined/foo.jar")
181 android.AssertPathsRelativeToTopEquals(t, "foo combined inputs", tt.fooCombinedInputs, fooCombinedJar.Inputs)
Colin Cross21fc9bb2019-01-18 15:05:09 -0800182
Colin Cross882d6002024-08-14 10:24:06 -0700183 fooCombinedHeaderJar := foo.Output("turbine-combined/foo.jar")
184 android.AssertPathsRelativeToTopEquals(t, "foo header combined inputs", tt.fooHeaderCombinedInputs, fooCombinedHeaderJar.Inputs)
Colin Cross21fc9bb2019-01-18 15:05:09 -0800185
Colin Cross90607e92025-02-11 14:58:07 -0800186 bar := result.ModuleForTests(t, "bar", "android_common")
Colin Cross882d6002024-08-14 10:24:06 -0700187 barKotlinc := bar.Rule("kotlinc")
188 android.AssertPathsRelativeToTopEquals(t, "bar kotlinc inputs", tt.barKotlincInputs, barKotlinc.Inputs)
Colin Cross21fc9bb2019-01-18 15:05:09 -0800189
Colin Cross882d6002024-08-14 10:24:06 -0700190 barKotlincClasspath := android.ContentFromFileRuleForTests(t, result.TestContext, bar.Output("kotlinc/classpath.rsp"))
191 android.AssertStringPathsRelativeToTopEquals(t, "bar kotlinc classpath", result.Config, tt.barKotlincClasspath, strings.Fields(barKotlincClasspath))
192
193 barCombinedJar := bar.Output("combined/bar.jar")
194 android.AssertPathsRelativeToTopEquals(t, "bar combined inputs", tt.barCombinedInputs, barCombinedJar.Inputs)
195
196 barCombinedHeaderJar := bar.Output("turbine-combined/bar.jar")
197 android.AssertPathsRelativeToTopEquals(t, "bar header combined inputs", tt.barHeaderCombinedInputs, barCombinedHeaderJar.Inputs)
198 })
Colin Cross21fc9bb2019-01-18 15:05:09 -0800199 }
200}
Colin Crossafbb1732019-01-17 15:42:52 -0800201
202func TestKapt(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800203 t.Parallel()
Colin Cross748b2d82020-11-19 13:52:06 -0800204 bp := `
Colin Crossafbb1732019-01-17 15:42:52 -0800205 java_library {
206 name: "foo",
207 srcs: ["a.java", "b.kt"],
Colin Cross5a116862020-04-22 11:44:34 -0700208 plugins: ["bar", "baz"],
Colin Cross748b2d82020-11-19 13:52:06 -0800209 errorprone: {
210 extra_check_modules: ["my_check"],
211 },
Colin Crossafbb1732019-01-17 15:42:52 -0800212 }
213
Colin Crossbe9cdb82019-01-21 21:37:16 -0800214 java_plugin {
Colin Crossafbb1732019-01-17 15:42:52 -0800215 name: "bar",
Colin Cross3a3e94c2019-01-23 15:39:50 -0800216 processor_class: "com.bar",
217 srcs: ["b.java"],
Colin Crossafbb1732019-01-17 15:42:52 -0800218 }
Colin Cross5a116862020-04-22 11:44:34 -0700219
220 java_plugin {
221 name: "baz",
222 processor_class: "com.baz",
223 srcs: ["b.java"],
224 }
Colin Crossafbb1732019-01-17 15:42:52 -0800225
Colin Cross748b2d82020-11-19 13:52:06 -0800226 java_plugin {
227 name: "my_check",
228 srcs: ["b.java"],
229 }
230 `
231 t.Run("", func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800232 t.Parallel()
Colin Cross748b2d82020-11-19 13:52:06 -0800233 ctx, _ := testJava(t, bp)
Colin Cross3a3e94c2019-01-23 15:39:50 -0800234
Colin Cross0c66bc62021-07-20 09:47:41 -0700235 buildOS := ctx.Config().BuildOS.String()
Colin Crossafbb1732019-01-17 15:42:52 -0800236
Colin Cross90607e92025-02-11 14:58:07 -0800237 foo := ctx.ModuleForTests(t, "foo", "android_common")
Colin Crossf61766e2022-03-16 18:06:48 -0700238 kaptStubs := foo.Rule("kapt")
239 turbineApt := foo.Description("turbine apt")
240 kotlinc := foo.Rule("kotlinc")
241 javac := foo.Rule("javac")
Colin Cross3a3e94c2019-01-23 15:39:50 -0800242
Colin Cross90607e92025-02-11 14:58:07 -0800243 bar := ctx.ModuleForTests(t, "bar", buildOS+"_common").Rule("javac").Output.String()
244 baz := ctx.ModuleForTests(t, "baz", buildOS+"_common").Rule("javac").Output.String()
Colin Crossafbb1732019-01-17 15:42:52 -0800245
Colin Cross748b2d82020-11-19 13:52:06 -0800246 // Test that the kotlin and java sources are passed to kapt and kotlinc
Colin Crossf61766e2022-03-16 18:06:48 -0700247 if len(kaptStubs.Inputs) != 2 || kaptStubs.Inputs[0].String() != "a.java" || kaptStubs.Inputs[1].String() != "b.kt" {
248 t.Errorf(`foo kapt inputs %v != ["a.java", "b.kt"]`, kaptStubs.Inputs)
Colin Cross748b2d82020-11-19 13:52:06 -0800249 }
250 if len(kotlinc.Inputs) != 2 || kotlinc.Inputs[0].String() != "a.java" || kotlinc.Inputs[1].String() != "b.kt" {
251 t.Errorf(`foo kotlinc inputs %v != ["a.java", "b.kt"]`, kotlinc.Inputs)
252 }
Colin Crossafbb1732019-01-17 15:42:52 -0800253
Colin Crossf61766e2022-03-16 18:06:48 -0700254 // Test that only the java sources are passed to turbine-apt and javac
255 if len(turbineApt.Inputs) != 1 || turbineApt.Inputs[0].String() != "a.java" {
256 t.Errorf(`foo turbine apt inputs %v != ["a.java"]`, turbineApt.Inputs)
257 }
Colin Cross748b2d82020-11-19 13:52:06 -0800258 if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "a.java" {
259 t.Errorf(`foo inputs %v != ["a.java"]`, javac.Inputs)
260 }
Colin Crossafbb1732019-01-17 15:42:52 -0800261
Colin Crossf61766e2022-03-16 18:06:48 -0700262 // Test that the kapt stubs jar is a dependency of turbine-apt
263 if !inList(kaptStubs.Output.String(), turbineApt.Implicits.Strings()) {
264 t.Errorf("expected %q in turbine-apt implicits %v", kaptStubs.Output.String(), kotlinc.Implicits.Strings())
Colin Cross748b2d82020-11-19 13:52:06 -0800265 }
Colin Cross3a3e94c2019-01-23 15:39:50 -0800266
Colin Crossf61766e2022-03-16 18:06:48 -0700267 // Test that the turbine-apt srcjar is a dependency of kotlinc and javac rules
Isaac Chioua23d9942022-04-06 06:14:38 +0000268 if !inList(turbineApt.Output.String(), kotlinc.Implicits.Strings()) {
269 t.Errorf("expected %q in kotlinc implicits %v", turbineApt.Output.String(), kotlinc.Implicits.Strings())
Colin Cross748b2d82020-11-19 13:52:06 -0800270 }
Isaac Chioua23d9942022-04-06 06:14:38 +0000271 if !inList(turbineApt.Output.String(), javac.Implicits.Strings()) {
272 t.Errorf("expected %q in javac implicits %v", turbineApt.Output.String(), javac.Implicits.Strings())
Colin Crossf61766e2022-03-16 18:06:48 -0700273 }
274
275 // Test that the turbine-apt srcjar is extracted by the kotlinc and javac rules
Isaac Chioua23d9942022-04-06 06:14:38 +0000276 if kotlinc.Args["srcJars"] != turbineApt.Output.String() {
277 t.Errorf("expected %q in kotlinc srcjars %v", turbineApt.Output.String(), kotlinc.Args["srcJars"])
Colin Crossf61766e2022-03-16 18:06:48 -0700278 }
Isaac Chioua23d9942022-04-06 06:14:38 +0000279 if javac.Args["srcJars"] != turbineApt.Output.String() {
280 t.Errorf("expected %q in javac srcjars %v", turbineApt.Output.String(), kotlinc.Args["srcJars"])
Colin Cross748b2d82020-11-19 13:52:06 -0800281 }
Colin Cross3a3e94c2019-01-23 15:39:50 -0800282
Colin Cross748b2d82020-11-19 13:52:06 -0800283 // Test that the processors are passed to kapt
284 expectedProcessorPath := "-P plugin:org.jetbrains.kotlin.kapt3:apclasspath=" + bar +
285 " -P plugin:org.jetbrains.kotlin.kapt3:apclasspath=" + baz
Colin Crossf61766e2022-03-16 18:06:48 -0700286 if kaptStubs.Args["kaptProcessorPath"] != expectedProcessorPath {
287 t.Errorf("expected kaptProcessorPath %q, got %q", expectedProcessorPath, kaptStubs.Args["kaptProcessorPath"])
Colin Cross748b2d82020-11-19 13:52:06 -0800288 }
289 expectedProcessor := "-P plugin:org.jetbrains.kotlin.kapt3:processors=com.bar -P plugin:org.jetbrains.kotlin.kapt3:processors=com.baz"
Colin Crossf61766e2022-03-16 18:06:48 -0700290 if kaptStubs.Args["kaptProcessor"] != expectedProcessor {
291 t.Errorf("expected kaptProcessor %q, got %q", expectedProcessor, kaptStubs.Args["kaptProcessor"])
292 }
293
294 // Test that the processors are passed to turbine-apt
295 expectedProcessorPath = "--processorpath " + bar + " " + baz
296 if !strings.Contains(turbineApt.Args["turbineFlags"], expectedProcessorPath) {
297 t.Errorf("expected turbine-apt processorpath %q, got %q", expectedProcessorPath, turbineApt.Args["turbineFlags"])
298 }
299 expectedProcessor = "--processors com.bar com.baz"
300 if !strings.Contains(turbineApt.Args["turbineFlags"], expectedProcessor) {
301 t.Errorf("expected turbine-apt processor %q, got %q", expectedProcessor, turbineApt.Args["turbineFlags"])
Colin Cross748b2d82020-11-19 13:52:06 -0800302 }
303
304 // Test that the processors are not passed to javac
305 if javac.Args["processorpath"] != "" {
306 t.Errorf("expected processorPath '', got %q", javac.Args["processorpath"])
307 }
308 if javac.Args["processor"] != "-proc:none" {
309 t.Errorf("expected processor '-proc:none', got %q", javac.Args["processor"])
310 }
311 })
312
313 t.Run("errorprone", func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800314 t.Parallel()
Colin Cross748b2d82020-11-19 13:52:06 -0800315 env := map[string]string{
316 "RUN_ERROR_PRONE": "true",
317 }
Paul Duffinb148a492021-03-22 17:31:52 +0000318
319 result := android.GroupFixturePreparers(
320 PrepareForTestWithJavaDefaultModules,
321 android.FixtureMergeEnv(env),
322 ).RunTestWithBp(t, bp)
Colin Cross748b2d82020-11-19 13:52:06 -0800323
Colin Cross0c66bc62021-07-20 09:47:41 -0700324 buildOS := result.Config.BuildOS.String()
Colin Cross748b2d82020-11-19 13:52:06 -0800325
Colin Cross90607e92025-02-11 14:58:07 -0800326 kapt := result.ModuleForTests(t, "foo", "android_common").Rule("kapt")
327 javac := result.ModuleForTests(t, "foo", "android_common").Description("javac")
328 errorprone := result.ModuleForTests(t, "foo", "android_common").Description("errorprone")
Colin Cross748b2d82020-11-19 13:52:06 -0800329
Colin Cross90607e92025-02-11 14:58:07 -0800330 bar := result.ModuleForTests(t, "bar", buildOS+"_common").Description("javac").Output.String()
331 baz := result.ModuleForTests(t, "baz", buildOS+"_common").Description("javac").Output.String()
332 myCheck := result.ModuleForTests(t, "my_check", buildOS+"_common").Description("javac").Output.String()
Colin Cross748b2d82020-11-19 13:52:06 -0800333
334 // Test that the errorprone plugins are not passed to kapt
335 expectedProcessorPath := "-P plugin:org.jetbrains.kotlin.kapt3:apclasspath=" + bar +
336 " -P plugin:org.jetbrains.kotlin.kapt3:apclasspath=" + baz
337 if kapt.Args["kaptProcessorPath"] != expectedProcessorPath {
338 t.Errorf("expected kaptProcessorPath %q, got %q", expectedProcessorPath, kapt.Args["kaptProcessorPath"])
339 }
340 expectedProcessor := "-P plugin:org.jetbrains.kotlin.kapt3:processors=com.bar -P plugin:org.jetbrains.kotlin.kapt3:processors=com.baz"
341 if kapt.Args["kaptProcessor"] != expectedProcessor {
342 t.Errorf("expected kaptProcessor %q, got %q", expectedProcessor, kapt.Args["kaptProcessor"])
343 }
344
345 // Test that the errorprone plugins are not passed to javac
346 if javac.Args["processorpath"] != "" {
347 t.Errorf("expected processorPath '', got %q", javac.Args["processorpath"])
348 }
349 if javac.Args["processor"] != "-proc:none" {
350 t.Errorf("expected processor '-proc:none', got %q", javac.Args["processor"])
351 }
352
353 // Test that the errorprone plugins are passed to errorprone
354 expectedProcessorPath = "-processorpath " + myCheck
355 if errorprone.Args["processorpath"] != expectedProcessorPath {
356 t.Errorf("expected processorpath %q, got %q", expectedProcessorPath, errorprone.Args["processorpath"])
357 }
358 if errorprone.Args["processor"] != "-proc:none" {
359 t.Errorf("expected processor '-proc:none', got %q", errorprone.Args["processor"])
360 }
361 })
Colin Crossafbb1732019-01-17 15:42:52 -0800362}
363
364func TestKaptEncodeFlags(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800365 t.Parallel()
Colin Crossafbb1732019-01-17 15:42:52 -0800366 // Compares the kaptEncodeFlags against the results of the example implementation at
367 // https://kotlinlang.org/docs/reference/kapt.html#apjavac-options-encoding
368 tests := []struct {
369 in [][2]string
370 out string
371 }{
372 {
373 // empty input
374 in: [][2]string{},
375 out: "rO0ABXcEAAAAAA==",
376 },
377 {
378 // common input
379 in: [][2]string{
380 {"-source", "1.8"},
381 {"-target", "1.8"},
382 },
383 out: "rO0ABXcgAAAAAgAHLXNvdXJjZQADMS44AActdGFyZ2V0AAMxLjg=",
384 },
385 {
386 // input that serializes to a 255 byte block
387 in: [][2]string{
388 {"-source", "1.8"},
389 {"-target", "1.8"},
390 {"a", strings.Repeat("b", 218)},
391 },
392 out: "rO0ABXf/AAAAAwAHLXNvdXJjZQADMS44AActdGFyZ2V0AAMxLjgAAWEA2mJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJi",
393 },
394 {
395 // input that serializes to a 256 byte block
396 in: [][2]string{
397 {"-source", "1.8"},
398 {"-target", "1.8"},
399 {"a", strings.Repeat("b", 219)},
400 },
401 out: "rO0ABXoAAAEAAAAAAwAHLXNvdXJjZQADMS44AActdGFyZ2V0AAMxLjgAAWEA22JiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYg==",
402 },
403 {
404 // input that serializes to a 257 byte block
405 in: [][2]string{
406 {"-source", "1.8"},
407 {"-target", "1.8"},
408 {"a", strings.Repeat("b", 220)},
409 },
410 out: "rO0ABXoAAAEBAAAAAwAHLXNvdXJjZQADMS44AActdGFyZ2V0AAMxLjgAAWEA3GJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmI=",
411 },
412 }
413
414 for i, test := range tests {
415 t.Run(strconv.Itoa(i), func(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800416 t.Parallel()
Colin Crossafbb1732019-01-17 15:42:52 -0800417 got := kaptEncodeFlags(test.in)
418 if got != test.out {
419 t.Errorf("\nwant %q\n got %q", test.out, got)
420 }
421 })
422 }
423}
Colin Crossa1ff7c62021-09-17 14:11:52 -0700424
425func TestKotlinCompose(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800426 t.Parallel()
Colin Crossa1ff7c62021-09-17 14:11:52 -0700427 result := android.GroupFixturePreparers(
428 PrepareForTestWithJavaDefaultModules,
429 ).RunTestWithBp(t, `
430 java_library {
431 name: "androidx.compose.runtime_runtime",
432 }
433
Luca Stefani50098f72024-10-12 17:55:31 +0200434 kotlin_plugin {
Dave Mankoff0a3ef842024-10-02 18:47:24 +0000435 name: "kotlin-compose-compiler-plugin",
Colin Crossa1ff7c62021-09-17 14:11:52 -0700436 }
437
438 java_library {
439 name: "withcompose",
440 srcs: ["a.kt"],
Colin Cross08b0a1c2022-05-02 13:59:33 -0700441 plugins: ["plugin"],
Colin Crossa1ff7c62021-09-17 14:11:52 -0700442 static_libs: ["androidx.compose.runtime_runtime"],
443 }
444
445 java_library {
446 name: "nocompose",
447 srcs: ["a.kt"],
448 }
Colin Cross08b0a1c2022-05-02 13:59:33 -0700449
450 java_plugin {
451 name: "plugin",
452 }
Colin Crossa1ff7c62021-09-17 14:11:52 -0700453 `)
454
455 buildOS := result.Config.BuildOS.String()
456
Colin Cross90607e92025-02-11 14:58:07 -0800457 composeCompiler := result.ModuleForTests(t, "kotlin-compose-compiler-plugin", buildOS+"_common").Rule("combineJar").Output
458 withCompose := result.ModuleForTests(t, "withcompose", "android_common")
459 noCompose := result.ModuleForTests(t, "nocompose", "android_common")
Colin Crossa1ff7c62021-09-17 14:11:52 -0700460
461 android.AssertStringListContains(t, "missing compose compiler dependency",
462 withCompose.Rule("kotlinc").Implicits.Strings(), composeCompiler.String())
463
464 android.AssertStringDoesContain(t, "missing compose compiler plugin",
465 withCompose.VariablesForTestsRelativeToTop()["kotlincFlags"], "-Xplugin="+composeCompiler.String())
466
Colin Cross08b0a1c2022-05-02 13:59:33 -0700467 android.AssertStringListContains(t, "missing kapt compose compiler dependency",
468 withCompose.Rule("kapt").Implicits.Strings(), composeCompiler.String())
469
Colin Crossa1ff7c62021-09-17 14:11:52 -0700470 android.AssertStringListDoesNotContain(t, "unexpected compose compiler dependency",
471 noCompose.Rule("kotlinc").Implicits.Strings(), composeCompiler.String())
472
473 android.AssertStringDoesNotContain(t, "unexpected compose compiler plugin",
474 noCompose.VariablesForTestsRelativeToTop()["kotlincFlags"], "-Xplugin="+composeCompiler.String())
475}
Luca Stefani50098f72024-10-12 17:55:31 +0200476
477func TestKotlinPlugin(t *testing.T) {
Colin Cross844cb6a2025-01-29 15:53:21 -0800478 t.Parallel()
Luca Stefani50098f72024-10-12 17:55:31 +0200479 result := android.GroupFixturePreparers(
480 PrepareForTestWithJavaDefaultModules,
481 ).RunTestWithBp(t, `
482 kotlin_plugin {
483 name: "kotlin_plugin",
484 }
485
486 java_library {
487 name: "with_kotlin_plugin",
488 srcs: ["a.kt"],
489 plugins: ["plugin"],
490 kotlin_plugins: ["kotlin_plugin"],
491 }
492
493 java_library {
494 name: "no_kotlin_plugin",
495 srcs: ["a.kt"],
496 }
497
498 java_plugin {
499 name: "plugin",
500 }
501 `)
502
503 buildOS := result.Config.BuildOS.String()
504
Colin Cross90607e92025-02-11 14:58:07 -0800505 kotlinPlugin := result.ModuleForTests(t, "kotlin_plugin", buildOS+"_common").Rule("combineJar").Output
506 withKotlinPlugin := result.ModuleForTests(t, "with_kotlin_plugin", "android_common")
507 noKotlinPlugin := result.ModuleForTests(t, "no_kotlin_plugin", "android_common")
Luca Stefani50098f72024-10-12 17:55:31 +0200508
509 android.AssertStringListContains(t, "missing plugin compiler dependency",
510 withKotlinPlugin.Rule("kotlinc").Implicits.Strings(), kotlinPlugin.String())
511
512 android.AssertStringDoesContain(t, "missing kotlin plugin",
513 withKotlinPlugin.VariablesForTestsRelativeToTop()["kotlincFlags"], "-Xplugin="+kotlinPlugin.String())
514
515 android.AssertStringListContains(t, "missing kapt kotlin plugin dependency",
516 withKotlinPlugin.Rule("kapt").Implicits.Strings(), kotlinPlugin.String())
517
518 android.AssertStringListDoesNotContain(t, "unexpected kotlin plugin dependency",
519 noKotlinPlugin.Rule("kotlinc").Implicits.Strings(), kotlinPlugin.String())
520
521 android.AssertStringDoesNotContain(t, "unexpected kotlin plugin",
522 noKotlinPlugin.VariablesForTestsRelativeToTop()["kotlincFlags"], "-Xplugin="+kotlinPlugin.String())
523}