Merge remote-tracking branch 'origin/master' into idea14

This commit is contained in:
Nikolay Krasko
2014-07-02 09:21:40 +04:00
188 changed files with 3674 additions and 189 deletions
@@ -57,9 +57,11 @@ public class SpecialFiles {
private static void fillExcludedFiles() { private static void fillExcludedFiles() {
excludedFiles.add("boxAgainstJava"); // Must compile Java files before excludedFiles.add("boxAgainstJava"); // Must compile Java files before
excludedFiles.add("boxWithJava"); // Must compile Java files before
excludedFiles.add("boxMultiFile"); // MultiFileTest not supported yet excludedFiles.add("boxMultiFile"); // MultiFileTest not supported yet
excludedFiles.add("boxInline"); // MultiFileTest not supported yet excludedFiles.add("boxInline"); // MultiFileTest not supported yet
excludedFiles.add("reflection");
excludedFiles.add("kt3238.kt"); // Reflection excludedFiles.add("kt3238.kt"); // Reflection
excludedFiles.add("kt1482_2279.kt"); // Reflection excludedFiles.add("kt1482_2279.kt"); // Reflection
@@ -68,11 +70,6 @@ public class SpecialFiles {
excludedFiles.add("packageQualifiedMethod.kt"); // Cannot change package name excludedFiles.add("packageQualifiedMethod.kt"); // Cannot change package name
excludedFiles.add("classObjectToString.kt"); // Cannot change package name excludedFiles.add("classObjectToString.kt"); // Cannot change package name
/* Reflection tests with full-qualified names*/
excludedFiles.add("insideLambda");
excludedFiles.add("lambda");
excludedFiles.add("kt5112.kt");
excludedFiles.add("kt326.kt"); // Commented excludedFiles.add("kt326.kt"); // Commented
excludedFiles.add("kt1213.kt"); // Commented excludedFiles.add("kt1213.kt"); // Commented
@@ -154,6 +154,11 @@ public class AsmUtil {
return Type.getType(internalName.substring(1)); return Type.getType(internalName.substring(1));
} }
@NotNull
public static Method method(@NotNull String name, @NotNull Type returnType, @NotNull Type... parameterTypes) {
return new Method(name, Type.getMethodDescriptor(returnType, parameterTypes));
}
public static boolean isAbstractMethod(FunctionDescriptor functionDescriptor, OwnerKind kind) { public static boolean isAbstractMethod(FunctionDescriptor functionDescriptor, OwnerKind kind) {
return (functionDescriptor.getModality() == Modality.ABSTRACT return (functionDescriptor.getModality() == Modality.ABSTRACT
|| isInterface(functionDescriptor.getContainingDeclaration())) || isInterface(functionDescriptor.getContainingDeclaration()))
@@ -785,4 +790,12 @@ public class AsmUtil {
return PackagePartClassUtils.getPackagePartInternalName(containingFile); return PackagePartClassUtils.getPackagePartInternalName(containingFile);
} }
public static void putJavaLangClassInstance(@NotNull InstructionAdapter v, @NotNull Type type) {
if (isPrimitive(type)) {
v.getstatic(boxType(type).getInternalName(), "TYPE", "Ljava/lang/Class;");
}
else {
v.aconst(type);
}
}
} }
@@ -49,6 +49,8 @@ import org.jetbrains.jet.lang.resolve.constants.IntegerValueConstant;
import org.jetbrains.jet.lang.resolve.constants.IntegerValueTypeConstant; import org.jetbrains.jet.lang.resolve.constants.IntegerValueTypeConstant;
import org.jetbrains.jet.lang.resolve.java.AsmTypeConstants; import org.jetbrains.jet.lang.resolve.java.AsmTypeConstants;
import org.jetbrains.jet.lang.resolve.java.JvmAbi; import org.jetbrains.jet.lang.resolve.java.JvmAbi;
import org.jetbrains.jet.lang.resolve.java.PackageClassUtils;
import org.jetbrains.jet.lang.resolve.java.descriptor.JavaClassDescriptor;
import org.jetbrains.jet.lang.resolve.java.descriptor.SamConstructorDescriptor; import org.jetbrains.jet.lang.resolve.java.descriptor.SamConstructorDescriptor;
import org.jetbrains.jet.lang.resolve.java.jvmSignature.JvmMethodSignature; import org.jetbrains.jet.lang.resolve.java.jvmSignature.JvmMethodSignature;
import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.name.Name;
@@ -68,7 +70,6 @@ import org.jetbrains.org.objectweb.asm.commons.Method;
import java.util.*; import java.util.*;
import static org.jetbrains.jet.codegen.AsmUtil.*; import static org.jetbrains.jet.codegen.AsmUtil.*;
import static org.jetbrains.jet.lang.resolve.java.diagnostics.DiagnosticsPackage.OtherOrigin;
import static org.jetbrains.jet.codegen.JvmCodegenUtil.*; import static org.jetbrains.jet.codegen.JvmCodegenUtil.*;
import static org.jetbrains.jet.codegen.binding.CodegenBinding.*; import static org.jetbrains.jet.codegen.binding.CodegenBinding.*;
import static org.jetbrains.jet.lang.resolve.BindingContext.*; import static org.jetbrains.jet.lang.resolve.BindingContext.*;
@@ -76,6 +77,7 @@ import static org.jetbrains.jet.lang.resolve.BindingContextUtils.getNotNull;
import static org.jetbrains.jet.lang.resolve.BindingContextUtils.isVarCapturedInClosure; import static org.jetbrains.jet.lang.resolve.BindingContextUtils.isVarCapturedInClosure;
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.*; import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.*;
import static org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames.KotlinSyntheticClass; import static org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames.KotlinSyntheticClass;
import static org.jetbrains.jet.lang.resolve.java.diagnostics.DiagnosticsPackage.OtherOrigin;
import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue.NO_RECEIVER; import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue.NO_RECEIVER;
import static org.jetbrains.org.objectweb.asm.Opcodes.*; import static org.jetbrains.org.objectweb.asm.Opcodes.*;
@@ -2410,19 +2412,90 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
@Override @Override
public StackValue visitCallableReferenceExpression(@NotNull JetCallableReferenceExpression expression, StackValue data) { public StackValue visitCallableReferenceExpression(@NotNull JetCallableReferenceExpression expression, StackValue data) {
// TODO: properties ResolvedCall<?> resolvedCall = resolvedCall(expression.getCallableReference());
FunctionDescriptor functionDescriptor = bindingContext.get(FUNCTION, expression); FunctionDescriptor functionDescriptor = bindingContext.get(FUNCTION, expression);
assert functionDescriptor != null : "Callable reference is not resolved to descriptor: " + expression.getText(); if (functionDescriptor != null) {
CallableReferenceGenerationStrategy strategy = new CallableReferenceGenerationStrategy(state, functionDescriptor, resolvedCall);
ClosureCodegen closureCodegen = new ClosureCodegen(state, expression, functionDescriptor, null, context,
KotlinSyntheticClass.Kind.CALLABLE_REFERENCE_WRAPPER,
this, strategy, getParentCodegen());
closureCodegen.gen();
return closureCodegen.putInstanceOnStack(v, this);
}
CallableReferenceGenerationStrategy strategy = VariableDescriptor variableDescriptor = bindingContext.get(VARIABLE, expression);
new CallableReferenceGenerationStrategy(state, functionDescriptor, resolvedCall(expression.getCallableReference())); if (variableDescriptor != null) {
ClosureCodegen closureCodegen = new ClosureCodegen(state, expression, functionDescriptor, null, context, VariableDescriptor descriptor = (VariableDescriptor) resolvedCall.getResultingDescriptor();
KotlinSyntheticClass.Kind.CALLABLE_REFERENCE_WRAPPER,
this, strategy, getParentCodegen());
closureCodegen.gen(); DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
if (containingDeclaration instanceof PackageFragmentDescriptor) {
return generateTopLevelPropertyReference(descriptor);
}
else if (containingDeclaration instanceof ClassDescriptor) {
return generateMemberPropertyReference(descriptor);
}
else {
throw new UnsupportedOperationException("Unsupported callable reference container: " + containingDeclaration);
}
}
return closureCodegen.putInstanceOnStack(v, this); throw new UnsupportedOperationException("Unsupported callable reference expression: " + expression.getText());
}
@NotNull
private StackValue generateTopLevelPropertyReference(@NotNull VariableDescriptor descriptor) {
PackageFragmentDescriptor containingPackage = (PackageFragmentDescriptor) descriptor.getContainingDeclaration();
String packageClassInternalName = PackageClassUtils.getPackageClassInternalName(containingPackage.getFqName());
ReceiverParameterDescriptor receiverParameter = descriptor.getReceiverParameter();
Method factoryMethod;
if (receiverParameter != null) {
Type[] parameterTypes = new Type[] {JAVA_STRING_TYPE, K_PACKAGE_IMPL_TYPE, getType(Class.class)};
factoryMethod = descriptor.isVar()
? method("mutableTopLevelExtensionProperty", K_MUTABLE_TOP_LEVEL_EXTENSION_PROPERTY_IMPL_TYPE, parameterTypes)
: method("topLevelExtensionProperty", K_TOP_LEVEL_EXTENSION_PROPERTY_IMPL_TYPE, parameterTypes);
}
else {
Type[] parameterTypes = new Type[] {JAVA_STRING_TYPE, K_PACKAGE_IMPL_TYPE};
factoryMethod = descriptor.isVar()
? method("mutableTopLevelVariable", K_MUTABLE_TOP_LEVEL_VARIABLE_IMPL_TYPE, parameterTypes)
: method("topLevelVariable", K_TOP_LEVEL_VARIABLE_IMPL_TYPE, parameterTypes);
}
v.visitLdcInsn(descriptor.getName().asString());
v.getstatic(packageClassInternalName, JvmAbi.KOTLIN_PACKAGE_FIELD_NAME, K_PACKAGE_IMPL_TYPE.getDescriptor());
if (receiverParameter != null) {
putJavaLangClassInstance(v, typeMapper.mapType(receiverParameter));
}
v.invokestatic(REFLECTION_INTERNAL_PACKAGE, factoryMethod.getName(), factoryMethod.getDescriptor(), false);
return StackValue.onStack(factoryMethod.getReturnType());
}
@NotNull
private StackValue generateMemberPropertyReference(@NotNull VariableDescriptor descriptor) {
ClassDescriptor containingClass = (ClassDescriptor) descriptor.getContainingDeclaration();
Type classAsmType = typeMapper.mapClass(containingClass);
if (containingClass instanceof JavaClassDescriptor) {
v.aconst(classAsmType);
v.invokestatic(REFLECTION_INTERNAL_PACKAGE, "foreignKotlinClass",
Type.getMethodDescriptor(K_CLASS_IMPL_TYPE, getType(Class.class)), false);
}
else {
v.getstatic(classAsmType.getInternalName(), JvmAbi.KOTLIN_CLASS_FIELD_NAME, K_CLASS_IMPL_TYPE.getDescriptor());
}
Method factoryMethod = descriptor.isVar()
? method("mutableMemberProperty", K_MUTABLE_MEMBER_PROPERTY_TYPE, JAVA_STRING_TYPE)
: method("memberProperty", K_MEMBER_PROPERTY_TYPE, JAVA_STRING_TYPE);
v.visitLdcInsn(descriptor.getName().asString());
v.invokevirtual(K_CLASS_IMPL_TYPE.getInternalName(), factoryMethod.getName(), factoryMethod.getDescriptor(), false);
return StackValue.onStack(factoryMethod.getReturnType());
} }
private static class CallableReferenceGenerationStrategy extends FunctionGenerationStrategy.CodegenBased<FunctionDescriptor> { private static class CallableReferenceGenerationStrategy extends FunctionGenerationStrategy.CodegenBased<FunctionDescriptor> {
@@ -22,6 +22,7 @@ import org.jetbrains.jet.OutputFile;
import java.net.URL; import java.net.URL;
import java.net.URLClassLoader; import java.net.URLClassLoader;
import java.util.List; import java.util.List;
import java.util.jar.Manifest;
public class GeneratedClassLoader extends URLClassLoader { public class GeneratedClassLoader extends URLClassLoader {
private ClassFileFactory state; private ClassFileFactory state;
@@ -39,6 +40,13 @@ public class GeneratedClassLoader extends URLClassLoader {
OutputFile outputFile = state.get(classFilePath); OutputFile outputFile = state.get(classFilePath);
if (outputFile != null) { if (outputFile != null) {
byte[] bytes = outputFile.asByteArray(); byte[] bytes = outputFile.asByteArray();
int lastDot = name.lastIndexOf('.');
if (lastDot >= 0) {
String pkgName = name.substring(0, lastDot);
if (getPackage(pkgName) == null) {
definePackage(pkgName, new Manifest(), null);
}
}
return defineClass(name, bytes, 0, bytes.length); return defineClass(name, bytes, 0, bytes.length);
} }
@@ -72,8 +72,7 @@ import static org.jetbrains.jet.codegen.binding.CodegenBinding.*;
import static org.jetbrains.jet.descriptors.serialization.NameSerializationUtil.createNameResolver; import static org.jetbrains.jet.descriptors.serialization.NameSerializationUtil.createNameResolver;
import static org.jetbrains.jet.lang.resolve.BindingContextUtils.descriptorToDeclaration; import static org.jetbrains.jet.lang.resolve.BindingContextUtils.descriptorToDeclaration;
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.*; import static org.jetbrains.jet.lang.resolve.DescriptorUtils.*;
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.JAVA_STRING_TYPE; import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.*;
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.OBJECT_TYPE;
import static org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames.KotlinSyntheticClass; import static org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames.KotlinSyntheticClass;
import static org.jetbrains.jet.lang.resolve.java.diagnostics.DiagnosticsPackage.DelegationToTraitImpl; import static org.jetbrains.jet.lang.resolve.java.diagnostics.DiagnosticsPackage.DelegationToTraitImpl;
import static org.jetbrains.jet.lang.resolve.java.diagnostics.DiagnosticsPackage.OtherOrigin; import static org.jetbrains.jet.lang.resolve.java.diagnostics.DiagnosticsPackage.OtherOrigin;
@@ -209,6 +208,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
writeInnerClasses(); writeInnerClasses();
AnnotationCodegen.forClass(v.getVisitor(), typeMapper).genAnnotations(descriptor, null); AnnotationCodegen.forClass(v.getVisitor(), typeMapper).genAnnotations(descriptor, null);
generateReflectionObjectFieldIfNeeded();
} }
@Override @Override
@@ -429,7 +430,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
@Override @Override
protected void generateSyntheticParts() { protected void generateSyntheticParts() {
generateDelegatedPropertyMetadataArray(); generatePropertyMetadataArrayFieldIfNeeded(classAsmType);
generateFieldForSingleton(); generateFieldForSingleton();
@@ -463,11 +464,19 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
generateToArray(); generateToArray();
genClosureFields(context.closure, v, state.getTypeMapper()); genClosureFields(context.closure, v, typeMapper);
} }
private void generateDelegatedPropertyMetadataArray() { private void generateReflectionObjectFieldIfNeeded() {
generatePropertyMetadataArrayFieldIfNeeded(classAsmType); if (isAnnotationClass(descriptor)) {
// There's a bug in JDK 6 and 7 that prevents us from generating a static field in an annotation class:
// http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6857918
// TODO: make reflection work on annotation classes somehow
return;
}
generateReflectionObjectField(state, classAsmType, v, method("kClassFromKotlin", K_CLASS_IMPL_TYPE, getType(Class.class)),
JvmAbi.KOTLIN_CLASS_FIELD_NAME, createOrGetClInitCodegen().v);
} }
private boolean isGenericToArrayPresent() { private boolean isGenericToArrayPresent() {
@@ -43,6 +43,7 @@ import org.jetbrains.jet.storage.NotNullLazyValue;
import org.jetbrains.org.objectweb.asm.MethodVisitor; import org.jetbrains.org.objectweb.asm.MethodVisitor;
import org.jetbrains.org.objectweb.asm.Type; import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter; import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
import org.jetbrains.org.objectweb.asm.commons.Method;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@@ -50,12 +51,12 @@ import java.util.List;
import static org.jetbrains.jet.codegen.AsmUtil.boxType; import static org.jetbrains.jet.codegen.AsmUtil.boxType;
import static org.jetbrains.jet.codegen.AsmUtil.isPrimitive; import static org.jetbrains.jet.codegen.AsmUtil.isPrimitive;
import static org.jetbrains.jet.lang.resolve.java.diagnostics.DiagnosticsPackage.OtherOrigin;
import static org.jetbrains.jet.lang.resolve.java.diagnostics.DiagnosticsPackage.TraitImpl;
import static org.jetbrains.jet.lang.resolve.java.diagnostics.JvmDeclarationOrigin.NO_ORIGIN;
import static org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor.Kind.SYNTHESIZED; import static org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor.Kind.SYNTHESIZED;
import static org.jetbrains.jet.lang.resolve.BindingContext.VARIABLE; import static org.jetbrains.jet.lang.resolve.BindingContext.VARIABLE;
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.*; import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.*;
import static org.jetbrains.jet.lang.resolve.java.diagnostics.DiagnosticsPackage.OtherOrigin;
import static org.jetbrains.jet.lang.resolve.java.diagnostics.DiagnosticsPackage.TraitImpl;
import static org.jetbrains.jet.lang.resolve.java.diagnostics.JvmDeclarationOrigin.NO_ORIGIN;
import static org.jetbrains.org.objectweb.asm.Opcodes.*; import static org.jetbrains.org.objectweb.asm.Opcodes.*;
public abstract class MemberCodegen<T extends JetElement/* TODO: & JetDeclarationContainer*/> extends ParentCodegenAware { public abstract class MemberCodegen<T extends JetElement/* TODO: & JetDeclarationContainer*/> extends ParentCodegenAware {
@@ -316,6 +317,25 @@ public abstract class MemberCodegen<T extends JetElement/* TODO: & JetDeclaratio
return false; return false;
} }
public static void generateReflectionObjectField(
@NotNull GenerationState state,
@NotNull Type thisAsmType,
@NotNull ClassBuilder classBuilder,
@NotNull Method factory,
@NotNull String fieldName,
@NotNull InstructionAdapter v
) {
String type = factory.getReturnType().getDescriptor();
// TODO: generic signature
classBuilder.newField(NO_ORIGIN, ACC_PUBLIC | ACC_STATIC | ACC_FINAL | ACC_SYNTHETIC, fieldName, type, null, null);
if (state.getClassBuilderMode() == ClassBuilderMode.LIGHT_CLASSES) return;
v.aconst(thisAsmType);
v.invokestatic(REFLECTION_INTERNAL_PACKAGE, factory.getName(), factory.getDescriptor(), false);
v.putstatic(thisAsmType.getInternalName(), fieldName, type);
}
protected void generatePropertyMetadataArrayFieldIfNeeded(@NotNull Type thisAsmType) { protected void generatePropertyMetadataArrayFieldIfNeeded(@NotNull Type thisAsmType) {
List<JetProperty> delegatedProperties = new ArrayList<JetProperty>(); List<JetProperty> delegatedProperties = new ArrayList<JetProperty>();
for (JetDeclaration declaration : ((JetDeclarationContainer) element).getDeclarations()) { for (JetDeclaration declaration : ((JetDeclarationContainer) element).getDeclarations()) {
@@ -56,27 +56,35 @@ import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.org.objectweb.asm.AnnotationVisitor; import org.jetbrains.org.objectweb.asm.AnnotationVisitor;
import org.jetbrains.org.objectweb.asm.MethodVisitor; import org.jetbrains.org.objectweb.asm.MethodVisitor;
import org.jetbrains.org.objectweb.asm.Type; import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
import org.jetbrains.org.objectweb.asm.commons.Method;
import java.util.*; import java.util.*;
import static org.jetbrains.jet.codegen.AsmUtil.asmDescByFqNameWithoutInnerClasses; import static org.jetbrains.jet.codegen.AsmUtil.asmDescByFqNameWithoutInnerClasses;
import static org.jetbrains.jet.codegen.AsmUtil.method;
import static org.jetbrains.jet.descriptors.serialization.NameSerializationUtil.createNameResolver; import static org.jetbrains.jet.descriptors.serialization.NameSerializationUtil.createNameResolver;
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.K_PACKAGE_IMPL_TYPE;
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.getType;
import static org.jetbrains.jet.lang.resolve.java.PackageClassUtils.getPackageClassFqName; import static org.jetbrains.jet.lang.resolve.java.PackageClassUtils.getPackageClassFqName;
import static org.jetbrains.jet.lang.resolve.java.diagnostics.DiagnosticsPackage.*; import static org.jetbrains.jet.lang.resolve.java.diagnostics.DiagnosticsPackage.*;
import static org.jetbrains.jet.lang.resolve.java.diagnostics.JvmDeclarationOrigin.NO_ORIGIN;
import static org.jetbrains.org.objectweb.asm.Opcodes.*; import static org.jetbrains.org.objectweb.asm.Opcodes.*;
public class PackageCodegen { public class PackageCodegen {
private final GenerationState state;
private final ClassBuilderOnDemand v; private final ClassBuilderOnDemand v;
private final GenerationState state;
private final Collection<JetFile> files; private final Collection<JetFile> files;
private final Type packageClassType;
private final PackageFragmentDescriptor packageFragment; private final PackageFragmentDescriptor packageFragment;
private final PackageFragmentDescriptor compiledPackageFragment; private final PackageFragmentDescriptor compiledPackageFragment;
private final List<DeserializedCallableMemberDescriptor> previouslyCompiledCallables; private final List<DeserializedCallableMemberDescriptor> previouslyCompiledCallables;
public PackageCodegen(@NotNull GenerationState state, @NotNull Collection<JetFile> files, @NotNull final FqName fqName) { public PackageCodegen(@NotNull GenerationState state, @NotNull Collection<JetFile> files, @NotNull FqName fqName) {
this.state = state; this.state = state;
this.files = files; this.files = files;
this.packageFragment = getOnlyPackageFragment(fqName); this.packageFragment = getOnlyPackageFragment(fqName);
this.packageClassType = AsmUtil.asmTypeByFqNameWithoutInnerClasses(getPackageClassFqName(fqName));
this.compiledPackageFragment = getCompiledPackageFragment(fqName); this.compiledPackageFragment = getCompiledPackageFragment(fqName);
this.previouslyCompiledCallables = filterDeserializedCallables(compiledPackageFragment); this.previouslyCompiledCallables = filterDeserializedCallables(compiledPackageFragment);
@@ -88,14 +96,13 @@ public class PackageCodegen {
Collection<JetFile> files = PackageCodegen.this.files; Collection<JetFile> files = PackageCodegen.this.files;
JetFile sourceFile = getRepresentativePackageFile(files); JetFile sourceFile = getRepresentativePackageFile(files);
String className = AsmUtil.internalNameByFqNameWithoutInnerClasses(getPackageClassFqName(fqName)); ClassBuilder v = PackageCodegen.this.state.getFactory().newVisitor(
ClassBuilder v = PackageCodegen.this.state.getFactory() PackageFacade(packageFragment == null ? compiledPackageFragment : packageFragment),
.newVisitor( packageClassType, PackagePartClassUtils.getPackageFilesWithCallables(files)
PackageFacade(packageFragment == null ? compiledPackageFragment : packageFragment), );
Type.getObjectType(className), PackagePartClassUtils.getPackageFilesWithCallables(files));
v.defineClass(sourceFile, V1_6, v.defineClass(sourceFile, V1_6,
ACC_PUBLIC | ACC_FINAL, ACC_PUBLIC | ACC_FINAL,
className, packageClassType.getInternalName(),
null, null,
"java/lang/Object", "java/lang/Object",
ArrayUtil.EMPTY_STRING_ARRAY ArrayUtil.EMPTY_STRING_ARRAY
@@ -216,18 +223,36 @@ public class PackageCodegen {
} }
} }
generateDelegationsToPreviouslyCompiled(generateCallableMemberTasks); if (!generateCallableMemberTasks.isEmpty()) {
generatePackageFacadeClass(generateCallableMemberTasks, bindings);
}
}
if (generateCallableMemberTasks.isEmpty()) return; private void generatePackageFacadeClass(
@NotNull Map<CallableMemberDescriptor, Runnable> tasks,
@NotNull List<JvmSerializationBindings> bindings
) {
generateKotlinPackageReflectionField();
for (CallableMemberDescriptor member : Ordering.from(MemberComparator.INSTANCE).sortedCopy(generateCallableMemberTasks.keySet())) { generateDelegationsToPreviouslyCompiled(tasks);
generateCallableMemberTasks.get(member).run();
for (CallableMemberDescriptor member : Ordering.from(MemberComparator.INSTANCE).sortedCopy(tasks.keySet())) {
tasks.get(member).run();
} }
bindings.add(v.getSerializationBindings()); bindings.add(v.getSerializationBindings());
writeKotlinPackageAnnotationIfNeeded(JvmSerializationBindings.union(bindings)); writeKotlinPackageAnnotationIfNeeded(JvmSerializationBindings.union(bindings));
} }
private void generateKotlinPackageReflectionField() {
MethodVisitor mv = v.newMethod(NO_ORIGIN, ACC_STATIC, "<clinit>", "()V", null, null);
Method method = method("kPackage", K_PACKAGE_IMPL_TYPE, getType(Class.class));
InstructionAdapter iv = new InstructionAdapter(mv);
MemberCodegen.generateReflectionObjectField(state, packageClassType, v, method, JvmAbi.KOTLIN_PACKAGE_FIELD_NAME, iv);
iv.areturn(Type.VOID_TYPE);
FunctionCodegen.endVisit(mv, "package facade static initializer", null);
}
private void writeKotlinPackageAnnotationIfNeeded(@NotNull JvmSerializationBindings bindings) { private void writeKotlinPackageAnnotationIfNeeded(@NotNull JvmSerializationBindings bindings) {
if (state.getClassBuilderMode() != ClassBuilderMode.FULL) { if (state.getClassBuilderMode() != ClassBuilderMode.FULL) {
return; return;
@@ -266,6 +266,9 @@ public class InlineCodegenUtil {
} }
public static boolean isCapturedFieldName(@NotNull String fieldName) { public static boolean isCapturedFieldName(@NotNull String fieldName) {
return fieldName.startsWith(CAPTURED_FIELD_PREFIX) || THIS$0.equals(fieldName) || RECEIVER$0.equals(fieldName); // TODO: improve this heuristic
return (fieldName.startsWith(CAPTURED_FIELD_PREFIX) && !fieldName.equals(JvmAbi.KOTLIN_CLASS_FIELD_NAME)) ||
THIS$0.equals(fieldName) ||
RECEIVER$0.equals(fieldName);
} }
} }
@@ -19,8 +19,6 @@ package org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.lang.psi.JetCallExpression; import org.jetbrains.jet.lang.psi.JetCallExpression;
@@ -28,11 +26,12 @@ import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
import java.util.List; import java.util.List;
import static org.jetbrains.jet.codegen.AsmUtil.boxType; import static org.jetbrains.jet.codegen.AsmUtil.putJavaLangClassInstance;
import static org.jetbrains.jet.codegen.AsmUtil.isPrimitive;
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.getType; import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.getType;
public class JavaClassFunction extends IntrinsicMethod { public class JavaClassFunction extends IntrinsicMethod {
@@ -51,13 +50,7 @@ public class JavaClassFunction extends IntrinsicMethod {
assert resolvedCall != null; assert resolvedCall != null;
JetType returnType = resolvedCall.getResultingDescriptor().getReturnType(); JetType returnType = resolvedCall.getResultingDescriptor().getReturnType();
assert returnType != null; assert returnType != null;
Type type = codegen.getState().getTypeMapper().mapType(returnType.getArguments().get(0).getType()); putJavaLangClassInstance(v, codegen.getState().getTypeMapper().mapType(returnType.getArguments().get(0).getType()));
if (isPrimitive(type)) {
v.getstatic(boxType(type).getInternalName(), "TYPE", "Ljava/lang/Class;");
}
else {
v.aconst(type);
}
return getType(Class.class); return getType(Class.class);
} }
+1 -1
View File
@@ -42,7 +42,7 @@ if "%_PROFILE_PRELOADER%"=="time" (
org.jetbrains.jet.preloading.Preloader "%_KOTLIN_HOME%\lib\kotlin-compiler.jar;%_KOTLIN_HOME%\lib\kotlin-runtime.jar" ^ org.jetbrains.jet.preloading.Preloader "%_KOTLIN_HOME%\lib\kotlin-compiler.jar;%_KOTLIN_HOME%\lib\kotlin-runtime.jar" ^
org.jetbrains.jet.cli.js.K2JSCompiler 4096 %_PROFILE_PRELOADER% %* org.jetbrains.jet.cli.js.K2JSCompiler 4096 %_PROFILE_PRELOADER% %*
) )
exit %ERRORLEVEL% exit /b %ERRORLEVEL%
goto end goto end
rem ########################################################################## rem ##########################################################################
+1 -1
View File
@@ -42,7 +42,7 @@ if "%_PROFILE_PRELOADER%"=="time" (
org.jetbrains.jet.preloading.Preloader "%_KOTLIN_HOME%\lib\kotlin-compiler.jar;%_KOTLIN_HOME%\lib\kotlin-runtime.jar" ^ org.jetbrains.jet.preloading.Preloader "%_KOTLIN_HOME%\lib\kotlin-compiler.jar;%_KOTLIN_HOME%\lib\kotlin-runtime.jar" ^
org.jetbrains.jet.cli.jvm.K2JVMCompiler 4096 %_PROFILE_PRELOADER% %* org.jetbrains.jet.cli.jvm.K2JVMCompiler 4096 %_PROFILE_PRELOADER% %*
) )
exit %ERRORLEVEL% exit /b %ERRORLEVEL%
goto end goto end
rem ########################################################################## rem ##########################################################################
@@ -57,8 +57,7 @@ public enum AnalyzerFacadeForJVM implements AnalyzerFacade {
new ImportPath("java.lang.*"), new ImportPath("java.lang.*"),
new ImportPath("kotlin.*"), new ImportPath("kotlin.*"),
new ImportPath("kotlin.jvm.*"), new ImportPath("kotlin.jvm.*"),
new ImportPath("kotlin.io.*"), new ImportPath("kotlin.io.*")
new ImportPath("kotlin.reflect.*")
); );
public static class JvmSetup extends BasicSetup { public static class JvmSetup extends BasicSetup {
@@ -38,8 +38,26 @@ public class AsmTypeConstants {
public static final Type PROPERTY_METADATA_TYPE = Type.getObjectType(BUILT_INS_PACKAGE_FQ_NAME + "/PropertyMetadata"); public static final Type PROPERTY_METADATA_TYPE = Type.getObjectType(BUILT_INS_PACKAGE_FQ_NAME + "/PropertyMetadata");
public static final Type PROPERTY_METADATA_IMPL_TYPE = Type.getObjectType(BUILT_INS_PACKAGE_FQ_NAME + "/PropertyMetadataImpl"); public static final Type PROPERTY_METADATA_IMPL_TYPE = Type.getObjectType(BUILT_INS_PACKAGE_FQ_NAME + "/PropertyMetadataImpl");
public static final Type K_MEMBER_PROPERTY_TYPE = Type.getObjectType("kotlin/reflect/KMemberProperty");
public static final Type K_MUTABLE_MEMBER_PROPERTY_TYPE = Type.getObjectType("kotlin/reflect/KMutableMemberProperty");
public static final Type K_CLASS_IMPL_TYPE = reflectInternal("KClassImpl");
public static final Type K_PACKAGE_IMPL_TYPE = reflectInternal("KPackageImpl");
public static final Type K_TOP_LEVEL_VARIABLE_IMPL_TYPE = reflectInternal("KTopLevelVariableImpl");
public static final Type K_MUTABLE_TOP_LEVEL_VARIABLE_IMPL_TYPE = reflectInternal("KMutableTopLevelVariableImpl");
public static final Type K_TOP_LEVEL_EXTENSION_PROPERTY_IMPL_TYPE = reflectInternal("KTopLevelExtensionPropertyImpl");
public static final Type K_MUTABLE_TOP_LEVEL_EXTENSION_PROPERTY_IMPL_TYPE = reflectInternal("KMutableTopLevelExtensionPropertyImpl");
public static final String REFLECTION_INTERNAL_PACKAGE = reflectInternal("InternalPackage").getInternalName();
public static final Type OBJECT_REF_TYPE = Type.getObjectType("kotlin/jvm/internal/Ref$ObjectRef"); public static final Type OBJECT_REF_TYPE = Type.getObjectType("kotlin/jvm/internal/Ref$ObjectRef");
@NotNull
private static Type reflectInternal(@NotNull String className) {
return Type.getObjectType("kotlin/reflect/jvm/internal/" + className);
}
@NotNull
public static Type getType(@NotNull Class<?> javaClass) { public static Type getType(@NotNull Class<?> javaClass) {
Type type = TYPES_MAP.get(javaClass); Type type = TYPES_MAP.get(javaClass);
if (type == null) { if (type == null) {
@@ -21,11 +21,10 @@ import org.jetbrains.jet.lang.descriptors.*
import org.jetbrains.jet.lang.resolve.name.FqName import org.jetbrains.jet.lang.resolve.name.FqName
import org.jetbrains.jet.lang.resolve.name.Name import org.jetbrains.jet.lang.resolve.name.Name
import org.jetbrains.jet.lang.resolve.scopes.JetScope import org.jetbrains.jet.lang.resolve.scopes.JetScope
import org.jetbrains.jet.lang.types.*
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns
import org.jetbrains.jet.lang.descriptors.annotations.Annotations import org.jetbrains.jet.lang.descriptors.annotations.Annotations
import org.jetbrains.jet.lang.types.JetType import java.util.ArrayList
import org.jetbrains.jet.lang.types.JetTypeImpl
import org.jetbrains.jet.lang.types.ErrorUtils
private val KOTLIN_REFLECT_FQ_NAME = FqName("kotlin.reflect") private val KOTLIN_REFLECT_FQ_NAME = FqName("kotlin.reflect")
@@ -40,10 +39,23 @@ public class ReflectionTypes(private val module: ModuleDescriptor) {
?: ErrorUtils.createErrorClass(KOTLIN_REFLECT_FQ_NAME.child(name).asString()) ?: ErrorUtils.createErrorClass(KOTLIN_REFLECT_FQ_NAME.child(name).asString())
} }
private object ClassLookup {
fun get(types: ReflectionTypes, property: PropertyMetadata): ClassDescriptor {
return types.find(property.name.capitalize())
}
}
public fun getKFunction(n: Int): ClassDescriptor = find("KFunction$n") public fun getKFunction(n: Int): ClassDescriptor = find("KFunction$n")
public fun getKExtensionFunction(n: Int): ClassDescriptor = find("KExtensionFunction$n") public fun getKExtensionFunction(n: Int): ClassDescriptor = find("KExtensionFunction$n")
public fun getKMemberFunction(n: Int): ClassDescriptor = find("KMemberFunction$n") public fun getKMemberFunction(n: Int): ClassDescriptor = find("KMemberFunction$n")
public val kTopLevelVariable: ClassDescriptor by ClassLookup
public val kMutableTopLevelVariable: ClassDescriptor by ClassLookup
public val kMemberProperty: ClassDescriptor by ClassLookup
public val kMutableMemberProperty: ClassDescriptor by ClassLookup
public val kTopLevelExtensionProperty: ClassDescriptor by ClassLookup
public val kMutableTopLevelExtensionProperty: ClassDescriptor by ClassLookup
public fun getKFunctionType( public fun getKFunctionType(
annotations: Annotations, annotations: Annotations,
receiverType: JetType?, receiverType: JetType?,
@@ -51,26 +63,47 @@ public class ReflectionTypes(private val module: ModuleDescriptor) {
returnType: JetType, returnType: JetType,
extensionFunction: Boolean extensionFunction: Boolean
): JetType { ): JetType {
val arguments = KotlinBuiltIns.getFunctionTypeArgumentProjections(receiverType, parameterTypes, returnType) val arity = parameterTypes.size()
val classDescriptor = correspondingKFunctionClass(receiverType, extensionFunction, parameterTypes.size) val classDescriptor =
if (extensionFunction) getKExtensionFunction(arity)
else if (receiverType != null) getKMemberFunction(arity)
else getKFunction(arity)
return if (ErrorUtils.isError(classDescriptor)) if (ErrorUtils.isError(classDescriptor)) {
classDescriptor.getDefaultType() return classDescriptor.getDefaultType()
else }
JetTypeImpl(annotations, classDescriptor.getTypeConstructor(), false, arguments, classDescriptor.getMemberScope(arguments))
val arguments = KotlinBuiltIns.getFunctionTypeArgumentProjections(receiverType, parameterTypes, returnType)
return JetTypeImpl(annotations, classDescriptor.getTypeConstructor(), false, arguments, classDescriptor.getMemberScope(arguments))
} }
private fun correspondingKFunctionClass( public fun getKPropertyType(
annotations: Annotations,
receiverType: JetType?, receiverType: JetType?,
extensionFunction: Boolean, returnType: JetType,
numberOfParameters: Int extensionProperty: Boolean,
): ClassDescriptor { mutable: Boolean
if (extensionFunction) { ): JetType {
return getKExtensionFunction(numberOfParameters) val classDescriptor = if (mutable) when {
extensionProperty -> kMutableTopLevelExtensionProperty
receiverType != null -> kMutableMemberProperty
else -> kMutableTopLevelVariable
} }
else when {
extensionProperty -> kTopLevelExtensionProperty
receiverType != null -> kMemberProperty
else -> kTopLevelVariable
}
if (ErrorUtils.isError(classDescriptor)) {
return classDescriptor.getDefaultType()
}
val arguments = ArrayList<TypeProjection>(2)
if (receiverType != null) { if (receiverType != null) {
return getKMemberFunction(numberOfParameters) arguments.add(TypeProjectionImpl(receiverType))
} }
return getKFunction(numberOfParameters) arguments.add(TypeProjectionImpl(returnType))
return JetTypeImpl(annotations, classDescriptor.getTypeConstructor(), false, arguments, classDescriptor.getMemberScope(arguments))
} }
} }
@@ -25,6 +25,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.Annotations; import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
import org.jetbrains.jet.lang.descriptors.impl.AnonymousFunctionDescriptor; import org.jetbrains.jet.lang.descriptors.impl.AnonymousFunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.impl.LocalVariableDescriptor;
import org.jetbrains.jet.lang.diagnostics.Diagnostic; import org.jetbrains.jet.lang.diagnostics.Diagnostic;
import org.jetbrains.jet.lang.diagnostics.Errors; import org.jetbrains.jet.lang.diagnostics.Errors;
import org.jetbrains.jet.lang.evaluate.ConstantExpressionEvaluator; import org.jetbrains.jet.lang.evaluate.ConstantExpressionEvaluator;
@@ -472,7 +473,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
JetSimpleNameExpression reference = expression.getCallableReference(); JetSimpleNameExpression reference = expression.getCallableReference();
boolean[] result = new boolean[1]; boolean[] result = new boolean[1];
FunctionDescriptor descriptor = resolveCallableReferenceTarget(lhsType, context, expression, result); CallableDescriptor descriptor = resolveCallableReferenceTarget(lhsType, context, expression, result);
if (!result[0]) { if (!result[0]) {
context.trace.report(UNRESOLVED_REFERENCE.on(reference, reference)); context.trace.report(UNRESOLVED_REFERENCE.on(reference, reference));
@@ -481,8 +482,8 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
ReceiverParameterDescriptor receiverParameter = descriptor.getReceiverParameter(); ReceiverParameterDescriptor receiverParameter = descriptor.getReceiverParameter();
ReceiverParameterDescriptor expectedThisObject = descriptor.getExpectedThisObject(); ReceiverParameterDescriptor expectedThisObject = descriptor.getExpectedThisObject();
if (receiverParameter != null && expectedThisObject != null) { if (receiverParameter != null && expectedThisObject != null && descriptor instanceof CallableMemberDescriptor) {
context.trace.report(EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED.on(reference, descriptor)); context.trace.report(EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED.on(reference, (CallableMemberDescriptor) descriptor));
return null; return null;
} }
@@ -493,14 +494,37 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
else if (expectedThisObject != null) { else if (expectedThisObject != null) {
receiverType = expectedThisObject.getType(); receiverType = expectedThisObject.getType();
} }
boolean isExtension = receiverParameter != null;
if (descriptor instanceof FunctionDescriptor) {
return createFunctionReferenceType(expression, context, (FunctionDescriptor) descriptor, receiverType, isExtension);
}
else if (descriptor instanceof PropertyDescriptor) {
return createPropertyReferenceType(expression, context, (PropertyDescriptor) descriptor, receiverType, isExtension);
}
else if (descriptor instanceof VariableDescriptor) {
context.trace.report(UNSUPPORTED.on(reference, "References to variables aren't supported yet"));
return null;
}
throw new UnsupportedOperationException("Callable reference resolved to an unsupported descriptor: " + descriptor);
}
@Nullable
private JetType createFunctionReferenceType(
@NotNull JetCallableReferenceExpression expression,
@NotNull ExpressionTypingContext context,
@NotNull FunctionDescriptor descriptor,
@Nullable JetType receiverType,
boolean isExtension
) {
//noinspection ConstantConditions //noinspection ConstantConditions
JetType type = components.reflectionTypes.getKFunctionType( JetType type = components.reflectionTypes.getKFunctionType(
Annotations.EMPTY, Annotations.EMPTY,
receiverType, receiverType,
getValueParametersTypes(descriptor.getValueParameters()), getValueParametersTypes(descriptor.getValueParameters()),
descriptor.getReturnType(), descriptor.getReturnType(),
receiverParameter != null isExtension
); );
if (type.isError()) { if (type.isError()) {
@@ -511,7 +535,8 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
AnonymousFunctionDescriptor functionDescriptor = new AnonymousFunctionDescriptor( AnonymousFunctionDescriptor functionDescriptor = new AnonymousFunctionDescriptor(
context.scope.getContainingDeclaration(), context.scope.getContainingDeclaration(),
Annotations.EMPTY, Annotations.EMPTY,
CallableMemberDescriptor.Kind.DECLARATION); CallableMemberDescriptor.Kind.DECLARATION
);
FunctionDescriptorUtil.initializeFromFunctionType(functionDescriptor, type, null, Modality.FINAL, Visibilities.PUBLIC); FunctionDescriptorUtil.initializeFromFunctionType(functionDescriptor, type, null, Modality.FINAL, Visibilities.PUBLIC);
@@ -521,7 +546,32 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
} }
@Nullable @Nullable
private FunctionDescriptor resolveCallableReferenceTarget( private JetType createPropertyReferenceType(
@NotNull JetCallableReferenceExpression expression,
@NotNull ExpressionTypingContext context,
@NotNull PropertyDescriptor descriptor,
@Nullable JetType receiverType,
boolean isExtension
) {
JetType type = components.reflectionTypes.getKPropertyType(Annotations.EMPTY, receiverType, descriptor.getType(), isExtension,
descriptor.isVar());
if (type.isError()) {
context.trace.report(REFLECTION_TYPES_NOT_LOADED.on(expression.getDoubleColonTokenReference()));
return null;
}
LocalVariableDescriptor localVariable =
new LocalVariableDescriptor(context.scope.getContainingDeclaration(), Annotations.EMPTY, Name.special("<anonymous>"),
type, /* mutable = */ false);
context.trace.record(VARIABLE, expression, localVariable);
return type;
}
@Nullable
private CallableDescriptor resolveCallableReferenceTarget(
@Nullable JetType lhsType, @Nullable JetType lhsType,
@NotNull ExpressionTypingContext context, @NotNull ExpressionTypingContext context,
@NotNull JetCallableReferenceExpression expression, @NotNull JetCallableReferenceExpression expression,
@@ -542,7 +592,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
ReceiverValue receiver = new TransientReceiver(lhsType); ReceiverValue receiver = new TransientReceiver(lhsType);
TemporaryTraceAndCache temporaryWithReceiver = TemporaryTraceAndCache.create( TemporaryTraceAndCache temporaryWithReceiver = TemporaryTraceAndCache.create(
context, "trace to resolve callable reference with receiver", reference); context, "trace to resolve callable reference with receiver", reference);
FunctionDescriptor descriptor = resolveCallableNotCheckingArguments( CallableDescriptor descriptor = resolveCallableNotCheckingArguments(
reference, receiver, context.replaceTraceAndCache(temporaryWithReceiver), result); reference, receiver, context.replaceTraceAndCache(temporaryWithReceiver), result);
if (result[0]) { if (result[0]) {
temporaryWithReceiver.commit(); temporaryWithReceiver.commit();
@@ -552,7 +602,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
JetScope staticScope = getStaticNestedClassesScope((ClassDescriptor) classifier); JetScope staticScope = getStaticNestedClassesScope((ClassDescriptor) classifier);
TemporaryTraceAndCache temporaryForStatic = TemporaryTraceAndCache.create( TemporaryTraceAndCache temporaryForStatic = TemporaryTraceAndCache.create(
context, "trace to resolve callable reference in static scope", reference); context, "trace to resolve callable reference in static scope", reference);
FunctionDescriptor possibleStaticNestedClassConstructor = resolveCallableNotCheckingArguments(reference, NO_RECEIVER, CallableDescriptor possibleStaticNestedClassConstructor = resolveCallableNotCheckingArguments(reference, NO_RECEIVER,
context.replaceTraceAndCache(temporaryForStatic).replaceScope(staticScope), result); context.replaceTraceAndCache(temporaryForStatic).replaceScope(staticScope), result);
if (result[0]) { if (result[0]) {
temporaryForStatic.commit(); temporaryForStatic.commit();
@@ -563,7 +613,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
} }
@Nullable @Nullable
private FunctionDescriptor resolveCallableNotCheckingArguments( private CallableDescriptor resolveCallableNotCheckingArguments(
@NotNull JetSimpleNameExpression reference, @NotNull JetSimpleNameExpression reference,
@NotNull ReceiverValue receiver, @NotNull ReceiverValue receiver,
@NotNull ExpressionTypingContext context, @NotNull ExpressionTypingContext context,
@@ -571,22 +621,41 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
) { ) {
Call call = CallMaker.makeCall(reference, receiver, null, reference, ThrowingList.<ValueArgument>instance()); Call call = CallMaker.makeCall(reference, receiver, null, reference, ThrowingList.<ValueArgument>instance());
TemporaryBindingTrace trace = TemporaryBindingTrace.create(context.trace, "trace to resolve as function", reference); TemporaryTraceAndCache funTrace = TemporaryTraceAndCache.create(context, "trace to resolve callable reference as function",
reference);
ExpressionTypingContext contextForResolve = context.replaceBindingTrace(trace).replaceExpectedType(NO_EXPECTED_TYPE);
ResolvedCall<FunctionDescriptor> function = components.expressionTypingServices.getCallExpressionResolver() ResolvedCall<FunctionDescriptor> function = components.expressionTypingServices.getCallExpressionResolver()
.getResolvedCallForFunction(call, reference, contextForResolve, CheckValueArgumentsMode.DISABLED, result); .getResolvedCallForFunction(call, reference, context.replaceTraceAndCache(funTrace).replaceExpectedType(NO_EXPECTED_TYPE),
if (!result[0]) return null; CheckValueArgumentsMode.DISABLED, result);
if (result[0]) {
funTrace.commit();
if (function instanceof VariableAsFunctionResolvedCall) { if (function instanceof VariableAsFunctionResolvedCall) {
// TODO: KProperty context.trace.report(UNSUPPORTED.on(reference, "References to variables aren't supported yet"));
context.trace.report(UNSUPPORTED.on(reference, "References to variables aren't supported yet")); return null;
context.trace.report(UNRESOLVED_REFERENCE.on(reference, reference)); }
return null;
return function != null ? function.getResultingDescriptor() : null;
} }
trace.commit(); TemporaryTraceAndCache varTrace = TemporaryTraceAndCache.create(context, "trace to resolve callable reference as variable",
return function != null ? function.getResultingDescriptor() : null; reference);
OverloadResolutionResults<VariableDescriptor> variableResults =
components.expressionTypingServices.getCallResolver().resolveSimpleProperty(
BasicCallResolutionContext.create(context.replaceTraceAndCache(varTrace).replaceExpectedType(NO_EXPECTED_TYPE),
call, CheckValueArgumentsMode.DISABLED)
);
if (!variableResults.isNothing()) {
ResolvedCall<VariableDescriptor> variable =
OverloadResolutionResultsUtil.getResultingCall(variableResults, context.contextDependency);
varTrace.commit();
if (variable != null) {
result[0] = true;
return variable.getResultingDescriptor();
}
}
return null;
} }
@Override @Override
@@ -20,15 +20,14 @@ import org.junit.Test;
import java.io.File; import java.io.File;
import static junit.framework.Assert.*; import static org.junit.Assert.assertEquals;
public class CompilerSmokeTest extends KotlinIntegrationTestBase { public class CompilerSmokeTest extends KotlinIntegrationTestBase {
@Test @Test
public void compileAndRunHelloApp() throws Exception { public void compileAndRunHelloApp() throws Exception {
String jar = tmpdir.getTmpDir().getAbsolutePath() + File.separator + "hello.jar"; String jar = tmpdir.getTmpDir().getAbsolutePath() + File.separator + "hello.jar";
assertEquals("compilation failed", 0, runCompiler("hello.compile", "-src", "hello.kt", "-jar", jar)); assertEquals("compilation failed", 0, runCompiler("hello.compile", "-includeRuntime", "hello.kt", "-jar", jar));
runJava("hello.run", "-cp", jar, "Hello.HelloPackage"); runJava("hello.run", "-cp", jar, "Hello.HelloPackage");
} }
@@ -36,7 +35,7 @@ public class CompilerSmokeTest extends KotlinIntegrationTestBase {
public void compileAndRunHelloAppFQMain() throws Exception { public void compileAndRunHelloAppFQMain() throws Exception {
String jar = tmpdir.getTmpDir().getAbsolutePath() + File.separator + "hello.jar"; String jar = tmpdir.getTmpDir().getAbsolutePath() + File.separator + "hello.jar";
assertEquals("compilation failed", 0, runCompiler("hello.compile", "-src", "hello.kt", "-jar", jar)); assertEquals("compilation failed", 0, runCompiler("hello.compile", "-includeRuntime", "hello.kt", "-jar", jar));
runJava("hello.run", "-cp", jar, "Hello.HelloPackage"); runJava("hello.run", "-cp", jar, "Hello.HelloPackage");
} }
@@ -44,7 +43,7 @@ public class CompilerSmokeTest extends KotlinIntegrationTestBase {
public void compileAndRunHelloAppVarargMain() throws Exception { public void compileAndRunHelloAppVarargMain() throws Exception {
String jar = tmpdir.getTmpDir().getAbsolutePath() + File.separator + "hello.jar"; String jar = tmpdir.getTmpDir().getAbsolutePath() + File.separator + "hello.jar";
assertEquals("compilation failed", 0, runCompiler("hello.compile", "-src", "hello.kt", "-jar", jar)); assertEquals("compilation failed", 0, runCompiler("hello.compile", "-includeRuntime", "hello.kt", "-jar", jar));
runJava("hello.run", "-cp", jar, "Hello.HelloPackage"); runJava("hello.run", "-cp", jar, "Hello.HelloPackage");
} }
@@ -0,0 +1,3 @@
public class publicFinalField {
public final String field = "OK";
}
@@ -0,0 +1 @@
fun box() = (publicFinalField::field).get(publicFinalField())
@@ -0,0 +1,3 @@
public class publicMutableField {
public int field = 239;
}
@@ -0,0 +1,11 @@
import publicMutableField as A
fun box(): String {
val a = A()
val f = A::field
if (f.get(a) != 239) return "Fail 1: ${f.get(a)}"
f[a] = 42
if (f.get(a) != 42) return "Fail 2: ${f.get(a)}"
if (f.get(a) != 42) return "Fail 2: ${f.get(a)}"
return "OK"
}
@@ -0,0 +1 @@
public class jClass2kClass {}
@@ -0,0 +1,11 @@
import jClass2kClass as J
import kotlin.reflect.jvm.*
import kotlin.test.assertEquals
fun box(): String {
val j = javaClass<J>()
assertEquals(j, j.kotlin.java)
return "OK"
}
@@ -0,0 +1,9 @@
public class javaFields {
public final int i;
public String s;
public javaFields(int i, String s) {
this.i = i;
this.s = s;
}
}
@@ -0,0 +1,43 @@
import javaFields as J
import java.lang.reflect.*
import kotlin.reflect.*
import kotlin.reflect.jvm.*
fun box(): String {
val i = J::i
val s = J::s
// Check that correct reflection objects are created
assert(i.javaClass.getSimpleName() == "KForeignMemberProperty", "Fail i class")
assert(s.javaClass.getSimpleName() == "KMutableForeignMemberProperty", "Fail s class")
// Check that no Method objects are created for such properties
assert(i.javaGetter == null, "Fail i getter")
assert(s.javaGetter == null, "Fail s getter")
assert(s.javaSetter == null, "Fail s setter")
// Check that correct Field objects are created
val ji = i.javaField!!
val js = s.javaField!!
assert(Modifier.isFinal(ji.getModifiers()), "Fail i final")
assert(!Modifier.isFinal(js.getModifiers()), "Fail s final")
// Check that those Field objects work as expected
val a = J(42, "abc")
assert(ji.get(a) == 42, "Fail ji get")
assert(js.get(a) == "abc", "Fail js get")
js.set(a, "def")
assert(js.get(a) == "def", "Fail js set")
assert(a.s == "def", "Fail js access")
// Check that valid Kotlin reflection objects are created by those Field objects
val ki = ji.kotlin as KMemberProperty<J, Int>
val ks = js.kotlin as KMutableMemberProperty<J, String>
assert(ki.get(a) == 42, "Fail ki get")
assert(ks.get(a) == "def", "Fail ks get")
ks.set(a, "ghi")
assert(ks.get(a) == "ghi", "Fail ks set")
return "OK"
}
@@ -0,0 +1,3 @@
public class J extends K {
public final int value = 42;
}
@@ -0,0 +1,7 @@
open class K
fun box(): String {
val f = J::value
val a = J()
return if (f.get(a) == 42) "OK" else "Fail: ${f[a]}"
}
@@ -0,0 +1,9 @@
abstract class Base {
val result = "OK"
}
class Derived : Base()
fun box(): String {
return (Base::result).get(Derived())
}
@@ -0,0 +1,22 @@
val four: Int by NumberDecrypter
class A {
val two: Int by NumberDecrypter
}
object NumberDecrypter {
fun get(instance: Any?, data: PropertyMetadata) = when (data.name) {
"four" -> 4
"two" -> 2
else -> throw AssertionError()
}
}
fun box(): String {
val x = ::four.get()
if (x != 4) return "Fail x: $x"
val a = A()
val y = A::two.get(a)
if (y != 2) return "Fail y: $y"
return "OK"
}
@@ -0,0 +1,22 @@
var result: String by Delegate
object Delegate {
var value = "lol"
fun get(instance: Any?, data: PropertyMetadata): String {
return value
}
fun set(instance: Any?, data: PropertyMetadata, newValue: String) {
value = newValue
}
}
fun box(): String {
val f = ::result
if (f.get() != "lol") return "Fail 1: {$f.get()}"
Delegate.value = "rofl"
if (f.get() != "rofl") return "Fail 2: {$f.get()}"
f.set("OK")
return f.get()
}
@@ -0,0 +1,14 @@
// Name of the getter should be 'getaBcde' according to JavaBean conventions
var aBcde: Int = 239
fun box(): String {
val x = (::aBcde).get()
if (x != 239) return "Fail x: $x"
(::aBcde).set(42)
val y = (::aBcde).get()
if (y != 42) return "Fail y: $y"
return "OK"
}
@@ -0,0 +1,13 @@
import kotlin.reflect.KMemberProperty
class A {
class object {
val ref: KMemberProperty<A, String> = A::foo
}
val foo: String = "OK"
}
fun box(): String {
return A.ref.get(A())
}
@@ -0,0 +1,9 @@
fun box(): String {
class Local {
var result = "Fail"
}
val l = Local()
(Local::result).set(l, "OK")
return (Local::result).get(l)
}
@@ -0,0 +1,9 @@
open class Base {
open val foo = "Base"
}
class Derived : Base() {
override val foo = "OK"
}
fun box() = (Base::foo).get(Derived())
@@ -0,0 +1,29 @@
import kotlin.reflect.IllegalAccessException
import kotlin.reflect.KMemberProperty
import kotlin.reflect.jvm.accessible
class Result {
private val value = "OK"
fun ref(): KMemberProperty<Result, String> = ::value
}
fun box(): String {
val p = Result().ref()
try {
p.get(Result())
return "Fail: private property is accessible by default"
} catch(e: IllegalAccessException) { }
p.accessible = true
val r = p.get(Result())
p.accessible = false
try {
p.get(Result())
return "Fail: setAccessible(false) had no effect"
} catch(e: IllegalAccessException) { }
return r
}
@@ -0,0 +1,31 @@
import kotlin.reflect.IllegalAccessException
import kotlin.reflect.KMutableMemberProperty
import kotlin.reflect.jvm.accessible
class A {
private var value = 0
fun ref(): KMutableMemberProperty<A, Int> = ::value
}
fun box(): String {
val a = A()
val p = a.ref()
try {
p.set(a, 1)
return "Fail: private property is accessible by default"
} catch(e: IllegalAccessException) { }
p.accessible = true
p.set(a, 2)
p.get(a)
p.accessible = false
try {
p.set(a, 3)
return "Fail: setAccessible(false) had no effect"
} catch(e: IllegalAccessException) { }
return "OK"
}
@@ -0,0 +1,29 @@
import kotlin.reflect.IllegalAccessException
import kotlin.reflect.jvm.accessible
class A(param: String) {
protected var v: String = param
fun ref() = ::v
}
fun box(): String {
val a = A(":(")
val f = a.ref()
try {
f.get(a)
return "Fail: protected property getter is accessible by default"
} catch (e: IllegalAccessException) { }
try {
f.set(a, ":D")
return "Fail: protected property setter is accessible by default"
} catch (e: IllegalAccessException) { }
f.accessible = true
f.set(a, ":)")
return if (f[a] != ":)") "Fail: ${f[a]}" else "OK"
}
@@ -0,0 +1,12 @@
import kotlin.reflect.jvm.accessible
class Result {
public val value: String = "OK"
}
fun box(): String {
val p = Result::value
p.accessible = false
// setAccessible(false) should have no effect on the accessibility of a public reflection object
return p.get(Result())
}
@@ -0,0 +1,12 @@
val String.id: String
get() = this
fun box(): String {
val pr = String::id
if (pr["123"] != "123") return "Fail value: ${pr["123"]}"
if (pr.name != "id") return "Fail name: ${pr.name}"
return pr.get("OK")
}
@@ -0,0 +1,9 @@
class A(val x: Int)
fun box(): String {
val p = A::x
if (p.get(A(42)) != 42) return "Fail 1"
if (p.get(A(-1)) != -1) return "Fail 2"
if (p.name != "x") return "Fail 3"
return "OK"
}
@@ -0,0 +1,18 @@
var storage = 0
var Int.foo: Int
get() {
return this + storage
}
set(value) {
storage = this + value
}
fun box(): String {
val pr = Int::foo
if (pr.get(42) != 42) return "Fail 1: ${pr[42]}"
pr.set(200, 39)
if (pr.get(-239) != 0) return "Fail 2: ${pr[-239]}"
if (storage != 239) return "Fail 3: $storage"
return "OK"
}
@@ -0,0 +1,16 @@
data class Box(var value: String)
fun box(): String {
val o = Box("lorem")
val prop = Box::value
if (prop.get(o) != "lorem") return "Fail 1: ${prop[o]}"
prop.set(o, "ipsum")
if (prop.get(o) != "ipsum") return "Fail 2: ${prop[o]}"
if (o.value != "ipsum") return "Fail 3: ${o.value}"
o.value = "dolor"
if (prop.get(o) != "dolor") return "Fail 4: ${prop.get(o)}"
if ("$o" != "Box(value=dolor)") return "Fail 5: $o"
return "OK"
}
@@ -0,0 +1,12 @@
data class Box(val value: String)
var pr = Box("first")
fun box(): String {
val property = ::pr
if (property.get() != Box("first")) return "Fail value: ${property.get()}"
if (property.name != "pr") return "Fail name: ${property.name}"
property.set(Box("second"))
if (property.get().value != "second") return "Fail value 2: ${property.get()}"
return "OK"
}
@@ -0,0 +1,10 @@
data class Box(val value: String)
val foo = Box("lol")
fun box(): String {
val property = ::foo
if (property.get() != Box("lol")) return "Fail value: ${property.get()}"
if (property.name != "foo") return "Fail name: ${property.name}"
return "OK"
}
@@ -0,0 +1,22 @@
import kotlin.reflect.jvm.internal.pcollections.HashPMap
import kotlin.test.*
fun box(): String {
val map = HashPMap.empty<String, Any>()!!
assertEquals(0, map.size())
assertFalse(map.containsKey(""))
assertFalse(map.containsKey("abacaba"))
assertEquals(null, map[""])
assertEquals(null, map["lol"])
// Check that doesn't create a new map
assertEquals(map, map.minus(""))
// Check that all empty()s are equal
val other = HashPMap.empty<String, Any>()!!
assertEquals(map, other)
return "OK"
}
@@ -0,0 +1,47 @@
import java.util.*
import kotlin.reflect.jvm.internal.pcollections.HashPMap
import kotlin.test.*
fun digitSum(number: Int): Int {
var x = number
var ans = 0
while (x != 0) {
ans += x % 10
x /= 10
}
return ans
}
val N = 1000000
fun box(): String {
var map = HashPMap.empty<Int, Any>()!!
for (x in 1..N) {
map = map.plus(x, digitSum(x))!!
}
assertEquals(N, map.size())
// Check in reverse order just in case
for (x in N downTo 1) {
assertTrue(map.containsKey(x), "Not found: $x")
assertEquals(digitSum(x), map[x], "Incorrect value for $x")
}
// Delete in random order
val list = (1..N).toCollection(ArrayList<Int>())
Collections.shuffle(list, Random(42))
for (x in list) {
map = map.minus(x)!!
}
assertEquals(0, map.size())
for (x in 1..N) {
assertFalse(map.containsKey(x), "Incorrectly found: $x")
assertEquals(null, map[x], "Incorrectly found value for $x")
}
return "OK"
}
@@ -0,0 +1,28 @@
import kotlin.reflect.jvm.internal.pcollections.HashPMap
import kotlin.test.*
fun box(): String {
var map = HashPMap.empty<String, Any>()!!
map = map.plus("lol", 42)!!
map = map.plus("lol", 239)!!
assertEquals(1, map.size())
assertTrue(map.containsKey("lol"))
assertFalse(map.containsKey(""))
assertEquals(239, map["lol"])
assertEquals(null, map[""])
map = map.plus("", 0)!!
map = map.plus("", 2.71828)!!
map = map.plus("lol", 42)!!
map = map.plus("", 3.14)!!
assertEquals(2, map.size())
assertTrue(map.containsKey("lol"))
assertTrue(map.containsKey(""))
assertEquals(42, map["lol"])
assertEquals(3.14, map[""])
return "OK"
}
@@ -0,0 +1,28 @@
import kotlin.reflect.jvm.internal.pcollections.HashPMap
import kotlin.test.*
fun box(): String {
var map = HashPMap.empty<String, Any>()!!
map = map.plus("lol", 42)!!
map = map.plus("lol", 42)!!
assertEquals(1, map.size())
assertTrue(map.containsKey("lol"))
assertFalse(map.containsKey(""))
assertEquals(42, map["lol"])
assertEquals(null, map[""])
map = map.plus("", 0)!!
map = map.plus("", 0)!!
map = map.plus("lol", 42)!!
map = map.plus("", 0)!!
assertEquals(2, map.size())
assertTrue(map.containsKey("lol"))
assertTrue(map.containsKey(""))
assertEquals(42, map["lol"])
assertEquals(0, map[""])
return "OK"
}
@@ -0,0 +1,24 @@
import kotlin.reflect.jvm.internal.pcollections.HashPMap
import kotlin.test.*
fun box(): String {
var map = HashPMap.empty<String, Any>()!!
map = map.plus("lol", 42)!!
assertEquals(1, map.size())
assertTrue(map.containsKey("lol"))
assertFalse(map.containsKey(""))
assertEquals(42, map["lol"])
assertEquals(null, map[""])
map = map.plus("", 0)!!
assertEquals(2, map.size())
assertTrue(map.containsKey("lol"))
assertTrue(map.containsKey(""))
assertEquals(42, map["lol"])
assertEquals(0, map[""])
return "OK"
}
@@ -0,0 +1,23 @@
import kotlin.reflect.jvm.internal.pcollections.HashPMap
import kotlin.test.*
fun box(): String {
var map = HashPMap.empty<String, Any>()!!
map = map.plus("lol", 42)!!
map = map.minus("lol")!!
assertEquals(0, map.size())
assertFalse(map.containsKey("lol"))
assertEquals(null, map["lol"])
map = map.plus("abc", "a")!!
map = map.minus("abc")!!
map = map.plus("abc", "d")!!
assertEquals(1, map.size())
assertTrue(map.containsKey("abc"))
assertEquals("d", map["abc"])
return "OK"
}
@@ -0,0 +1,27 @@
import kotlin.reflect.jvm.*
import kotlin.test.assertEquals
class K(var value: Long)
var K.ext: Double
get() = value.toDouble()
set(value) {
this.value = value.toLong()
}
fun box(): String {
val p = K::ext
val getter = p.javaGetter!!
val setter = p.javaSetter!!
assertEquals(getter, Class.forName("_DefaultPackage").getMethod("getExt", javaClass<K>()))
assertEquals(setter, Class.forName("_DefaultPackage").getMethod("setExt", javaClass<K>(), javaClass<Double>()))
val k = K(42L)
assert(getter.invoke(null, k) == 42.0, "Fail k getter")
setter.invoke(null, k, -239.0)
assert(getter.invoke(null, k) == -239.0, "Fail k setter")
return "OK"
}
@@ -0,0 +1,23 @@
import kotlin.reflect.jvm.*
import kotlin.test.assertEquals
class K(var value: Long)
fun box(): String {
val p = K::value
assert(p.javaField != null, "Fail p field")
val getter = p.javaGetter!!
val setter = p.javaSetter!!
assertEquals(getter, javaClass<K>().getMethod("getValue"))
assertEquals(setter, javaClass<K>().getMethod("setValue", javaClass<Long>()))
val k = K(42L)
assert(getter.invoke(k) == 42L, "Fail k getter")
setter.invoke(k, -239L)
assert(getter.invoke(k) == -239L, "Fail k setter")
return "OK"
}
@@ -0,0 +1,13 @@
package test
import kotlin.reflect.jvm.*
import kotlin.test.*
fun box(): String {
val facadeJClass = Class.forName("test.TestPackage") as Class<Any>
assertEquals(facadeJClass, facadeJClass.kotlinPackage.javaFacade)
assertEquals(facadeJClass, facadeJClass.kotlin.java)
return "OK"
}
@@ -0,0 +1,23 @@
import kotlin.reflect.jvm.*
import kotlin.test.assertEquals
var topLevel = "123"
fun box(): String {
val p = ::topLevel
// TODO: uncomment when fields are loaded from package parts
// assert(p.javaField != null, "Fail p field")
val getter = p.javaGetter!!
val setter = p.javaSetter!!
assertEquals(getter, Class.forName("_DefaultPackage").getMethod("getTopLevel"))
assertEquals(setter, Class.forName("_DefaultPackage").getMethod("setTopLevel", javaClass<String>()))
assert(getter.invoke(null) == "123", "Fail k getter")
setter.invoke(null, "456")
assert(getter.invoke(null) == "456", "Fail k setter")
return "OK"
}
@@ -0,0 +1,14 @@
import kotlin.test.*
import kotlin.reflect.jvm.kotlin
class A
fun box(): String {
val p = javaClass<A>().kotlin
if ("$p" != "class A") return "Fail: $p"
val s = javaClass<String>().kotlin
if ("$s" != "class java.lang.String") return "Fail: $s"
return "OK"
}
@@ -0,0 +1,8 @@
import kotlin.test.*
import kotlin.reflect.jvm.kotlinPackage
fun box(): String {
val p = Class.forName("_DefaultPackage").kotlinPackage
if ("$p" != "package <default>") return "Fail: $p"
return "OK"
}
@@ -0,0 +1,29 @@
import kotlin.test.*
val top = 42
var top2 = -23
val Int.intExt: Int get() = this
val Char.charExt: Int get() = this.toInt()
class A(var mem: String)
class B(var mem: String)
fun checkEqual(x: Any, y: Any) {
assertEquals(x, y)
assertEquals(x.hashCode(), y.hashCode(), "Elements are equal but their hash codes are not: ${x.hashCode()} != ${y.hashCode()}")
}
fun box(): String {
checkEqual(::top, ::top)
checkEqual(::top2, ::top2)
checkEqual(Int::intExt, Int::intExt)
checkEqual(A::mem, A::mem)
assertFalse(::top == ::top2)
assertFalse(Int::intExt == Char::charExt)
assertFalse(A::mem == B::mem)
return "OK"
}
@@ -0,0 +1,66 @@
import kotlin.reflect.KExtensionProperty
import kotlin.test.assertEquals
fun check(expected: String, p: KExtensionProperty<*, *>) {
var s = p.toString()
// Strip "val" or "var"
s = s.substring(4)
// Strip property name, leave only receiver class
s = s.substring(0, s.lastIndexOf('.'))
assertEquals(expected, s)
}
val Boolean.x: Any get() = this
val Char.x: Any get() = this
val Byte.x: Any get() = this
val Short.x: Any get() = this
val Int.x: Any get() = this
val Float.x: Any get() = this
val Long.x: Any get() = this
val Double.x: Any get() = this
val BooleanArray.x: Any get() = this
val CharArray.x: Any get() = this
val ByteArray.x: Any get() = this
val ShortArray.x: Any get() = this
val IntArray.x: Any get() = this
val FloatArray.x: Any get() = this
val LongArray.x: Any get() = this
val DoubleArray.x: Any get() = this
val Array<Int>.a1: Any get() = this
val Array<Any>.a2: Any get() = this
val Array<Array<String>>.a3: Any get() = this
val Array<BooleanArray>.a4: Any get() = this
val Map<String, Runnable>.m: Any get() = this
fun box(): String {
check("kotlin.Boolean", Boolean::x)
check("kotlin.Char", Char::x)
check("kotlin.Byte", Byte::x)
check("kotlin.Short", Short::x)
check("kotlin.Int", Int::x)
check("kotlin.Float", Float::x)
check("kotlin.Long", Long::x)
check("kotlin.Double", Double::x)
check("kotlin.BooleanArray", BooleanArray::x)
check("kotlin.CharArray", CharArray::x)
check("kotlin.ByteArray", ByteArray::x)
check("kotlin.ShortArray", ShortArray::x)
check("kotlin.IntArray", IntArray::x)
check("kotlin.FloatArray", FloatArray::x)
check("kotlin.LongArray", LongArray::x)
check("kotlin.DoubleArray", DoubleArray::x)
check("kotlin.Array<java.lang.Integer>", Array<Int>::a1)
check("kotlin.Array<java.lang.Object>", Array<Any>::a2)
check("kotlin.Array<kotlin.Array<java.lang.String>>", Array<Array<String>>::a3)
check("kotlin.Array<kotlin.BooleanArray>", Array<BooleanArray>::a4)
check("java.util.Map", Map<String, Runnable>::m)
return "OK"
}
@@ -0,0 +1,8 @@
import kotlin.test.*
import kotlin.reflect.jvm.kotlinPackage
fun box(): String {
val p = javaClass<String>().kotlinPackage
if ("$p" != "package java.lang.String") return "Fail: $p"
return "OK"
}
@@ -0,0 +1,10 @@
package test.foo.bar
import kotlin.test.*
import kotlin.reflect.jvm.kotlinPackage
fun box(): String {
val p = Class.forName("test.foo.bar.BarPackage").kotlinPackage
if ("$p" != "package test.foo.bar") return "Fail: $p"
return "OK"
}
@@ -0,0 +1,26 @@
package test
import kotlin.test.assertEquals
val top = 42
var top2 = -23
val String.ext: Int get() = 0
var IntRange?.ext2: Int get() = 0; set(value) {}
class A(val mem: String)
class B(var mem: String)
fun assertToString(s: String, x: Any) {
assertEquals(s, x.toString())
}
fun box(): String {
assertToString("val top", ::top)
assertToString("var top2", ::top2)
assertToString("val java.lang.String.ext", String::ext)
assertToString("var kotlin.IntRange.ext2", IntRange::ext2)
assertToString("val test.A.mem", A::mem)
assertToString("var test.B.mem", B::mem)
return "OK"
}
@@ -18,4 +18,4 @@ class B {
} }
// 0 INVOKEVIRTUAL // 0 INVOKEVIRTUAL
// 4 INVOKESPECIAL // 2 INVOKESPECIAL [AB]\.
@@ -13,4 +13,4 @@ fun box(): String {
} }
// 0 INVOKEVIRTUAL // 0 INVOKEVIRTUAL
// 3 INVOKESPECIAL // 2 INVOKESPECIAL B\.foo
@@ -3,8 +3,10 @@ import java.lang.annotation.RetentionPolicy
import a.* import a.*
Ann(i, s, f, d, l, b, bool, c, str) Ann(i, s, f, d, l, b, bool, c, str)
class MyClass1
Ann(i2, s2, f2, d2, l2, b2, bool2, c2, str2) Ann(i2, s2, f2, d2, l2, b2, bool2, c2, str2)
class MyClass class MyClass2
Retention(RetentionPolicy.RUNTIME) Retention(RetentionPolicy.RUNTIME)
annotation class Ann( annotation class Ann(
@@ -20,7 +22,7 @@ annotation class Ann(
) )
fun main(args: Array<String>) { fun main(args: Array<String>) {
MyClass() // Trigger annotation loading
(MyClass1() as java.lang.Object).getClass().getAnnotations()
(MyClass2() as java.lang.Object).getClass().getAnnotations()
} }
@@ -0,0 +1,6 @@
package a
public var topLevel: Int = 42
public val String.extension: Long
get() = length.toLong()
@@ -0,0 +1,14 @@
import a.*
fun main(args: Array<String>) {
val f = ::topLevel
val x1 = f.get()
if (x1 != 42) throw AssertionError("Fail x1: $x1")
f.set(239)
val x2 = f.get()
if (x2 != 239) throw AssertionError("Fail x2: $x2")
val g = String::extension
val y1 = g.get("abcde")
if (y1 != 5L) throw AssertionError("Fail y1: $y1")
}
@@ -0,0 +1,19 @@
// FILE: Super.java
public class Super {
public boolean foo;
public boolean bar;
public void setFoo(boolean foo) {
this.foo = foo;
}
}
// FILE: b.kt
public class Sub: Super() {
}
fun main(args: Array<String>) {
val x = Sub()
x.foo = true
x.bar = true
}
@@ -1,3 +1,5 @@
import kotlin.reflect.KFunction0
class A { class A {
fun main() { fun main() {
val x = ::A val x = ::A
@@ -1,3 +1,5 @@
import kotlin.reflect.KFunction0
class A class A
class B class B
@@ -1,3 +1,5 @@
import kotlin.reflect.KFunction0
class A class A
class B { class B {
@@ -1,3 +1,5 @@
import kotlin.reflect.KFunction0
class A class A
fun main() { fun main() {
@@ -12,6 +12,8 @@ class A {
package other package other
import kotlin.reflect.*
import first.A import first.A
fun main() { fun main() {
@@ -12,6 +12,8 @@ fun A.baz() {}
package other package other
import kotlin.reflect.KExtensionFunction0
import first.A import first.A
import first.foo import first.foo
@@ -10,6 +10,8 @@ fun baz() = "OK"
package other package other
import kotlin.reflect.*
import first.foo import first.foo
import first.bar import first.bar
import first.baz import first.baz
@@ -1,3 +1,5 @@
import kotlin.reflect.*
class A { class A {
fun main() { fun main() {
val x = ::foo val x = ::foo
@@ -1,3 +1,5 @@
import kotlin.reflect.*
class A class A
fun A.main() { fun A.main() {
@@ -1,3 +1,5 @@
import kotlin.reflect.*
class B class B
class A { class A {
@@ -1,3 +1,5 @@
import kotlin.reflect.*
class A class A
fun A.foo() {} fun A.foo() {}
@@ -1,3 +1,5 @@
import kotlin.reflect.*
class A { class A {
fun foo() {} fun foo() {}
} }
@@ -1,3 +1,5 @@
import kotlin.reflect.KMemberFunction0
class A<T>(val t: T) { class A<T>(val t: T) {
fun foo(): T = t fun foo(): T = t
} }
@@ -1,3 +1,5 @@
import kotlin.reflect.KMemberFunction0
class A { class A {
inner class Inner inner class Inner
@@ -1,3 +1,5 @@
import kotlin.reflect.KMemberFunction0
class A { class A {
inner class Inner inner class Inner
} }
@@ -1,3 +1,5 @@
import kotlin.reflect.KMemberFunction0
class A { class A {
inner class Inner inner class Inner
} }
@@ -1,3 +1,5 @@
import kotlin.reflect.KFunction0
fun main() { fun main() {
class A class A
@@ -1,3 +1,5 @@
import kotlin.reflect.KFunction0
fun main() { fun main() {
class A class A

Some files were not shown because too many files have changed in this diff Show More