Conform functions to extension functions and vice versa
#KT-5989 Fixed
This commit is contained in:
@@ -131,6 +131,14 @@ public class JvmRuntimeTypes {
|
||||
kFunctionClass.getMemberScope(typeArguments)
|
||||
);
|
||||
|
||||
return Arrays.asList(functionImplType, kFunctionType);
|
||||
//noinspection ConstantConditions
|
||||
JetType functionType = getBuiltIns(descriptor).getFunctionType(
|
||||
Annotations.EMPTY,
|
||||
receiverType,
|
||||
ExpressionTypingUtils.getValueParametersTypes(descriptor.getValueParameters()),
|
||||
descriptor.getReturnType()
|
||||
);
|
||||
|
||||
return Arrays.asList(functionImplType, kFunctionType, functionType);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,7 +58,6 @@ import org.jetbrains.org.objectweb.asm.util.TraceMethodVisitor;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.Arrays;
|
||||
import java.util.ListIterator;
|
||||
|
||||
import static kotlin.KotlinPackage.substringAfterLast;
|
||||
@@ -70,14 +69,11 @@ public class InlineCodegenUtil {
|
||||
public static final int API = Opcodes.ASM5;
|
||||
|
||||
public static final String CAPTURED_FIELD_PREFIX = "$";
|
||||
|
||||
public static final String THIS$0 = "this$0";
|
||||
|
||||
public static final String RECEIVER$0 = "receiver$0";
|
||||
|
||||
public static final String NON_LOCAL_RETURN = "$$$$$NON_LOCAL_RETURN$$$$$";
|
||||
|
||||
public static final String FIRST_FUN_LABEL = "$$$$$ROOT$$$$$";
|
||||
public static final String NUMBERED_FUNCTION_PREFIX = "kotlin/jvm/functions/Function";
|
||||
public static final String INLINE_MARKER_CLASS_NAME = "kotlin/jvm/internal/InlineMarker";
|
||||
public static final String INLINE_MARKER_BEFORE_METHOD_NAME = "beforeInlineCall";
|
||||
public static final String INLINE_MARKER_AFTER_METHOD_NAME = "afterInlineCall";
|
||||
@@ -251,20 +247,10 @@ public class InlineCodegenUtil {
|
||||
return getInlineName(codegenContext, currentDescriptor.getContainingDeclaration(), typeMapper) + "$" + suffix;
|
||||
}
|
||||
|
||||
public static boolean isInvokeOnLambda(String owner, String name) {
|
||||
if (!OperatorConventions.INVOKE.asString().equals(name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (String prefix : Arrays.asList("kotlin/jvm/functions/Function", "kotlin/ExtensionFunction")) {
|
||||
if (owner.startsWith(prefix)) {
|
||||
String suffix = owner.substring(prefix.length());
|
||||
if (isInteger(suffix)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
public static boolean isInvokeOnLambda(@NotNull String owner, @NotNull String name) {
|
||||
return OperatorConventions.INVOKE.asString().equals(name) &&
|
||||
owner.startsWith(NUMBERED_FUNCTION_PREFIX) &&
|
||||
isInteger(owner.substring(NUMBERED_FUNCTION_PREFIX.length()));
|
||||
}
|
||||
|
||||
public static boolean isAnonymousConstructorCall(@NotNull String internalName, @NotNull String methodName) {
|
||||
|
||||
+30
-5
@@ -16,16 +16,20 @@
|
||||
|
||||
package org.jetbrains.kotlin.resolve.calls.tasks.collectors
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.functions.FunctionInvokeDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils.isStaticNestedClass
|
||||
import org.jetbrains.kotlin.resolve.LibrarySourceHacks
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.createSynthesizedInvokes
|
||||
import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.hasClassObjectType
|
||||
import org.jetbrains.kotlin.resolve.scopes.JetScope
|
||||
import org.jetbrains.kotlin.types.ErrorUtils
|
||||
import org.jetbrains.kotlin.types.JetType
|
||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||
|
||||
public trait CallableDescriptorCollector<D : CallableDescriptor> {
|
||||
|
||||
@@ -48,8 +52,8 @@ public class CallableDescriptorCollectors<D : CallableDescriptor>(val collectors
|
||||
Iterable<CallableDescriptorCollector<D>> {
|
||||
override fun iterator(): Iterator<CallableDescriptorCollector<D>> = collectors.iterator()
|
||||
|
||||
[suppress("UNCHECKED_CAST")] companion
|
||||
object {
|
||||
@suppress("UNCHECKED_CAST")
|
||||
companion object {
|
||||
public val FUNCTIONS_AND_VARIABLES: CallableDescriptorCollectors<CallableDescriptor> =
|
||||
CallableDescriptorCollectors(listOf(
|
||||
FUNCTIONS_COLLECTOR as CallableDescriptorCollector<CallableDescriptor>,
|
||||
@@ -73,7 +77,20 @@ private object FunctionCollector : CallableDescriptorCollector<FunctionDescripto
|
||||
|
||||
override fun getMembersByName(receiver: JetType, name: Name, bindingTrace: BindingTrace): Collection<FunctionDescriptor> {
|
||||
val receiverScope = receiver.getMemberScope()
|
||||
return receiverScope.getFunctions(name) + getConstructors(receiverScope, name, { !isStaticNestedClass(it) })
|
||||
val members = receiverScope.getFunctions(name)
|
||||
val constructors = getConstructors(receiverScope, name, { !isStaticNestedClass(it) })
|
||||
|
||||
if (name == OperatorConventions.INVOKE && KotlinBuiltIns.isExtensionFunctionType(receiver)) {
|
||||
// If we're looking for members of an extension function type, we ignore the non-extension "invoke"s
|
||||
// that originate from the Function{n} class and only consider the synthesized "invoke" extensions.
|
||||
// Otherwise confusing errors will be reported because the non-extension here beats the extension
|
||||
// (because declarations beat synthesized members)
|
||||
val (candidatesForReplacement, irrelevantInvokes) =
|
||||
members.partition { it is FunctionInvokeDescriptor && it.getValueParameters().isNotEmpty() }
|
||||
return createSynthesizedInvokes(candidatesForReplacement) + irrelevantInvokes + constructors
|
||||
}
|
||||
|
||||
return members + constructors
|
||||
}
|
||||
|
||||
override fun getStaticMembersByName(receiver: JetType, name: Name, bindingTrace: BindingTrace): Collection<FunctionDescriptor> {
|
||||
@@ -81,7 +98,15 @@ private object FunctionCollector : CallableDescriptorCollector<FunctionDescripto
|
||||
}
|
||||
|
||||
override fun getExtensionsByName(scope: JetScope, name: Name, bindingTrace: BindingTrace): Collection<FunctionDescriptor> {
|
||||
return scope.getFunctions(name).filter { it.getExtensionReceiverParameter() != null }
|
||||
val functions = scope.getFunctions(name)
|
||||
val (extensions, nonExtensions) = functions.partition { it.getExtensionReceiverParameter() != null }
|
||||
|
||||
if (name == OperatorConventions.INVOKE) {
|
||||
// Create synthesized "invoke" extensions for each non-extension "invoke" found in the scope
|
||||
return extensions + createSynthesizedInvokes(nonExtensions)
|
||||
}
|
||||
|
||||
return extensions
|
||||
}
|
||||
|
||||
private fun getConstructors(
|
||||
@@ -180,4 +205,4 @@ private fun <D : CallableDescriptor> CallableDescriptorCollector<D>.filtered(fil
|
||||
return delegate.toString()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.resolve.calls.tasks
|
||||
|
||||
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor
|
||||
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor.Kind.Function
|
||||
import org.jetbrains.kotlin.builtins.functions.FunctionInvokeDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||
import java.util.ArrayList
|
||||
|
||||
fun createSynthesizedInvokes(functions: Collection<FunctionDescriptor>): Collection<FunctionDescriptor> {
|
||||
val result = ArrayList<FunctionDescriptor>(1)
|
||||
|
||||
for (invoke in functions) {
|
||||
if (invoke !is FunctionInvokeDescriptor || invoke.getValueParameters().isEmpty()) continue
|
||||
|
||||
val synthesized = if ((invoke.getContainingDeclaration() as? FunctionClassDescriptor)?.functionKind == Function) {
|
||||
createSynthesizedFunctionWithFirstParameterAsReceiver(invoke)
|
||||
}
|
||||
else {
|
||||
val invokeDeclaration = invoke.getOverriddenDescriptors().single()
|
||||
val synthesizedSuperFun = createSynthesizedFunctionWithFirstParameterAsReceiver(invokeDeclaration)
|
||||
val fakeOverride = synthesizedSuperFun.copy(
|
||||
invoke.getContainingDeclaration(),
|
||||
synthesizedSuperFun.getModality(),
|
||||
synthesizedSuperFun.getVisibility(),
|
||||
CallableMemberDescriptor.Kind.FAKE_OVERRIDE,
|
||||
true
|
||||
)
|
||||
fakeOverride.addOverriddenDescriptor(synthesizedSuperFun)
|
||||
fakeOverride
|
||||
}
|
||||
|
||||
result.add(synthesized.substitute(TypeSubstitutor.create(invoke.getDispatchReceiverParameter()!!.getType())))
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
private fun createSynthesizedFunctionWithFirstParameterAsReceiver(descriptor: FunctionDescriptor): FunctionDescriptor {
|
||||
val result = SimpleFunctionDescriptorImpl.create(
|
||||
descriptor.getContainingDeclaration(),
|
||||
descriptor.getAnnotations(),
|
||||
descriptor.getName(),
|
||||
CallableMemberDescriptor.Kind.SYNTHESIZED,
|
||||
descriptor.getSource()
|
||||
)
|
||||
|
||||
val original = descriptor.getOriginal()
|
||||
result.initialize(
|
||||
original.getValueParameters().first().getType(),
|
||||
original.getDispatchReceiverParameter(),
|
||||
original.getTypeParameters(),
|
||||
original.getValueParameters().drop(1).map { p ->
|
||||
ValueParameterDescriptorImpl(
|
||||
result, null, p.getIndex() - 1, p.getAnnotations(), Name.identifier("p${p.getIndex() + 1}"), p.getType(),
|
||||
p.declaresDefaultValue(), p.getVarargElementType(), p.getSource()
|
||||
)
|
||||
},
|
||||
original.getReturnType(),
|
||||
original.getModality(),
|
||||
original.getVisibility()
|
||||
)
|
||||
|
||||
return result
|
||||
}
|
||||
@@ -15,13 +15,13 @@ fun box(): String {
|
||||
check("kotlin.jvm.functions.Function2<java.lang.Integer, java.lang.Integer, kotlin.Unit>")
|
||||
{ x: Int, y: Int -> }
|
||||
|
||||
check("kotlin.ExtensionFunction0<java.lang.Integer, kotlin.Unit>",
|
||||
check("kotlin.jvm.functions.Function1<java.lang.Integer, kotlin.Unit>",
|
||||
fun Int.() {})
|
||||
check("kotlin.ExtensionFunction0<kotlin.Unit, java.lang.Integer>",
|
||||
check("kotlin.jvm.functions.Function1<kotlin.Unit, java.lang.Integer>",
|
||||
fun Unit.(): Int = 42)
|
||||
check("kotlin.ExtensionFunction1<java.lang.String, java.lang.String, java.lang.Long>",
|
||||
check("kotlin.jvm.functions.Function2<java.lang.String, java.lang.String, java.lang.Long>",
|
||||
fun String.(s: String): Long = 42.toLong())
|
||||
check("kotlin.ExtensionFunction2<java.lang.Integer, java.lang.Integer, java.lang.Integer, kotlin.Unit>",
|
||||
check("kotlin.jvm.functions.Function3<java.lang.Integer, java.lang.Integer, java.lang.Integer, kotlin.Unit>",
|
||||
fun Int.(x: Int, y: Int) {})
|
||||
|
||||
return "OK"
|
||||
|
||||
@@ -26,8 +26,8 @@ fun box(): String {
|
||||
assertGenericSuper("kotlin.jvm.functions.Function1<java.util.List<java.lang.Double>, java.util.List<java.lang.Integer>>", mutableListFun)
|
||||
assertGenericSuper("kotlin.jvm.functions.Function1<java.lang.Comparable<? super java.lang.String>, kotlin.Unit>", funWithIn)
|
||||
|
||||
assertGenericSuper("kotlin.ExtensionFunction0<java.lang.Object, kotlin.Unit>", extensionFun)
|
||||
assertGenericSuper("kotlin.ExtensionFunction1<java.lang.Long, java.lang.Object, java.util.Date>", extensionWithArgFun)
|
||||
assertGenericSuper("kotlin.jvm.functions.Function1<java.lang.Object, kotlin.Unit>", extensionFun)
|
||||
assertGenericSuper("kotlin.jvm.functions.Function2<java.lang.Long, java.lang.Object, java.util.Date>", extensionWithArgFun)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
@@ -11,9 +11,9 @@ fun test1() {
|
||||
}
|
||||
|
||||
fun test2() {
|
||||
val a: ExtensionFunction1<*, *, *>.(ExtensionFunction1<*, *, *>)->Unit = {}
|
||||
val b: ExtensionFunction1<*, *, *>.(ExtensionFunction1<*, *, *>)->Unit = {"$this $it"}
|
||||
val c: ExtensionFunction1<*, *, *>.(ExtensionFunction1<*, *, *>)->Unit = {}
|
||||
val a: (@extension Function2<*, *, *>).(@extension Function2<*, *, *>)->Unit = {}
|
||||
val b: (@extension Function2<*, *, *>).(@extension Function2<*, *, *>)->Unit = {"$this $it"}
|
||||
val c: (@extension Function2<*, *, *>).(@extension Function2<*, *, *>)->Unit = {}
|
||||
a.b(c)
|
||||
a b c
|
||||
}
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
fun foo(s: String) {}
|
||||
|
||||
class A {
|
||||
fun bar(): String = ""
|
||||
}
|
||||
|
||||
fun A.baz(x: Int) {}
|
||||
|
||||
|
||||
fun box(): String {
|
||||
val f = "${::foo}"
|
||||
if (f != "kotlin.reflect.KFunction1<java.lang.String, kotlin.Unit>") return "Fail foo: $f"
|
||||
|
||||
val nameOfA = (A() as java.lang.Object).getClass().getName()
|
||||
|
||||
val g = "${A::bar}"
|
||||
if (g != "kotlin.reflect.KMemberFunction0<$nameOfA, java.lang.String>") return "Fail bar: $g"
|
||||
|
||||
val h = "${A::baz}"
|
||||
if (h != "kotlin.reflect.KExtensionFunction1<$nameOfA, java.lang.Integer, kotlin.Unit>") return "Fail baz: $h"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -3,13 +3,8 @@ inline fun <T, U> Function1<T, U>.get(index : Int) {
|
||||
|
||||
}
|
||||
|
||||
inline fun <T, U, V> ExtensionFunction1<T, U, V>.get(index : Int) {
|
||||
|
||||
}
|
||||
|
||||
inline fun <T, U, V> inlineFunWithInvoke(s: (p: T) -> U, ext: T.(p: U) -> V) {
|
||||
inline fun <T, U, V> inlineFunWithInvoke(s: (p: T) -> U) {
|
||||
s[1]
|
||||
ext[1]
|
||||
}
|
||||
|
||||
//noinline
|
||||
@@ -17,11 +12,11 @@ fun <T, U, V> Function2<T, U, V>.get(index : Int) {
|
||||
|
||||
}
|
||||
|
||||
fun <T, U, V, W> ExtensionFunction2<T, U, V, W>.get(index : Int) {
|
||||
fun <T, U, V, W> @extension Function3<T, U, V, W>.get(index : Int) {
|
||||
|
||||
}
|
||||
|
||||
inline fun <T, U, V, W> inlineFunWithInvoke(s: (p: T, l: U) -> V, ext: T.(p: U, l: V) -> W) {
|
||||
<!USAGE_IS_NOT_INLINABLE!>s<!>[1]
|
||||
<!USAGE_IS_NOT_INLINABLE!>ext<!>[1]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package
|
||||
package
|
||||
|
||||
kotlin.inline() internal fun </*0*/ T, /*1*/ U, /*2*/ V> inlineFunWithInvoke(/*0*/ s: (T) -> U, /*1*/ ext: T.(U) -> V): kotlin.Unit
|
||||
kotlin.inline() internal fun </*0*/ T, /*1*/ U, /*2*/ V> inlineFunWithInvoke(/*0*/ s: (T) -> U): kotlin.Unit
|
||||
kotlin.inline() internal fun </*0*/ T, /*1*/ U, /*2*/ V, /*3*/ W> inlineFunWithInvoke(/*0*/ s: (T, U) -> V, /*1*/ ext: T.(U, V) -> W): kotlin.Unit
|
||||
kotlin.inline() internal fun </*0*/ T, /*1*/ U> ((T) -> U).get(/*0*/ index: kotlin.Int): kotlin.Unit
|
||||
internal fun </*0*/ T, /*1*/ U, /*2*/ V> ((T, U) -> V).get(/*0*/ index: kotlin.Int): kotlin.Unit
|
||||
kotlin.inline() internal fun </*0*/ T, /*1*/ U, /*2*/ V> (T.(U) -> V).get(/*0*/ index: kotlin.Int): kotlin.Unit
|
||||
internal fun </*0*/ T, /*1*/ U, /*2*/ V, /*3*/ W> (T.(U, V) -> W).get(/*0*/ index: kotlin.Int): kotlin.Unit
|
||||
|
||||
@@ -12,14 +12,14 @@ inline fun <T, U> Function1<T, U>.plusAssign(p: Function1<T, U>) {
|
||||
<!USAGE_IS_NOT_INLINABLE!>p<!> -= <!USAGE_IS_NOT_INLINABLE!>this<!>
|
||||
}
|
||||
|
||||
fun <T, U, V> ExtensionFunction1<T, U, V>.minusAssign(ext : ExtensionFunction1<T, U, V>) {}
|
||||
fun <T, U, V> @extension Function2<T, U, V>.minusAssign(ext : @extension Function2<T, U, V>) {}
|
||||
|
||||
inline fun <T, U, V> ExtensionFunction1<T, U, V>.modAssign(ext : ExtensionFunction1<T, U, V>) = {
|
||||
inline fun <T, U, V> @extension Function2<T, U, V>.modAssign(ext : @extension Function2<T, U, V>) = {
|
||||
this += ext
|
||||
ext += this
|
||||
}
|
||||
|
||||
inline fun <T, U, V> ExtensionFunction1<T, U, V>.plusAssign(ext : ExtensionFunction1<T, U, V>) {
|
||||
inline fun <T, U, V> @extension Function2<T, U, V>.plusAssign(ext : @extension Function2<T, U, V>) {
|
||||
<!USAGE_IS_NOT_INLINABLE!>this<!> -= <!USAGE_IS_NOT_INLINABLE!>ext<!>
|
||||
<!USAGE_IS_NOT_INLINABLE!>ext<!> -= <!USAGE_IS_NOT_INLINABLE!>this<!>
|
||||
}
|
||||
@@ -27,4 +27,4 @@ inline fun <T, U, V> ExtensionFunction1<T, U, V>.plusAssign(ext : ExtensionFunct
|
||||
inline fun <T, U, V> inlineFunWithInvoke(s: (p: T) -> U, ext: T.(p: U) -> V) {
|
||||
s += s
|
||||
ext += ext
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,23 +1,17 @@
|
||||
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE
|
||||
|
||||
inline fun <T, U> Function1<T, U>.compareTo(p: Function1<T, U>) = 1
|
||||
inline fun <T, U, V> ExtensionFunction1<T, U, V>.compareTo(index : ExtensionFunction1<T, U, V>) = 1
|
||||
|
||||
inline fun <T, U, V> inlineFunWithInvoke(s: (p: T) -> U, ext: T.(p: U) -> V) {
|
||||
inline fun <T, U, V> inlineFunWithInvoke(s: (p: T) -> U) {
|
||||
s < s
|
||||
s <= s
|
||||
s > s
|
||||
s >= s
|
||||
|
||||
ext < ext
|
||||
ext > ext
|
||||
ext <= ext
|
||||
ext >= ext
|
||||
}
|
||||
|
||||
//noinline
|
||||
fun <T, U, V> Function2<T, U, V>.compareTo(index : Function2<T, U, V>) = 1
|
||||
fun <T, U, V, W> ExtensionFunction2<T, U, V, W>.compareTo(index : ExtensionFunction2<T, U, V, W>) = 1
|
||||
fun <T, U, V, W> @extension Function3<T, U, V, W>.compareTo(index : @extension Function3<T, U, V, W>) = 1
|
||||
|
||||
inline fun <T, U, V, W> inlineFunWithInvoke(s: (p: T, l: U) -> V, ext: T.(p: U, l: V) -> W) {
|
||||
<!USAGE_IS_NOT_INLINABLE!>s<!> < <!USAGE_IS_NOT_INLINABLE!>s<!>
|
||||
@@ -29,4 +23,4 @@ inline fun <T, U, V, W> inlineFunWithInvoke(s: (p: T, l: U) -> V, ext: T.(p: U,
|
||||
<!USAGE_IS_NOT_INLINABLE!>ext<!> > <!USAGE_IS_NOT_INLINABLE!>ext<!>
|
||||
<!USAGE_IS_NOT_INLINABLE!>ext<!> <= <!USAGE_IS_NOT_INLINABLE!>ext<!>
|
||||
<!USAGE_IS_NOT_INLINABLE!>ext<!> >= <!USAGE_IS_NOT_INLINABLE!>ext<!>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package
|
||||
package
|
||||
|
||||
kotlin.inline() internal fun </*0*/ T, /*1*/ U, /*2*/ V> inlineFunWithInvoke(/*0*/ s: (T) -> U, /*1*/ ext: T.(U) -> V): kotlin.Unit
|
||||
kotlin.inline() internal fun </*0*/ T, /*1*/ U, /*2*/ V> inlineFunWithInvoke(/*0*/ s: (T) -> U): kotlin.Unit
|
||||
kotlin.inline() internal fun </*0*/ T, /*1*/ U, /*2*/ V, /*3*/ W> inlineFunWithInvoke(/*0*/ s: (T, U) -> V, /*1*/ ext: T.(U, V) -> W): kotlin.Unit
|
||||
kotlin.inline() internal fun </*0*/ T, /*1*/ U> ((T) -> U).compareTo(/*0*/ p: (T) -> U): kotlin.Int
|
||||
internal fun </*0*/ T, /*1*/ U, /*2*/ V> ((T, U) -> V).compareTo(/*0*/ index: (T, U) -> V): kotlin.Int
|
||||
kotlin.inline() internal fun </*0*/ T, /*1*/ U, /*2*/ V> (T.(U) -> V).compareTo(/*0*/ index: T.(U) -> V): kotlin.Int
|
||||
internal fun </*0*/ T, /*1*/ U, /*2*/ V, /*3*/ W> (T.(U, V) -> W).compareTo(/*0*/ index: T.(U, V) -> W): kotlin.Int
|
||||
|
||||
@@ -2,21 +2,17 @@
|
||||
inline fun <T, U> Function1<T, U>.component1() = 1
|
||||
inline fun <T, U> Function1<T, U>.component2() = 2
|
||||
|
||||
inline fun <T, U, V> ExtensionFunction1<T, U, V>.component1() = 1
|
||||
inline fun <T, U, V> ExtensionFunction1<T, U, V>.component2() = 2
|
||||
|
||||
inline fun <T, U, V> inlineFunWithInvoke(s: (p: T) -> U, ext: T.(p: U) -> V) {
|
||||
inline fun <T, U, V> inlineFunWithInvoke(s: (p: T) -> U) {
|
||||
val (d1, e1) = s
|
||||
val (d2, e2) = ext
|
||||
}
|
||||
|
||||
fun <T, U, V> Function2<T, U, V>.component1() = 1
|
||||
fun <T, U, V> Function2<T, U, V>.component2() = 2
|
||||
|
||||
fun <T, U, V, W> ExtensionFunction2<T, U, V, W>.component1() = 1
|
||||
fun <T, U, V, W> ExtensionFunction2<T, U, V, W>.component2() = 2
|
||||
fun <T, U, V, W> @extension Function3<T, U, V, W>.component1() = 1
|
||||
fun <T, U, V, W> @extension Function3<T, U, V, W>.component2() = 2
|
||||
|
||||
inline fun <T, U, V, W> inlineFunWithInvoke(s: (p: T, l: U) -> V, ext: T.(p: U, l: V) -> W) {
|
||||
val (d1, e1) = <!USAGE_IS_NOT_INLINABLE, USAGE_IS_NOT_INLINABLE!>s<!>
|
||||
val (d2, e2) = <!USAGE_IS_NOT_INLINABLE, USAGE_IS_NOT_INLINABLE!>ext<!>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
package
|
||||
package
|
||||
|
||||
kotlin.inline() internal fun </*0*/ T, /*1*/ U, /*2*/ V> inlineFunWithInvoke(/*0*/ s: (T) -> U, /*1*/ ext: T.(U) -> V): kotlin.Unit
|
||||
kotlin.inline() internal fun </*0*/ T, /*1*/ U, /*2*/ V> inlineFunWithInvoke(/*0*/ s: (T) -> U): kotlin.Unit
|
||||
kotlin.inline() internal fun </*0*/ T, /*1*/ U, /*2*/ V, /*3*/ W> inlineFunWithInvoke(/*0*/ s: (T, U) -> V, /*1*/ ext: T.(U, V) -> W): kotlin.Unit
|
||||
kotlin.inline() internal fun </*0*/ T, /*1*/ U> ((T) -> U).component1(): kotlin.Int
|
||||
internal fun </*0*/ T, /*1*/ U, /*2*/ V> ((T, U) -> V).component1(): kotlin.Int
|
||||
kotlin.inline() internal fun </*0*/ T, /*1*/ U, /*2*/ V> (T.(U) -> V).component1(): kotlin.Int
|
||||
internal fun </*0*/ T, /*1*/ U, /*2*/ V, /*3*/ W> (T.(U, V) -> W).component1(): kotlin.Int
|
||||
kotlin.inline() internal fun </*0*/ T, /*1*/ U> ((T) -> U).component2(): kotlin.Int
|
||||
internal fun </*0*/ T, /*1*/ U, /*2*/ V> ((T, U) -> V).component2(): kotlin.Int
|
||||
kotlin.inline() internal fun </*0*/ T, /*1*/ U, /*2*/ V> (T.(U) -> V).component2(): kotlin.Int
|
||||
internal fun </*0*/ T, /*1*/ U, /*2*/ V, /*3*/ W> (T.(U, V) -> W).component2(): kotlin.Int
|
||||
|
||||
@@ -5,25 +5,15 @@ inline fun <T, U> Function1<T, U>.contains(p: Function1<T, U>): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
inline fun <T, U, V> ExtensionFunction1<T, U, V>.contains(ext: ExtensionFunction1<T, U, V>): Boolean {
|
||||
ext in this
|
||||
this in ext
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
inline fun <T, U, V> inlineFunWithInvoke(s: (p: T) -> U, ext: T.(p: U) -> V) {
|
||||
inline fun <T, U, V> inlineFunWithInvoke(s: (p: T) -> U) {
|
||||
s in s
|
||||
s !in s
|
||||
|
||||
ext in ext
|
||||
ext !in ext
|
||||
}
|
||||
|
||||
|
||||
fun <T, U, V> Function2<T, U, V>.contains(p: Function2<T, U, V>): Boolean = false
|
||||
|
||||
fun <T, U, V, W> ExtensionFunction2<T, U, V, W>.contains(ext: ExtensionFunction2<T, U, V, W>): Boolean = false
|
||||
fun <T, U, V, W> @extension Function3<T, U, V, W>.contains(ext: @extension Function3<T, U, V, W>): Boolean = false
|
||||
|
||||
inline fun <T, U, V> inlineFunWithInvoke(s: (p: T, l: U) -> U, ext: T.(p: U, l: U) -> V) {
|
||||
<!USAGE_IS_NOT_INLINABLE!>s<!> in <!USAGE_IS_NOT_INLINABLE!>s<!>
|
||||
@@ -31,4 +21,4 @@ inline fun <T, U, V> inlineFunWithInvoke(s: (p: T, l: U) -> U, ext: T.(p: U, l:
|
||||
|
||||
<!USAGE_IS_NOT_INLINABLE!>ext<!> in <!USAGE_IS_NOT_INLINABLE!>ext<!>
|
||||
<!USAGE_IS_NOT_INLINABLE!>ext<!> !in <!USAGE_IS_NOT_INLINABLE!>ext<!>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package
|
||||
package
|
||||
|
||||
kotlin.inline() internal fun </*0*/ T, /*1*/ U, /*2*/ V> inlineFunWithInvoke(/*0*/ s: (T) -> U, /*1*/ ext: T.(U) -> V): kotlin.Unit
|
||||
kotlin.inline() internal fun </*0*/ T, /*1*/ U, /*2*/ V> inlineFunWithInvoke(/*0*/ s: (T) -> U): kotlin.Unit
|
||||
kotlin.inline() internal fun </*0*/ T, /*1*/ U, /*2*/ V> inlineFunWithInvoke(/*0*/ s: (T, U) -> U, /*1*/ ext: T.(U, U) -> V): kotlin.Unit
|
||||
kotlin.inline() internal fun </*0*/ T, /*1*/ U> ((T) -> U).contains(/*0*/ p: (T) -> U): kotlin.Boolean
|
||||
internal fun </*0*/ T, /*1*/ U, /*2*/ V> ((T, U) -> V).contains(/*0*/ p: (T, U) -> V): kotlin.Boolean
|
||||
kotlin.inline() internal fun </*0*/ T, /*1*/ U, /*2*/ V> (T.(U) -> V).contains(/*0*/ ext: T.(U) -> V): kotlin.Boolean
|
||||
internal fun </*0*/ T, /*1*/ U, /*2*/ V, /*3*/ W> (T.(U, V) -> W).contains(/*0*/ ext: T.(U, V) -> W): kotlin.Boolean
|
||||
|
||||
@@ -3,7 +3,7 @@ fun <T, U> Function1<T, U>.minus(p: Function1<T, U>) {
|
||||
|
||||
}
|
||||
|
||||
fun <T, U, V> ExtensionFunction1<T, U, V>.minus(p: T.(p: U) -> V) {
|
||||
fun <T, U, V> @extension Function2<T, U, V>.minus(p: T.(p: U) -> V) {
|
||||
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ inline fun <T, U> Function1<T, U>.plus(p: Function1<T, U>) {
|
||||
<!USAGE_IS_NOT_INLINABLE!>this<!> - <!USAGE_IS_NOT_INLINABLE!>p<!>
|
||||
}
|
||||
|
||||
inline fun <T, U, V> ExtensionFunction1<T, U, V>.plus(p: T.(p: U) -> V) {
|
||||
inline fun <T, U, V> @extension Function2<T, U, V>.plus(p: T.(p: U) -> V) {
|
||||
<!USAGE_IS_NOT_INLINABLE!>this<!> - <!USAGE_IS_NOT_INLINABLE!>p<!>
|
||||
}
|
||||
|
||||
@@ -29,6 +29,6 @@ inline fun <T, U> Function1<T, U>.submit() {
|
||||
this + this
|
||||
}
|
||||
|
||||
inline fun <T, U, V> ExtensionFunction1<T, U, V>.submit() {
|
||||
inline fun <T, U, V> @extension Function2<T, U, V>.submit() {
|
||||
this + this
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,19 +6,9 @@ inline fun <T, U> Function1<T, U>.rangeTo(p: Function1<T, U>): Range<Int> {
|
||||
return 1..2
|
||||
}
|
||||
|
||||
inline fun <T, U, V> ExtensionFunction1<T, U, V>.rangeTo(ext: ExtensionFunction1<T, U, V>): Range<Int> {
|
||||
ext..this
|
||||
this..ext
|
||||
return 1..2
|
||||
}
|
||||
|
||||
|
||||
inline fun <T, U, V> inlineFunWithInvoke(s: (p: T) -> U, ext: T.(p: U) -> V) {
|
||||
inline fun <T, U, V> inlineFunWithInvoke(s: (p: T) -> U) {
|
||||
s..s
|
||||
s..s
|
||||
|
||||
ext..ext
|
||||
ext..ext
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +16,7 @@ fun <T, U, V> Function2<T, U, V>.rangeTo(p: Function2<T, U, V>): Range<Int> {
|
||||
return 1..2
|
||||
}
|
||||
|
||||
fun <T, U, V, W> ExtensionFunction2<T, U, V, W>.rangeTo(ext: ExtensionFunction2<T, U, V, W>): Range<Int> {
|
||||
fun <T, U, V, W> @extension Function3<T, U, V, W>.rangeTo(ext: @extension Function3<T, U, V, W>): Range<Int> {
|
||||
return 1..2
|
||||
}
|
||||
|
||||
@@ -36,4 +26,4 @@ inline fun <T, U, V> inlineFunWithInvoke(s: (p: T, l: U) -> U, ext: T.(p: U, l:
|
||||
|
||||
<!USAGE_IS_NOT_INLINABLE!>ext<!>..<!USAGE_IS_NOT_INLINABLE!>ext<!>
|
||||
<!USAGE_IS_NOT_INLINABLE!>ext<!>..<!USAGE_IS_NOT_INLINABLE!>ext<!>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package
|
||||
package
|
||||
|
||||
kotlin.inline() internal fun </*0*/ T, /*1*/ U, /*2*/ V> inlineFunWithInvoke(/*0*/ s: (T) -> U, /*1*/ ext: T.(U) -> V): kotlin.Unit
|
||||
kotlin.inline() internal fun </*0*/ T, /*1*/ U, /*2*/ V> inlineFunWithInvoke(/*0*/ s: (T) -> U): kotlin.Unit
|
||||
kotlin.inline() internal fun </*0*/ T, /*1*/ U, /*2*/ V> inlineFunWithInvoke(/*0*/ s: (T, U) -> U, /*1*/ ext: T.(U, U) -> V): kotlin.Unit
|
||||
kotlin.inline() internal fun </*0*/ T, /*1*/ U> ((T) -> U).rangeTo(/*0*/ p: (T) -> U): kotlin.Range<kotlin.Int>
|
||||
internal fun </*0*/ T, /*1*/ U, /*2*/ V> ((T, U) -> V).rangeTo(/*0*/ p: (T, U) -> V): kotlin.Range<kotlin.Int>
|
||||
kotlin.inline() internal fun </*0*/ T, /*1*/ U, /*2*/ V> (T.(U) -> V).rangeTo(/*0*/ ext: T.(U) -> V): kotlin.Range<kotlin.Int>
|
||||
internal fun </*0*/ T, /*1*/ U, /*2*/ V, /*3*/ W> (T.(U, V) -> W).rangeTo(/*0*/ ext: T.(U, V) -> W): kotlin.Range<kotlin.Int>
|
||||
|
||||
@@ -5,10 +5,10 @@ fun <T, V> Function1<T, V>.minus() = this
|
||||
inline fun <T, V> Function1<T, V>.inc() = <!USAGE_IS_NOT_INLINABLE!>this<!>
|
||||
fun <T, V> Function1<T, V>.dec() = this
|
||||
|
||||
inline fun <T, V> ExtensionFunction1<T, T, V>.plus(){}
|
||||
fun <T, V> ExtensionFunction1<T, T, V>.minus(){}
|
||||
inline fun <T, V> ExtensionFunction1<T, T, V>.inc() = <!USAGE_IS_NOT_INLINABLE!>this<!>
|
||||
fun <T, V> ExtensionFunction1<T, T, V>.dec() = this
|
||||
inline fun <T, V> @extension Function2<T, T, V>.plus(){}
|
||||
fun <T, V> @extension Function2<T, T, V>.minus(){}
|
||||
inline fun <T, V> @extension Function2<T, T, V>.inc() = <!USAGE_IS_NOT_INLINABLE!>this<!>
|
||||
fun <T, V> @extension Function2<T, T, V>.dec() = this
|
||||
|
||||
inline fun <T, V> inlineFunWithInvoke(s: (p: T) -> V, ext: T.(p: T) -> V) {
|
||||
+s
|
||||
@@ -32,4 +32,4 @@ inline fun <T, V> Function1<T, V>.inlineFunWithInvoke() {
|
||||
++this
|
||||
<!USAGE_IS_NOT_INLINABLE!>this<!>--
|
||||
--<!USAGE_IS_NOT_INLINABLE!>this<!>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,24 +3,19 @@ inline fun <T, V> Function1<T, V>.not() : Boolean {
|
||||
return !this
|
||||
}
|
||||
|
||||
inline fun <T, V> ExtensionFunction1<T, T, V>.not() : Boolean {
|
||||
return !this
|
||||
}
|
||||
|
||||
inline fun <T, V> inlineFunWithInvoke(s: (p: T) -> V, ext: T.(p: T) -> V) {
|
||||
inline fun <T, V> inlineFunWithInvoke(s: (p: T) -> V) {
|
||||
!s
|
||||
!ext
|
||||
}
|
||||
|
||||
fun <T, U, V> Function2<T, U, V>.not() : Boolean {
|
||||
return !this
|
||||
}
|
||||
|
||||
fun <T, U, V, W> ExtensionFunction2<T, U, V, W>.not() : Boolean {
|
||||
fun <T, U, V, W> @extension Function3<T, U, V, W>.not() : Boolean {
|
||||
return !this
|
||||
}
|
||||
|
||||
inline fun <T, U, V> inlineFunWithInvoke(s: (p: T, l: U) -> V, ext: T.(p: T, l : U) -> V) {
|
||||
!<!USAGE_IS_NOT_INLINABLE!>s<!>
|
||||
!<!USAGE_IS_NOT_INLINABLE!>ext<!>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package
|
||||
package
|
||||
|
||||
kotlin.inline() internal fun </*0*/ T, /*1*/ V> inlineFunWithInvoke(/*0*/ s: (T) -> V, /*1*/ ext: T.(T) -> V): kotlin.Unit
|
||||
kotlin.inline() internal fun </*0*/ T, /*1*/ V> inlineFunWithInvoke(/*0*/ s: (T) -> V): kotlin.Unit
|
||||
kotlin.inline() internal fun </*0*/ T, /*1*/ U, /*2*/ V> inlineFunWithInvoke(/*0*/ s: (T, U) -> V, /*1*/ ext: T.(T, U) -> V): kotlin.Unit
|
||||
kotlin.inline() internal fun </*0*/ T, /*1*/ V> ((T) -> V).not(): kotlin.Boolean
|
||||
internal fun </*0*/ T, /*1*/ U, /*2*/ V> ((T, U) -> V).not(): kotlin.Boolean
|
||||
kotlin.inline() internal fun </*0*/ T, /*1*/ V> (T.(T) -> V).not(): kotlin.Boolean
|
||||
internal fun </*0*/ T, /*1*/ U, /*2*/ V, /*3*/ W> (T.(U, V) -> W).not(): kotlin.Boolean
|
||||
|
||||
+3
-3
@@ -5,7 +5,7 @@ fun test1(f: String.() -> Unit) {
|
||||
}
|
||||
|
||||
fun test2(f: (Int) -> Int) {
|
||||
1.<!UNRESOLVED_REFERENCE!>f<!>(2)
|
||||
1.f(<!TOO_MANY_ARGUMENTS!>2<!>)
|
||||
|
||||
2.<!NO_RECEIVER_ALLOWED!>(f)<!>(2)
|
||||
}
|
||||
2.(f)(<!TOO_MANY_ARGUMENTS!>2<!>)
|
||||
}
|
||||
|
||||
@@ -5,18 +5,18 @@ var v4: Function1<Int, String>
|
||||
var v4: (() -> Int, (String) -> Unit) -> String
|
||||
var v5: Int.() -> Int
|
||||
var v6 : Int.(String, Int) -> Unit
|
||||
var v7 : ExtensionFunction1<Int, String, Boolean>
|
||||
var v7 : [extension] Function2<Int, String, Boolean>
|
||||
|
||||
class F: Function0<Unit>
|
||||
var v8: F
|
||||
|
||||
class EF: ExtensionFunction0<Unit>
|
||||
class EF: [extension] Function1<String, Unit>
|
||||
var v9: EF
|
||||
|
||||
class GF<T>: Function0<T>
|
||||
var v10: GF<Any>
|
||||
|
||||
class GEF<A, B>: ExtensionFunction0<A, B>
|
||||
class GEF<A, B>: [extension] Function1<A, B>
|
||||
var v11: GEF<Any, Any>
|
||||
|
||||
//internal var v1: () -> kotlin.Unit defined in root package
|
||||
@@ -30,7 +30,7 @@ var v11: GEF<Any, Any>
|
||||
//internal final class F : () -> kotlin.Unit defined in root package
|
||||
//public constructor F() defined in F
|
||||
//internal var v8: F defined in root package
|
||||
//internal final class EF defined in root package
|
||||
//internal final class EF : kotlin.String.() -> kotlin.Unit defined in root package
|
||||
//public constructor EF() defined in EF
|
||||
//internal var v9: EF defined in root package
|
||||
//internal final class GF<T> : () -> T defined in root package
|
||||
|
||||
@@ -5,8 +5,8 @@ fun bar(f: Int.()->Unit) {
|
||||
|
||||
Resolved call:
|
||||
|
||||
Resulting descriptor: fun Int.invoke(): Unit defined in kotlin.ExtensionFunction0
|
||||
Resulting descriptor: fun Int.invoke(): Unit defined in kotlin.Function1
|
||||
|
||||
Explicit receiver kind = BOTH_RECEIVERS
|
||||
Dispatch receiver = f {ExtensionFunction0<Int, Unit>}
|
||||
Dispatch receiver = f {[kotlin.extension] Function1<Int, Unit>}
|
||||
Extension receiver = 1 {Int}
|
||||
|
||||
@@ -9,8 +9,8 @@ interface A {
|
||||
|
||||
Resolved call:
|
||||
|
||||
Resulting descriptor: fun Int.invoke(): Unit defined in kotlin.ExtensionFunction0
|
||||
Resulting descriptor: fun Int.invoke(): Unit defined in kotlin.Function1
|
||||
|
||||
Explicit receiver kind = BOTH_RECEIVERS
|
||||
Dispatch receiver = foo {ExtensionFunction0<Int, Unit>}
|
||||
Dispatch receiver = foo {[kotlin.extension] Function1<Int, Unit>}
|
||||
Extension receiver = 1 {Int}
|
||||
|
||||
-6
@@ -561,12 +561,6 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("toString.kt")
|
||||
public void testToString() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/callableReference/function/toString.kt");
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("topLevelFromClass.kt")
|
||||
public void testTopLevelFromClass() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/callableReference/function/topLevelFromClass.kt");
|
||||
|
||||
@@ -24,13 +24,16 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.builtins.functions.BuiltInFictitiousFunctionClassFactory;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptorImpl;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationsImpl;
|
||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl;
|
||||
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.name.FqNameUnsafe;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
|
||||
import org.jetbrains.kotlin.resolve.scopes.JetScope;
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager;
|
||||
import org.jetbrains.kotlin.types.*;
|
||||
@@ -39,8 +42,7 @@ import org.jetbrains.kotlin.types.checker.JetTypeChecker;
|
||||
import java.io.InputStream;
|
||||
import java.util.*;
|
||||
|
||||
import static kotlin.KotlinPackage.setOf;
|
||||
import static kotlin.KotlinPackage.single;
|
||||
import static kotlin.KotlinPackage.*;
|
||||
import static org.jetbrains.kotlin.builtins.PrimitiveType.*;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.getFqName;
|
||||
|
||||
@@ -178,6 +180,7 @@ public class KotlinBuiltIns {
|
||||
public final FqName inline = fqName("inline");
|
||||
public final FqName noinline = fqName("noinline");
|
||||
public final FqName inlineOptions = fqName("inlineOptions");
|
||||
public final FqName extension = fqName("extension");
|
||||
|
||||
public final FqNameUnsafe kClass = new FqName("kotlin.reflect.KClass").toUnsafe();
|
||||
|
||||
@@ -193,7 +196,6 @@ public class KotlinBuiltIns {
|
||||
}
|
||||
|
||||
public final Set<FqNameUnsafe> functionClasses = computeIndexedFqNames("Function", FUNCTION_TRAIT_COUNT);
|
||||
public final Set<FqNameUnsafe> extensionFunctionClasses = computeIndexedFqNames("ExtensionFunction", FUNCTION_TRAIT_COUNT);
|
||||
|
||||
@NotNull
|
||||
private static FqNameUnsafe fqNameUnsafe(@NotNull String simpleName) {
|
||||
@@ -346,9 +348,14 @@ public class KotlinBuiltIns {
|
||||
return getBuiltInClassByName("Function" + parameterCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the descriptor representing the class kotlin.Function{parameterCount + 1}
|
||||
* @deprecated there are no ExtensionFunction classes anymore, use {@link #getFunction(int)} instead
|
||||
*/
|
||||
@Deprecated
|
||||
@NotNull
|
||||
public ClassDescriptor getExtensionFunction(int parameterCount) {
|
||||
return getBuiltInClassByName("ExtensionFunction" + parameterCount);
|
||||
return getBuiltInClassByName("Function" + (parameterCount + 1));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -650,6 +657,16 @@ public class KotlinBuiltIns {
|
||||
return getBuiltInClassByName("PropertyMetadataImpl");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public AnnotationDescriptor createExtensionAnnotation() {
|
||||
return new AnnotationDescriptorImpl(getBuiltInClassByName("extension").getDefaultType(),
|
||||
Collections.<ValueParameterDescriptor, CompileTimeConstant<?>>emptyMap());
|
||||
}
|
||||
|
||||
private static boolean isTypeAnnotatedWithExtension(@NotNull JetType type) {
|
||||
return type.getAnnotations().findAnnotation(FQ_NAMES.extension) != null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JetType getFunctionType(
|
||||
@NotNull Annotations annotations,
|
||||
@@ -662,7 +679,17 @@ public class KotlinBuiltIns {
|
||||
ClassDescriptor classDescriptor = receiverType == null ? getFunction(size) : getExtensionFunction(size);
|
||||
TypeConstructor constructor = classDescriptor.getTypeConstructor();
|
||||
|
||||
return new JetTypeImpl(annotations, constructor, false, arguments, classDescriptor.getMemberScope(arguments));
|
||||
Annotations typeAnnotations = receiverType == null ? annotations : addExtensionAnnotation(annotations);
|
||||
|
||||
return new JetTypeImpl(typeAnnotations, constructor, false, arguments, classDescriptor.getMemberScope(arguments));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Annotations addExtensionAnnotation(@NotNull Annotations annotations) {
|
||||
if (annotations.findAnnotation(FQ_NAMES.extension) != null) return annotations;
|
||||
|
||||
// TODO: preserve laziness of given annotations
|
||||
return new AnnotationsImpl(plus(annotations, listOf(createExtensionAnnotation())));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -741,21 +768,20 @@ public class KotlinBuiltIns {
|
||||
}
|
||||
|
||||
public static boolean isExactFunctionType(@NotNull JetType type) {
|
||||
return isTypeConstructorFqNameInSet(type, FQ_NAMES.functionClasses);
|
||||
return isTypeConstructorFqNameInSet(type, FQ_NAMES.functionClasses) && !isTypeAnnotatedWithExtension(type);
|
||||
}
|
||||
|
||||
public static boolean isExactExtensionFunctionType(@NotNull JetType type) {
|
||||
return isTypeConstructorFqNameInSet(type, FQ_NAMES.extensionFunctionClasses);
|
||||
return isTypeConstructorFqNameInSet(type, FQ_NAMES.functionClasses) && isTypeAnnotatedWithExtension(type);
|
||||
}
|
||||
|
||||
public static boolean isExactFunctionType(@NotNull FqNameUnsafe fqName) {
|
||||
/**
|
||||
* @return true if this is an FQ name of a fictitious class representing the function type, e.g. kotlin.Function1
|
||||
*/
|
||||
public static boolean isNumberedFunctionClassFqName(@NotNull FqNameUnsafe fqName) {
|
||||
return FQ_NAMES.functionClasses.contains(fqName);
|
||||
}
|
||||
|
||||
public static boolean isExactExtensionFunctionType(@NotNull FqNameUnsafe fqName) {
|
||||
return FQ_NAMES.extensionFunctionClasses.contains(fqName);
|
||||
}
|
||||
|
||||
private static boolean isTypeConstructorFqNameInSet(@NotNull JetType type, @NotNull Set<FqNameUnsafe> classes) {
|
||||
ClassifierDescriptor declarationDescriptor = type.getConstructor().getDeclarationDescriptor();
|
||||
|
||||
@@ -769,6 +795,7 @@ public class KotlinBuiltIns {
|
||||
public static JetType getReceiverType(@NotNull JetType type) {
|
||||
assert isFunctionOrExtensionFunctionType(type) : type;
|
||||
if (isExtensionFunctionType(type)) {
|
||||
// TODO: this is incorrect when a class extends from an extension function and swaps type arguments
|
||||
return type.getArguments().get(0).getType();
|
||||
}
|
||||
return null;
|
||||
|
||||
+11
-1
@@ -16,10 +16,12 @@
|
||||
|
||||
package org.jetbrains.kotlin.builtins.functions
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME
|
||||
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor.Kind
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationsImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.AbstractClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
@@ -140,7 +142,15 @@ public class FunctionClassDescriptor(
|
||||
|
||||
val module = containingDeclaration.getContainingDeclaration()
|
||||
val kotlinPackageFragment = module.getPackage(BUILT_INS_PACKAGE_FQ_NAME)!!.getFragments().single()
|
||||
add(kotlinPackageFragment, Kind.Function.numberedClassName(functionArity), Annotations.EMPTY)
|
||||
|
||||
// If this is a KMemberFunction{n} or KExtensionFunction{n}, it extends Function{n} with the annotation kotlin.extension,
|
||||
// so that the value of this type is callable as an extension function, with the receiver before the dot
|
||||
val annotations =
|
||||
if (functionKind.hasDispatchReceiver || functionKind.hasExtensionReceiver)
|
||||
AnnotationsImpl(listOf(KotlinBuiltIns.getInstance().createExtensionAnnotation()))
|
||||
else Annotations.EMPTY
|
||||
|
||||
add(kotlinPackageFragment, Kind.Function.numberedClassName(functionArity), annotations)
|
||||
}
|
||||
|
||||
result.toReadOnlyList()
|
||||
|
||||
+7
-6
@@ -25,7 +25,9 @@ import org.jetbrains.kotlin.idea.decompiler.stubBuilder.FlagsToModifiers.VISIBIL
|
||||
import org.jetbrains.kotlin.lexer.JetModifierKeywordToken
|
||||
import org.jetbrains.kotlin.lexer.JetTokens
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.JetClassBody
|
||||
import org.jetbrains.kotlin.psi.JetDelegationSpecifierList
|
||||
import org.jetbrains.kotlin.psi.JetDelegatorToSuperClass
|
||||
import org.jetbrains.kotlin.psi.stubs.elements.JetClassElementType
|
||||
import org.jetbrains.kotlin.psi.stubs.elements.JetStubElementTypes
|
||||
import org.jetbrains.kotlin.psi.stubs.impl.KotlinClassStubImpl
|
||||
@@ -103,11 +105,10 @@ private class ClassClsStubBuilder(
|
||||
val isCompanionObject = classKind == ProtoBuf.Class.Kind.CLASS_OBJECT
|
||||
val fqName = outerContext.containerFqName.child(classId.getShortClassName())
|
||||
val shortName = fqName.shortName().ref()
|
||||
val superTypeRefs = supertypeIds.filter {
|
||||
val superTypeRefs = supertypeIds.filterNot {
|
||||
//TODO: filtering function types should go away
|
||||
!KotlinBuiltIns.isExactFunctionType(it.asSingleFqName().toUnsafe()) &&
|
||||
!KotlinBuiltIns.isExactExtensionFunctionType(it.asSingleFqName().toUnsafe())
|
||||
}.map { it.getShortClassName().ref() }.copyToArray()
|
||||
KotlinBuiltIns.isNumberedFunctionClassFqName(it.asSingleFqName().toUnsafe())
|
||||
}.map { it.getShortClassName().ref() }.toTypedArray()
|
||||
return when (classKind) {
|
||||
ProtoBuf.Class.Kind.OBJECT, ProtoBuf.Class.Kind.CLASS_OBJECT -> {
|
||||
KotlinObjectStubImpl(
|
||||
@@ -184,7 +185,7 @@ private class ClassClsStubBuilder(
|
||||
classBody,
|
||||
qualifiedName = c.containerFqName.child(name).ref(),
|
||||
name = name.ref(),
|
||||
superNames = array(),
|
||||
superNames = arrayOf(),
|
||||
isTrait = false,
|
||||
isEnumEntry = true,
|
||||
isLocal = false,
|
||||
|
||||
+17
-19
@@ -42,35 +42,31 @@ import java.util.ArrayList
|
||||
|
||||
class TypeClsStubBuilder(private val c: ClsStubBuilderContext) {
|
||||
|
||||
fun createTypeReferenceStub(parent: StubElement<out PsiElement>, typeProto: Type) {
|
||||
fun createTypeReferenceStub(parent: StubElement<out PsiElement>, type: Type) {
|
||||
val typeReference = KotlinPlaceHolderStubImpl<JetTypeReference>(parent, JetStubElementTypes.TYPE_REFERENCE)
|
||||
|
||||
val typeAnnotations = c.components.annotationLoader.loadTypeAnnotations(typeProto, c.nameResolver).filterNot {
|
||||
val annotations = c.components.annotationLoader.loadTypeAnnotations(type, c.nameResolver).filterNot {
|
||||
val isTopLevelClass = !it.isNestedClass()
|
||||
isTopLevelClass && it.asSingleFqName() in JvmAnnotationNames.ANNOTATIONS_COPIED_TO_TYPES
|
||||
}
|
||||
if (typeAnnotations.isNotEmpty()) {
|
||||
createAnnotationStubs(typeAnnotations, typeReference, needWrappingAnnotationEntries = true)
|
||||
}
|
||||
|
||||
createTypeStub(typeReference, typeProto)
|
||||
}
|
||||
val effectiveParent =
|
||||
if (type.getNullable()) KotlinPlaceHolderStubImpl<JetNullableType>(typeReference, JetStubElementTypes.NULLABLE_TYPE)
|
||||
else typeReference
|
||||
|
||||
private fun createTypeStub(parent: StubElement<out PsiElement>, type: Type) {
|
||||
val isNullable = type.getNullable()
|
||||
val effectiveParent = if (isNullable) KotlinPlaceHolderStubImpl<JetNullableType>(parent, JetStubElementTypes.NULLABLE_TYPE) else parent
|
||||
when (type.getConstructor().getKind()) {
|
||||
Type.Constructor.Kind.CLASS -> {
|
||||
createClassReferenceTypeStub(effectiveParent, type)
|
||||
createClassReferenceTypeStub(effectiveParent, type, annotations)
|
||||
}
|
||||
Type.Constructor.Kind.TYPE_PARAMETER -> {
|
||||
createTypeAnnotationStubs(effectiveParent, annotations)
|
||||
val typeParameterName = c.typeParameters[type.getConstructor().getId()]
|
||||
createStubForTypeName(ClassId.topLevel(FqName.topLevel(typeParameterName)), effectiveParent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun createClassReferenceTypeStub(parent: StubElement<out PsiElement>, type: Type) {
|
||||
private fun createClassReferenceTypeStub(parent: KotlinStubBaseImpl<*>, type: Type, annotations: List<ClassId>) {
|
||||
if (type.hasFlexibleTypeCapabilitiesId()) {
|
||||
val id = c.nameResolver.getString(type.getFlexibleTypeCapabilitiesId())
|
||||
|
||||
@@ -81,17 +77,19 @@ class TypeClsStubBuilder(private val c: ClsStubBuilderContext) {
|
||||
}
|
||||
|
||||
val classId = c.nameResolver.getClassId(type.getConstructor().getId())
|
||||
val fqName = classId.asSingleFqName().toUnsafe()
|
||||
val isFunctionType = KotlinBuiltIns.isExactFunctionType(fqName)
|
||||
val isExtensionFunctionType = KotlinBuiltIns.isExactExtensionFunctionType(fqName)
|
||||
if (isFunctionType || isExtensionFunctionType) {
|
||||
createFunctionTypeStub(parent, type, isExtensionFunctionType)
|
||||
if (KotlinBuiltIns.isNumberedFunctionClassFqName(classId.asSingleFqName().toUnsafe())) {
|
||||
val extension = annotations.any { annotation -> annotation.asSingleFqName() == KotlinBuiltIns.FQ_NAMES.extension }
|
||||
createFunctionTypeStub(parent, type, extension)
|
||||
return
|
||||
}
|
||||
createTypeAnnotationStubs(parent, annotations)
|
||||
val typeStub = createStubForTypeName(classId, parent)
|
||||
val typeArgumentProtoList = type.getArgumentList()
|
||||
createTypeArgumentListStub(typeStub, typeArgumentProtoList)
|
||||
return
|
||||
}
|
||||
|
||||
private fun createTypeAnnotationStubs(parent: KotlinStubBaseImpl<*>, annotations: List<ClassId>) {
|
||||
createAnnotationStubs(annotations, parent, needWrappingAnnotationEntries = true)
|
||||
}
|
||||
|
||||
private fun createTypeArgumentListStub(typeStub: KotlinUserTypeStub, typeArgumentProtoList: List<Type.Argument>) {
|
||||
@@ -129,7 +127,7 @@ class TypeClsStubBuilder(private val c: ClsStubBuilderContext) {
|
||||
|
||||
val parameterList = KotlinPlaceHolderStubImpl<JetParameterList>(functionType, JetStubElementTypes.VALUE_PARAMETER_LIST)
|
||||
val typeArgumentsWithoutReceiverAndReturnType
|
||||
= typeArgumentList.subList(if (isExtensionFunctionType) 1 else 0, typeArgumentList.size - 1)
|
||||
= typeArgumentList.subList(if (isExtensionFunctionType) 1 else 0, typeArgumentList.size() - 1)
|
||||
typeArgumentsWithoutReceiverAndReturnType.forEach { argument ->
|
||||
val parameter = KotlinParameterStubImpl(parameterList, fqName = null, name = null, isMutable = false, hasValOrVarNode = false, hasDefaultValue = false)
|
||||
createTypeReferenceStub(parameter, argument.getType())
|
||||
|
||||
@@ -62,8 +62,8 @@ private fun JetTypeElement.index<TDeclaration : JetCallableDeclaration>(declarat
|
||||
is JetNullableType -> getInnerType()?.index(declaration, sink)
|
||||
|
||||
is JetFunctionType -> {
|
||||
val typeName = (if (getReceiverTypeReference() != null) "ExtensionFunction" else "Function") + getParameters().size()
|
||||
occurrence(typeName)
|
||||
val arity = getParameters().size() + (if (getReceiverTypeReference() != null) 1 else 0)
|
||||
occurrence("Function$arity")
|
||||
}
|
||||
|
||||
is JetDynamicType -> occurrence("Any")
|
||||
|
||||
+2
-2
@@ -6,11 +6,11 @@ fun (() -> Unit)?.helloFun1() {
|
||||
fun Function0<Unit>.helloFun2() {
|
||||
}
|
||||
|
||||
fun ExtensionFunction0<String, Unit>.helloFun3() {
|
||||
fun @extension Function1<String, Unit>.helloFun3() {
|
||||
}
|
||||
|
||||
fun Function1<String, Unit>.helloFun4() {
|
||||
}
|
||||
|
||||
fun Any.helloAny() {
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -6,14 +6,14 @@ fun (String.() -> Unit)?.helloFun1() {
|
||||
fun Function0<Unit>.helloFun2() {
|
||||
}
|
||||
|
||||
fun ExtensionFunction0<String, Unit>.helloFun3() {
|
||||
fun @extension Function1<String, Unit>.helloFun3() {
|
||||
}
|
||||
|
||||
fun ExtensionFunction0<Int, Unit>.helloFun4() {
|
||||
fun @extension Function1<Int, Unit>.helloFun4() {
|
||||
}
|
||||
|
||||
fun Function1<String, Unit>.helloFun5() {
|
||||
}
|
||||
|
||||
fun Any.helloAny() {
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -8,6 +8,6 @@ fun firstFun(p: String.() -> Unit) {
|
||||
// ABSENT: helloFun2
|
||||
// EXIST: helloFun3
|
||||
// ABSENT: helloFun4
|
||||
// ABSENT: helloFun5
|
||||
// EXIST: helloFun5
|
||||
// EXIST: helloAny
|
||||
// NOTHING_ELSE: true
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.jetbrains.eval4j.jdi.asJdiValue
|
||||
import org.jetbrains.eval4j.jdi.asValue
|
||||
import org.jetbrains.eval4j.obj
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil
|
||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
@@ -99,8 +100,8 @@ class FrameVisitor(context: EvaluationContextImpl) {
|
||||
}
|
||||
|
||||
private fun isFunctionType(type: Type?): Boolean {
|
||||
if (type == null || AsmUtil.isPrimitive(type)) return false
|
||||
return type.getInternalName().startsWith("kotlin/Function") || type.getInternalName().startsWith("kotlin/ExtensionFunction")
|
||||
return type?.getSort() == Type.OBJECT &&
|
||||
type!!.getInternalName().startsWith(InlineCodegenUtil.NUMBERED_FUNCTION_PREFIX)
|
||||
}
|
||||
|
||||
private fun findLocalVariable(name: String, asmType: Type?, checkType: Boolean): Value? {
|
||||
|
||||
@@ -4,4 +4,4 @@ val c: <selection>() -> String</selection> = { "" }
|
||||
val d: () -> kotlin.String = { "" }
|
||||
val e: () -> Unit = { }
|
||||
val f: Any.() -> String = { "" }
|
||||
val g: ExtensionFunction0<String, String> = { "" }
|
||||
val g: @extension Function1<String, String> = { "" }
|
||||
|
||||
@@ -5,6 +5,6 @@ val d: (n: Int) -> kotlin.String = { "" }
|
||||
val e: (String) -> Int = { 0 }
|
||||
val f: () -> Int = { 0 }
|
||||
val g: Int.() -> String = { "" }
|
||||
val h: ExtensionFunction1<Int, Int, String> = { "" }
|
||||
val h: @extension Function2<Int, Int, String> = { "" }
|
||||
val i: (m: Int) -> kotlin.String = { "" }
|
||||
val j: ExtensionFunction0<Int, String> = { "" }
|
||||
val j: @extension Function1<Int, String> = { "" }
|
||||
|
||||
@@ -6,4 +6,8 @@ kotlin.Function1<kotlin.Int, kotlin.String>
|
||||
|
||||
(n: Int) -> kotlin.String
|
||||
|
||||
(m: Int) -> kotlin.String
|
||||
Int.() -> String
|
||||
|
||||
(m: Int) -> kotlin.String
|
||||
|
||||
@extension Function1<Int, String>
|
||||
|
||||
@@ -6,6 +6,6 @@ val e: (String) -> Int = { 0 }
|
||||
val f: () -> Int = { 0 }
|
||||
val g: Any.(Int) -> String = { "" }
|
||||
val h: Int.(Any) -> String = { "" }
|
||||
val i: ExtensionFunction2<Any, Any, Int, String> = { a, b -> "" }
|
||||
val i: @extension Function3<Any, Any, Int, String> = { a, b -> "" }
|
||||
val j: (t: Any, u: Int) -> kotlin.String = { a, b -> "" }
|
||||
val k: ExtensionFunction1<Any, Int, String> = { "" }
|
||||
val k: @extension Function2<Any, Int, String> = { "" }
|
||||
|
||||
@@ -6,4 +6,8 @@ kotlin.Function2<kotlin.Any, kotlin.Int, kotlin.String>
|
||||
|
||||
(a: Any, n: Int) -> kotlin.String
|
||||
|
||||
(t: Any, u: Int) -> kotlin.String
|
||||
Any.(Int) -> String
|
||||
|
||||
(t: Any, u: Int) -> kotlin.String
|
||||
|
||||
@extension Function2<Any, Int, String>
|
||||
|
||||
@@ -15,13 +15,13 @@ fun test1(): String {
|
||||
}
|
||||
|
||||
fun test2(): String {
|
||||
val a: ExtensionFunction1<*, *, *>.(ExtensionFunction1<*, *, *>)->String = { "a" }
|
||||
val b: ExtensionFunction1<*, *, *>.(ExtensionFunction1<*, *, *>)->String = {
|
||||
val aa = this as ExtensionFunction1<Any?, Any?, Any?>;
|
||||
val cc = it as ExtensionFunction1<Any?, Any?, Any?>;
|
||||
val a: (@extension Function2<*, *, *>).(@extension Function2<*, *, *>)->String = { "a" }
|
||||
val b: (@extension Function2<*, *, *>).(@extension Function2<*, *, *>)->String = {
|
||||
val aa = this as @extension Function2<Any?, Any?, Any?>;
|
||||
val cc = it as @extension Function2<Any?, Any?, Any?>;
|
||||
"${null.aa(null)} b ${null.cc(null)}"
|
||||
}
|
||||
val c: ExtensionFunction1<*, *, *>.(ExtensionFunction1<*, *, *>)->String = { "c" }
|
||||
val c: (@extension Function2<*, *, *>).(@extension Function2<*, *, *>)->String = { "c" }
|
||||
|
||||
val f = a.b(c) // works
|
||||
val s = a b c //compiler crashes
|
||||
|
||||
+1
-1
@@ -134,7 +134,7 @@ abstract class KDocTemplate() : TextTemplate() {
|
||||
return if (c != null) {
|
||||
val prefix = if (c.isAnnotation()) "@" else ""
|
||||
val cname = c.name
|
||||
if ((cname.startsWith("kotlin.Function") || cname.startsWith("kotlin.ExtensionFunction")) && arguments.isNotEmpty()) {
|
||||
if (cname.startsWith("kotlin.Function") && arguments.isNotEmpty()) {
|
||||
val rt = arguments.last()
|
||||
// TODO use drop()
|
||||
val rest = arguments.subList(0, arguments.size - 1).orEmpty()
|
||||
|
||||
Reference in New Issue
Block a user