1 /*
<lambda>null2  * Copyright (C) 2023 The Android Open Source Project
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 com.android.tools.metalava.model.source
18 
19 import com.android.tools.metalava.model.Codebase
20 import com.android.tools.metalava.model.noOpAnnotationManager
21 import com.android.tools.metalava.model.provider.Capability
22 import com.android.tools.metalava.model.provider.InputFormat
23 import com.android.tools.metalava.model.testsuite.ModelSuiteRunner
24 import com.android.tools.metalava.model.testsuite.ModelSuiteRunner.TestConfiguration
25 import com.android.tools.metalava.reporter.BasicReporter
26 import com.android.tools.metalava.testing.getAndroidJar
27 import com.android.tools.metalava.testing.getKotlinStdlibPaths
28 import java.io.File
29 import java.io.PrintWriter
30 
31 /**
32  * A [ModelSuiteRunner] that is implemented using a [SourceModelProvider].
33  *
34  * This expects to be loaded on a class path that contains a single [SourceModelProvider] service
35  * (retrievable via [SourceModelProvider.getImplementation]).
36  */
37 // @AutoService(ModelSuiteRunner.class)
38 class SourceModelSuiteRunner : ModelSuiteRunner {
39 
40     /** Get the [SourceModelProvider] implementation that is available. */
41     private val sourceModelProvider = SourceModelProvider.getImplementation({ true }, "of any type")
42 
43     override val providerName = sourceModelProvider.providerName
44 
45     override val supportedInputFormats = sourceModelProvider.supportedInputFormats
46 
47     override val capabilities: Set<Capability> = sourceModelProvider.capabilities
48 
49     override val testConfigurations: List<TestConfiguration> =
50         supportedInputFormats.flatMap { inputFormat ->
51             sourceModelProvider.modelOptionsList.map { modelOptions ->
52                 TestConfiguration(inputFormat, modelOptions)
53             }
54         }
55 
56     override fun createCodebaseAndRun(
57         inputs: ModelSuiteRunner.TestInputs,
58         test: (Codebase) -> Unit
59     ) {
60         sourceModelProvider.createEnvironmentManager(forTesting = true).use { environmentManager ->
61             val classPath = buildList {
62                 add(getAndroidJar())
63                 if (inputs.inputFormat == InputFormat.KOTLIN) {
64                     addAll(getKotlinStdlibPaths())
65                 }
66             }
67             val codebase =
68                 createTestCodebase(
69                     environmentManager,
70                     inputs,
71                     classPath,
72                 )
73             test(codebase)
74         }
75     }
76 
77     private fun createTestCodebase(
78         environmentManager: EnvironmentManager,
79         inputs: ModelSuiteRunner.TestInputs,
80         classPath: List<File>,
81     ): Codebase {
82         val reporter = BasicReporter(PrintWriter(System.err))
83         val sourceParser =
84             environmentManager.createSourceParser(
85                 reporter = reporter,
86                 annotationManager = noOpAnnotationManager,
87                 modelOptions = inputs.modelOptions,
88             )
89         return sourceParser.parseSources(
90             sourceSet(inputs.mainSourceDir),
91             sourceSet(inputs.commonSourceDir),
92             description = "Test Codebase",
93             classPath = classPath,
94         )
95     }
96 
97     private fun sourceSet(sourceDir: ModelSuiteRunner.SourceDir?) =
98         if (sourceDir == null) SourceSet.empty()
99         else SourceSet(sourceDir.createFiles(), listOf(sourceDir.dir))
100 
101     override fun toString(): String = sourceModelProvider.providerName
102 }
103