blob: 491ce293986efdea6275596c836f9bd812e5aec5 [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 Crossafbb1732019-01-17 15:42:52 -080018 "strconv"
Colin Cross21fc9bb2019-01-18 15:05:09 -080019 "strings"
20 "testing"
Colin Cross0c66bc62021-07-20 09:47:41 -070021
22 "android/soong/android"
Colin Cross21fc9bb2019-01-18 15:05:09 -080023)
24
25func TestKotlin(t *testing.T) {
Jaewoong Jungf9a04432019-07-17 11:15:09 -070026 ctx, _ := testJava(t, `
Colin Cross21fc9bb2019-01-18 15:05:09 -080027 java_library {
28 name: "foo",
29 srcs: ["a.java", "b.kt"],
30 }
31
32 java_library {
33 name: "bar",
34 srcs: ["b.kt"],
35 libs: ["foo"],
36 static_libs: ["baz"],
37 }
38
39 java_library {
40 name: "baz",
41 srcs: ["c.java"],
42 }
43 `)
44
Colin Cross26d3d712022-05-03 14:20:24 -070045 kotlinStdlib := ctx.ModuleForTests("kotlin-stdlib", "android_common").
46 Output("turbine-combined/kotlin-stdlib.jar").Output
47 kotlinAnnotations := ctx.ModuleForTests("kotlin-annotations", "android_common").
48 Output("turbine-combined/kotlin-annotations.jar").Output
49
Colin Cross21fc9bb2019-01-18 15:05:09 -080050 fooKotlinc := ctx.ModuleForTests("foo", "android_common").Rule("kotlinc")
51 fooJavac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
52 fooJar := ctx.ModuleForTests("foo", "android_common").Output("combined/foo.jar")
Colin Cross220a9a12022-03-28 17:08:01 -070053 fooHeaderJar := ctx.ModuleForTests("foo", "android_common").Output("turbine-combined/foo.jar")
54
55 fooKotlincClasses := fooKotlinc.Output
56 fooKotlincHeaderClasses := fooKotlinc.ImplicitOutput
Colin Cross21fc9bb2019-01-18 15:05:09 -080057
58 if len(fooKotlinc.Inputs) != 2 || fooKotlinc.Inputs[0].String() != "a.java" ||
59 fooKotlinc.Inputs[1].String() != "b.kt" {
60 t.Errorf(`foo kotlinc inputs %v != ["a.java", "b.kt"]`, fooKotlinc.Inputs)
61 }
62
63 if len(fooJavac.Inputs) != 1 || fooJavac.Inputs[0].String() != "a.java" {
64 t.Errorf(`foo inputs %v != ["a.java"]`, fooJavac.Inputs)
65 }
66
Colin Cross220a9a12022-03-28 17:08:01 -070067 if !strings.Contains(fooJavac.Args["classpath"], fooKotlincHeaderClasses.String()) {
Colin Cross21fc9bb2019-01-18 15:05:09 -080068 t.Errorf("foo classpath %v does not contain %q",
Colin Cross220a9a12022-03-28 17:08:01 -070069 fooJavac.Args["classpath"], fooKotlincHeaderClasses.String())
Colin Cross21fc9bb2019-01-18 15:05:09 -080070 }
71
Colin Cross220a9a12022-03-28 17:08:01 -070072 if !inList(fooKotlincClasses.String(), fooJar.Inputs.Strings()) {
Colin Cross21fc9bb2019-01-18 15:05:09 -080073 t.Errorf("foo jar inputs %v does not contain %q",
Colin Cross220a9a12022-03-28 17:08:01 -070074 fooJar.Inputs.Strings(), fooKotlincClasses.String())
Colin Cross21fc9bb2019-01-18 15:05:09 -080075 }
76
Colin Cross26d3d712022-05-03 14:20:24 -070077 if !inList(kotlinStdlib.String(), fooJar.Inputs.Strings()) {
78 t.Errorf("foo jar inputs %v does not contain %v",
79 fooJar.Inputs.Strings(), kotlinStdlib.String())
80 }
81
82 if !inList(kotlinAnnotations.String(), fooJar.Inputs.Strings()) {
83 t.Errorf("foo jar inputs %v does not contain %v",
84 fooJar.Inputs.Strings(), kotlinAnnotations.String())
85 }
86
Colin Cross220a9a12022-03-28 17:08:01 -070087 if !inList(fooKotlincHeaderClasses.String(), fooHeaderJar.Inputs.Strings()) {
88 t.Errorf("foo header jar inputs %v does not contain %q",
89 fooHeaderJar.Inputs.Strings(), fooKotlincHeaderClasses.String())
90 }
91
Colin Cross21fc9bb2019-01-18 15:05:09 -080092 bazHeaderJar := ctx.ModuleForTests("baz", "android_common").Output("turbine-combined/baz.jar")
93 barKotlinc := ctx.ModuleForTests("bar", "android_common").Rule("kotlinc")
94
95 if len(barKotlinc.Inputs) != 1 || barKotlinc.Inputs[0].String() != "b.kt" {
96 t.Errorf(`bar kotlinc inputs %v != ["b.kt"]`, barKotlinc.Inputs)
97 }
98
99 if !inList(fooHeaderJar.Output.String(), barKotlinc.Implicits.Strings()) {
100 t.Errorf(`expected %q in bar implicits %v`,
101 fooHeaderJar.Output.String(), barKotlinc.Implicits.Strings())
102 }
103
104 if !inList(bazHeaderJar.Output.String(), barKotlinc.Implicits.Strings()) {
105 t.Errorf(`expected %q in bar implicits %v`,
106 bazHeaderJar.Output.String(), barKotlinc.Implicits.Strings())
107 }
108}
Colin Crossafbb1732019-01-17 15:42:52 -0800109
110func TestKapt(t *testing.T) {
Colin Cross748b2d82020-11-19 13:52:06 -0800111 bp := `
Colin Crossafbb1732019-01-17 15:42:52 -0800112 java_library {
113 name: "foo",
114 srcs: ["a.java", "b.kt"],
Colin Cross5a116862020-04-22 11:44:34 -0700115 plugins: ["bar", "baz"],
Colin Cross748b2d82020-11-19 13:52:06 -0800116 errorprone: {
117 extra_check_modules: ["my_check"],
118 },
Colin Crossafbb1732019-01-17 15:42:52 -0800119 }
120
Colin Crossbe9cdb82019-01-21 21:37:16 -0800121 java_plugin {
Colin Crossafbb1732019-01-17 15:42:52 -0800122 name: "bar",
Colin Cross3a3e94c2019-01-23 15:39:50 -0800123 processor_class: "com.bar",
124 srcs: ["b.java"],
Colin Crossafbb1732019-01-17 15:42:52 -0800125 }
Colin Cross5a116862020-04-22 11:44:34 -0700126
127 java_plugin {
128 name: "baz",
129 processor_class: "com.baz",
130 srcs: ["b.java"],
131 }
Colin Crossafbb1732019-01-17 15:42:52 -0800132
Colin Cross748b2d82020-11-19 13:52:06 -0800133 java_plugin {
134 name: "my_check",
135 srcs: ["b.java"],
136 }
137 `
138 t.Run("", func(t *testing.T) {
139 ctx, _ := testJava(t, bp)
Colin Cross3a3e94c2019-01-23 15:39:50 -0800140
Colin Cross0c66bc62021-07-20 09:47:41 -0700141 buildOS := ctx.Config().BuildOS.String()
Colin Crossafbb1732019-01-17 15:42:52 -0800142
Colin Crossf61766e2022-03-16 18:06:48 -0700143 foo := ctx.ModuleForTests("foo", "android_common")
144 kaptStubs := foo.Rule("kapt")
145 turbineApt := foo.Description("turbine apt")
146 kotlinc := foo.Rule("kotlinc")
147 javac := foo.Rule("javac")
Colin Cross3a3e94c2019-01-23 15:39:50 -0800148
Colin Cross748b2d82020-11-19 13:52:06 -0800149 bar := ctx.ModuleForTests("bar", buildOS+"_common").Rule("javac").Output.String()
150 baz := ctx.ModuleForTests("baz", buildOS+"_common").Rule("javac").Output.String()
Colin Crossafbb1732019-01-17 15:42:52 -0800151
Colin Cross748b2d82020-11-19 13:52:06 -0800152 // Test that the kotlin and java sources are passed to kapt and kotlinc
Colin Crossf61766e2022-03-16 18:06:48 -0700153 if len(kaptStubs.Inputs) != 2 || kaptStubs.Inputs[0].String() != "a.java" || kaptStubs.Inputs[1].String() != "b.kt" {
154 t.Errorf(`foo kapt inputs %v != ["a.java", "b.kt"]`, kaptStubs.Inputs)
Colin Cross748b2d82020-11-19 13:52:06 -0800155 }
156 if len(kotlinc.Inputs) != 2 || kotlinc.Inputs[0].String() != "a.java" || kotlinc.Inputs[1].String() != "b.kt" {
157 t.Errorf(`foo kotlinc inputs %v != ["a.java", "b.kt"]`, kotlinc.Inputs)
158 }
Colin Crossafbb1732019-01-17 15:42:52 -0800159
Colin Crossf61766e2022-03-16 18:06:48 -0700160 // Test that only the java sources are passed to turbine-apt and javac
161 if len(turbineApt.Inputs) != 1 || turbineApt.Inputs[0].String() != "a.java" {
162 t.Errorf(`foo turbine apt inputs %v != ["a.java"]`, turbineApt.Inputs)
163 }
Colin Cross748b2d82020-11-19 13:52:06 -0800164 if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "a.java" {
165 t.Errorf(`foo inputs %v != ["a.java"]`, javac.Inputs)
166 }
Colin Crossafbb1732019-01-17 15:42:52 -0800167
Colin Crossf61766e2022-03-16 18:06:48 -0700168 // Test that the kapt stubs jar is a dependency of turbine-apt
169 if !inList(kaptStubs.Output.String(), turbineApt.Implicits.Strings()) {
170 t.Errorf("expected %q in turbine-apt implicits %v", kaptStubs.Output.String(), kotlinc.Implicits.Strings())
Colin Cross748b2d82020-11-19 13:52:06 -0800171 }
Colin Cross3a3e94c2019-01-23 15:39:50 -0800172
Colin Crossf61766e2022-03-16 18:06:48 -0700173 // Test that the turbine-apt srcjar is a dependency of kotlinc and javac rules
Isaac Chioua23d9942022-04-06 06:14:38 +0000174 if !inList(turbineApt.Output.String(), kotlinc.Implicits.Strings()) {
175 t.Errorf("expected %q in kotlinc implicits %v", turbineApt.Output.String(), kotlinc.Implicits.Strings())
Colin Cross748b2d82020-11-19 13:52:06 -0800176 }
Isaac Chioua23d9942022-04-06 06:14:38 +0000177 if !inList(turbineApt.Output.String(), javac.Implicits.Strings()) {
178 t.Errorf("expected %q in javac implicits %v", turbineApt.Output.String(), javac.Implicits.Strings())
Colin Crossf61766e2022-03-16 18:06:48 -0700179 }
180
181 // Test that the turbine-apt srcjar is extracted by the kotlinc and javac rules
Isaac Chioua23d9942022-04-06 06:14:38 +0000182 if kotlinc.Args["srcJars"] != turbineApt.Output.String() {
183 t.Errorf("expected %q in kotlinc srcjars %v", turbineApt.Output.String(), kotlinc.Args["srcJars"])
Colin Crossf61766e2022-03-16 18:06:48 -0700184 }
Isaac Chioua23d9942022-04-06 06:14:38 +0000185 if javac.Args["srcJars"] != turbineApt.Output.String() {
186 t.Errorf("expected %q in javac srcjars %v", turbineApt.Output.String(), kotlinc.Args["srcJars"])
Colin Cross748b2d82020-11-19 13:52:06 -0800187 }
Colin Cross3a3e94c2019-01-23 15:39:50 -0800188
Colin Cross748b2d82020-11-19 13:52:06 -0800189 // Test that the processors are passed to kapt
190 expectedProcessorPath := "-P plugin:org.jetbrains.kotlin.kapt3:apclasspath=" + bar +
191 " -P plugin:org.jetbrains.kotlin.kapt3:apclasspath=" + baz
Colin Crossf61766e2022-03-16 18:06:48 -0700192 if kaptStubs.Args["kaptProcessorPath"] != expectedProcessorPath {
193 t.Errorf("expected kaptProcessorPath %q, got %q", expectedProcessorPath, kaptStubs.Args["kaptProcessorPath"])
Colin Cross748b2d82020-11-19 13:52:06 -0800194 }
195 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 -0700196 if kaptStubs.Args["kaptProcessor"] != expectedProcessor {
197 t.Errorf("expected kaptProcessor %q, got %q", expectedProcessor, kaptStubs.Args["kaptProcessor"])
198 }
199
200 // Test that the processors are passed to turbine-apt
201 expectedProcessorPath = "--processorpath " + bar + " " + baz
202 if !strings.Contains(turbineApt.Args["turbineFlags"], expectedProcessorPath) {
203 t.Errorf("expected turbine-apt processorpath %q, got %q", expectedProcessorPath, turbineApt.Args["turbineFlags"])
204 }
205 expectedProcessor = "--processors com.bar com.baz"
206 if !strings.Contains(turbineApt.Args["turbineFlags"], expectedProcessor) {
207 t.Errorf("expected turbine-apt processor %q, got %q", expectedProcessor, turbineApt.Args["turbineFlags"])
Colin Cross748b2d82020-11-19 13:52:06 -0800208 }
209
210 // Test that the processors are not passed to javac
211 if javac.Args["processorpath"] != "" {
212 t.Errorf("expected processorPath '', got %q", javac.Args["processorpath"])
213 }
214 if javac.Args["processor"] != "-proc:none" {
215 t.Errorf("expected processor '-proc:none', got %q", javac.Args["processor"])
216 }
217 })
218
219 t.Run("errorprone", func(t *testing.T) {
220 env := map[string]string{
221 "RUN_ERROR_PRONE": "true",
222 }
Paul Duffinb148a492021-03-22 17:31:52 +0000223
224 result := android.GroupFixturePreparers(
225 PrepareForTestWithJavaDefaultModules,
226 android.FixtureMergeEnv(env),
227 ).RunTestWithBp(t, bp)
Colin Cross748b2d82020-11-19 13:52:06 -0800228
Colin Cross0c66bc62021-07-20 09:47:41 -0700229 buildOS := result.Config.BuildOS.String()
Colin Cross748b2d82020-11-19 13:52:06 -0800230
Paul Duffinb148a492021-03-22 17:31:52 +0000231 kapt := result.ModuleForTests("foo", "android_common").Rule("kapt")
Paul Duffinb148a492021-03-22 17:31:52 +0000232 javac := result.ModuleForTests("foo", "android_common").Description("javac")
233 errorprone := result.ModuleForTests("foo", "android_common").Description("errorprone")
Colin Cross748b2d82020-11-19 13:52:06 -0800234
Paul Duffinb148a492021-03-22 17:31:52 +0000235 bar := result.ModuleForTests("bar", buildOS+"_common").Description("javac").Output.String()
236 baz := result.ModuleForTests("baz", buildOS+"_common").Description("javac").Output.String()
237 myCheck := result.ModuleForTests("my_check", buildOS+"_common").Description("javac").Output.String()
Colin Cross748b2d82020-11-19 13:52:06 -0800238
239 // Test that the errorprone plugins are not passed to kapt
240 expectedProcessorPath := "-P plugin:org.jetbrains.kotlin.kapt3:apclasspath=" + bar +
241 " -P plugin:org.jetbrains.kotlin.kapt3:apclasspath=" + baz
242 if kapt.Args["kaptProcessorPath"] != expectedProcessorPath {
243 t.Errorf("expected kaptProcessorPath %q, got %q", expectedProcessorPath, kapt.Args["kaptProcessorPath"])
244 }
245 expectedProcessor := "-P plugin:org.jetbrains.kotlin.kapt3:processors=com.bar -P plugin:org.jetbrains.kotlin.kapt3:processors=com.baz"
246 if kapt.Args["kaptProcessor"] != expectedProcessor {
247 t.Errorf("expected kaptProcessor %q, got %q", expectedProcessor, kapt.Args["kaptProcessor"])
248 }
249
250 // Test that the errorprone plugins are not passed to javac
251 if javac.Args["processorpath"] != "" {
252 t.Errorf("expected processorPath '', got %q", javac.Args["processorpath"])
253 }
254 if javac.Args["processor"] != "-proc:none" {
255 t.Errorf("expected processor '-proc:none', got %q", javac.Args["processor"])
256 }
257
258 // Test that the errorprone plugins are passed to errorprone
259 expectedProcessorPath = "-processorpath " + myCheck
260 if errorprone.Args["processorpath"] != expectedProcessorPath {
261 t.Errorf("expected processorpath %q, got %q", expectedProcessorPath, errorprone.Args["processorpath"])
262 }
263 if errorprone.Args["processor"] != "-proc:none" {
264 t.Errorf("expected processor '-proc:none', got %q", errorprone.Args["processor"])
265 }
266 })
Colin Crossafbb1732019-01-17 15:42:52 -0800267}
268
269func TestKaptEncodeFlags(t *testing.T) {
270 // Compares the kaptEncodeFlags against the results of the example implementation at
271 // https://kotlinlang.org/docs/reference/kapt.html#apjavac-options-encoding
272 tests := []struct {
273 in [][2]string
274 out string
275 }{
276 {
277 // empty input
278 in: [][2]string{},
279 out: "rO0ABXcEAAAAAA==",
280 },
281 {
282 // common input
283 in: [][2]string{
284 {"-source", "1.8"},
285 {"-target", "1.8"},
286 },
287 out: "rO0ABXcgAAAAAgAHLXNvdXJjZQADMS44AActdGFyZ2V0AAMxLjg=",
288 },
289 {
290 // input that serializes to a 255 byte block
291 in: [][2]string{
292 {"-source", "1.8"},
293 {"-target", "1.8"},
294 {"a", strings.Repeat("b", 218)},
295 },
296 out: "rO0ABXf/AAAAAwAHLXNvdXJjZQADMS44AActdGFyZ2V0AAMxLjgAAWEA2mJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJi",
297 },
298 {
299 // input that serializes to a 256 byte block
300 in: [][2]string{
301 {"-source", "1.8"},
302 {"-target", "1.8"},
303 {"a", strings.Repeat("b", 219)},
304 },
305 out: "rO0ABXoAAAEAAAAAAwAHLXNvdXJjZQADMS44AActdGFyZ2V0AAMxLjgAAWEA22JiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYg==",
306 },
307 {
308 // input that serializes to a 257 byte block
309 in: [][2]string{
310 {"-source", "1.8"},
311 {"-target", "1.8"},
312 {"a", strings.Repeat("b", 220)},
313 },
314 out: "rO0ABXoAAAEBAAAAAwAHLXNvdXJjZQADMS44AActdGFyZ2V0AAMxLjgAAWEA3GJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmI=",
315 },
316 }
317
318 for i, test := range tests {
319 t.Run(strconv.Itoa(i), func(t *testing.T) {
320 got := kaptEncodeFlags(test.in)
321 if got != test.out {
322 t.Errorf("\nwant %q\n got %q", test.out, got)
323 }
324 })
325 }
326}
Colin Crossa1ff7c62021-09-17 14:11:52 -0700327
328func TestKotlinCompose(t *testing.T) {
329 result := android.GroupFixturePreparers(
330 PrepareForTestWithJavaDefaultModules,
331 ).RunTestWithBp(t, `
332 java_library {
333 name: "androidx.compose.runtime_runtime",
334 }
335
336 java_library_host {
337 name: "androidx.compose.compiler_compiler-hosted",
338 }
339
340 java_library {
341 name: "withcompose",
342 srcs: ["a.kt"],
Colin Crossdddb4022022-05-02 13:59:33 -0700343 plugins: ["plugin"],
Colin Crossa1ff7c62021-09-17 14:11:52 -0700344 static_libs: ["androidx.compose.runtime_runtime"],
345 }
346
347 java_library {
348 name: "nocompose",
349 srcs: ["a.kt"],
350 }
Colin Crossdddb4022022-05-02 13:59:33 -0700351
352 java_plugin {
353 name: "plugin",
354 }
Colin Crossa1ff7c62021-09-17 14:11:52 -0700355 `)
356
357 buildOS := result.Config.BuildOS.String()
358
359 composeCompiler := result.ModuleForTests("androidx.compose.compiler_compiler-hosted", buildOS+"_common").Rule("combineJar").Output
360 withCompose := result.ModuleForTests("withcompose", "android_common")
361 noCompose := result.ModuleForTests("nocompose", "android_common")
362
363 android.AssertStringListContains(t, "missing compose compiler dependency",
364 withCompose.Rule("kotlinc").Implicits.Strings(), composeCompiler.String())
365
366 android.AssertStringDoesContain(t, "missing compose compiler plugin",
367 withCompose.VariablesForTestsRelativeToTop()["kotlincFlags"], "-Xplugin="+composeCompiler.String())
368
Colin Crossdddb4022022-05-02 13:59:33 -0700369 android.AssertStringListContains(t, "missing kapt compose compiler dependency",
370 withCompose.Rule("kapt").Implicits.Strings(), composeCompiler.String())
371
Colin Crossa1ff7c62021-09-17 14:11:52 -0700372 android.AssertStringListDoesNotContain(t, "unexpected compose compiler dependency",
373 noCompose.Rule("kotlinc").Implicits.Strings(), composeCompiler.String())
374
375 android.AssertStringDoesNotContain(t, "unexpected compose compiler plugin",
376 noCompose.VariablesForTestsRelativeToTop()["kotlincFlags"], "-Xplugin="+composeCompiler.String())
377}