Codegen for callable reference expressions

#KT-1183 In Progress
This commit is contained in:
Alexander Udalov
2013-04-15 19:47:10 +04:00
parent 1eeaaad05d
commit 054e5fb5e7
46 changed files with 877 additions and 7 deletions
@@ -36,7 +36,7 @@ import org.jetbrains.jet.codegen.binding.CodegenBinding;
import org.jetbrains.jet.codegen.binding.MutableClosure;
import org.jetbrains.jet.codegen.context.*;
import org.jetbrains.jet.codegen.intrinsics.IntrinsicMethod;
import org.jetbrains.jet.codegen.signature.JvmPropertyAccessorSignature;
import org.jetbrains.jet.codegen.signature.JvmMethodSignature;
import org.jetbrains.jet.codegen.state.GenerationState;
import org.jetbrains.jet.codegen.state.JetTypeMapper;
import org.jetbrains.jet.codegen.state.JetTypeMapperMode;
@@ -67,12 +67,16 @@ import java.util.*;
import static org.jetbrains.asm4.Opcodes.*;
import static org.jetbrains.jet.codegen.AsmUtil.*;
import static org.jetbrains.jet.codegen.CodegenUtil.*;
import static org.jetbrains.jet.codegen.FunctionTypesUtil.functionTypeToImpl;
import static org.jetbrains.jet.codegen.FunctionTypesUtil.getFunctionImplClassName;
import static org.jetbrains.jet.codegen.binding.CodegenBinding.*;
import static org.jetbrains.jet.lang.resolve.BindingContext.*;
import static org.jetbrains.jet.lang.resolve.BindingContextUtils.descriptorToDeclaration;
import static org.jetbrains.jet.lang.resolve.BindingContextUtils.getNotNull;
import static org.jetbrains.jet.lang.resolve.calls.tasks.ExplicitReceiverKind.RECEIVER_ARGUMENT;
import static org.jetbrains.jet.lang.resolve.calls.tasks.ExplicitReceiverKind.THIS_OBJECT;
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.*;
import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue.NO_RECEIVER;
public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implements LocalLookup {
@@ -2320,6 +2324,164 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
return lookupLocalIndex(declarationDescriptor);
}
@Override
public StackValue visitCallableReferenceExpression(JetCallableReferenceExpression expression, StackValue data) {
// TODO: properties
final FunctionDescriptor functionDescriptor = bindingContext.get(CALLABLE_REFERENCE, expression);
assert functionDescriptor != null : "Callable reference is not resolved to descriptor: " + expression.getText();
final ResolvedCall<? extends CallableDescriptor> resolvedCall = bindingContext.get(RESOLVED_CALL, expression.getCallableReference());
assert resolvedCall != null : "Callable reference is not resolved: " + functionDescriptor + " " + expression.getText();
JetType kFunctionType = bindingContext.get(EXPRESSION_TYPE, expression);
assert kFunctionType != null : "Callable reference is not type checked: " + expression.getText();
ClassDescriptor kFunctionImpl = functionTypeToImpl(kFunctionType);
assert kFunctionImpl != null : "Impl type is not found for the function type: " + kFunctionType;
JvmClassName closureSuperClass = JvmClassName.byType(typeMapper.mapType(kFunctionImpl));
ClosureCodegen closureCodegen = new ClosureCodegen(state, expression, functionDescriptor, null, closureSuperClass, context, this,
new FunctionGenerationStrategy() {
@Override
public void generateBody(
@NotNull MethodVisitor mv,
@NotNull JvmMethodSignature signature,
@NotNull MethodContext context,
@NotNull FrameMap frameMap
) {
/*
Here we need to put the arguments from our locals to the stack and invoke the referenced method. Since invokation
of methods is highly dependent on expressions, we create a fake call expression. Then we create a new instance of
ExpressionCodegen and, in order for it to generate code correctly, we save to its 'tempVariables' field every
argument of our fake expression, pointing it to the corresponding index in our locals. This way generation of
every argument boils down to calling LOAD with the corresponding index
*/
FunctionDescriptor referencedFunction = (FunctionDescriptor) resolvedCall.getResultingDescriptor();
JetType returnJetType = referencedFunction.getReturnType();
assert returnJetType != null : "Return type can't be null: " + referencedFunction;
Type returnType = typeMapper.mapReturnType(returnJetType);
JetCallExpression fakeExpression = constructFakeFunctionCall(referencedFunction);
final List<? extends ValueArgument> fakeArguments = fakeExpression.getValueArguments();
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, returnType, context, state);
final ReceiverValue receiverValue = computeAndSaveReceiver(signature, codegen);
computeAndSaveArguments(frameMap, fakeArguments, codegen);
ResolvedCall<CallableDescriptor> fakeResolvedCall = new DelegatingResolvedCall<CallableDescriptor>(resolvedCall) {
@NotNull
@Override
public ReceiverValue getReceiverArgument() {
return resolvedCall.getExplicitReceiverKind() == RECEIVER_ARGUMENT ? receiverValue : NO_RECEIVER;
}
@NotNull
@Override
public ReceiverValue getThisObject() {
return resolvedCall.getExplicitReceiverKind() == THIS_OBJECT ? receiverValue : NO_RECEIVER;
}
@NotNull
@Override
public List<ResolvedValueArgument> getValueArgumentsByIndex() {
List<ResolvedValueArgument> result = new ArrayList<ResolvedValueArgument>(fakeArguments.size());
for (ValueArgument argument : fakeArguments) {
result.add(new ExpressionValueArgument(argument));
}
return result;
}
};
StackValue result;
if (referencedFunction instanceof ConstructorDescriptor) {
if (returnType.getSort() == Type.ARRAY) {
codegen.generateNewArray(fakeExpression, returnJetType);
result = StackValue.onStack(returnType);
}
else {
result = codegen.generateConstructorCall(fakeResolvedCall, StackValue.none(), returnType);
}
}
else {
Call call = CallMaker.makeCall(fakeExpression, NO_RECEIVER, null, fakeExpression, fakeArguments);
result = codegen.invokeFunction(call, StackValue.none(), fakeResolvedCall);
}
InstructionAdapter v = new InstructionAdapter(mv);
result.put(returnType, v);
v.areturn(returnType);
}
@NotNull
private JetCallExpression constructFakeFunctionCall(@NotNull CallableDescriptor referencedFunction) {
StringBuilder fakeFunctionCall = new StringBuilder("callableReferenceFakeCall(");
for (Iterator<ValueParameterDescriptor> iterator = referencedFunction.getValueParameters().iterator();
iterator.hasNext(); ) {
ValueParameterDescriptor descriptor = iterator.next();
fakeFunctionCall.append("p").append(descriptor.getIndex());
if (iterator.hasNext()) {
fakeFunctionCall.append(", ");
}
}
fakeFunctionCall.append(")");
return (JetCallExpression) JetPsiFactory.createExpression(state.getProject(), fakeFunctionCall.toString());
}
private void computeAndSaveArguments(
@NotNull FrameMap frameMap,
@NotNull List<? extends ValueArgument> fakeArguments,
@NotNull ExpressionCodegen codegen
) {
for (ValueParameterDescriptor parameter : functionDescriptor.getValueParameters()) {
ValueArgument fakeArgument = fakeArguments.get(parameter.getIndex());
Type type = typeMapper.mapType(parameter);
int localIndex = frameMap.getIndex(parameter);
codegen.tempVariables.put(fakeArgument.getArgumentExpression(), StackValue.local(localIndex, type));
}
}
@NotNull
private ReceiverValue computeAndSaveReceiver(
@NotNull JvmMethodSignature signature,
@NotNull ExpressionCodegen codegen
) {
CallableDescriptor referencedFunction = resolvedCall.getCandidateDescriptor();
ReceiverParameterDescriptor receiverParameter = referencedFunction.getReceiverParameter();
ReceiverParameterDescriptor expectedThisObject = referencedFunction.getExpectedThisObject();
assert receiverParameter == null || expectedThisObject == null :
"Extensions in classes can't be referenced via callable reference expressions: " + referencedFunction;
ReceiverParameterDescriptor receiver = receiverParameter != null ? receiverParameter : expectedThisObject;
if (receiver == null) {
return NO_RECEIVER;
}
JetExpression receiverExpression = JetPsiFactory.createExpression(state.getProject(),
"callableReferenceFakeReceiver");
Type firstParameterType = signature.getAsmMethod().getArgumentTypes()[0];
// 0 is this (the closure class), 1 is the method's first parameter
codegen.tempVariables.put(receiverExpression, StackValue.local(1, firstParameterType));
return new ExpressionReceiver(receiverExpression, receiver.getType());
}
@Override
public boolean needsLocalVariableTable() {
return false;
}
}
);
closureCodegen.gen();
return closureCodegen.putInstanceOnStack(v, this);
}
@Override
public StackValue visitDotQualifiedExpression(JetDotQualifiedExpression expression, StackValue receiver) {
StackValue receiverValue = StackValue.none();
@@ -182,8 +182,10 @@ public class FunctionCodegen extends GenerationStateAware {
Label methodEnd = new Label();
mv.visitLabel(methodEnd);
Type thisType = getThisTypeForFunction(functionDescriptor, context);
generateLocalVariableTable(mv, functionDescriptor, thisType, methodBegin, methodEnd, localVariableNames, labelsForSharedVars);
if (strategy.needsLocalVariableTable()) {
Type thisType = getThisTypeForFunction(functionDescriptor, context);
generateLocalVariableTable(mv, functionDescriptor, thisType, methodBegin, methodEnd, localVariableNames, labelsForSharedVars);
}
}
@NotNull
@@ -45,6 +45,10 @@ public abstract class FunctionGenerationStrategy {
return localVariableNames;
}
public boolean needsLocalVariableTable() {
return true;
}
public static class Default extends FunctionGenerationStrategy {
private final GenerationState state;
@@ -16,7 +16,9 @@
package org.jetbrains.jet.codegen;
import com.google.common.collect.ImmutableMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor;
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
@@ -31,11 +33,19 @@ import java.util.List;
public class FunctionTypesUtil {
private static final List<ClassDescriptor> FUNCTIONS;
private static final List<ClassDescriptor> EXTENSION_FUNCTIONS;
private static final List<ClassDescriptor> K_FUNCTIONS;
private static final List<ClassDescriptor> K_MEMBER_FUNCTIONS;
private static final List<ClassDescriptor> K_EXTENSION_FUNCTIONS;
private static final ImmutableMap<ClassDescriptor, ClassDescriptor> FUNCTION_TO_IMPL;
static {
int n = KotlinBuiltIns.FUNCTION_TRAIT_COUNT;
FUNCTIONS = new ArrayList<ClassDescriptor>(n);
EXTENSION_FUNCTIONS = new ArrayList<ClassDescriptor>(n);
K_FUNCTIONS = new ArrayList<ClassDescriptor>(n);
K_MEMBER_FUNCTIONS = new ArrayList<ClassDescriptor>(n);
K_EXTENSION_FUNCTIONS = new ArrayList<ClassDescriptor>(n);
KotlinBuiltIns builtIns = KotlinBuiltIns.getInstance();
for (int i = 0; i < n; i++) {
@@ -44,13 +54,36 @@ public class FunctionTypesUtil {
Name extensionFunctionImpl = Name.identifier("ExtensionFunctionImpl" + i);
EXTENSION_FUNCTIONS.add(createFunctionImplDescriptor(extensionFunctionImpl, builtIns.getExtensionFunction(i)));
Name kFunctionImpl = Name.identifier("KFunctionImpl" + i);
K_FUNCTIONS.add(createFunctionImplDescriptor(kFunctionImpl, builtIns.getKFunction(i)));
Name kMemberFunctionImpl = Name.identifier("KMemberFunctionImpl" + i);
K_MEMBER_FUNCTIONS.add(createFunctionImplDescriptor(kMemberFunctionImpl, builtIns.getKMemberFunction(i)));
Name kExtensionFunctionImpl = Name.identifier("KExtensionFunctionImpl" + i);
K_EXTENSION_FUNCTIONS.add(createFunctionImplDescriptor(kExtensionFunctionImpl, builtIns.getKExtensionFunction(i)));
}
ImmutableMap.Builder<ClassDescriptor, ClassDescriptor> builder = ImmutableMap.builder();
for (int i = 0; i < n; i++) {
builder.put(builtIns.getKFunction(i), K_FUNCTIONS.get(i));
builder.put(builtIns.getKMemberFunction(i), K_MEMBER_FUNCTIONS.get(i));
builder.put(builtIns.getKExtensionFunction(i), K_EXTENSION_FUNCTIONS.get(i));
}
FUNCTION_TO_IMPL = builder.build();
}
private FunctionTypesUtil() {
}
@Nullable
public static ClassDescriptor functionTypeToImpl(@NotNull JetType functionType) {
//noinspection SuspiciousMethodCalls
return FUNCTION_TO_IMPL.get(functionType.getConstructor().getDeclarationDescriptor());
}
@NotNull
public static JetType getSuperTypeForClosure(@NotNull FunctionDescriptor funDescriptor, int arity) {
if (funDescriptor.getReceiverParameter() != null) {
@@ -115,11 +115,12 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
if (declaration instanceof JetFunctionLiteralExpression ||
declaration instanceof JetNamedFunction ||
declaration instanceof JetObjectLiteralExpression ||
declaration instanceof JetCallExpression) {
declaration instanceof JetCallExpression ||
declaration instanceof JetCallableReferenceExpression) {
}
else {
throw new IllegalStateException(
"Class-less declaration which is not JetFunctionLiteralExpression|JetNamedFunction|JetObjectLiteralExpression|JetCallExpression : " +
"Class-less declaration which is not JetFunctionLiteralExpression|JetNamedFunction|JetObjectLiteralExpression|JetCallExpression|JetCallableReferenceExpression : " +
declaration.getClass().getName());
}
}
@@ -267,6 +268,23 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
classStack.pop();
}
@Override
public void visitCallableReferenceExpression(JetCallableReferenceExpression expression) {
FunctionDescriptor functionDescriptor = bindingContext.get(CALLABLE_REFERENCE, expression);
// working around a problem with shallow analysis
if (functionDescriptor == null) return;
String name = inventAnonymousClassName(expression);
ClassDescriptor classDescriptor = recordClassForFunction(functionDescriptor);
recordClosure(bindingTrace, expression, classDescriptor, peekFromStack(classStack), JvmClassName.byInternalName(name), true);
classStack.push(classDescriptor);
nameStack.push(name);
super.visitCallableReferenceExpression(expression);
nameStack.pop();
classStack.pop();
}
@Override
public void visitProperty(JetProperty property) {
DeclarationDescriptor propertyDescriptor = bindingContext.get(DECLARATION_TO_DESCRIPTOR, property);
@@ -0,0 +1,96 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.resolve.calls.model;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
import org.jetbrains.jet.lang.resolve.calls.tasks.ExplicitReceiverKind;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.jet.lang.types.JetType;
import java.util.List;
import java.util.Map;
public abstract class DelegatingResolvedCall<D extends CallableDescriptor> implements ResolvedCall<D> {
private final ResolvedCall<? extends D> resolvedCall;
public DelegatingResolvedCall(@NotNull ResolvedCall<? extends D> resolvedCall) {
this.resolvedCall = resolvedCall;
}
@NotNull
@Override
public D getCandidateDescriptor() {
return resolvedCall.getCandidateDescriptor();
}
@NotNull
@Override
public D getResultingDescriptor() {
return resolvedCall.getResultingDescriptor();
}
@NotNull
@Override
public ReceiverValue getReceiverArgument() {
return resolvedCall.getReceiverArgument();
}
@NotNull
@Override
public ReceiverValue getThisObject() {
return resolvedCall.getThisObject();
}
@NotNull
@Override
public ExplicitReceiverKind getExplicitReceiverKind() {
return resolvedCall.getExplicitReceiverKind();
}
@NotNull
@Override
public Map<ValueParameterDescriptor, ResolvedValueArgument> getValueArguments() {
return resolvedCall.getValueArguments();
}
@NotNull
@Override
public List<ResolvedValueArgument> getValueArgumentsByIndex() {
return resolvedCall.getValueArgumentsByIndex();
}
@NotNull
@Override
public Map<TypeParameterDescriptor, JetType> getTypeArguments() {
return resolvedCall.getTypeArguments();
}
@NotNull
@Override
public DataFlowInfo getDataFlowInfo() {
return resolvedCall.getDataFlowInfo();
}
@Override
public boolean isSafeCall() {
return resolvedCall.isSafeCall();
}
}
@@ -0,0 +1,9 @@
abstract class A {
abstract fun foo(): String
}
class B : A() {
override fun foo() = "OK"
}
fun box(): String = B().(A::foo)()
@@ -0,0 +1,5 @@
fun box(): String {
if (true.(Boolean::not)() != false) return "Fail 1"
if (false.(Boolean::not)() != true) return "Fail 2"
return "OK"
}
@@ -0,0 +1,11 @@
class A {
fun foo(k: Int) = k
fun result() = this.(::foo)(111)
}
fun box(): String {
val result = A().result()
if (result != 111) return "Fail $result"
return "OK"
}
@@ -0,0 +1,12 @@
class A {
fun o() = 111
fun k(k: Int) = k
}
fun A.foo() = this.(::o)() + this.(A::k)(222)
fun box(): String {
val result = A().foo()
if (result != 333) return "Fail $result"
return "OK"
}
@@ -0,0 +1,8 @@
class A {
fun foo() = "OK"
}
fun box(): String {
val x = A::foo
return A().x()
}
@@ -0,0 +1,8 @@
class A {
fun foo(result: String) = result
}
fun box(): String {
val x = A::foo
return A().x("OK")
}
@@ -0,0 +1,14 @@
class A {
var result = "Fail"
fun foo() {
result = "OK"
}
}
fun box(): String {
val a = A()
val x = A::foo
a.x()
return a.result
}
@@ -0,0 +1,14 @@
class A {
var result = "Fail"
fun foo(newResult: String) {
result = newResult
}
}
fun box(): String {
val a = A()
val x = A::foo
a.x("OK")
return a.result
}
@@ -0,0 +1,5 @@
class A {
var result = "OK"
}
fun box() = (::A)().result
@@ -0,0 +1,3 @@
class A(val result: String)
fun box() = (::A)("OK").result
@@ -0,0 +1,9 @@
enum class E {
I
}
fun box(): String {
val i = E.I.(E::name)()
if (i != "I") return "Fail $i"
return "OK"
}
@@ -0,0 +1,3 @@
class A
fun box() = if (A().(A::equals)(A())) "Fail" else "OK"
@@ -0,0 +1,7 @@
class A {
fun result() = this.(::foo)("OK")
}
fun A.foo(x: String) = x
fun box() = A().result()
@@ -0,0 +1,7 @@
class A
fun A.foo() = this.(A::bar)("OK")
fun A.bar(x: String) = x
fun box() = A().foo()
@@ -0,0 +1,8 @@
class A
fun A.foo() = "OK"
fun box(): String {
val x = A::foo
return A().x()
}
@@ -0,0 +1,8 @@
class A
fun A.foo(result: String) = result
fun box(): String {
val x = A::foo
return A().x("OK")
}
@@ -0,0 +1,14 @@
class A {
var result = "Fail"
}
fun A.foo() {
result = "OK"
}
fun box(): String {
val a = A()
val x = A::foo
a.x()
return a.result
}
@@ -0,0 +1,14 @@
class A {
var result = "Fail"
}
fun A.foo(newResult: String) {
result = newResult
}
fun box(): String {
val a = A()
val x = A::foo
a.x("OK")
return a.result
}
@@ -0,0 +1,5 @@
class A<T>(val t: T) {
fun foo(): T = t
}
fun box() = A("OK").(A<String>::foo)()
@@ -0,0 +1,14 @@
class A {
inner class Inner {
val o = 111
val k = 222
}
fun result() = this.(A::Inner)().o + this.(::Inner)().k
}
fun box(): String {
val result = A().result()
if (result != 333) return "Fail $result"
return "OK"
}
@@ -0,0 +1,14 @@
class A {
inner class Inner {
val o = 111
val k = 222
}
}
fun A.foo() = this.(A::Inner)().o + this.(::Inner)().k
fun box(): String {
val result = A().foo()
if (result != 333) return "Fail $result"
return "OK"
}
@@ -0,0 +1,12 @@
class A {
inner class Inner {
val o = 111
val k = 222
}
}
fun box(): String {
val result = (::A)().(A::Inner)().o + A().(A::Inner)().k
if (result != 333) return "Fail $result"
return "OK"
}
@@ -0,0 +1,9 @@
class A {
inner class Inner(val result: Int)
}
fun box(): String {
val result = (::A)().(A::Inner)(111).result + A().(A::Inner)(222).result
if (result != 333) return "Fail $result"
return "OK"
}
@@ -0,0 +1,14 @@
class A {
class Nested {
val o = 111
val k = 222
}
fun result() = (::Nested)().o + (A::Nested)().k
}
fun box(): String {
val result = A().result()
if (result != 333) return "Fail $result"
return "OK"
}
@@ -0,0 +1,7 @@
class A {
class Nested {
val result = "OK"
}
}
fun box() = (A::Nested)().result
@@ -0,0 +1,5 @@
class A {
class Nested(val result: String)
}
fun box() = (A::Nested)("OK").result
@@ -0,0 +1,11 @@
fun box(): String {
(::ByteArray)(10)
(::IntArray)(10)
(::ShortArray)(10)
(::LongArray)(10)
(::DoubleArray)(10)
(::FloatArray)(10)
(::BooleanArray)(10)
return "OK"
}
@@ -0,0 +1,19 @@
import java.util.ArrayList
import java.util.Arrays
import java.util.Collections
import java.util.Comparator
fun sort(list: MutableList<String>, comparator: (String, String) -> Int) {
Collections.sort(list, object : Comparator<String> {
override fun compare(p0: String, p1: String) = comparator(p0, p1)
})
}
fun compare(s1: String, s2: String) = s1 compareTo s2
fun box(): String {
val l = ArrayList(Arrays.asList("d", "b", "c", "e", "a"))
sort(l, ::compare)
if (l != Arrays.asList("a", "b", "c", "d", "e")) return "Fail: $l"
return "OK"
}
@@ -0,0 +1,11 @@
fun foo(o: Int, k: Int) = o + k
class A {
fun bar() = (::foo)(111, 222)
}
fun box(): String {
val result = A().bar()
if (result != 333) return "Fail $result"
return "OK"
}
@@ -0,0 +1,11 @@
fun foo(o: Int, k: Int) = o + k
class A
fun A.bar() = (::foo)(111, 222)
fun box(): String {
val result = A().bar()
if (result != 333) return "Fail $result"
return "OK"
}
@@ -0,0 +1,6 @@
fun foo() = "OK"
fun box(): String {
val x = ::foo
return x()
}
@@ -0,0 +1,6 @@
fun foo(x: String) = x
fun box(): String {
val x = ::foo
return x("OK")
}
@@ -0,0 +1,11 @@
var result = "Fail"
fun foo() {
result = "OK"
}
fun box(): String {
val x = ::foo
x()
return result
}
@@ -0,0 +1,11 @@
var result = "Fail"
fun foo(newResult: String) {
result = newResult
}
fun box(): String {
val x = ::foo
x("OK")
return result
}
@@ -0,0 +1,11 @@
trait T {
fun foo() = "OK"
}
class B : T {
inner class C {
fun bar() = this@B.(::foo)()
}
}
fun box() = B().C().bar()
@@ -0,0 +1,9 @@
trait A {
fun foo(): String
}
class B : A {
override fun foo() = "OK"
}
fun box() = B().(A::foo)()
@@ -0,0 +1,3 @@
class A {
public A(double x, int y) { }
}
@@ -0,0 +1,4 @@
fun box(): String {
(::A)(0.0, 0)
return "OK"
}
@@ -31,7 +31,7 @@ import org.jetbrains.jet.codegen.generated.AbstractBlackBoxCodegenTest;
/** This class is generated by {@link org.jetbrains.jet.generators.tests.GenerateTests}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
@TestMetadata("compiler/testData/codegen/box")
@InnerTestClasses({BlackBoxCodegenTestGenerated.Arrays.class, BlackBoxCodegenTestGenerated.Bridges.class, BlackBoxCodegenTestGenerated.Casts.class, BlackBoxCodegenTestGenerated.Classes.class, BlackBoxCodegenTestGenerated.Closures.class, BlackBoxCodegenTestGenerated.ControlStructures.class, BlackBoxCodegenTestGenerated.DefaultArguments.class, BlackBoxCodegenTestGenerated.Elvis.class, BlackBoxCodegenTestGenerated.Enum.class, BlackBoxCodegenTestGenerated.ExclExcl.class, BlackBoxCodegenTestGenerated.ExtensionFunctions.class, BlackBoxCodegenTestGenerated.ExtensionProperties.class, BlackBoxCodegenTestGenerated.Functions.class, BlackBoxCodegenTestGenerated.InnerNested.class, BlackBoxCodegenTestGenerated.Instructions.class, BlackBoxCodegenTestGenerated.Intrinsics.class, BlackBoxCodegenTestGenerated.Labels.class, BlackBoxCodegenTestGenerated.LocalClasses.class, BlackBoxCodegenTestGenerated.MultiDecl.class, BlackBoxCodegenTestGenerated.Namespace.class, BlackBoxCodegenTestGenerated.Objects.class, BlackBoxCodegenTestGenerated.OperatorConventions.class, BlackBoxCodegenTestGenerated.PrimitiveTypes.class, BlackBoxCodegenTestGenerated.Properties.class, BlackBoxCodegenTestGenerated.Reflection.class, BlackBoxCodegenTestGenerated.SafeCall.class, BlackBoxCodegenTestGenerated.Sam.class, BlackBoxCodegenTestGenerated.Strings.class, BlackBoxCodegenTestGenerated.Super.class, BlackBoxCodegenTestGenerated.Traits.class, BlackBoxCodegenTestGenerated.TypeInfo.class, BlackBoxCodegenTestGenerated.Unit.class, BlackBoxCodegenTestGenerated.Vararg.class, BlackBoxCodegenTestGenerated.When.class})
@InnerTestClasses({BlackBoxCodegenTestGenerated.Arrays.class, BlackBoxCodegenTestGenerated.Bridges.class, BlackBoxCodegenTestGenerated.CallableReference.class, BlackBoxCodegenTestGenerated.Casts.class, BlackBoxCodegenTestGenerated.Classes.class, BlackBoxCodegenTestGenerated.Closures.class, BlackBoxCodegenTestGenerated.ControlStructures.class, BlackBoxCodegenTestGenerated.DefaultArguments.class, BlackBoxCodegenTestGenerated.Elvis.class, BlackBoxCodegenTestGenerated.Enum.class, BlackBoxCodegenTestGenerated.ExclExcl.class, BlackBoxCodegenTestGenerated.ExtensionFunctions.class, BlackBoxCodegenTestGenerated.ExtensionProperties.class, BlackBoxCodegenTestGenerated.Functions.class, BlackBoxCodegenTestGenerated.InnerNested.class, BlackBoxCodegenTestGenerated.Instructions.class, BlackBoxCodegenTestGenerated.Intrinsics.class, BlackBoxCodegenTestGenerated.Labels.class, BlackBoxCodegenTestGenerated.LocalClasses.class, BlackBoxCodegenTestGenerated.MultiDecl.class, BlackBoxCodegenTestGenerated.Namespace.class, BlackBoxCodegenTestGenerated.Objects.class, BlackBoxCodegenTestGenerated.OperatorConventions.class, BlackBoxCodegenTestGenerated.PrimitiveTypes.class, BlackBoxCodegenTestGenerated.Properties.class, BlackBoxCodegenTestGenerated.Reflection.class, BlackBoxCodegenTestGenerated.SafeCall.class, BlackBoxCodegenTestGenerated.Sam.class, BlackBoxCodegenTestGenerated.Strings.class, BlackBoxCodegenTestGenerated.Super.class, BlackBoxCodegenTestGenerated.Traits.class, BlackBoxCodegenTestGenerated.TypeInfo.class, BlackBoxCodegenTestGenerated.Unit.class, BlackBoxCodegenTestGenerated.Vararg.class, BlackBoxCodegenTestGenerated.When.class})
public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
public void testAllFilesPresentInBox() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/box"), Pattern.compile("^(.+)\\.kt$"), true);
@@ -418,6 +418,194 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
}
@TestMetadata("compiler/testData/codegen/box/callableReference")
public static class CallableReference extends AbstractBlackBoxCodegenTest {
@TestMetadata("abstractClassMember.kt")
public void testAbstractClassMember() throws Exception {
doTest("compiler/testData/codegen/box/callableReference/abstractClassMember.kt");
}
public void testAllFilesPresentInCallableReference() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/box/callableReference"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("booleanNotIntrinsic.kt")
public void testBooleanNotIntrinsic() throws Exception {
doTest("compiler/testData/codegen/box/callableReference/booleanNotIntrinsic.kt");
}
@TestMetadata("classMemberFromClass.kt")
public void testClassMemberFromClass() throws Exception {
doTest("compiler/testData/codegen/box/callableReference/classMemberFromClass.kt");
}
@TestMetadata("classMemberFromExtension.kt")
public void testClassMemberFromExtension() throws Exception {
doTest("compiler/testData/codegen/box/callableReference/classMemberFromExtension.kt");
}
@TestMetadata("classMemberFromTopLevelStringNoArgs.kt")
public void testClassMemberFromTopLevelStringNoArgs() throws Exception {
doTest("compiler/testData/codegen/box/callableReference/classMemberFromTopLevelStringNoArgs.kt");
}
@TestMetadata("classMemberFromTopLevelStringOneStringArg.kt")
public void testClassMemberFromTopLevelStringOneStringArg() throws Exception {
doTest("compiler/testData/codegen/box/callableReference/classMemberFromTopLevelStringOneStringArg.kt");
}
@TestMetadata("classMemberFromTopLevelUnitNoArgs.kt")
public void testClassMemberFromTopLevelUnitNoArgs() throws Exception {
doTest("compiler/testData/codegen/box/callableReference/classMemberFromTopLevelUnitNoArgs.kt");
}
@TestMetadata("classMemberFromTopLevelUnitOneStringArg.kt")
public void testClassMemberFromTopLevelUnitOneStringArg() throws Exception {
doTest("compiler/testData/codegen/box/callableReference/classMemberFromTopLevelUnitOneStringArg.kt");
}
@TestMetadata("constructorFromTopLevelNoArgs.kt")
public void testConstructorFromTopLevelNoArgs() throws Exception {
doTest("compiler/testData/codegen/box/callableReference/constructorFromTopLevelNoArgs.kt");
}
@TestMetadata("constructorFromTopLevelOneStringArg.kt")
public void testConstructorFromTopLevelOneStringArg() throws Exception {
doTest("compiler/testData/codegen/box/callableReference/constructorFromTopLevelOneStringArg.kt");
}
@TestMetadata("enumNameMethod.kt")
public void testEnumNameMethod() throws Exception {
doTest("compiler/testData/codegen/box/callableReference/enumNameMethod.kt");
}
@TestMetadata("equalsIntrinsic.kt")
public void testEqualsIntrinsic() throws Exception {
doTest("compiler/testData/codegen/box/callableReference/equalsIntrinsic.kt");
}
@TestMetadata("extensionFromClass.kt")
public void testExtensionFromClass() throws Exception {
doTest("compiler/testData/codegen/box/callableReference/extensionFromClass.kt");
}
@TestMetadata("extensionFromExtension.kt")
public void testExtensionFromExtension() throws Exception {
doTest("compiler/testData/codegen/box/callableReference/extensionFromExtension.kt");
}
@TestMetadata("extensionFromTopLevelStringNoArgs.kt")
public void testExtensionFromTopLevelStringNoArgs() throws Exception {
doTest("compiler/testData/codegen/box/callableReference/extensionFromTopLevelStringNoArgs.kt");
}
@TestMetadata("extensionFromTopLevelStringOneStringArg.kt")
public void testExtensionFromTopLevelStringOneStringArg() throws Exception {
doTest("compiler/testData/codegen/box/callableReference/extensionFromTopLevelStringOneStringArg.kt");
}
@TestMetadata("extensionFromTopLevelUnitNoArgs.kt")
public void testExtensionFromTopLevelUnitNoArgs() throws Exception {
doTest("compiler/testData/codegen/box/callableReference/extensionFromTopLevelUnitNoArgs.kt");
}
@TestMetadata("extensionFromTopLevelUnitOneStringArg.kt")
public void testExtensionFromTopLevelUnitOneStringArg() throws Exception {
doTest("compiler/testData/codegen/box/callableReference/extensionFromTopLevelUnitOneStringArg.kt");
}
@TestMetadata("genericMember.kt")
public void testGenericMember() throws Exception {
doTest("compiler/testData/codegen/box/callableReference/genericMember.kt");
}
@TestMetadata("innerConstructorFromClass.kt")
public void testInnerConstructorFromClass() throws Exception {
doTest("compiler/testData/codegen/box/callableReference/innerConstructorFromClass.kt");
}
@TestMetadata("innerConstructorFromExtension.kt")
public void testInnerConstructorFromExtension() throws Exception {
doTest("compiler/testData/codegen/box/callableReference/innerConstructorFromExtension.kt");
}
@TestMetadata("innerConstructorFromTopLevelNoArgs.kt")
public void testInnerConstructorFromTopLevelNoArgs() throws Exception {
doTest("compiler/testData/codegen/box/callableReference/innerConstructorFromTopLevelNoArgs.kt");
}
@TestMetadata("innerConstructorFromTopLevelOneStringArg.kt")
public void testInnerConstructorFromTopLevelOneStringArg() throws Exception {
doTest("compiler/testData/codegen/box/callableReference/innerConstructorFromTopLevelOneStringArg.kt");
}
@TestMetadata("nestedConstructorFromClass.kt")
public void testNestedConstructorFromClass() throws Exception {
doTest("compiler/testData/codegen/box/callableReference/nestedConstructorFromClass.kt");
}
@TestMetadata("nestedConstructorFromTopLevelNoArgs.kt")
public void testNestedConstructorFromTopLevelNoArgs() throws Exception {
doTest("compiler/testData/codegen/box/callableReference/nestedConstructorFromTopLevelNoArgs.kt");
}
@TestMetadata("nestedConstructorFromTopLevelOneStringArg.kt")
public void testNestedConstructorFromTopLevelOneStringArg() throws Exception {
doTest("compiler/testData/codegen/box/callableReference/nestedConstructorFromTopLevelOneStringArg.kt");
}
@TestMetadata("newArray.kt")
public void testNewArray() throws Exception {
doTest("compiler/testData/codegen/box/callableReference/newArray.kt");
}
@TestMetadata("sortListOfStrings.kt")
public void testSortListOfStrings() throws Exception {
doTest("compiler/testData/codegen/box/callableReference/sortListOfStrings.kt");
}
@TestMetadata("topLevelFromClass.kt")
public void testTopLevelFromClass() throws Exception {
doTest("compiler/testData/codegen/box/callableReference/topLevelFromClass.kt");
}
@TestMetadata("topLevelFromExtension.kt")
public void testTopLevelFromExtension() throws Exception {
doTest("compiler/testData/codegen/box/callableReference/topLevelFromExtension.kt");
}
@TestMetadata("topLevelFromTopLevelStringNoArgs.kt")
public void testTopLevelFromTopLevelStringNoArgs() throws Exception {
doTest("compiler/testData/codegen/box/callableReference/topLevelFromTopLevelStringNoArgs.kt");
}
@TestMetadata("topLevelFromTopLevelStringOneStringArg.kt")
public void testTopLevelFromTopLevelStringOneStringArg() throws Exception {
doTest("compiler/testData/codegen/box/callableReference/topLevelFromTopLevelStringOneStringArg.kt");
}
@TestMetadata("topLevelFromTopLevelUnitNoArgs.kt")
public void testTopLevelFromTopLevelUnitNoArgs() throws Exception {
doTest("compiler/testData/codegen/box/callableReference/topLevelFromTopLevelUnitNoArgs.kt");
}
@TestMetadata("topLevelFromTopLevelUnitOneStringArg.kt")
public void testTopLevelFromTopLevelUnitOneStringArg() throws Exception {
doTest("compiler/testData/codegen/box/callableReference/topLevelFromTopLevelUnitOneStringArg.kt");
}
@TestMetadata("traitImplMethodWithClassReceiver.kt")
public void testTraitImplMethodWithClassReceiver() throws Exception {
doTest("compiler/testData/codegen/box/callableReference/traitImplMethodWithClassReceiver.kt");
}
@TestMetadata("traitMember.kt")
public void testTraitMember() throws Exception {
doTest("compiler/testData/codegen/box/callableReference/traitMember.kt");
}
}
@TestMetadata("compiler/testData/codegen/box/casts")
public static class Casts extends AbstractBlackBoxCodegenTest {
public void testAllFilesPresentInCasts() throws Exception {
@@ -3640,6 +3828,7 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
suite.addTestSuite(BlackBoxCodegenTestGenerated.class);
suite.addTestSuite(Arrays.class);
suite.addTestSuite(Bridges.class);
suite.addTestSuite(CallableReference.class);
suite.addTestSuite(Casts.class);
suite.addTestSuite(Classes.class);
suite.addTest(Closures.innerSuite());
@@ -31,12 +31,25 @@ import org.jetbrains.jet.codegen.generated.AbstractBlackBoxCodegenTest;
/** This class is generated by {@link org.jetbrains.jet.generators.tests.GenerateTests}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
@TestMetadata("compiler/testData/codegen/boxWithJava")
@InnerTestClasses({BlackBoxWithJavaCodegenTestGenerated.Enum.class, BlackBoxWithJavaCodegenTestGenerated.Functions.class, BlackBoxWithJavaCodegenTestGenerated.Property.class, BlackBoxWithJavaCodegenTestGenerated.SamAdapters.class, BlackBoxWithJavaCodegenTestGenerated.StaticFun.class, BlackBoxWithJavaCodegenTestGenerated.Visibility.class})
@InnerTestClasses({BlackBoxWithJavaCodegenTestGenerated.CallableReference.class, BlackBoxWithJavaCodegenTestGenerated.Enum.class, BlackBoxWithJavaCodegenTestGenerated.Functions.class, BlackBoxWithJavaCodegenTestGenerated.Property.class, BlackBoxWithJavaCodegenTestGenerated.SamAdapters.class, BlackBoxWithJavaCodegenTestGenerated.StaticFun.class, BlackBoxWithJavaCodegenTestGenerated.Visibility.class})
public class BlackBoxWithJavaCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
public void testAllFilesPresentInBoxWithJava() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/boxWithJava"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("compiler/testData/codegen/boxWithJava/callableReference")
public static class CallableReference extends AbstractBlackBoxCodegenTest {
public void testAllFilesPresentInCallableReference() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/boxWithJava/callableReference"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("constructor.kt")
public void testConstructor() throws Exception {
doTestWithJava("compiler/testData/codegen/boxWithJava/callableReference/constructor.kt");
}
}
@TestMetadata("compiler/testData/codegen/boxWithJava/enum")
public static class Enum extends AbstractBlackBoxCodegenTest {
public void testAllFilesPresentInEnum() throws Exception {
@@ -316,6 +329,7 @@ public class BlackBoxWithJavaCodegenTestGenerated extends AbstractBlackBoxCodege
public static Test suite() {
TestSuite suite = new TestSuite("BlackBoxWithJavaCodegenTestGenerated");
suite.addTestSuite(BlackBoxWithJavaCodegenTestGenerated.class);
suite.addTestSuite(CallableReference.class);
suite.addTestSuite(Enum.class);
suite.addTestSuite(Functions.class);
suite.addTestSuite(Property.class);