Support loading Java records

^KT-43677 In Progress
This commit is contained in:
Denis.Zharkov
2020-11-23 16:02:26 +03:00
parent f25b7672a7
commit 513f7177ca
45 changed files with 688 additions and 61 deletions
@@ -0,0 +1,25 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.checkers
import org.jetbrains.kotlin.test.TestJdkKind
abstract class AbstractDiagnosticsWithJdk15Test : AbstractDiagnosticsTest() {
override fun getTestJdkKind(files: List<TestFile>): TestJdkKind {
return TestJdkKind.FULL_JDK_15
}
}
@@ -0,0 +1,18 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.jvm.compiler
import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.test.TestJdkKind
import java.io.File
abstract class AbstractLoadJava15Test : AbstractLoadJavaTest() {
override fun getJdkKind(): TestJdkKind = TestJdkKind.FULL_JDK_15
override fun getJdkHomeForJavac(): File = KotlinTestUtils.getJdk15Home()
override fun getAdditionalJavacArgs(): List<String> = ADDITIONAL_JAVAC_ARGS_FOR_15
}
val ADDITIONAL_JAVAC_ARGS_FOR_15 = listOf("--release", "15", "--enable-preview")
@@ -0,0 +1,16 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.jvm.compiler
import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.test.TestJdkKind
import java.io.File
abstract class AbstractLoadJava15WithPsiClassReadingTest : AbstractLoadJavaWithPsiClassReadingTest() {
override fun getJdkKind(): TestJdkKind = TestJdkKind.FULL_JDK_15
override fun getJdkHomeForJavac(): File = KotlinTestUtils.getJdk15Home()
override fun getAdditionalJavacArgs(): List<String> = ADDITIONAL_JAVAC_ARGS_FOR_15
}
@@ -9,6 +9,7 @@ import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.io.FileUtil;
import junit.framework.ComparisonFailure;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.analyzer.AnalysisResult;
import org.jetbrains.kotlin.checkers.CompilerTestLanguageVersionSettingsKt;
import org.jetbrains.kotlin.cli.common.config.ContentRootsKt;
@@ -299,7 +300,19 @@ public abstract class AbstractLoadJavaTest extends TestCaseWithTmpdir {
Pair<PackageViewDescriptor, BindingContext> javaPackageAndContext = compileJavaAndLoadTestPackageAndBindingContextFromBinary(
srcFiles, compiledDir, ConfigurationKind.ALL
);
checkJavaPackage(getExpectedFile(javaFileName.replaceFirst("\\.java$", ".txt")), javaPackageAndContext.first, javaPackageAndContext.second, configuration);
checkJavaPackage(getExpectedFile(
useTxtSuffixIfFileExists(javaFileName.replaceFirst("\\.java$", ".txt"), "compiled")
), javaPackageAndContext.first, javaPackageAndContext.second, configuration);
}
public static String useTxtSuffixIfFileExists(String name, String suffix) {
File differentResultFile = KotlinTestUtils.replaceExtension(new File(name), suffix + ".txt");
if (differentResultFile.exists()) return differentResultFile.getPath();
return name;
}
@NotNull
@@ -308,12 +321,21 @@ public abstract class AbstractLoadJavaTest extends TestCaseWithTmpdir {
@NotNull File outDir,
@NotNull ConfigurationKind configurationKind
) throws IOException {
compileJavaWithAnnotationsJar(javaFiles, outDir);
compileJavaWithAnnotationsJar(javaFiles, outDir, getAdditionalJavacArgs(), getJdkHomeForJavac());
return loadTestPackageAndBindingContextFromJavaRoot(outDir, getTestRootDisposable(), getJdkKind(), configurationKind, true,
usePsiClassFilesReading(), useJavacWrapper(), null,
getExtraClasspath(), this::configureEnvironment);
}
protected List<String> getAdditionalJavacArgs() {
return Collections.emptyList();
}
@Nullable
protected File getJdkHomeForJavac() {
return null;
}
private static void checkJavaPackage(
File txtFile,
PackageViewDescriptor javaPackage,
@@ -142,7 +142,12 @@ public class LoadDescriptorUtil {
return Pair.create(packageView, analysisResult.getBindingContext());
}
public static void compileJavaWithAnnotationsJar(@NotNull Collection<File> javaFiles, @NotNull File outDir) throws IOException {
public static void compileJavaWithAnnotationsJar(
@NotNull Collection<File> javaFiles,
@NotNull File outDir,
@NotNull List<String> additionalArgs,
@Nullable File customJdkHomeForJavac
) throws IOException {
List<String> args = new ArrayList<>(Arrays.asList(
"-sourcepath", "compiler/testData/loadJava/include",
"-d", outDir.getPath())
@@ -170,7 +175,14 @@ public class LoadDescriptorUtil {
args.add("-classpath");
args.add(classpath.stream().map(File::getPath).collect(Collectors.joining(File.pathSeparator)));
KotlinTestUtils.compileJavaFiles(javaFiles, args);
args.addAll(additionalArgs);
if (customJdkHomeForJavac != null) {
KotlinTestUtils.compileJavaFilesExternally(javaFiles, args, customJdkHomeForJavac);
}
else {
KotlinTestUtils.compileJavaFiles(javaFiles, args);
}
}
@NotNull
@@ -680,6 +680,10 @@ public class KotlinTestUtils {
}
public static boolean compileJavaFilesExternallyWithJava9(@NotNull Collection<File> files, @NotNull List<String> options) {
return compileJavaFilesExternally(files, options, getJdk9Home());
}
public static boolean compileJavaFilesExternally(@NotNull Collection<File> files, @NotNull List<String> options, @NotNull File jdkHome) {
List<String> command = new ArrayList<>();
command.add(new File(jdkHome, "bin/javac").getPath());
command.addAll(options);
@@ -27,6 +27,8 @@ import org.jetbrains.kotlin.contracts.description.*;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.impl.SubpackagesScope;
import org.jetbrains.kotlin.jvm.compiler.ExpectedLoadErrorsUtil;
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor;
import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.platform.TargetPlatformKt;
import org.jetbrains.kotlin.renderer.*;
@@ -193,7 +195,24 @@ public class RecursiveDescriptorComparator {
boolean isPrimaryConstructor = conf.checkPrimaryConstructors &&
descriptor instanceof ConstructorDescriptor && ((ConstructorDescriptor) descriptor).isPrimary();
printer.print(isPrimaryConstructor ? "/*primary*/ " : "", conf.renderer.render(descriptor));
boolean isRecord = descriptor instanceof JavaClassDescriptor && ((JavaClassDescriptor) descriptor).isRecord();
boolean isRecordComponent = descriptor instanceof JavaMethodDescriptor && ((JavaMethodDescriptor) descriptor).isForRecordComponent();
StringBuilder prefix = new StringBuilder();
if (isPrimaryConstructor) {
prefix.append("/*primary*/ ");
}
if (isRecord) {
prefix.append("/*record*/ ");
}
if (isRecordComponent) {
prefix.append("/*record component*/ ");
}
printer.print(prefix.toString(), conf.renderer.render(descriptor));
if (descriptor instanceof FunctionDescriptor && conf.checkFunctionContracts) {
printEffectsIfAny((FunctionDescriptor) descriptor, printer);