diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/FunctionDescriptorUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/FunctionDescriptorUtil.java index 95b0446da29..3e5650d8ee6 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/FunctionDescriptorUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/FunctionDescriptorUtil.java @@ -127,10 +127,20 @@ public class FunctionDescriptorUtil { JetStandardClasses.getValueParameters(functionDescriptor, functionType), JetStandardClasses.getReturnTypeFromFunctionType(functionType), Modality.FINAL, - Visibilities.LOCAL); + Visibilities.PUBLIC); } public static D alphaConvertTypeParameters(D candidate) { return (D) candidate.substitute(MAKE_TYPE_PARAMETERS_FRESH); } + + public static FunctionDescriptor getInvokeFunction(@NotNull JetType functionType) { + assert JetStandardClasses.isFunctionType(functionType); + + ClassifierDescriptor classDescriptorForFunction = functionType.getConstructor().getDeclarationDescriptor(); + assert classDescriptorForFunction instanceof ClassDescriptor; + Set invokeFunctions = ((ClassDescriptor) classDescriptorForFunction).getMemberScope(functionType.getArguments()).getFunctions("invoke"); + assert invokeFunctions.size() == 1; + return invokeFunctions.iterator().next(); + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/lang/JetStandardClasses.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/lang/JetStandardClasses.java index 4074771ecb7..c34da66c0f7 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/lang/JetStandardClasses.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/lang/JetStandardClasses.java @@ -18,6 +18,7 @@ package org.jetbrains.jet.lang.types.lang; import com.google.common.collect.Lists; import com.google.common.collect.Sets; +import com.intellij.openapi.util.Pair; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; @@ -25,6 +26,8 @@ import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.FqName; import org.jetbrains.jet.lang.resolve.scopes.*; +import org.jetbrains.jet.lang.resolve.scopes.receivers.ClassReceiver; +import org.jetbrains.jet.lang.resolve.scopes.receivers.ExtensionReceiver; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetTypeImpl; @@ -189,16 +192,23 @@ public class JetStandardClasses { STANDARD_CLASSES_NAMESPACE, Collections.emptyList(), "Function" + i); + + SimpleFunctionDescriptorImpl invoke = new SimpleFunctionDescriptorImpl(function, Collections.emptyList(), "invoke", CallableMemberDescriptor.Kind.DECLARATION); + WritableScope scopeForInvoke = createScopeForInvokeFunction(function, invoke); + List typeParameters = createTypeParameters(i, function); FUNCTION[i] = function.initialize( false, - createTypeParameters(i, function), - Collections.singleton(getAnyType()), STUB, Collections.emptySet(), null); + typeParameters, + Collections.singleton(getAnyType()), scopeForInvoke, Collections.emptySet(), null); FUNCTION_TYPE_CONSTRUCTORS.add(FUNCTION[i].getTypeConstructor()); + FunctionDescriptorUtil.initializeFromFunctionType(invoke, function.getDefaultType(), new ClassReceiver(FUNCTION[i])); ClassDescriptorImpl receiverFunction = new ClassDescriptorImpl( STANDARD_CLASSES_NAMESPACE, Collections.emptyList(), "ExtensionFunction" + i); + SimpleFunctionDescriptorImpl invokeWithReceiver = new SimpleFunctionDescriptorImpl(receiverFunction, Collections.emptyList(), "invoke", CallableMemberDescriptor.Kind.DECLARATION); + WritableScope scopeForInvokeWithReceiver = createScopeForInvokeFunction(receiverFunction, invokeWithReceiver); List parameters = createTypeParameters(i, receiverFunction); parameters.add(0, TypeParameterDescriptor.createWithDefaultBound( receiverFunction, @@ -207,11 +217,19 @@ public class JetStandardClasses { RECEIVER_FUNCTION[i] = receiverFunction.initialize( false, parameters, - Collections.singleton(getAnyType()), STUB, Collections.emptySet(), null); + Collections.singleton(getAnyType()), scopeForInvokeWithReceiver, Collections.emptySet(), null); RECEIVER_FUNCTION_TYPE_CONSTRUCTORS.add(RECEIVER_FUNCTION[i].getTypeConstructor()); + FunctionDescriptorUtil.initializeFromFunctionType(invokeWithReceiver, receiverFunction.getDefaultType(), new ClassReceiver(RECEIVER_FUNCTION[i])); } } + private static WritableScope createScopeForInvokeFunction(ClassDescriptorImpl function, SimpleFunctionDescriptorImpl invoke) { + WritableScope scopeForInvoke = new WritableScopeImpl(STUB, function, RedeclarationHandler.THROW_EXCEPTION).setDebugName("Scope for function type"); + scopeForInvoke.addFunctionDescriptor(invoke); + scopeForInvoke.changeLockLevel(WritableScope.LockLevel.READING); + return scopeForInvoke; + } + private static List createTypeParameters(int parameterCount, ClassDescriptorImpl function) { List parameters = new ArrayList(); for (int j = 0; j < parameterCount; j++) { @@ -411,8 +429,9 @@ public class JetStandardClasses { } arguments.add(defaultProjection(returnType)); int size = parameterTypes.size(); - TypeConstructor constructor = receiverType == null ? FUNCTION[size].getTypeConstructor() : RECEIVER_FUNCTION[size].getTypeConstructor(); - return new JetTypeImpl(annotations, constructor, false, arguments, STUB); + ClassDescriptor classDescriptor = receiverType == null ? FUNCTION[size] : RECEIVER_FUNCTION[size]; + TypeConstructor constructor = classDescriptor.getTypeConstructor(); + return new JetTypeImpl(annotations, constructor, false, arguments, classDescriptor.getMemberScope(arguments)); } private static TypeProjection defaultProjection(JetType returnType) {