Drop package facades: JVM BE tests passed.
This commit is contained in:
@@ -85,9 +85,6 @@ public class ClassFileFactory implements OutputFileCollection {
|
||||
if (!isDone) {
|
||||
isDone = true;
|
||||
Collection<PackageCodegen> packageCodegens = package2codegen.values();
|
||||
for (PackageCodegen codegen : packageCodegens) {
|
||||
codegen.done();
|
||||
}
|
||||
Collection<MultifileClassCodegen> multifileClassCodegens = multifileClass2codegen.values();
|
||||
for (MultifileClassCodegen codegen : multifileClassCodegens) {
|
||||
codegen.done();
|
||||
|
||||
@@ -1105,7 +1105,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
v.load(incrementVar, incrementType);
|
||||
|
||||
Type methodParamType = asmElementType.getSort() == Type.LONG ? Type.LONG_TYPE : Type.INT_TYPE;
|
||||
v.invokestatic("kotlin/internal/InternalPackage", "getProgressionFinalElement",
|
||||
v.invokestatic("kotlin/internal/ProgressionUtilKt", "getProgressionFinalElement",
|
||||
Type.getMethodDescriptor(methodParamType, methodParamType, methodParamType, methodParamType), false);
|
||||
|
||||
finalVar = createLoopTempVariable(asmElementType);
|
||||
|
||||
@@ -16,71 +16,34 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Ordering;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import kotlin.jvm.functions.Function0;
|
||||
import org.jetbrains.annotations.Mutable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.codegen.context.CodegenContext;
|
||||
import org.jetbrains.kotlin.codegen.context.FieldOwnerContext;
|
||||
import org.jetbrains.kotlin.codegen.context.MethodContext;
|
||||
import org.jetbrains.kotlin.codegen.context.PackageContext;
|
||||
import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings;
|
||||
import org.jetbrains.kotlin.codegen.serialization.JvmSerializerExtension;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
|
||||
import org.jetbrains.kotlin.config.IncrementalCompilation;
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities;
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils;
|
||||
import org.jetbrains.kotlin.fileClasses.FileClasses;
|
||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassInfo;
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
|
||||
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils;
|
||||
import org.jetbrains.kotlin.load.kotlin.PackageParts;
|
||||
import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackageFragmentProvider;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.MemberComparator;
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt;
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
|
||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter;
|
||||
import org.jetbrains.kotlin.resolve.scopes.JetScope;
|
||||
import org.jetbrains.kotlin.serialization.DescriptorSerializer;
|
||||
import org.jetbrains.kotlin.serialization.ProtoBuf;
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor;
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor;
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor;
|
||||
import org.jetbrains.org.objectweb.asm.AnnotationVisitor;
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.asmDescByFqNameWithoutInnerClasses;
|
||||
import static org.jetbrains.kotlin.load.kotlin.PackageClassUtils.getPackageClassFqName;
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
||||
import java.util.Collection;
|
||||
|
||||
public class PackageCodegen {
|
||||
private final ClassBuilderOnDemand v;
|
||||
private final GenerationState state;
|
||||
private final Collection<JetFile> files;
|
||||
private final Type packageClassType;
|
||||
private final PackageFragmentDescriptor packageFragment;
|
||||
private final IncrementalPackageFragmentProvider.IncrementalPackageFragment compiledPackageFragment;
|
||||
private final List<DeserializedCallableMemberDescriptor> previouslyCompiledCallables;
|
||||
|
||||
private final PackageParts packageParts;
|
||||
|
||||
public PackageCodegen(
|
||||
@@ -91,139 +54,14 @@ public class PackageCodegen {
|
||||
this.state = state;
|
||||
this.files = files;
|
||||
this.packageFragment = getOnlyPackageFragment(fqName);
|
||||
this.packageClassType = AsmUtil.asmTypeByFqNameWithoutInnerClasses(getPackageClassFqName(fqName));
|
||||
this.compiledPackageFragment = getCompiledPackageFragment(fqName);
|
||||
this.previouslyCompiledCallables = filterDeserializedCallables(compiledPackageFragment);
|
||||
|
||||
assert packageFragment != null || compiledPackageFragment != null : fqName.asString() + " " + files;
|
||||
|
||||
this.v = new ClassBuilderOnDemand(new Function0<ClassBuilder>() {
|
||||
@Override
|
||||
public ClassBuilder invoke() {
|
||||
Collection<JetFile> files = PackageCodegen.this.files;
|
||||
JetFile sourceFile = getRepresentativePackageFile(files);
|
||||
|
||||
ClassBuilder v = PackageCodegen.this.state.getFactory().newVisitor(
|
||||
JvmDeclarationOriginKt.PackageFacade(packageFragment == null ? compiledPackageFragment : packageFragment),
|
||||
packageClassType, PackagePartClassUtils.getFilesWithCallables(files)
|
||||
);
|
||||
v.defineClass(sourceFile, V1_6,
|
||||
ACC_PUBLIC | ACC_FINAL | ACC_DEPRECATED,
|
||||
packageClassType.getInternalName(),
|
||||
null,
|
||||
"java/lang/Object",
|
||||
ArrayUtil.EMPTY_STRING_ARRAY
|
||||
);
|
||||
//We don't generate any source information for package with multiple files
|
||||
if (sourceFile != null) {
|
||||
v.visitSource(sourceFile.getName(), null);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
});
|
||||
packageParts = new PackageParts(fqName.asString());
|
||||
}
|
||||
|
||||
// Returns null if file has callables in several files
|
||||
@Nullable
|
||||
private JetFile getRepresentativePackageFile(@NotNull Collection<JetFile> packageFiles) {
|
||||
if (!previouslyCompiledCallables.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<JetFile> packageFilesWithCallables = PackagePartClassUtils.getFilesWithCallables(packageFiles);
|
||||
return packageFilesWithCallables.size() == 1 ? packageFilesWithCallables.get(0) : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private IncrementalPackageFragmentProvider.IncrementalPackageFragment getCompiledPackageFragment(@NotNull FqName fqName) {
|
||||
if (!IncrementalCompilation.isEnabled()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// TODO rewrite it to something more robust when module system is implemented
|
||||
for (PackageFragmentDescriptor fragment : state.getModule().getPackage(fqName).getFragments()) {
|
||||
if (fragment instanceof IncrementalPackageFragmentProvider.IncrementalPackageFragment &&
|
||||
((IncrementalPackageFragmentProvider.IncrementalPackageFragment) fragment).getTarget().equals(state.getTargetId())) {
|
||||
return (IncrementalPackageFragmentProvider.IncrementalPackageFragment) fragment;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<DeserializedCallableMemberDescriptor> filterDeserializedCallables(@Nullable PackageFragmentDescriptor packageFragment) {
|
||||
if (packageFragment == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<DeserializedCallableMemberDescriptor> callables = Lists.newArrayList();
|
||||
for (DeclarationDescriptor member : packageFragment.getMemberScope().getDescriptors(DescriptorKindFilter.CALLABLES, JetScope.Companion.getALL_NAME_FILTER())) {
|
||||
if (member instanceof DeserializedCallableMemberDescriptor) {
|
||||
callables.add((DeserializedCallableMemberDescriptor) member);
|
||||
}
|
||||
}
|
||||
return callables;
|
||||
}
|
||||
|
||||
private void generateDelegationsToPreviouslyCompiled(@NotNull @Mutable Map<CallableMemberDescriptor, Runnable> generateCallableMemberTasks) {
|
||||
for (final DeserializedCallableMemberDescriptor member : previouslyCompiledCallables) {
|
||||
generateCallableMemberTasks.put(member, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
JetTypeMapper.ContainingClassesInfo containingClasses = state.getTypeMapper().getContainingClassesForDeserializedCallable(member);
|
||||
|
||||
Type facadeType = AsmUtil.asmTypeByFqNameWithoutInnerClasses(containingClasses.getFacadeClassId().asSingleFqName());
|
||||
Type partType = AsmUtil.asmTypeByFqNameWithoutInnerClasses(containingClasses.getImplClassId().asSingleFqName());
|
||||
FieldOwnerContext context = state.getRootContext().intoPackageFacade(partType, compiledPackageFragment, facadeType);
|
||||
|
||||
MemberCodegen<?> memberCodegen = createCodegenForPartOfPackageFacade(context);
|
||||
|
||||
if (member instanceof DeserializedSimpleFunctionDescriptor) {
|
||||
DeserializedSimpleFunctionDescriptor function = (DeserializedSimpleFunctionDescriptor) member;
|
||||
memberCodegen.functionCodegen.generateMethod(JvmDeclarationOriginKt.OtherOrigin(function), function,
|
||||
new FunctionGenerationStrategy() {
|
||||
@Override
|
||||
public void generateBody(
|
||||
@NotNull MethodVisitor mv,
|
||||
@NotNull FrameMap frameMap,
|
||||
@NotNull JvmMethodSignature signature,
|
||||
@NotNull MethodContext context,
|
||||
@NotNull MemberCodegen<?> parentCodegen
|
||||
) {
|
||||
throw new IllegalStateException("shouldn't be called");
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
memberCodegen.functionCodegen.generateDefaultIfNeeded(
|
||||
context.intoFunction(function), function, OwnerKind.PACKAGE, DefaultParameterValueLoader.DEFAULT, null
|
||||
);
|
||||
|
||||
memberCodegen.functionCodegen.generateOverloadsWithDefaultValues(null, function, function);
|
||||
}
|
||||
else if (member instanceof DeserializedPropertyDescriptor) {
|
||||
memberCodegen.propertyCodegen.generateInPackageFacade((DeserializedPropertyDescriptor) member);
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException("Unexpected member: " + member);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void generate(@NotNull CompilationErrorHandler errorHandler) {
|
||||
List<JvmSerializationBindings> bindings = new ArrayList<JvmSerializationBindings>(files.size() + 1);
|
||||
|
||||
Map<CallableMemberDescriptor, Runnable> generateCallableMemberTasks = new HashMap<CallableMemberDescriptor, Runnable>();
|
||||
|
||||
for (JetFile file : files) {
|
||||
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled();
|
||||
try {
|
||||
ClassBuilder builder = generateFile(file, generateCallableMemberTasks);
|
||||
if (builder != null) {
|
||||
bindings.add(builder.getSerializationBindings());
|
||||
}
|
||||
generateFile(file);
|
||||
}
|
||||
catch (ProcessCanceledException e) {
|
||||
throw e;
|
||||
@@ -238,69 +76,13 @@ public class PackageCodegen {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
generateDelegationsToPreviouslyCompiled(generateCallableMemberTasks);
|
||||
|
||||
if (!generateCallableMemberTasks.isEmpty()) {
|
||||
generatePackageFacadeClass(generateCallableMemberTasks, bindings);
|
||||
}
|
||||
}
|
||||
|
||||
private void generatePackageFacadeClass(
|
||||
@NotNull Map<CallableMemberDescriptor, Runnable> tasks,
|
||||
@NotNull List<JvmSerializationBindings> bindings
|
||||
) {
|
||||
MemberCodegen.generateModuleNameField(state, v);
|
||||
|
||||
for (CallableMemberDescriptor member : Ordering.from(MemberComparator.INSTANCE).sortedCopy(tasks.keySet())) {
|
||||
tasks.get(member).run();
|
||||
}
|
||||
|
||||
bindings.add(v.getSerializationBindings());
|
||||
writeDeprecatedAnnotation();
|
||||
writeKotlinPackageAnnotationIfNeeded(JvmSerializationBindings.union(bindings));
|
||||
}
|
||||
|
||||
private void writeKotlinPackageAnnotationIfNeeded(@NotNull JvmSerializationBindings bindings) {
|
||||
if (state.getClassBuilderMode() != ClassBuilderMode.FULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
// SCRIPT: Do not write KotlinPackage annotation for scripts (if any is??)
|
||||
for (JetFile file : files) {
|
||||
if (file.isScript()) return;
|
||||
}
|
||||
|
||||
DescriptorSerializer serializer = DescriptorSerializer.createTopLevel(new JvmSerializerExtension(
|
||||
bindings, state.getTypeMapper(), state.getUseTypeTableInSerializer()
|
||||
));
|
||||
Collection<PackageFragmentDescriptor> packageFragments = Lists.newArrayList();
|
||||
ContainerUtil.addIfNotNull(packageFragments, packageFragment);
|
||||
ContainerUtil.addIfNotNull(packageFragments, compiledPackageFragment);
|
||||
ProtoBuf.Package packageProto = serializer.packageProtoWithoutDescriptors().build();
|
||||
|
||||
AnnotationVisitor av = v.newAnnotation(asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_PACKAGE), true);
|
||||
AsmUtil.writeAnnotationData(av, serializer, packageProto);
|
||||
av.visitEnd();
|
||||
}
|
||||
|
||||
private void writeDeprecatedAnnotation() {
|
||||
AnnotationVisitor av = v.newAnnotation(asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.JAVA_LANG_DEPRECATED), true);
|
||||
av.visitEnd();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private ClassBuilder generateFile(
|
||||
@NotNull JetFile file,
|
||||
@NotNull Map<CallableMemberDescriptor, Runnable> generateCallableMemberTasks
|
||||
) {
|
||||
private ClassBuilder generateFile(@NotNull JetFile file) {
|
||||
JvmFileClassInfo fileClassInfo = state.getFileClassesProvider().getFileClassInfo(file);
|
||||
|
||||
if (fileClassInfo.getWithJvmMultifileClass()) {
|
||||
FqName partClassFqName = fileClassInfo.getFileClassFqName();
|
||||
Type delegateToType = AsmUtil.asmTypeByFqNameWithoutInnerClasses(partClassFqName);
|
||||
Type publicFacadeType = AsmUtil.asmTypeByFqNameWithoutInnerClasses(fileClassInfo.getFacadeClassFqName());
|
||||
addDelegateToFileClassMemberTasks(file, generateCallableMemberTasks, delegateToType, publicFacadeType);
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -338,59 +120,9 @@ public class PackageCodegen {
|
||||
|
||||
new PackagePartCodegen(builder, file, fileClassType, packagePartContext, state).generate();
|
||||
|
||||
addDelegateToFileClassMemberTasks(file, generateCallableMemberTasks, fileClassType, fileClassType);
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
private void addDelegateToFileClassMemberTasks(
|
||||
@NotNull JetFile file,
|
||||
@NotNull Map<CallableMemberDescriptor, Runnable> generateCallableMemberTasks,
|
||||
@NotNull Type fileClassType,
|
||||
@NotNull Type publicFacadeType
|
||||
) {
|
||||
FieldOwnerContext packageFacade = state.getRootContext().intoPackageFacade(fileClassType, packageFragment, publicFacadeType);
|
||||
final MemberCodegen<?> memberCodegen = createCodegenForPartOfPackageFacade(packageFacade);
|
||||
|
||||
for (final JetDeclaration declaration : file.getDeclarations()) {
|
||||
if (declaration instanceof JetNamedFunction || declaration instanceof JetProperty) {
|
||||
DeclarationDescriptor descriptor = state.getBindingContext().get(BindingContext.DECLARATION_TO_DESCRIPTOR, declaration);
|
||||
assert descriptor instanceof CallableMemberDescriptor :
|
||||
"Expected callable member, was " + descriptor + " for " + declaration.getText();
|
||||
if (!Visibilities.isPrivate(((CallableMemberDescriptor) descriptor).getVisibility())) {
|
||||
generateCallableMemberTasks.put(
|
||||
(CallableMemberDescriptor) descriptor,
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
memberCodegen.genFunctionOrProperty(declaration);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private MemberCodegen<?> createCodegenForPartOfPackageFacade(@NotNull FieldOwnerContext packageFacade) {
|
||||
return new MemberCodegen<JetFile>(state, null, packageFacade, null, v) {
|
||||
@Override
|
||||
protected void generateDeclaration() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void generateBody() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void generateKotlinAnnotation() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PackageFragmentDescriptor getOnlyPackageFragment(@NotNull FqName expectedFqName) {
|
||||
SmartList<PackageFragmentDescriptor> fragments = new SmartList<PackageFragmentDescriptor>();
|
||||
@@ -419,10 +151,6 @@ public class PackageCodegen {
|
||||
MemberCodegen.genClassOrObject(packagePartContext, classOrObject, state, null);
|
||||
}
|
||||
|
||||
public void done() {
|
||||
v.done();
|
||||
}
|
||||
|
||||
public PackageParts getPackageParts() {
|
||||
return packageParts;
|
||||
}
|
||||
|
||||
@@ -184,11 +184,6 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
||||
return new PackageContext(descriptor, this, packagePartType);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public FieldOwnerContext intoPackageFacade(@NotNull Type delegateTo, @NotNull PackageFragmentDescriptor descriptor, @NotNull Type publicFacadeType) {
|
||||
return new PackageFacadeContext(descriptor, this, delegateTo, publicFacadeType);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public FieldOwnerContext<PackageFragmentDescriptor> intoMultifileClassPart(
|
||||
@NotNull PackageFragmentDescriptor descriptor,
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.kotlin.codegen.Callable
|
||||
import org.jetbrains.kotlin.codegen.CallableMethod
|
||||
|
||||
@@ -23,6 +24,11 @@ public class ArrayIterator : IntrinsicMethod() {
|
||||
override fun toCallable(method: CallableMethod): Callable =
|
||||
createUnaryIntrinsicCallable(method) {
|
||||
val methodSignature = "(${method.owner.getDescriptor()})${returnType.getDescriptor()}"
|
||||
it.invokestatic("kotlin/jvm/internal/InternalPackage", "iterator", methodSignature, false)
|
||||
val intrinsicOwner =
|
||||
if (AsmUtil.isPrimitive(method.owner.elementType))
|
||||
"kotlin/jvm/internal/ArrayIteratorsKt"
|
||||
else
|
||||
"kotlin/jvm/internal/ArrayIteratorKt"
|
||||
it.invokestatic(intrinsicOwner, "iterator", methodSignature, false)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -270,7 +270,7 @@ public class JetTypeMapper {
|
||||
|
||||
@Nullable
|
||||
private ContainingClassesInfo getPackageMemberContainingClassesInfo(@NotNull DeserializedCallableMemberDescriptor descriptor) {
|
||||
// XXX This method (and getPackageMemberOwnerShortName) is a dirty hack.
|
||||
// XXX This method is a dirty hack.
|
||||
// We need some safe, concise way to identify multifile facade and multifile part
|
||||
// from a deserialized package member descriptor.
|
||||
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
public class Test {
|
||||
public static void checkCallFromJava() {
|
||||
try {
|
||||
String x = _DefaultPackage.foo().iterator().next();
|
||||
String x = SubstitutedIterableKt.foo().iterator().next();
|
||||
throw new AssertionError("E should have been thrown");
|
||||
} catch (E e) { }
|
||||
}
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
import test.TestPackage;
|
||||
|
||||
public class Baz {
|
||||
public static String baz() {
|
||||
return TestPackage.foo() + TestPackage.bar();
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
@file:JvmName("Util")
|
||||
@file:JvmMultifileClass
|
||||
package test
|
||||
|
||||
public fun bar(): String = "K"
|
||||
@@ -1,4 +0,0 @@
|
||||
@file:[JvmName("Util") JvmMultifileClass]
|
||||
package test
|
||||
|
||||
public fun foo(): String = "O"
|
||||
-5
@@ -1,5 +0,0 @@
|
||||
package test
|
||||
|
||||
import Baz
|
||||
|
||||
fun box(): String = Baz.baz()
|
||||
Vendored
+2
-2
@@ -1,11 +1,11 @@
|
||||
public class Test {
|
||||
public static String invokeFoo() {
|
||||
try {
|
||||
_DefaultPackage.foo(null);
|
||||
ExtensionKt.foo(null);
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
try {
|
||||
_DefaultPackage.getBar(null);
|
||||
ExtensionKt.getBar(null);
|
||||
}
|
||||
catch (IllegalArgumentException f) {
|
||||
return "OK";
|
||||
|
||||
-18
@@ -1,18 +0,0 @@
|
||||
package test
|
||||
|
||||
fun findClassOrFail(className: String): Class<*> =
|
||||
try {
|
||||
Class.forName(className)
|
||||
}
|
||||
catch (e: Exception) {
|
||||
throw AssertionError("Class $className not found")
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val testPackage = findClassOrFail("test.TestPackage")
|
||||
val deprecated = findClassOrFail("java.lang.Deprecated") as Class<Annotation>
|
||||
val ann = testPackage.getAnnotation(deprecated)
|
||||
assert(ann != null) { "Package facade ${testPackage.name} is not deprecated" }
|
||||
|
||||
return "OK"
|
||||
}
|
||||
-47
@@ -1,47 +0,0 @@
|
||||
package test
|
||||
|
||||
import kotlin.jvm.internal.KotlinDelegatedMethod
|
||||
|
||||
fun findClassOrFail(className: String): Class<*> =
|
||||
try {
|
||||
Class.forName(className)
|
||||
}
|
||||
catch (e: Exception) {
|
||||
throw AssertionError("Class $className not found")
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val testPackage = findClassOrFail("test.TestPackage")
|
||||
val kotlinDelegatedMethod = findClassOrFail("kotlin.jvm.internal.KotlinDelegatedMethod") as Class<Annotation>
|
||||
|
||||
assert(testPackage.declaredMethods.size() > 0) { "Class ${testPackage.name} has no declared methods" }
|
||||
|
||||
for (method in testPackage.declaredMethods) {
|
||||
val ann = method.getAnnotation(kotlinDelegatedMethod) as? KotlinDelegatedMethod
|
||||
if (ann == null) {
|
||||
throw AssertionError("Method ${method.name} has no ${kotlinDelegatedMethod.simpleName} annotation.")
|
||||
}
|
||||
|
||||
val implementationClassName = ann.implementationClassName
|
||||
val implementationClass = try {
|
||||
Class.forName(implementationClassName)
|
||||
}
|
||||
catch (e: Exception) {
|
||||
throw AssertionError("Implementation class $implementationClassName for method ${method.name} not found.")
|
||||
}
|
||||
|
||||
val implementationMethod = try {
|
||||
implementationClass.getMethod(method.name, *method.parameterTypes)
|
||||
}
|
||||
catch (e: Exception) {
|
||||
throw AssertionError("Implementation class $implementationClassName for method ${method.name} has no corresponding implementation method.")
|
||||
}
|
||||
|
||||
assert(implementationMethod.modifiers == method.modifiers) {
|
||||
"Implementation method for ${method.name} in $implementationClassName: " +
|
||||
"expected modifiers: ${method.modifiers}; actual modifiers: ${implementationMethod.modifiers}"
|
||||
}
|
||||
}
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -6,6 +6,6 @@ class C {
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val m = javaClass<C>().getClassLoader().loadClass("_DefaultPackage").getMethod("foo", javaClass<C>(), javaClass<String>())
|
||||
val m = javaClass<C>().getClassLoader().loadClass("ExtensionMethodKt").getMethod("foo", javaClass<C>(), javaClass<String>())
|
||||
return m.invoke(null, C(), "O") as String
|
||||
}
|
||||
|
||||
@@ -44,10 +44,4 @@
|
||||
|
||||
@kotlin.jvm.internal.KotlinClass My {
|
||||
public method <init>(): void
|
||||
}
|
||||
|
||||
@java.lang.Deprecated @kotlin.jvm.internal.KotlinPackage _DefaultPackage {
|
||||
public synthetic final field $moduleName: java.lang.String
|
||||
public final @kotlin.jvm.internal.KotlinDelegatedMethod method bar(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function0): int
|
||||
public final @kotlin.jvm.internal.KotlinDelegatedMethod @org.jetbrains.annotations.NotNull method foo(p0: int): My
|
||||
}
|
||||
}
|
||||
@@ -9,10 +9,4 @@
|
||||
@kotlin.jvm.internal.KotlinFileFacade OnReceiverKt {
|
||||
public final @org.jetbrains.annotations.NotNull method getTopLevelP(@Ann p0: java.lang.String): java.lang.String
|
||||
public final @org.jetbrains.annotations.NotNull method topLevelF(@Ann p0: java.lang.String): java.lang.String
|
||||
}
|
||||
|
||||
@java.lang.Deprecated @kotlin.jvm.internal.KotlinPackage _DefaultPackage {
|
||||
public synthetic final field $moduleName: java.lang.String
|
||||
public final @kotlin.jvm.internal.KotlinDelegatedMethod @org.jetbrains.annotations.NotNull method getTopLevelP(@Ann p0: java.lang.String): java.lang.String
|
||||
public final @kotlin.jvm.internal.KotlinDelegatedMethod @org.jetbrains.annotations.NotNull method topLevelF(@Ann p0: java.lang.String): java.lang.String
|
||||
}
|
||||
}
|
||||
@@ -11,10 +11,8 @@ class B {
|
||||
}
|
||||
|
||||
/*
|
||||
One DEPRECATED is for _DefaultPackage
|
||||
One is for _DefaultPackage.getCONST_VAL
|
||||
One DEPRECATED is for INSTANCE$ temporarily
|
||||
3 others are for getCONST_VAL
|
||||
One more for INSTANCE$ temporarily
|
||||
*/
|
||||
|
||||
// 6 DEPRECATED
|
||||
// 4 DEPRECATED
|
||||
@@ -16,7 +16,7 @@ fun box(): String {
|
||||
|
||||
/*
|
||||
3 return's are defined in functions
|
||||
2 are from package facade
|
||||
*/
|
||||
|
||||
// 5 RETURN
|
||||
// 2 IRETURN
|
||||
// 1 ARETURN
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
package foo
|
||||
|
||||
fun simpleFoo(s: Int = 111) {
|
||||
|
||||
}
|
||||
|
||||
// 1 BIPUSH 111
|
||||
// 1 INVOKESTATIC foo/DefaultDelegationKt.simpleFoo\$default \(II\)V
|
||||
+3
-3
@@ -7,10 +7,10 @@ fun foo() : String {
|
||||
}
|
||||
|
||||
// 3 ISTORE
|
||||
// 11 ILOAD
|
||||
// 7 ILOAD
|
||||
// 2 ASTORE
|
||||
// 8 ALOAD
|
||||
// 6 ALOAD
|
||||
// 2 LSTORE
|
||||
// 6 LLOAD
|
||||
// 4 LLOAD
|
||||
// 1 MAXLOCALS = 10
|
||||
// 0 InlineMarker
|
||||
|
||||
+2
-2
@@ -9,9 +9,9 @@ fun test() {
|
||||
}
|
||||
|
||||
// 1 ISTORE
|
||||
// 3 ILOAD
|
||||
// 2 ILOAD
|
||||
// 2 ASTORE
|
||||
// 7 ALOAD
|
||||
// 5 ALOAD
|
||||
// 2 MAXLOCALS = 3
|
||||
// 1 MAXLOCALS = 4
|
||||
// 0 InlineMarker
|
||||
|
||||
@@ -10,5 +10,5 @@ fun foo() : Int {
|
||||
}
|
||||
|
||||
// 3 ISTORE
|
||||
// 11 ILOAD
|
||||
// 7 ILOAD
|
||||
// 0 InlineMarker
|
||||
|
||||
+1
-1
@@ -16,6 +16,6 @@ fun foo() : String {
|
||||
)
|
||||
}
|
||||
|
||||
// 14 ALOAD
|
||||
// 10 ALOAD
|
||||
// 2 ASTORE
|
||||
// 0 InlineMarker
|
||||
|
||||
+1
-1
@@ -6,6 +6,6 @@ fun foo() : String {
|
||||
}
|
||||
|
||||
// 6 ASTORE
|
||||
// 21 ALOAD
|
||||
// 16 ALOAD
|
||||
// 1 MAXLOCALS = 7
|
||||
// 0 InlineMarker
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
fun foo(a: Int = 1) {}
|
||||
|
||||
// 0 _DefaultPackage.foo
|
||||
// 3 INVOKESTATIC TopLevelFunWithDefaultArgsKt\.foo
|
||||
// 1 INVOKESTATIC TopLevelFunWithDefaultArgsKt\.foo
|
||||
|
||||
@@ -4,5 +4,5 @@ fun test2() {
|
||||
1.test1()
|
||||
}
|
||||
|
||||
// 2 INVOKESTATIC _1Kt.test1 \(I\)V
|
||||
// 1 INVOKESTATIC _1Kt.test2 \(\)V
|
||||
// 1 INVOKESTATIC _1Kt.test1 \(I\)V
|
||||
// 0 INVOKESTATIC _1Kt.test2 \(\)V
|
||||
|
||||
+2
-2
@@ -2,5 +2,5 @@ package a
|
||||
|
||||
fun test1() {}
|
||||
|
||||
// 2 INVOKESTATIC a/_1Kt.test1 \(\)V
|
||||
// 1 INVOKESTATIC b/_2Kt.test2 \(\)V
|
||||
// 1 INVOKESTATIC a/_1Kt.test1 \(\)V
|
||||
// 0 INVOKESTATIC b/_2Kt.test2 \(\)V
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
fun test1() {}
|
||||
|
||||
// 2 INVOKESTATIC _1Kt.test1 \(\)V
|
||||
// 1 INVOKESTATIC _2Kt.test2 \(\)V
|
||||
// 1 INVOKESTATIC _1Kt.test1 \(\)V
|
||||
// 0 INVOKESTATIC _2Kt.test2 \(\)V
|
||||
|
||||
+2
-2
@@ -4,5 +4,5 @@ fun test2() {
|
||||
test1()
|
||||
}
|
||||
|
||||
// 2 INVOKESTATIC _1Kt.test1 \(\)V
|
||||
// 1 INVOKESTATIC _1Kt.test2 \(\)V
|
||||
// 1 INVOKESTATIC _1Kt.test1 \(\)V
|
||||
// 0 INVOKESTATIC _1Kt.test2 \(\)V
|
||||
|
||||
@@ -2,5 +2,5 @@ package a
|
||||
|
||||
val prop = 1
|
||||
|
||||
// 2 INVOKESTATIC a/_1Kt.getProp \(\)I
|
||||
// 1 INVOKESTATIC a/_1Kt.getProp \(\)I
|
||||
// 1 GETSTATIC a/_1Kt.prop \: I
|
||||
|
||||
@@ -5,5 +5,5 @@ val prop: Int = 0
|
||||
return field + 1
|
||||
}
|
||||
|
||||
// 2 INVOKESTATIC a/_1Kt.getProp \(\)I
|
||||
// 1 INVOKESTATIC a/_1Kt.getProp \(\)I
|
||||
// 1 GETSTATIC a/_1Kt.prop \: I
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
|
||||
fun bar() {
|
||||
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
|
||||
fun foo(): Int {
|
||||
return 42
|
||||
}
|
||||
@@ -3,5 +3,5 @@ class MyClass() { }
|
||||
@Deprecated("") fun MyClass.test() {}
|
||||
|
||||
// TESTED_OBJECT_KIND: function
|
||||
// TESTED_OBJECTS: _DefaultPackage, test
|
||||
// TESTED_OBJECTS: ExtentionFunKt, test
|
||||
// FLAGS: ACC_DEPRECATED, ACC_PUBLIC, ACC_FINAL, ACC_STATIC
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
@Deprecated("") fun test() {}
|
||||
|
||||
// TESTED_OBJECT_KIND: function
|
||||
// TESTED_OBJECTS: _DefaultPackage, test
|
||||
// TESTED_OBJECTS: TopLevelFunKt, test
|
||||
// FLAGS: ACC_DEPRECATED, ACC_PUBLIC, ACC_FINAL, ACC_STATIC
|
||||
|
||||
@@ -47,7 +47,7 @@ import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class AbstractLineNumberTest extends TestCaseWithTmpdir {
|
||||
public abstract class AbstractLineNumberTest extends TestCaseWithTmpdir {
|
||||
|
||||
private static final String LINE_NUMBER_FUN = "lineNumber";
|
||||
private static final Pattern TEST_LINE_NUMBER_PATTERN = Pattern.compile("^.*test." + LINE_NUMBER_FUN + "\\(\\).*$");
|
||||
@@ -244,20 +244,4 @@ public class AbstractLineNumberTest extends TestCaseWithTmpdir {
|
||||
}, ClassReader.SKIP_FRAMES);
|
||||
return result;
|
||||
}
|
||||
|
||||
public void testStaticDelegate() {
|
||||
JetFile foo = createPsiFile(getTestDataPath() + "/staticDelegate/foo.kt").getFirst();
|
||||
JetFile bar = createPsiFile(getTestDataPath() + "/staticDelegate/bar.kt").getFirst();
|
||||
GenerationState state = GenerationUtils.compileManyFilesGetGenerationStateForTest(foo.getProject(), Arrays.asList(foo, bar));
|
||||
OutputFile file = state.getFactory().get(PackageClassUtils.getPackageClassName(FqName.ROOT) + ".class");
|
||||
assertNotNull(file);
|
||||
ClassReader reader = new ClassReader(file.asByteArray());
|
||||
|
||||
// There must be exactly one line number attribute for each static delegate in package facade class, and it should point to the first
|
||||
// line. There are two static delegates in this test, hence the [1, 1]
|
||||
List<Integer> expectedLineNumbers = Arrays.asList(1, 1);
|
||||
List<Integer> actualLineNumbers = readAllLineNumbers(reader);
|
||||
|
||||
assertSameElements(actualLineNumbers, expectedLineNumbers);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,9 +55,6 @@ public class AnnotationGenTest extends CodegenTestCase {
|
||||
|
||||
public void testPropField() throws Exception {
|
||||
ClassLoader loader = loadFileGetClassLoader("@[java.lang.Deprecated] var x = 0");
|
||||
Class<?> packageClass = getPackageClass(loader);
|
||||
assertNull(packageClass.getDeclaredMethod("getX").getAnnotation(Deprecated.class));
|
||||
assertNull(packageClass.getDeclaredMethod("setX", int.class).getAnnotation(Deprecated.class));
|
||||
Class<?> srcClass = getPackageSrcClass(loader);
|
||||
assertNull(srcClass.getDeclaredMethod("getX").getAnnotation(Deprecated.class));
|
||||
assertNull(srcClass.getDeclaredMethod("setX", int.class).getAnnotation(Deprecated.class));
|
||||
@@ -67,9 +64,6 @@ public class AnnotationGenTest extends CodegenTestCase {
|
||||
public void testPropGetter() throws Exception {
|
||||
ClassLoader loader = loadFileGetClassLoader("var x = 0\n" +
|
||||
"@[java.lang.Deprecated] get");
|
||||
Class<?> packageClass = getPackageClass(loader);
|
||||
assertNotNull(packageClass.getDeclaredMethod("getX").getAnnotation(Deprecated.class));
|
||||
assertNull(packageClass.getDeclaredMethod("setX", int.class).getAnnotation(Deprecated.class));
|
||||
Class<?> srcClass = getPackageSrcClass(loader);
|
||||
assertNotNull(srcClass.getDeclaredMethod("getX").getAnnotation(Deprecated.class));
|
||||
assertNull(srcClass.getDeclaredMethod("setX", int.class).getAnnotation(Deprecated.class));
|
||||
@@ -79,9 +73,6 @@ public class AnnotationGenTest extends CodegenTestCase {
|
||||
public void testPropSetter() throws Exception {
|
||||
ClassLoader loader = loadFileGetClassLoader("var x = 0\n" +
|
||||
"@[java.lang.Deprecated] set");
|
||||
Class<?> packageClass = getPackageClass(loader);
|
||||
assertNull(packageClass.getDeclaredMethod("getX").getAnnotation(Deprecated.class));
|
||||
assertNotNull(packageClass.getDeclaredMethod("setX", int.class).getAnnotation(Deprecated.class));
|
||||
Class<?> scrClass = getPackageSrcClass(loader);
|
||||
assertNull(scrClass.getDeclaredMethod("getX").getAnnotation(Deprecated.class));
|
||||
assertNotNull(scrClass.getDeclaredMethod("setX", int.class).getAnnotation(Deprecated.class));
|
||||
@@ -90,10 +81,6 @@ public class AnnotationGenTest extends CodegenTestCase {
|
||||
|
||||
public void testAnnotationForParamInTopLevelFunction() throws Exception {
|
||||
ClassLoader loader = loadFileGetClassLoader("fun x(@[java.lang.Deprecated] i: Int) {}");
|
||||
Class<?> packageClass = getPackageClass(loader);
|
||||
Method packageClassMethod = packageClass.getMethod("x", int.class);
|
||||
assertNotNull(packageClassMethod);
|
||||
assertNotNull(getDeprecatedAnnotationFromList(packageClassMethod.getParameterAnnotations()[0]));
|
||||
Class<?> srcClass = getPackageSrcClass(loader);
|
||||
Method srcClassMethod = srcClass.getMethod("x", int.class);
|
||||
assertNotNull(srcClassMethod);
|
||||
@@ -208,11 +195,6 @@ public class AnnotationGenTest extends CodegenTestCase {
|
||||
|
||||
public void testMethod() throws Exception {
|
||||
ClassLoader loader = loadFileGetClassLoader("@[java.lang.Deprecated] fun x () {}");
|
||||
|
||||
Class<?> packageClass = getPackageClass(loader);
|
||||
Method packageClassMethod = packageClass.getDeclaredMethod("x");
|
||||
assertNotNull(packageClassMethod.getAnnotation(Deprecated.class));
|
||||
|
||||
Class<?> srcClass = getPackageSrcClass(loader);
|
||||
Method srcClassMethod = srcClass.getDeclaredMethod("x");
|
||||
assertNotNull(srcClassMethod.getAnnotation(Deprecated.class));
|
||||
|
||||
@@ -107,12 +107,6 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("defaultDelegation.kt")
|
||||
public void testDefaultDelegation() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/defaultDelegation.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("inlineFromOtherModule.kt")
|
||||
public void testInlineFromOtherModule() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/inlineFromOtherModule.kt");
|
||||
|
||||
@@ -54,7 +54,7 @@ public class ClassGenTest extends CodegenTestCase {
|
||||
public void testDelegationToVal() throws Exception {
|
||||
loadFile("classes/delegationToVal.kt");
|
||||
GeneratedClassLoader loader = generateAndCreateClassLoader();
|
||||
Class<?> aClass = loader.loadClass(PackageClassUtils.getPackageClassName(FqName.ROOT));
|
||||
Class<?> aClass = loader.loadClass("DelegationToValKt");
|
||||
assertEquals("OK", aClass.getMethod("box").invoke(null));
|
||||
|
||||
Class<?> test = loader.loadClass("Test");
|
||||
|
||||
@@ -29,6 +29,8 @@ import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment;
|
||||
import org.jetbrains.kotlin.cli.jvm.config.JvmContentRootsKt;
|
||||
import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime;
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration;
|
||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil;
|
||||
import org.jetbrains.kotlin.fileClasses.NoResolveFileClassesProvider;
|
||||
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.test.ConfigurationKind;
|
||||
@@ -57,13 +59,13 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.jetbrains.kotlin.codegen.CodegenTestUtil.*;
|
||||
import static org.jetbrains.kotlin.load.kotlin.PackageClassUtils.getPackageClassFqName;
|
||||
import static org.jetbrains.kotlin.test.JetTestUtils.compilerConfigurationForTests;
|
||||
import static org.jetbrains.kotlin.test.JetTestUtils.getAnnotationsJar;
|
||||
|
||||
public abstract class CodegenTestCase extends UsefulTestCase {
|
||||
|
||||
public static final String DEFAULT_TEST_FILE_NAME = "a_test";
|
||||
public static final String DEFAULT_TEST_FILE_CLASS_NAME = "A_testKt";
|
||||
|
||||
protected KotlinCoreEnvironment myEnvironment;
|
||||
protected CodegenTestFiles myFiles;
|
||||
@@ -205,15 +207,15 @@ public abstract class CodegenTestCase extends UsefulTestCase {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected Class<?> generatePackageClass() {
|
||||
FqName packageFqName = myFiles.getPsiFile().getPackageFqName();
|
||||
return generateClass(getPackageClassFqName(packageFqName).asString());
|
||||
protected Class<?> generateFacadeClass() {
|
||||
FqName facadeClassFqName = JvmFileClassUtil.getFileClassInfoNoResolve(myFiles.getPsiFile()).getFacadeClassFqName();
|
||||
return generateClass(facadeClassFqName.asString());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected Class<?> generatePackagePartClass() {
|
||||
String name = PackagePartClassUtils.getPackagePartInternalName(myFiles.getPsiFile());
|
||||
return generateClass(name);
|
||||
protected Class<?> generateFileClass() {
|
||||
FqName fileClassFqName = JvmFileClassUtil.getFileClassInfoNoResolve(myFiles.getPsiFile()).getFileClassFqName();
|
||||
return generateClass(fileClassFqName.asString());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -303,7 +305,7 @@ public abstract class CodegenTestCase extends UsefulTestCase {
|
||||
|
||||
@NotNull
|
||||
protected Method generateFunction() {
|
||||
Class<?> aClass = generatePackageClass();
|
||||
Class<?> aClass = generateFacadeClass();
|
||||
try {
|
||||
return findTheOnlyMethod(aClass);
|
||||
} catch (Error e) {
|
||||
@@ -314,7 +316,7 @@ public abstract class CodegenTestCase extends UsefulTestCase {
|
||||
|
||||
@NotNull
|
||||
protected Method generateFunction(@NotNull String name) {
|
||||
return findDeclaredMethodByName(generatePackageClass(), name);
|
||||
return findDeclaredMethodByName(generateFacadeClass(), name);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -26,8 +26,8 @@ import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles;
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment;
|
||||
import org.jetbrains.kotlin.cli.jvm.config.JVMConfigurationKeys;
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration;
|
||||
import org.jetbrains.kotlin.load.kotlin.PackageClassUtils;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil;
|
||||
import org.jetbrains.kotlin.psi.JetFile;
|
||||
import org.jetbrains.kotlin.test.ConfigurationKind;
|
||||
import org.jetbrains.kotlin.test.JetTestUtils;
|
||||
import org.jetbrains.kotlin.test.TestJdkKind;
|
||||
@@ -79,7 +79,7 @@ public class GenerateNotNullAssertionsTest extends CodegenTestCase {
|
||||
|
||||
loadFiles("notNullAssertions/noAssertionsForKotlin.kt", "notNullAssertions/noAssertionsForKotlinMain.kt");
|
||||
|
||||
assertNoIntrinsicsMethodIsCalled(PackageClassUtils.getPackageClassName(FqName.ROOT));
|
||||
assertNoIntrinsicsMethodIsCalledInMyClasses(true);
|
||||
}
|
||||
|
||||
public void testNoAssertionsForKotlinFromBinary() throws Exception {
|
||||
@@ -92,7 +92,7 @@ public class GenerateNotNullAssertionsTest extends CodegenTestCase {
|
||||
setUpEnvironment(false, true, compiledDirectory);
|
||||
loadFile("notNullAssertions/noAssertionsForKotlinMain.kt");
|
||||
|
||||
assertNoIntrinsicsMethodIsCalled(PackageClassUtils.getPackageClassName(FqName.ROOT));
|
||||
assertNoIntrinsicsMethodIsCalledInMyClasses(false);
|
||||
}
|
||||
|
||||
public void testGenerateParamAssertions() throws Exception {
|
||||
@@ -109,7 +109,7 @@ public class GenerateNotNullAssertionsTest extends CodegenTestCase {
|
||||
|
||||
loadFile("notNullAssertions/doNotGenerateParamAssertions.kt");
|
||||
|
||||
assertNoIntrinsicsMethodIsCalled("A");
|
||||
assertNoIntrinsicsMethodIsCalled("A", true);
|
||||
}
|
||||
|
||||
public void testNoParamAssertionForPrivateMethod() throws Exception {
|
||||
@@ -117,7 +117,7 @@ public class GenerateNotNullAssertionsTest extends CodegenTestCase {
|
||||
|
||||
loadFile("notNullAssertions/noAssertionForPrivateMethod.kt");
|
||||
|
||||
assertNoIntrinsicsMethodIsCalled("A");
|
||||
assertNoIntrinsicsMethodIsCalled("A", true);
|
||||
}
|
||||
|
||||
public void testArrayListGet() {
|
||||
@@ -154,7 +154,7 @@ public class GenerateNotNullAssertionsTest extends CodegenTestCase {
|
||||
|
||||
loadFile("notNullAssertions/noAssertionForNullableGenericMethod.kt");
|
||||
|
||||
assertNoIntrinsicsMethodIsCalled(PackageClassUtils.getPackageClassName(FqName.ROOT));
|
||||
assertNoIntrinsicsMethodIsCalledInMyClasses(true);
|
||||
}
|
||||
|
||||
public void testNoAssertionForNullableGenericMethodCall() {
|
||||
@@ -162,7 +162,7 @@ public class GenerateNotNullAssertionsTest extends CodegenTestCase {
|
||||
|
||||
loadFile("notNullAssertions/noAssertionForNullableGenericMethodCall.kt");
|
||||
|
||||
assertNoIntrinsicsMethodIsCalled("A");
|
||||
assertNoIntrinsicsMethodIsCalled("A", true);
|
||||
}
|
||||
|
||||
public void testParamAssertionMessage() throws Exception {
|
||||
@@ -184,10 +184,22 @@ public class GenerateNotNullAssertionsTest extends CodegenTestCase {
|
||||
fail("Assertion should have been fired");
|
||||
}
|
||||
|
||||
private void assertNoIntrinsicsMethodIsCalled(String className) {
|
||||
private void assertNoIntrinsicsMethodIsCalledInMyClasses(boolean noClassFileIsAnError) {
|
||||
for (JetFile jetFile : myFiles.getPsiFiles()) {
|
||||
String fileClassName = JvmFileClassUtil.getFileClassInfoNoResolve(jetFile).getFileClassFqName().asString();
|
||||
assertNoIntrinsicsMethodIsCalled(fileClassName, noClassFileIsAnError);
|
||||
}
|
||||
}
|
||||
|
||||
private void assertNoIntrinsicsMethodIsCalled(String className, boolean noClassFileIsAnError) {
|
||||
OutputFileCollection classes = generateClassesInFile();
|
||||
OutputFile file = classes.get(className + ".class");
|
||||
assertNotNull(file);
|
||||
if (noClassFileIsAnError) {
|
||||
assertNotNull("File for " + className + " is absent", file);
|
||||
}
|
||||
else if (file == null) {
|
||||
return;
|
||||
}
|
||||
ClassReader reader = new ClassReader(file.asByteArray());
|
||||
|
||||
reader.accept(new ClassVisitor(Opcodes.ASM5) {
|
||||
|
||||
@@ -50,7 +50,7 @@ public class JUnitUsageGenTest extends CodegenTestCase {
|
||||
|
||||
public void testKt1592() throws Exception {
|
||||
loadFile("junit/kt1592.kt");
|
||||
Class<?> packageClass = generatePackageClass();
|
||||
Class<?> packageClass = generateFacadeClass();
|
||||
Method method = packageClass.getMethod("foo", Method.class);
|
||||
method.setAccessible(true);
|
||||
Annotation annotation = method.getAnnotation(loadAnnotationClassQuietly(Test.class.getName()));
|
||||
|
||||
@@ -42,36 +42,6 @@ public class KotlinPackageAnnotationTest extends CodegenTestCase {
|
||||
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
||||
}
|
||||
|
||||
public void testOldPackageKotlinInfo() throws Exception {
|
||||
loadText("package " + PACKAGE_NAME + "\n" +
|
||||
"\n" +
|
||||
"fun foo() = 42\n" +
|
||||
"val bar = 239\n" +
|
||||
"\n" +
|
||||
"class A\n" +
|
||||
"class B\n" +
|
||||
"object C\n");
|
||||
Class aClass = generateClass(PackageClassUtils.getPackageClassFqName(PACKAGE_NAME).asString());
|
||||
|
||||
Class<? extends Annotation> annotationClass = loadAnnotationClassQuietly(JvmAnnotationNames.KOTLIN_PACKAGE.asString());
|
||||
assertTrue(aClass.isAnnotationPresent(annotationClass));
|
||||
|
||||
Annotation kotlinPackage = aClass.getAnnotation(annotationClass);
|
||||
|
||||
String[] data = (String[]) CodegenTestUtil.getAnnotationAttribute(kotlinPackage, "data");
|
||||
assertNotNull(data);
|
||||
String[] strings = (String[]) CodegenTestUtil.getAnnotationAttribute(kotlinPackage, "strings");
|
||||
assertNotNull(strings);
|
||||
PackageData packageData = JvmProtoBufUtil.readPackageDataFrom(data, strings);
|
||||
|
||||
Set<String> callableNames = collectCallableNames(
|
||||
packageData.getPackageProto().getFunctionList(),
|
||||
packageData.getPackageProto().getPropertyList(),
|
||||
packageData.getNameResolver()
|
||||
);
|
||||
assertEmpty(callableNames);
|
||||
}
|
||||
|
||||
public void testPackagePartKotlinInfo() throws Exception {
|
||||
loadText("package " + PACKAGE_NAME + "\n" +
|
||||
"\n" +
|
||||
@@ -81,7 +51,7 @@ public class KotlinPackageAnnotationTest extends CodegenTestCase {
|
||||
"class A\n" +
|
||||
"class B\n" +
|
||||
"object C\n");
|
||||
Class aClass = generateClass(PackagePartClassUtils.getPackagePartFqName(PACKAGE_NAME, DEFAULT_TEST_FILE_NAME).asString());
|
||||
Class aClass = generateFileClass();
|
||||
|
||||
Class<? extends Annotation> annotationClass = loadAnnotationClassQuietly(JvmAnnotationNames.KOTLIN_FILE_FACADE.asString());
|
||||
assertTrue(aClass.isAnnotationPresent(annotationClass));
|
||||
|
||||
@@ -159,7 +159,7 @@ public class PrimitiveTypesTest extends CodegenTestCase {
|
||||
|
||||
public void testCastOnStack() throws Exception {
|
||||
loadText("fun foo(l: Long): Double = l.toDouble()");
|
||||
Class<?> mainClass = generatePackagePartClass();
|
||||
Class<?> mainClass = generateFileClass();
|
||||
Method main = mainClass.getDeclaredMethod("foo", long.class);
|
||||
double result = (Double) main.invoke(null, 42L);
|
||||
assertTrue(Math.abs(42L - result) <= 1e-9);
|
||||
|
||||
@@ -73,7 +73,7 @@ public class PropertyGenTest extends CodegenTestCase {
|
||||
|
||||
public void testPrivatePropertyInPackage() throws Exception {
|
||||
loadText("private val x = 239");
|
||||
Class<?> nsClass = generatePackagePartClass();
|
||||
Class<?> nsClass = generateFileClass();
|
||||
Field[] fields = nsClass.getDeclaredFields();
|
||||
assertEquals(1, fields.length);
|
||||
Field field = fields[0];
|
||||
|
||||
@@ -31,17 +31,6 @@ public class SourceInfoGenTest extends CodegenTestCase {
|
||||
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
||||
}
|
||||
|
||||
public void testSingleFilePackage() {
|
||||
String producer = "foo1.kt";
|
||||
loadFiles(TEST_FOLDER + producer);
|
||||
assertEquals(producer, getProducerInfo("foo/FooPackage.class"));
|
||||
}
|
||||
|
||||
public void testMultiFilePackage() {
|
||||
loadFiles(TEST_FOLDER + "foo1.kt", TEST_FOLDER + "foo2.kt");
|
||||
assertEquals(null, getProducerInfo("foo/FooPackage.class"));
|
||||
}
|
||||
|
||||
public void testSingleClass() {
|
||||
String producer = "singleClass.kt";
|
||||
loadFiles(TEST_FOLDER + producer);
|
||||
|
||||
+37
-13
@@ -27,8 +27,10 @@ import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles;
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment;
|
||||
import org.jetbrains.kotlin.cli.jvm.config.JvmContentRootsKt;
|
||||
import org.jetbrains.kotlin.codegen.CodegenTestCase;
|
||||
import org.jetbrains.kotlin.codegen.GeneratedClassLoader;
|
||||
import org.jetbrains.kotlin.codegen.GenerationUtils;
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration;
|
||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil;
|
||||
import org.jetbrains.kotlin.psi.JetFile;
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.JvmPackagePartProvider;
|
||||
import org.jetbrains.kotlin.test.ConfigurationKind;
|
||||
@@ -44,7 +46,6 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.kotlin.codegen.CodegenTestUtil.compileJava;
|
||||
import static org.jetbrains.kotlin.load.kotlin.PackageClassUtils.getPackageClassFqName;
|
||||
|
||||
public abstract class AbstractBlackBoxCodegenTest extends CodegenTestCase {
|
||||
public void doTest(@NotNull String filename) {
|
||||
@@ -176,19 +177,42 @@ public abstract class AbstractBlackBoxCodegenTest extends CodegenTestCase {
|
||||
}
|
||||
|
||||
protected void blackBox() {
|
||||
// If there are many files, the first of them should contain the 'box(): String' function
|
||||
JetFile firstFile = myFiles.getPsiFiles().get(0);
|
||||
String fqName = getPackageClassFqName(firstFile.getPackageFqName()).asString();
|
||||
|
||||
Class<?> aClass = generateClass(fqName);
|
||||
try {
|
||||
Method method = aClass.getMethod("box");
|
||||
String r = (String) method.invoke(null);
|
||||
assertEquals("OK", r);
|
||||
// If there are many files, the first 'box(): String' function will be executed.
|
||||
GeneratedClassLoader generatedClassLoader = generateAndCreateClassLoader();
|
||||
for (JetFile firstFile : myFiles.getPsiFiles()) {
|
||||
String className = JvmFileClassUtil.getFileClassInfoNoResolve(firstFile).getFacadeClassFqName().asString();
|
||||
Class<?> aClass = getGeneratedClass(generatedClassLoader, className);
|
||||
try {
|
||||
Method method = getBoxMethodOrNull(aClass);
|
||||
if (method != null) {
|
||||
String r = (String) method.invoke(null);
|
||||
assertEquals("OK", r);
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (Throwable e) {
|
||||
System.out.println(generateToText());
|
||||
throw ExceptionUtilsKt.rethrow(e);
|
||||
}
|
||||
}
|
||||
catch (Throwable e) {
|
||||
System.out.println(generateToText());
|
||||
throw ExceptionUtilsKt.rethrow(e);
|
||||
}
|
||||
|
||||
private static Class<?> getGeneratedClass(GeneratedClassLoader generatedClassLoader, String className) {
|
||||
try {
|
||||
return generatedClassLoader.loadClass(className);
|
||||
}
|
||||
catch (ClassNotFoundException e) {
|
||||
fail("No class file was generated for: " + className);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Method getBoxMethodOrNull(Class<?> aClass) {
|
||||
try {
|
||||
return aClass.getMethod("box");
|
||||
}
|
||||
catch (NoSuchMethodException e){
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-6
@@ -255,12 +255,6 @@ public class BlackBoxWithJavaCodegenTestGenerated extends AbstractBlackBoxCodege
|
||||
doTestWithJava(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("withPackageFacade")
|
||||
public void testWithPackageFacade() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithJava/fileClasses/withPackageFacade/");
|
||||
doTestWithJava(fileName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/boxWithJava/interfaces")
|
||||
|
||||
-12
@@ -106,18 +106,6 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("packageFacadeIsDeprecated.kt")
|
||||
public void testPackageFacadeIsDeprecated() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/annotations/packageFacadeIsDeprecated.kt");
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("packageFacadeMethodsAnnotation.kt")
|
||||
public void testPackageFacadeMethodsAnnotation() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/annotations/packageFacadeMethodsAnnotation.kt");
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("parameterWithPrimitiveType.kt")
|
||||
public void testParameterWithPrimitiveType() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/annotations/parameterWithPrimitiveType.kt");
|
||||
|
||||
@@ -31,7 +31,7 @@ public class ProgressionUtilTest extends UsefulTestCase {
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
Class<?> progressionUtil = ForTestCompileRuntime.runtimeAndReflectJarClassLoader().loadClass("kotlin.internal.InternalPackage");
|
||||
Class<?> progressionUtil = ForTestCompileRuntime.runtimeAndReflectJarClassLoader().loadClass("kotlin.internal.ProgressionUtilKt");
|
||||
this.intMethod = progressionUtil.getMethod("getProgressionFinalElement", int.class, int.class, int.class);
|
||||
this.longMethod = progressionUtil.getMethod("getProgressionFinalElement", long.class, long.class, long.class);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user