From 6fb8af1dda9ae6f3a8aca08855673507e6c84529 Mon Sep 17 00:00:00 2001 From: Stanislav Erokhin Date: Tue, 24 Feb 2015 15:36:06 +0300 Subject: [PATCH] Move util backend function isNamedFun && isNamedFunOrLambda to frontend --- .../kotlin/codegen/ClosureCodegen.java | 2 +- .../kotlin/codegen/ExpressionCodegen.java | 2 +- .../kotlin/codegen/FunctionCodegen.java | 13 ++++--- .../codegen/ImplementationBodyCodegen.java | 3 +- .../codegen/binding/CodegenBinding.java | 17 --------- .../kotlin/codegen/context/LocalLookup.java | 3 +- .../kotlin/codegen/inline/InlineCodegen.java | 5 +-- .../kotlin/codegen/state/JetTypeMapper.java | 13 ++++--- .../kotlin/resolve/DescriptorResolver.java | 26 ++++++++++---- .../impl/FunctionExpressionDescriptor.java | 35 +++++++++++++++++++ .../kotlin/resolve/DescriptorUtils.java | 15 +++++++- 11 files changed, 88 insertions(+), 46 deletions(-) create mode 100644 core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/FunctionExpressionDescriptor.java diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ClosureCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ClosureCodegen.java index 42ca86dc3ae..83bcb97c50f 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ClosureCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ClosureCodegen.java @@ -336,7 +336,7 @@ public class ClosureCodegen extends MemberCodegen { : typeMapper.mapType((VariableDescriptor) descriptor); args.add(FieldInfo.createForHiddenField(ownerType, type, "$" + descriptor.getName().asString())); } - else if (isLocalNamedFun(descriptor)) { + else if (DescriptorUtils.isLocalFunction(descriptor)) { Type classType = asmTypeForAnonymousClass(bindingContext, (FunctionDescriptor) descriptor); args.add(FieldInfo.createForHiddenField(ownerType, classType, "$" + descriptor.getName().asString())); } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index e1c6abd5f76..90ba9dc699e 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -1820,7 +1820,7 @@ public class ExpressionCodegen extends JetVisitor implem @Nullable private NonLocalReturnInfo getNonLocalReturnInfo(@NotNull CallableMemberDescriptor descriptor, @NotNull JetReturnExpression expression) { //call inside lambda - if (isLambda(descriptor)) { + if (DescriptorUtils.isFunctionLiteral(descriptor)) { if (expression.getLabelName() == null) { //non labeled return couldn't be local in lambda FunctionDescriptor containingFunction = diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java index 0171be8782f..e135cf9d505 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java @@ -72,16 +72,12 @@ import java.util.*; import static org.jetbrains.kotlin.codegen.AsmUtil.*; import static org.jetbrains.kotlin.codegen.JvmSerializationBindings.*; -import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.isLocalNamedFun; import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DECLARATION; import static org.jetbrains.kotlin.load.java.JvmAnnotationNames.OLD_JET_VALUE_PARAMETER_ANNOTATION; import static org.jetbrains.kotlin.resolve.DescriptorToSourceUtils.getSourceFromDescriptor; -import static org.jetbrains.kotlin.resolve.DescriptorUtils.isFunctionLiteral; -import static org.jetbrains.kotlin.resolve.DescriptorUtils.isTrait; +import static org.jetbrains.kotlin.resolve.DescriptorUtils.*; import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE; -import static org.jetbrains.kotlin.resolve.jvm.diagnostics.DiagnosticsPackage.Delegation; -import static org.jetbrains.kotlin.resolve.jvm.diagnostics.DiagnosticsPackage.OtherOrigin; -import static org.jetbrains.kotlin.resolve.jvm.diagnostics.DiagnosticsPackage.Synthetic; +import static org.jetbrains.kotlin.resolve.jvm.diagnostics.DiagnosticsPackage.*; import static org.jetbrains.org.objectweb.asm.Opcodes.*; public class FunctionCodegen { @@ -305,7 +301,10 @@ public class FunctionCodegen { else if (dispatchReceiver != null) { return typeMapper.mapType(dispatchReceiver.getType()); } - else if (isFunctionLiteral(functionDescriptor) || isLocalNamedFun(functionDescriptor)) { + else if (isFunctionLiteral(functionDescriptor) || + isLocalFunction(functionDescriptor) || + isFunctionExpression(functionDescriptor) + ) { return typeMapper.mapType(context.getThisDescriptor()); } else { diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java index 2f6c94a3662..b2ea4e4810d 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java @@ -74,7 +74,6 @@ import static kotlin.KotlinPackage.firstOrNull; import static org.jetbrains.kotlin.codegen.AsmUtil.*; import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.*; import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.enumEntryNeedSubclass; -import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.isLocalNamedFun; import static org.jetbrains.kotlin.resolve.DescriptorToSourceUtils.descriptorToDeclaration; import static org.jetbrains.kotlin.resolve.DescriptorUtils.*; import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.*; @@ -1322,7 +1321,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { DeclarationDescriptor descriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, expr); DeclarationDescriptor toLookup; - if (isLocalNamedFun(descriptor)) { + if (isLocalFunction(descriptor)) { toLookup = descriptor; } else if (descriptor instanceof CallableMemberDescriptor) { diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenBinding.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenBinding.java index 8d62df29fa7..16d60c063bd 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenBinding.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenBinding.java @@ -252,23 +252,6 @@ public class CodegenBinding { return sortedAnswer; } - public static boolean isLocalNamedFun(@Nullable DeclarationDescriptor fd) { - return isLocalFunOrLambda(fd) && !fd.getName().isSpecial(); - } - - /*named or not*/ - public static boolean isLocalFunOrLambda(@Nullable DeclarationDescriptor fd) { - if (fd instanceof FunctionDescriptor) { - FunctionDescriptor descriptor = (FunctionDescriptor) fd; - return descriptor.getVisibility() == Visibilities.LOCAL; - } - return false; - } - - public static boolean isLambda(@Nullable DeclarationDescriptor fd) { - return fd instanceof AnonymousFunctionDescriptor; - } - @NotNull public static Type getAsmType(@NotNull BindingContext bindingContext, @NotNull ClassDescriptor klass) { Type type = bindingContext.get(ASM_TYPE, klass); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/context/LocalLookup.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/context/LocalLookup.java index 41965600b0f..e555b630c94 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/context/LocalLookup.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/context/LocalLookup.java @@ -30,6 +30,7 @@ import org.jetbrains.org.objectweb.asm.Type; import static org.jetbrains.kotlin.codegen.AsmUtil.CAPTURED_RECEIVER_FIELD; import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.*; +import static org.jetbrains.kotlin.resolve.DescriptorUtils.isLocalFunction; public interface LocalLookup { boolean lookupLocal(DeclarationDescriptor descriptor); @@ -74,7 +75,7 @@ public interface LocalLookup { LOCAL_NAMED_FUNCTION { @Override public boolean isCase(DeclarationDescriptor d) { - return isLocalNamedFun(d); + return isLocalFunction(d); } @Override diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.java index 665a69f6b8f..a59fab079b6 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.java @@ -23,7 +23,6 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.builtins.InlineStrategy; import org.jetbrains.kotlin.builtins.InlineUtil; import org.jetbrains.kotlin.codegen.*; -import org.jetbrains.kotlin.codegen.binding.CodegenBinding; import org.jetbrains.kotlin.codegen.context.CodegenContext; import org.jetbrains.kotlin.codegen.context.MethodContext; import org.jetbrains.kotlin.codegen.context.PackageContext; @@ -59,6 +58,8 @@ import java.util.Map; import static org.jetbrains.kotlin.codegen.AsmUtil.getMethodAsmFlags; import static org.jetbrains.kotlin.codegen.AsmUtil.isPrimitive; import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil.addInlineMarker; +import static org.jetbrains.kotlin.resolve.DescriptorUtils.isFunctionExpression; +import static org.jetbrains.kotlin.resolve.DescriptorUtils.isFunctionLiteral; public class InlineCodegen extends CallGenerator { private final GenerationState state; @@ -234,7 +235,7 @@ public class InlineCodegen extends CallGenerator { final CallableMemberDescriptor descriptor = codegen.getContext().getContextDescriptor(); - final boolean isLambda = CodegenBinding.isLocalFunOrLambda(descriptor) && descriptor.getName().isSpecial(); + final boolean isLambda = isFunctionExpression(descriptor) || isFunctionLiteral(descriptor); @Override public boolean isMyLabel(@NotNull String name) { diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/JetTypeMapper.java index 4e2c9560b80..9bca0bb5cd1 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/JetTypeMapper.java @@ -20,18 +20,17 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicObjects; import org.jetbrains.kotlin.builtins.KotlinBuiltIns; import org.jetbrains.kotlin.codegen.*; import org.jetbrains.kotlin.codegen.binding.CodegenBinding; import org.jetbrains.kotlin.codegen.binding.MutableClosure; import org.jetbrains.kotlin.codegen.binding.PsiCodegenPredictor; import org.jetbrains.kotlin.codegen.context.CodegenContext; +import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicObjects; import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter; import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.annotations.Annotated; import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor; -import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor; import org.jetbrains.kotlin.load.java.JvmAbi; import org.jetbrains.kotlin.load.kotlin.PackageClassUtils; import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils; @@ -113,7 +112,7 @@ public class JetTypeMapper { @NotNull public Type mapOwner(@NotNull DeclarationDescriptor descriptor, boolean isInsideModule) { - if (isLocalNamedFun(descriptor)) { + if (isLocalFunction(descriptor)) { return asmTypeForAnonymousClass(bindingContext, (FunctionDescriptor) descriptor); } @@ -561,7 +560,7 @@ public class JetTypeMapper { } } - Type calleeType = isLocalNamedFun(functionDescriptor) ? owner : null; + Type calleeType = isLocalFunction(functionDescriptor) ? owner : null; Type receiverParameterType; ReceiverParameterDescriptor receiverParameter = functionDescriptor.getOriginal().getExtensionReceiverParameter(); @@ -621,7 +620,7 @@ public class JetTypeMapper { return isAccessor ? "access$" + accessorName : accessorName; } - else if (descriptor instanceof AnonymousFunctionDescriptor) { + else if (isFunctionLiteral(descriptor)) { PsiElement element = DescriptorToSourceUtils.getSourceFromDescriptor(descriptor); if (element instanceof JetFunctionLiteral) { PsiElement expression = element.getParent(); @@ -635,7 +634,7 @@ public class JetTypeMapper { return "invoke"; } - else if (isLocalFunOrLambda(descriptor)) { + else if (isLocalFunction(descriptor) || isFunctionExpression(descriptor)) { return "invoke"; } else { @@ -896,7 +895,7 @@ public class JetTypeMapper { } type = sharedVarType; } - else if (isLocalNamedFun(variableDescriptor)) { + else if (isLocalFunction(variableDescriptor)) { //noinspection CastConflictsWithInstanceof type = asmTypeForAnonymousClass(bindingContext, (FunctionDescriptor) variableDescriptor); } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java index 8bf40a7c4d6..ac0e834279e 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java @@ -278,13 +278,25 @@ public class DescriptorResolver { trace.report(FUNCTION_DECLARATION_WITH_NO_NAME.on(function)); } - final SimpleFunctionDescriptorImpl functionDescriptor = SimpleFunctionDescriptorImpl.create( - containingDescriptor, - annotations, - function.getNameAsSafeName(), - CallableMemberDescriptor.Kind.DECLARATION, - toSourceElement(function) - ); + final SimpleFunctionDescriptorImpl functionDescriptor; + if (nameCanBeOmitted) { // todo remove this hack + functionDescriptor = new FunctionExpressionDescriptor( + containingDescriptor, + annotations, + function.getNameAsSafeName(), + CallableMemberDescriptor.Kind.DECLARATION, + toSourceElement(function) + ); + } + else { + functionDescriptor = SimpleFunctionDescriptorImpl.create( + containingDescriptor, + annotations, + function.getNameAsSafeName(), + CallableMemberDescriptor.Kind.DECLARATION, + toSourceElement(function) + ); + } WritableScope innerScope = new WritableScopeImpl(scope, functionDescriptor, new TraceBasedRedeclarationHandler(trace), "Function descriptor header scope"); innerScope.addLabeledDeclaration(functionDescriptor); diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/FunctionExpressionDescriptor.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/FunctionExpressionDescriptor.java new file mode 100644 index 00000000000..f05cc300eb6 --- /dev/null +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/FunctionExpressionDescriptor.java @@ -0,0 +1,35 @@ +/* + * 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.descriptors.impl; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor; +import org.jetbrains.kotlin.descriptors.SourceElement; +import org.jetbrains.kotlin.descriptors.annotations.Annotations; +import org.jetbrains.kotlin.name.Name; + +public class FunctionExpressionDescriptor extends SimpleFunctionDescriptorImpl { + public FunctionExpressionDescriptor( + @NotNull DeclarationDescriptor containingDeclaration, + @NotNull Annotations annotations, + @NotNull Name name, + @NotNull Kind kind, + @NotNull SourceElement source + ) { + super(containingDeclaration, null, annotations, name, kind, source); + } +} diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.java b/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.java index 782dffddee4..a82d0676d32 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.java +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.java @@ -22,6 +22,8 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.builtins.KotlinBuiltIns; import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor; +import org.jetbrains.kotlin.descriptors.impl.FunctionExpressionDescriptor; +import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl; import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.name.FqNameUnsafe; import org.jetbrains.kotlin.name.Name; @@ -236,10 +238,21 @@ public class DescriptorUtils { return false; } - public static boolean isFunctionLiteral(@NotNull FunctionDescriptor descriptor) { + public static boolean isFunctionLiteral(@Nullable DeclarationDescriptor descriptor) { return descriptor instanceof AnonymousFunctionDescriptor; } + public static boolean isLocalFunction(@Nullable DeclarationDescriptor descriptor) { + if (descriptor != null && descriptor.getClass() == SimpleFunctionDescriptorImpl.class) { + return ((SimpleFunctionDescriptorImpl) descriptor).getVisibility() == Visibilities.LOCAL; + } + return false; + } + + public static boolean isFunctionExpression(@Nullable DeclarationDescriptor descriptor) { + return descriptor instanceof FunctionExpressionDescriptor; + } + public static boolean isDefaultObject(@Nullable DeclarationDescriptor descriptor) { return isKindOf(descriptor, ClassKind.OBJECT) && ((ClassDescriptor) descriptor).isDefaultObject(); }