| // Copyright (c) 2025, the R8 project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| package com.android.tools.r8; |
| |
| import com.android.tools.r8.KotlinCompilerTool.KotlinCompiler; |
| import com.android.tools.r8.KotlinCompilerTool.KotlinLambdaGeneration; |
| import com.android.tools.r8.KotlinCompilerTool.KotlinTargetVersion; |
| import com.android.tools.r8.TestRuntime.CfRuntime; |
| import java.io.IOException; |
| import java.nio.file.Path; |
| import java.util.Collection; |
| import java.util.IdentityHashMap; |
| import java.util.Map; |
| import java.util.Objects; |
| import java.util.function.Consumer; |
| import org.junit.rules.TemporaryFolder; |
| |
| public class KotlinCompileMemoizer { |
| |
| static class CompilerConfigurationKey { |
| |
| private final KotlinTargetVersion targetVersion; |
| private final KotlinLambdaGeneration lambdaGeneration; |
| |
| private CompilerConfigurationKey( |
| KotlinTargetVersion targetVersion, KotlinLambdaGeneration lambdaGeneration) { |
| this.targetVersion = targetVersion; |
| this.lambdaGeneration = lambdaGeneration; |
| } |
| |
| @Override |
| public boolean equals(Object o) { |
| if (this == o) { |
| return true; |
| } |
| if (!(o instanceof CompilerConfigurationKey)) { |
| return false; |
| } |
| CompilerConfigurationKey other = (CompilerConfigurationKey) o; |
| return targetVersion == other.targetVersion && lambdaGeneration == other.lambdaGeneration; |
| } |
| |
| @Override |
| public int hashCode() { |
| return Objects.hash(targetVersion, lambdaGeneration); |
| } |
| } |
| |
| private final Collection<Path> sources; |
| private final CfRuntime runtime; |
| private final TemporaryFolder temporaryFolder; |
| |
| private Consumer<KotlinCompilerTool> kotlinCompilerToolConsumer = x -> {}; |
| private final Map<KotlinCompiler, Map<CompilerConfigurationKey, Path>> compiledPaths = |
| new IdentityHashMap<>(); |
| |
| public KotlinCompileMemoizer(Collection<Path> sources) { |
| this(sources, CfRuntime.getCheckedInJdk9(), null); |
| } |
| |
| public KotlinCompileMemoizer( |
| Collection<Path> sources, CfRuntime runtime, TemporaryFolder temporaryFolder) { |
| this.sources = sources; |
| this.runtime = runtime; |
| this.temporaryFolder = temporaryFolder; |
| } |
| |
| public KotlinCompileMemoizer configure(Consumer<KotlinCompilerTool> consumer) { |
| this.kotlinCompilerToolConsumer = consumer; |
| return this; |
| } |
| |
| public Path getForConfiguration(KotlinTestParameters kotlinParameters) { |
| return getForConfiguration( |
| kotlinParameters.getCompiler(), |
| kotlinParameters.getTargetVersion(), |
| kotlinParameters.getLambdaGeneration()); |
| } |
| |
| public Path getForConfiguration( |
| KotlinCompiler compiler, |
| KotlinTargetVersion targetVersion, |
| KotlinLambdaGeneration lambdaGeneration) { |
| Map<CompilerConfigurationKey, Path> kotlinTargetVersionPathMap = compiledPaths.get(compiler); |
| if (kotlinTargetVersionPathMap == null) { |
| kotlinTargetVersionPathMap = new IdentityHashMap<>(); |
| compiledPaths.put(compiler, kotlinTargetVersionPathMap); |
| } |
| return kotlinTargetVersionPathMap.computeIfAbsent( |
| new CompilerConfigurationKey(targetVersion, lambdaGeneration), |
| ignored -> { |
| try { |
| KotlinCompilerTool kotlinc = |
| temporaryFolder == null |
| ? TestBase.kotlinc(runtime, compiler, targetVersion, lambdaGeneration) |
| : TestBase.kotlinc( |
| runtime, temporaryFolder, compiler, targetVersion, lambdaGeneration); |
| return kotlinc.addSourceFiles(sources).apply(kotlinCompilerToolConsumer).compile(); |
| } catch (IOException e) { |
| throw new RuntimeException(e); |
| } |
| }); |
| } |
| } |