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() {
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("boxInline"); // MultiFileTest not supported yet
excludedFiles.add("reflection");
excludedFiles.add("kt3238.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("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("kt1213.kt"); // Commented
@@ -154,6 +154,11 @@ public class AsmUtil {
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) {
return (functionDescriptor.getModality() == Modality.ABSTRACT
|| isInterface(functionDescriptor.getContainingDeclaration()))
@@ -785,4 +790,12 @@ public class AsmUtil {
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.java.AsmTypeConstants;
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.jvmSignature.JvmMethodSignature;
import org.jetbrains.jet.lang.resolve.name.Name;
@@ -68,7 +70,6 @@ import org.jetbrains.org.objectweb.asm.commons.Method;
import java.util.*;
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.binding.CodegenBinding.*;
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.java.AsmTypeConstants.*;
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.org.objectweb.asm.Opcodes.*;
@@ -2410,19 +2412,90 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
@Override
public StackValue visitCallableReferenceExpression(@NotNull JetCallableReferenceExpression expression, StackValue data) {
// TODO: properties
ResolvedCall<?> resolvedCall = resolvedCall(expression.getCallableReference());
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 =
new CallableReferenceGenerationStrategy(state, functionDescriptor, resolvedCall(expression.getCallableReference()));
ClosureCodegen closureCodegen = new ClosureCodegen(state, expression, functionDescriptor, null, context,
KotlinSyntheticClass.Kind.CALLABLE_REFERENCE_WRAPPER,
this, strategy, getParentCodegen());
VariableDescriptor variableDescriptor = bindingContext.get(VARIABLE, expression);
if (variableDescriptor != null) {
VariableDescriptor descriptor = (VariableDescriptor) resolvedCall.getResultingDescriptor();
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> {
@@ -22,6 +22,7 @@ import org.jetbrains.jet.OutputFile;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.List;
import java.util.jar.Manifest;
public class GeneratedClassLoader extends URLClassLoader {
private ClassFileFactory state;
@@ -39,6 +40,13 @@ public class GeneratedClassLoader extends URLClassLoader {
OutputFile outputFile = state.get(classFilePath);
if (outputFile != null) {
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);
}
@@ -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.lang.resolve.BindingContextUtils.descriptorToDeclaration;
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.OBJECT_TYPE;
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.diagnostics.DiagnosticsPackage.DelegationToTraitImpl;
import static org.jetbrains.jet.lang.resolve.java.diagnostics.DiagnosticsPackage.OtherOrigin;
@@ -209,6 +208,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
writeInnerClasses();
AnnotationCodegen.forClass(v.getVisitor(), typeMapper).genAnnotations(descriptor, null);
generateReflectionObjectFieldIfNeeded();
}
@Override
@@ -429,7 +430,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
@Override
protected void generateSyntheticParts() {
generateDelegatedPropertyMetadataArray();
generatePropertyMetadataArrayFieldIfNeeded(classAsmType);
generateFieldForSingleton();
@@ -463,11 +464,19 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
generateToArray();
genClosureFields(context.closure, v, state.getTypeMapper());
genClosureFields(context.closure, v, typeMapper);
}
private void generateDelegatedPropertyMetadataArray() {
generatePropertyMetadataArrayFieldIfNeeded(classAsmType);
private void generateReflectionObjectFieldIfNeeded() {
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() {
@@ -43,6 +43,7 @@ import org.jetbrains.jet.storage.NotNullLazyValue;
import org.jetbrains.org.objectweb.asm.MethodVisitor;
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.ArrayList;
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.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.resolve.BindingContext.VARIABLE;
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.*;
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;
}
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) {
List<JetProperty> delegatedProperties = new ArrayList<JetProperty>();
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.MethodVisitor;
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 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.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.diagnostics.DiagnosticsPackage.*;
import static org.jetbrains.jet.lang.resolve.java.diagnostics.JvmDeclarationOrigin.NO_ORIGIN;
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
public class PackageCodegen {
private final GenerationState state;
private final ClassBuilderOnDemand v;
private final GenerationState state;
private final Collection<JetFile> files;
private final Type packageClassType;
private final PackageFragmentDescriptor packageFragment;
private final PackageFragmentDescriptor compiledPackageFragment;
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.files = files;
this.packageFragment = getOnlyPackageFragment(fqName);
this.packageClassType = AsmUtil.asmTypeByFqNameWithoutInnerClasses(getPackageClassFqName(fqName));
this.compiledPackageFragment = getCompiledPackageFragment(fqName);
this.previouslyCompiledCallables = filterDeserializedCallables(compiledPackageFragment);
@@ -88,14 +96,13 @@ public class PackageCodegen {
Collection<JetFile> files = PackageCodegen.this.files;
JetFile sourceFile = getRepresentativePackageFile(files);
String className = AsmUtil.internalNameByFqNameWithoutInnerClasses(getPackageClassFqName(fqName));
ClassBuilder v = PackageCodegen.this.state.getFactory()
.newVisitor(
PackageFacade(packageFragment == null ? compiledPackageFragment : packageFragment),
Type.getObjectType(className), PackagePartClassUtils.getPackageFilesWithCallables(files));
ClassBuilder v = PackageCodegen.this.state.getFactory().newVisitor(
PackageFacade(packageFragment == null ? compiledPackageFragment : packageFragment),
packageClassType, PackagePartClassUtils.getPackageFilesWithCallables(files)
);
v.defineClass(sourceFile, V1_6,
ACC_PUBLIC | ACC_FINAL,
className,
packageClassType.getInternalName(),
null,
"java/lang/Object",
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())) {
generateCallableMemberTasks.get(member).run();
generateDelegationsToPreviouslyCompiled(tasks);
for (CallableMemberDescriptor member : Ordering.from(MemberComparator.INSTANCE).sortedCopy(tasks.keySet())) {
tasks.get(member).run();
}
bindings.add(v.getSerializationBindings());
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) {
if (state.getClassBuilderMode() != ClassBuilderMode.FULL) {
return;
@@ -266,6 +266,9 @@ public class InlineCodegenUtil {
}
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 org.jetbrains.annotations.NotNull;
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.StackValue;
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.calls.model.ResolvedCall;
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 static org.jetbrains.jet.codegen.AsmUtil.boxType;
import static org.jetbrains.jet.codegen.AsmUtil.isPrimitive;
import static org.jetbrains.jet.codegen.AsmUtil.putJavaLangClassInstance;
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.getType;
public class JavaClassFunction extends IntrinsicMethod {
@@ -51,13 +50,7 @@ public class JavaClassFunction extends IntrinsicMethod {
assert resolvedCall != null;
JetType returnType = resolvedCall.getResultingDescriptor().getReturnType();
assert returnType != null;
Type type = 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);
}
putJavaLangClassInstance(v, codegen.getState().getTypeMapper().mapType(returnType.getArguments().get(0).getType()));
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.cli.js.K2JSCompiler 4096 %_PROFILE_PRELOADER% %*
)
exit %ERRORLEVEL%
exit /b %ERRORLEVEL%
goto end
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.cli.jvm.K2JVMCompiler 4096 %_PROFILE_PRELOADER% %*
)
exit %ERRORLEVEL%
exit /b %ERRORLEVEL%
goto end
rem ##########################################################################
@@ -57,8 +57,7 @@ public enum AnalyzerFacadeForJVM implements AnalyzerFacade {
new ImportPath("java.lang.*"),
new ImportPath("kotlin.*"),
new ImportPath("kotlin.jvm.*"),
new ImportPath("kotlin.io.*"),
new ImportPath("kotlin.reflect.*")
new ImportPath("kotlin.io.*")
);
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_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");
@NotNull
private static Type reflectInternal(@NotNull String className) {
return Type.getObjectType("kotlin/reflect/jvm/internal/" + className);
}
@NotNull
public static Type getType(@NotNull Class<?> javaClass) {
Type type = TYPES_MAP.get(javaClass);
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.Name
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.descriptors.annotations.Annotations
import org.jetbrains.jet.lang.types.JetType
import org.jetbrains.jet.lang.types.JetTypeImpl
import org.jetbrains.jet.lang.types.ErrorUtils
import java.util.ArrayList
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())
}
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 getKExtensionFunction(n: Int): ClassDescriptor = find("KExtensionFunction$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(
annotations: Annotations,
receiverType: JetType?,
@@ -51,26 +63,47 @@ public class ReflectionTypes(private val module: ModuleDescriptor) {
returnType: JetType,
extensionFunction: Boolean
): JetType {
val arguments = KotlinBuiltIns.getFunctionTypeArgumentProjections(receiverType, parameterTypes, returnType)
val classDescriptor = correspondingKFunctionClass(receiverType, extensionFunction, parameterTypes.size)
val arity = parameterTypes.size()
val classDescriptor =
if (extensionFunction) getKExtensionFunction(arity)
else if (receiverType != null) getKMemberFunction(arity)
else getKFunction(arity)
return if (ErrorUtils.isError(classDescriptor))
classDescriptor.getDefaultType()
else
JetTypeImpl(annotations, classDescriptor.getTypeConstructor(), false, arguments, classDescriptor.getMemberScope(arguments))
if (ErrorUtils.isError(classDescriptor)) {
return classDescriptor.getDefaultType()
}
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?,
extensionFunction: Boolean,
numberOfParameters: Int
): ClassDescriptor {
if (extensionFunction) {
return getKExtensionFunction(numberOfParameters)
returnType: JetType,
extensionProperty: Boolean,
mutable: Boolean
): JetType {
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) {
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.annotations.Annotations;
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.Errors;
import org.jetbrains.jet.lang.evaluate.ConstantExpressionEvaluator;
@@ -472,7 +473,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
JetSimpleNameExpression reference = expression.getCallableReference();
boolean[] result = new boolean[1];
FunctionDescriptor descriptor = resolveCallableReferenceTarget(lhsType, context, expression, result);
CallableDescriptor descriptor = resolveCallableReferenceTarget(lhsType, context, expression, result);
if (!result[0]) {
context.trace.report(UNRESOLVED_REFERENCE.on(reference, reference));
@@ -481,8 +482,8 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
ReceiverParameterDescriptor receiverParameter = descriptor.getReceiverParameter();
ReceiverParameterDescriptor expectedThisObject = descriptor.getExpectedThisObject();
if (receiverParameter != null && expectedThisObject != null) {
context.trace.report(EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED.on(reference, descriptor));
if (receiverParameter != null && expectedThisObject != null && descriptor instanceof CallableMemberDescriptor) {
context.trace.report(EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED.on(reference, (CallableMemberDescriptor) descriptor));
return null;
}
@@ -493,14 +494,37 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
else if (expectedThisObject != null) {
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
JetType type = components.reflectionTypes.getKFunctionType(
Annotations.EMPTY,
receiverType,
getValueParametersTypes(descriptor.getValueParameters()),
descriptor.getReturnType(),
receiverParameter != null
isExtension
);
if (type.isError()) {
@@ -511,7 +535,8 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
AnonymousFunctionDescriptor functionDescriptor = new AnonymousFunctionDescriptor(
context.scope.getContainingDeclaration(),
Annotations.EMPTY,
CallableMemberDescriptor.Kind.DECLARATION);
CallableMemberDescriptor.Kind.DECLARATION
);
FunctionDescriptorUtil.initializeFromFunctionType(functionDescriptor, type, null, Modality.FINAL, Visibilities.PUBLIC);
@@ -521,7 +546,32 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
}
@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,
@NotNull ExpressionTypingContext context,
@NotNull JetCallableReferenceExpression expression,
@@ -542,7 +592,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
ReceiverValue receiver = new TransientReceiver(lhsType);
TemporaryTraceAndCache temporaryWithReceiver = TemporaryTraceAndCache.create(
context, "trace to resolve callable reference with receiver", reference);
FunctionDescriptor descriptor = resolveCallableNotCheckingArguments(
CallableDescriptor descriptor = resolveCallableNotCheckingArguments(
reference, receiver, context.replaceTraceAndCache(temporaryWithReceiver), result);
if (result[0]) {
temporaryWithReceiver.commit();
@@ -552,7 +602,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
JetScope staticScope = getStaticNestedClassesScope((ClassDescriptor) classifier);
TemporaryTraceAndCache temporaryForStatic = TemporaryTraceAndCache.create(
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);
if (result[0]) {
temporaryForStatic.commit();
@@ -563,7 +613,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
}
@Nullable
private FunctionDescriptor resolveCallableNotCheckingArguments(
private CallableDescriptor resolveCallableNotCheckingArguments(
@NotNull JetSimpleNameExpression reference,
@NotNull ReceiverValue receiver,
@NotNull ExpressionTypingContext context,
@@ -571,22 +621,41 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
) {
Call call = CallMaker.makeCall(reference, receiver, null, reference, ThrowingList.<ValueArgument>instance());
TemporaryBindingTrace trace = TemporaryBindingTrace.create(context.trace, "trace to resolve as function", reference);
ExpressionTypingContext contextForResolve = context.replaceBindingTrace(trace).replaceExpectedType(NO_EXPECTED_TYPE);
TemporaryTraceAndCache funTrace = TemporaryTraceAndCache.create(context, "trace to resolve callable reference as function",
reference);
ResolvedCall<FunctionDescriptor> function = components.expressionTypingServices.getCallExpressionResolver()
.getResolvedCallForFunction(call, reference, contextForResolve, CheckValueArgumentsMode.DISABLED, result);
if (!result[0]) return null;
.getResolvedCallForFunction(call, reference, context.replaceTraceAndCache(funTrace).replaceExpectedType(NO_EXPECTED_TYPE),
CheckValueArgumentsMode.DISABLED, result);
if (result[0]) {
funTrace.commit();
if (function instanceof VariableAsFunctionResolvedCall) {
// TODO: KProperty
context.trace.report(UNSUPPORTED.on(reference, "References to variables aren't supported yet"));
context.trace.report(UNRESOLVED_REFERENCE.on(reference, reference));
return null;
if (function instanceof VariableAsFunctionResolvedCall) {
context.trace.report(UNSUPPORTED.on(reference, "References to variables aren't supported yet"));
return null;
}
return function != null ? function.getResultingDescriptor() : null;
}
trace.commit();
return function != null ? function.getResultingDescriptor() : null;
TemporaryTraceAndCache varTrace = TemporaryTraceAndCache.create(context, "trace to resolve callable reference as variable",
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
@@ -20,15 +20,14 @@ import org.junit.Test;
import java.io.File;
import static junit.framework.Assert.*;
import static org.junit.Assert.assertEquals;
public class CompilerSmokeTest extends KotlinIntegrationTestBase {
@Test
public void compileAndRunHelloApp() throws Exception {
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");
}
@@ -36,7 +35,7 @@ public class CompilerSmokeTest extends KotlinIntegrationTestBase {
public void compileAndRunHelloAppFQMain() throws Exception {
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");
}
@@ -44,7 +43,7 @@ public class CompilerSmokeTest extends KotlinIntegrationTestBase {
public void compileAndRunHelloAppVarargMain() throws Exception {
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");
}
@@ -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
// 4 INVOKESPECIAL
// 2 INVOKESPECIAL [AB]\.
@@ -13,4 +13,4 @@ fun box(): String {
}
// 0 INVOKEVIRTUAL
// 3 INVOKESPECIAL
// 2 INVOKESPECIAL B\.foo
@@ -3,8 +3,10 @@ import java.lang.annotation.RetentionPolicy
import a.*
Ann(i, s, f, d, l, b, bool, c, str)
class MyClass1
Ann(i2, s2, f2, d2, l2, b2, bool2, c2, str2)
class MyClass
class MyClass2
Retention(RetentionPolicy.RUNTIME)
annotation class Ann(
@@ -20,7 +22,7 @@ annotation class Ann(
)
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 {
fun main() {
val x = ::A
@@ -1,3 +1,5 @@
import kotlin.reflect.KFunction0
class A
class B
@@ -1,3 +1,5 @@
import kotlin.reflect.KFunction0
class A
class B {
@@ -1,3 +1,5 @@
import kotlin.reflect.KFunction0
class A
fun main() {
@@ -12,6 +12,8 @@ class A {
package other
import kotlin.reflect.*
import first.A
fun main() {
@@ -12,6 +12,8 @@ fun A.baz() {}
package other
import kotlin.reflect.KExtensionFunction0
import first.A
import first.foo
@@ -10,6 +10,8 @@ fun baz() = "OK"
package other
import kotlin.reflect.*
import first.foo
import first.bar
import first.baz
@@ -1,3 +1,5 @@
import kotlin.reflect.*
class A {
fun main() {
val x = ::foo
@@ -1,3 +1,5 @@
import kotlin.reflect.*
class A
fun A.main() {
@@ -1,3 +1,5 @@
import kotlin.reflect.*
class B
class A {
@@ -1,3 +1,5 @@
import kotlin.reflect.*
class A
fun A.foo() {}
@@ -1,3 +1,5 @@
import kotlin.reflect.*
class A {
fun foo() {}
}
@@ -1,3 +1,5 @@
import kotlin.reflect.KMemberFunction0
class A<T>(val t: T) {
fun foo(): T = t
}
@@ -1,3 +1,5 @@
import kotlin.reflect.KMemberFunction0
class A {
inner class Inner
@@ -1,3 +1,5 @@
import kotlin.reflect.KMemberFunction0
class A {
inner class Inner
}
@@ -1,3 +1,5 @@
import kotlin.reflect.KMemberFunction0
class A {
inner class Inner
}
@@ -1,3 +1,5 @@
import kotlin.reflect.KFunction0
fun main() {
class A
@@ -1,3 +1,5 @@
import kotlin.reflect.KFunction0
fun main() {
class A

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