blob: cac0af3b99d3af7d6aeb6016cc7cf2806dcad7fd [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
45 fooKotlinc := ctx.ModuleForTests("foo", "android_common").Rule("kotlinc")
46 fooJavac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
47 fooJar := ctx.ModuleForTests("foo", "android_common").Output("combined/foo.jar")
48
49 if len(fooKotlinc.Inputs) != 2 || fooKotlinc.Inputs[0].String() != "a.java" ||
50 fooKotlinc.Inputs[1].String() != "b.kt" {
51 t.Errorf(`foo kotlinc inputs %v != ["a.java", "b.kt"]`, fooKotlinc.Inputs)
52 }
53
54 if len(fooJavac.Inputs) != 1 || fooJavac.Inputs[0].String() != "a.java" {
55 t.Errorf(`foo inputs %v != ["a.java"]`, fooJavac.Inputs)
56 }
57
58 if !strings.Contains(fooJavac.Args["classpath"], fooKotlinc.Output.String()) {
59 t.Errorf("foo classpath %v does not contain %q",
60 fooJavac.Args["classpath"], fooKotlinc.Output.String())
61 }
62
63 if !inList(fooKotlinc.Output.String(), fooJar.Inputs.Strings()) {
64 t.Errorf("foo jar inputs %v does not contain %q",
65 fooJar.Inputs.Strings(), fooKotlinc.Output.String())
66 }
67
68 fooHeaderJar := ctx.ModuleForTests("foo", "android_common").Output("turbine-combined/foo.jar")
69 bazHeaderJar := ctx.ModuleForTests("baz", "android_common").Output("turbine-combined/baz.jar")
70 barKotlinc := ctx.ModuleForTests("bar", "android_common").Rule("kotlinc")
71
72 if len(barKotlinc.Inputs) != 1 || barKotlinc.Inputs[0].String() != "b.kt" {
73 t.Errorf(`bar kotlinc inputs %v != ["b.kt"]`, barKotlinc.Inputs)
74 }
75
76 if !inList(fooHeaderJar.Output.String(), barKotlinc.Implicits.Strings()) {
77 t.Errorf(`expected %q in bar implicits %v`,
78 fooHeaderJar.Output.String(), barKotlinc.Implicits.Strings())
79 }
80
81 if !inList(bazHeaderJar.Output.String(), barKotlinc.Implicits.Strings()) {
82 t.Errorf(`expected %q in bar implicits %v`,
83 bazHeaderJar.Output.String(), barKotlinc.Implicits.Strings())
84 }
85}
Colin Crossafbb1732019-01-17 15:42:52 -080086
87func TestKapt(t *testing.T) {
Colin Cross748b2d82020-11-19 13:52:06 -080088 bp := `
Colin Crossafbb1732019-01-17 15:42:52 -080089 java_library {
90 name: "foo",
91 srcs: ["a.java", "b.kt"],
Colin Cross5a116862020-04-22 11:44:34 -070092 plugins: ["bar", "baz"],
Colin Cross748b2d82020-11-19 13:52:06 -080093 errorprone: {
94 extra_check_modules: ["my_check"],
95 },
Colin Crossafbb1732019-01-17 15:42:52 -080096 }
97
Colin Crossbe9cdb82019-01-21 21:37:16 -080098 java_plugin {
Colin Crossafbb1732019-01-17 15:42:52 -080099 name: "bar",
Colin Cross3a3e94c2019-01-23 15:39:50 -0800100 processor_class: "com.bar",
101 srcs: ["b.java"],
Colin Crossafbb1732019-01-17 15:42:52 -0800102 }
Colin Cross5a116862020-04-22 11:44:34 -0700103
104 java_plugin {
105 name: "baz",
106 processor_class: "com.baz",
107 srcs: ["b.java"],
108 }
Colin Crossafbb1732019-01-17 15:42:52 -0800109
Colin Cross748b2d82020-11-19 13:52:06 -0800110 java_plugin {
111 name: "my_check",
112 srcs: ["b.java"],
113 }
114 `
115 t.Run("", func(t *testing.T) {
116 ctx, _ := testJava(t, bp)
Colin Cross3a3e94c2019-01-23 15:39:50 -0800117
Colin Cross0c66bc62021-07-20 09:47:41 -0700118 buildOS := ctx.Config().BuildOS.String()
Colin Crossafbb1732019-01-17 15:42:52 -0800119
Colin Cross748b2d82020-11-19 13:52:06 -0800120 kapt := ctx.ModuleForTests("foo", "android_common").Rule("kapt")
121 kotlinc := ctx.ModuleForTests("foo", "android_common").Rule("kotlinc")
122 javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
Colin Cross3a3e94c2019-01-23 15:39:50 -0800123
Colin Cross748b2d82020-11-19 13:52:06 -0800124 bar := ctx.ModuleForTests("bar", buildOS+"_common").Rule("javac").Output.String()
125 baz := ctx.ModuleForTests("baz", buildOS+"_common").Rule("javac").Output.String()
Colin Crossafbb1732019-01-17 15:42:52 -0800126
Colin Cross748b2d82020-11-19 13:52:06 -0800127 // Test that the kotlin and java sources are passed to kapt and kotlinc
128 if len(kapt.Inputs) != 2 || kapt.Inputs[0].String() != "a.java" || kapt.Inputs[1].String() != "b.kt" {
129 t.Errorf(`foo kapt inputs %v != ["a.java", "b.kt"]`, kapt.Inputs)
130 }
131 if len(kotlinc.Inputs) != 2 || kotlinc.Inputs[0].String() != "a.java" || kotlinc.Inputs[1].String() != "b.kt" {
132 t.Errorf(`foo kotlinc inputs %v != ["a.java", "b.kt"]`, kotlinc.Inputs)
133 }
Colin Crossafbb1732019-01-17 15:42:52 -0800134
Colin Cross748b2d82020-11-19 13:52:06 -0800135 // Test that only the java sources are passed to javac
136 if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "a.java" {
137 t.Errorf(`foo inputs %v != ["a.java"]`, javac.Inputs)
138 }
Colin Crossafbb1732019-01-17 15:42:52 -0800139
Colin Cross748b2d82020-11-19 13:52:06 -0800140 // Test that the kapt srcjar is a dependency of kotlinc and javac rules
141 if !inList(kapt.Output.String(), kotlinc.Implicits.Strings()) {
142 t.Errorf("expected %q in kotlinc implicits %v", kapt.Output.String(), kotlinc.Implicits.Strings())
143 }
144 if !inList(kapt.Output.String(), javac.Implicits.Strings()) {
145 t.Errorf("expected %q in javac implicits %v", kapt.Output.String(), javac.Implicits.Strings())
146 }
Colin Cross3a3e94c2019-01-23 15:39:50 -0800147
Colin Cross748b2d82020-11-19 13:52:06 -0800148 // Test that the kapt srcjar is extracted by the kotlinc and javac rules
149 if kotlinc.Args["srcJars"] != kapt.Output.String() {
150 t.Errorf("expected %q in kotlinc srcjars %v", kapt.Output.String(), kotlinc.Args["srcJars"])
151 }
152 if javac.Args["srcJars"] != kapt.Output.String() {
153 t.Errorf("expected %q in javac srcjars %v", kapt.Output.String(), kotlinc.Args["srcJars"])
154 }
Colin Cross3a3e94c2019-01-23 15:39:50 -0800155
Colin Cross748b2d82020-11-19 13:52:06 -0800156 // Test that the processors are passed to kapt
157 expectedProcessorPath := "-P plugin:org.jetbrains.kotlin.kapt3:apclasspath=" + bar +
158 " -P plugin:org.jetbrains.kotlin.kapt3:apclasspath=" + baz
159 if kapt.Args["kaptProcessorPath"] != expectedProcessorPath {
160 t.Errorf("expected kaptProcessorPath %q, got %q", expectedProcessorPath, kapt.Args["kaptProcessorPath"])
161 }
162 expectedProcessor := "-P plugin:org.jetbrains.kotlin.kapt3:processors=com.bar -P plugin:org.jetbrains.kotlin.kapt3:processors=com.baz"
163 if kapt.Args["kaptProcessor"] != expectedProcessor {
164 t.Errorf("expected kaptProcessor %q, got %q", expectedProcessor, kapt.Args["kaptProcessor"])
165 }
166
167 // Test that the processors are not passed to javac
168 if javac.Args["processorpath"] != "" {
169 t.Errorf("expected processorPath '', got %q", javac.Args["processorpath"])
170 }
171 if javac.Args["processor"] != "-proc:none" {
172 t.Errorf("expected processor '-proc:none', got %q", javac.Args["processor"])
173 }
174 })
175
176 t.Run("errorprone", func(t *testing.T) {
177 env := map[string]string{
178 "RUN_ERROR_PRONE": "true",
179 }
Paul Duffinb148a492021-03-22 17:31:52 +0000180
181 result := android.GroupFixturePreparers(
182 PrepareForTestWithJavaDefaultModules,
183 android.FixtureMergeEnv(env),
184 ).RunTestWithBp(t, bp)
Colin Cross748b2d82020-11-19 13:52:06 -0800185
Colin Cross0c66bc62021-07-20 09:47:41 -0700186 buildOS := result.Config.BuildOS.String()
Colin Cross748b2d82020-11-19 13:52:06 -0800187
Paul Duffinb148a492021-03-22 17:31:52 +0000188 kapt := result.ModuleForTests("foo", "android_common").Rule("kapt")
Paul Duffinb148a492021-03-22 17:31:52 +0000189 javac := result.ModuleForTests("foo", "android_common").Description("javac")
190 errorprone := result.ModuleForTests("foo", "android_common").Description("errorprone")
Colin Cross748b2d82020-11-19 13:52:06 -0800191
Paul Duffinb148a492021-03-22 17:31:52 +0000192 bar := result.ModuleForTests("bar", buildOS+"_common").Description("javac").Output.String()
193 baz := result.ModuleForTests("baz", buildOS+"_common").Description("javac").Output.String()
194 myCheck := result.ModuleForTests("my_check", buildOS+"_common").Description("javac").Output.String()
Colin Cross748b2d82020-11-19 13:52:06 -0800195
196 // Test that the errorprone plugins are not passed to kapt
197 expectedProcessorPath := "-P plugin:org.jetbrains.kotlin.kapt3:apclasspath=" + bar +
198 " -P plugin:org.jetbrains.kotlin.kapt3:apclasspath=" + baz
199 if kapt.Args["kaptProcessorPath"] != expectedProcessorPath {
200 t.Errorf("expected kaptProcessorPath %q, got %q", expectedProcessorPath, kapt.Args["kaptProcessorPath"])
201 }
202 expectedProcessor := "-P plugin:org.jetbrains.kotlin.kapt3:processors=com.bar -P plugin:org.jetbrains.kotlin.kapt3:processors=com.baz"
203 if kapt.Args["kaptProcessor"] != expectedProcessor {
204 t.Errorf("expected kaptProcessor %q, got %q", expectedProcessor, kapt.Args["kaptProcessor"])
205 }
206
207 // Test that the errorprone plugins are not passed to javac
208 if javac.Args["processorpath"] != "" {
209 t.Errorf("expected processorPath '', got %q", javac.Args["processorpath"])
210 }
211 if javac.Args["processor"] != "-proc:none" {
212 t.Errorf("expected processor '-proc:none', got %q", javac.Args["processor"])
213 }
214
215 // Test that the errorprone plugins are passed to errorprone
216 expectedProcessorPath = "-processorpath " + myCheck
217 if errorprone.Args["processorpath"] != expectedProcessorPath {
218 t.Errorf("expected processorpath %q, got %q", expectedProcessorPath, errorprone.Args["processorpath"])
219 }
220 if errorprone.Args["processor"] != "-proc:none" {
221 t.Errorf("expected processor '-proc:none', got %q", errorprone.Args["processor"])
222 }
223 })
Colin Crossafbb1732019-01-17 15:42:52 -0800224}
225
226func TestKaptEncodeFlags(t *testing.T) {
227 // Compares the kaptEncodeFlags against the results of the example implementation at
228 // https://kotlinlang.org/docs/reference/kapt.html#apjavac-options-encoding
229 tests := []struct {
230 in [][2]string
231 out string
232 }{
233 {
234 // empty input
235 in: [][2]string{},
236 out: "rO0ABXcEAAAAAA==",
237 },
238 {
239 // common input
240 in: [][2]string{
241 {"-source", "1.8"},
242 {"-target", "1.8"},
243 },
244 out: "rO0ABXcgAAAAAgAHLXNvdXJjZQADMS44AActdGFyZ2V0AAMxLjg=",
245 },
246 {
247 // input that serializes to a 255 byte block
248 in: [][2]string{
249 {"-source", "1.8"},
250 {"-target", "1.8"},
251 {"a", strings.Repeat("b", 218)},
252 },
253 out: "rO0ABXf/AAAAAwAHLXNvdXJjZQADMS44AActdGFyZ2V0AAMxLjgAAWEA2mJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJi",
254 },
255 {
256 // input that serializes to a 256 byte block
257 in: [][2]string{
258 {"-source", "1.8"},
259 {"-target", "1.8"},
260 {"a", strings.Repeat("b", 219)},
261 },
262 out: "rO0ABXoAAAEAAAAAAwAHLXNvdXJjZQADMS44AActdGFyZ2V0AAMxLjgAAWEA22JiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYg==",
263 },
264 {
265 // input that serializes to a 257 byte block
266 in: [][2]string{
267 {"-source", "1.8"},
268 {"-target", "1.8"},
269 {"a", strings.Repeat("b", 220)},
270 },
271 out: "rO0ABXoAAAEBAAAAAwAHLXNvdXJjZQADMS44AActdGFyZ2V0AAMxLjgAAWEA3GJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmI=",
272 },
273 }
274
275 for i, test := range tests {
276 t.Run(strconv.Itoa(i), func(t *testing.T) {
277 got := kaptEncodeFlags(test.in)
278 if got != test.out {
279 t.Errorf("\nwant %q\n got %q", test.out, got)
280 }
281 })
282 }
283}
Colin Crossa1ff7c62021-09-17 14:11:52 -0700284
285func TestKotlinCompose(t *testing.T) {
286 result := android.GroupFixturePreparers(
287 PrepareForTestWithJavaDefaultModules,
288 ).RunTestWithBp(t, `
289 java_library {
290 name: "androidx.compose.runtime_runtime",
291 }
292
293 java_library_host {
294 name: "androidx.compose.compiler_compiler-hosted",
295 }
296
297 java_library {
298 name: "withcompose",
299 srcs: ["a.kt"],
300 static_libs: ["androidx.compose.runtime_runtime"],
301 }
302
303 java_library {
304 name: "nocompose",
305 srcs: ["a.kt"],
306 }
307 `)
308
309 buildOS := result.Config.BuildOS.String()
310
311 composeCompiler := result.ModuleForTests("androidx.compose.compiler_compiler-hosted", buildOS+"_common").Rule("combineJar").Output
312 withCompose := result.ModuleForTests("withcompose", "android_common")
313 noCompose := result.ModuleForTests("nocompose", "android_common")
314
315 android.AssertStringListContains(t, "missing compose compiler dependency",
316 withCompose.Rule("kotlinc").Implicits.Strings(), composeCompiler.String())
317
318 android.AssertStringDoesContain(t, "missing compose compiler plugin",
319 withCompose.VariablesForTestsRelativeToTop()["kotlincFlags"], "-Xplugin="+composeCompiler.String())
320
321 android.AssertStringListDoesNotContain(t, "unexpected compose compiler dependency",
322 noCompose.Rule("kotlinc").Implicits.Strings(), composeCompiler.String())
323
324 android.AssertStringDoesNotContain(t, "unexpected compose compiler plugin",
325 noCompose.VariablesForTestsRelativeToTop()["kotlincFlags"], "-Xplugin="+composeCompiler.String())
326}