Move util backend function isNamedFun && isNamedFunOrLambda to frontend

This commit is contained in:
Stanislav Erokhin
2015-02-24 15:36:06 +03:00
parent fa9ca54e78
commit 6fb8af1dda
11 changed files with 88 additions and 46 deletions
@@ -336,7 +336,7 @@ public class ClosureCodegen extends MemberCodegen<JetElement> {
: typeMapper.mapType((VariableDescriptor) descriptor); : typeMapper.mapType((VariableDescriptor) descriptor);
args.add(FieldInfo.createForHiddenField(ownerType, type, "$" + descriptor.getName().asString())); args.add(FieldInfo.createForHiddenField(ownerType, type, "$" + descriptor.getName().asString()));
} }
else if (isLocalNamedFun(descriptor)) { else if (DescriptorUtils.isLocalFunction(descriptor)) {
Type classType = asmTypeForAnonymousClass(bindingContext, (FunctionDescriptor) descriptor); Type classType = asmTypeForAnonymousClass(bindingContext, (FunctionDescriptor) descriptor);
args.add(FieldInfo.createForHiddenField(ownerType, classType, "$" + descriptor.getName().asString())); args.add(FieldInfo.createForHiddenField(ownerType, classType, "$" + descriptor.getName().asString()));
} }
@@ -1820,7 +1820,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
@Nullable @Nullable
private NonLocalReturnInfo getNonLocalReturnInfo(@NotNull CallableMemberDescriptor descriptor, @NotNull JetReturnExpression expression) { private NonLocalReturnInfo getNonLocalReturnInfo(@NotNull CallableMemberDescriptor descriptor, @NotNull JetReturnExpression expression) {
//call inside lambda //call inside lambda
if (isLambda(descriptor)) { if (DescriptorUtils.isFunctionLiteral(descriptor)) {
if (expression.getLabelName() == null) { if (expression.getLabelName() == null) {
//non labeled return couldn't be local in lambda //non labeled return couldn't be local in lambda
FunctionDescriptor containingFunction = FunctionDescriptor containingFunction =
@@ -72,16 +72,12 @@ import java.util.*;
import static org.jetbrains.kotlin.codegen.AsmUtil.*; import static org.jetbrains.kotlin.codegen.AsmUtil.*;
import static org.jetbrains.kotlin.codegen.JvmSerializationBindings.*; 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.descriptors.CallableMemberDescriptor.Kind.DECLARATION;
import static org.jetbrains.kotlin.load.java.JvmAnnotationNames.OLD_JET_VALUE_PARAMETER_ANNOTATION; 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.DescriptorToSourceUtils.getSourceFromDescriptor;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isFunctionLiteral; import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isTrait;
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE; 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.*;
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.DiagnosticsPackage.OtherOrigin;
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.DiagnosticsPackage.Synthetic;
import static org.jetbrains.org.objectweb.asm.Opcodes.*; import static org.jetbrains.org.objectweb.asm.Opcodes.*;
public class FunctionCodegen { public class FunctionCodegen {
@@ -305,7 +301,10 @@ public class FunctionCodegen {
else if (dispatchReceiver != null) { else if (dispatchReceiver != null) {
return typeMapper.mapType(dispatchReceiver.getType()); return typeMapper.mapType(dispatchReceiver.getType());
} }
else if (isFunctionLiteral(functionDescriptor) || isLocalNamedFun(functionDescriptor)) { else if (isFunctionLiteral(functionDescriptor) ||
isLocalFunction(functionDescriptor) ||
isFunctionExpression(functionDescriptor)
) {
return typeMapper.mapType(context.getThisDescriptor()); return typeMapper.mapType(context.getThisDescriptor());
} }
else { else {
@@ -74,7 +74,6 @@ import static kotlin.KotlinPackage.firstOrNull;
import static org.jetbrains.kotlin.codegen.AsmUtil.*; import static org.jetbrains.kotlin.codegen.AsmUtil.*;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.*; import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.*;
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.enumEntryNeedSubclass; 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.DescriptorToSourceUtils.descriptorToDeclaration;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*; import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.*; 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 descriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, expr);
DeclarationDescriptor toLookup; DeclarationDescriptor toLookup;
if (isLocalNamedFun(descriptor)) { if (isLocalFunction(descriptor)) {
toLookup = descriptor; toLookup = descriptor;
} }
else if (descriptor instanceof CallableMemberDescriptor) { else if (descriptor instanceof CallableMemberDescriptor) {
@@ -252,23 +252,6 @@ public class CodegenBinding {
return sortedAnswer; 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 @NotNull
public static Type getAsmType(@NotNull BindingContext bindingContext, @NotNull ClassDescriptor klass) { public static Type getAsmType(@NotNull BindingContext bindingContext, @NotNull ClassDescriptor klass) {
Type type = bindingContext.get(ASM_TYPE, klass); Type type = bindingContext.get(ASM_TYPE, klass);
@@ -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.AsmUtil.CAPTURED_RECEIVER_FIELD;
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.*; import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.*;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isLocalFunction;
public interface LocalLookup { public interface LocalLookup {
boolean lookupLocal(DeclarationDescriptor descriptor); boolean lookupLocal(DeclarationDescriptor descriptor);
@@ -74,7 +75,7 @@ public interface LocalLookup {
LOCAL_NAMED_FUNCTION { LOCAL_NAMED_FUNCTION {
@Override @Override
public boolean isCase(DeclarationDescriptor d) { public boolean isCase(DeclarationDescriptor d) {
return isLocalNamedFun(d); return isLocalFunction(d);
} }
@Override @Override
@@ -23,7 +23,6 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.builtins.InlineStrategy; import org.jetbrains.kotlin.builtins.InlineStrategy;
import org.jetbrains.kotlin.builtins.InlineUtil; import org.jetbrains.kotlin.builtins.InlineUtil;
import org.jetbrains.kotlin.codegen.*; 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.CodegenContext;
import org.jetbrains.kotlin.codegen.context.MethodContext; import org.jetbrains.kotlin.codegen.context.MethodContext;
import org.jetbrains.kotlin.codegen.context.PackageContext; 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.getMethodAsmFlags;
import static org.jetbrains.kotlin.codegen.AsmUtil.isPrimitive; import static org.jetbrains.kotlin.codegen.AsmUtil.isPrimitive;
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil.addInlineMarker; 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 { public class InlineCodegen extends CallGenerator {
private final GenerationState state; private final GenerationState state;
@@ -234,7 +235,7 @@ public class InlineCodegen extends CallGenerator {
final CallableMemberDescriptor descriptor = codegen.getContext().getContextDescriptor(); final CallableMemberDescriptor descriptor = codegen.getContext().getContextDescriptor();
final boolean isLambda = CodegenBinding.isLocalFunOrLambda(descriptor) && descriptor.getName().isSpecial(); final boolean isLambda = isFunctionExpression(descriptor) || isFunctionLiteral(descriptor);
@Override @Override
public boolean isMyLabel(@NotNull String name) { public boolean isMyLabel(@NotNull String name) {
@@ -20,18 +20,17 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicObjects;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns; import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.codegen.*; import org.jetbrains.kotlin.codegen.*;
import org.jetbrains.kotlin.codegen.binding.CodegenBinding; import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
import org.jetbrains.kotlin.codegen.binding.MutableClosure; import org.jetbrains.kotlin.codegen.binding.MutableClosure;
import org.jetbrains.kotlin.codegen.binding.PsiCodegenPredictor; import org.jetbrains.kotlin.codegen.binding.PsiCodegenPredictor;
import org.jetbrains.kotlin.codegen.context.CodegenContext; 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.codegen.signature.BothSignatureWriter;
import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.Annotated; import org.jetbrains.kotlin.descriptors.annotations.Annotated;
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor; 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.java.JvmAbi;
import org.jetbrains.kotlin.load.kotlin.PackageClassUtils; import org.jetbrains.kotlin.load.kotlin.PackageClassUtils;
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils; import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils;
@@ -113,7 +112,7 @@ public class JetTypeMapper {
@NotNull @NotNull
public Type mapOwner(@NotNull DeclarationDescriptor descriptor, boolean isInsideModule) { public Type mapOwner(@NotNull DeclarationDescriptor descriptor, boolean isInsideModule) {
if (isLocalNamedFun(descriptor)) { if (isLocalFunction(descriptor)) {
return asmTypeForAnonymousClass(bindingContext, (FunctionDescriptor) 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; Type receiverParameterType;
ReceiverParameterDescriptor receiverParameter = functionDescriptor.getOriginal().getExtensionReceiverParameter(); ReceiverParameterDescriptor receiverParameter = functionDescriptor.getOriginal().getExtensionReceiverParameter();
@@ -621,7 +620,7 @@ public class JetTypeMapper {
return isAccessor ? "access$" + accessorName : accessorName; return isAccessor ? "access$" + accessorName : accessorName;
} }
else if (descriptor instanceof AnonymousFunctionDescriptor) { else if (isFunctionLiteral(descriptor)) {
PsiElement element = DescriptorToSourceUtils.getSourceFromDescriptor(descriptor); PsiElement element = DescriptorToSourceUtils.getSourceFromDescriptor(descriptor);
if (element instanceof JetFunctionLiteral) { if (element instanceof JetFunctionLiteral) {
PsiElement expression = element.getParent(); PsiElement expression = element.getParent();
@@ -635,7 +634,7 @@ public class JetTypeMapper {
return "invoke"; return "invoke";
} }
else if (isLocalFunOrLambda(descriptor)) { else if (isLocalFunction(descriptor) || isFunctionExpression(descriptor)) {
return "invoke"; return "invoke";
} }
else { else {
@@ -896,7 +895,7 @@ public class JetTypeMapper {
} }
type = sharedVarType; type = sharedVarType;
} }
else if (isLocalNamedFun(variableDescriptor)) { else if (isLocalFunction(variableDescriptor)) {
//noinspection CastConflictsWithInstanceof //noinspection CastConflictsWithInstanceof
type = asmTypeForAnonymousClass(bindingContext, (FunctionDescriptor) variableDescriptor); type = asmTypeForAnonymousClass(bindingContext, (FunctionDescriptor) variableDescriptor);
} }
@@ -278,13 +278,25 @@ public class DescriptorResolver {
trace.report(FUNCTION_DECLARATION_WITH_NO_NAME.on(function)); trace.report(FUNCTION_DECLARATION_WITH_NO_NAME.on(function));
} }
final SimpleFunctionDescriptorImpl functionDescriptor = SimpleFunctionDescriptorImpl.create( final SimpleFunctionDescriptorImpl functionDescriptor;
containingDescriptor, if (nameCanBeOmitted) { // todo remove this hack
annotations, functionDescriptor = new FunctionExpressionDescriptor(
function.getNameAsSafeName(), containingDescriptor,
CallableMemberDescriptor.Kind.DECLARATION, annotations,
toSourceElement(function) 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), WritableScope innerScope = new WritableScopeImpl(scope, functionDescriptor, new TraceBasedRedeclarationHandler(trace),
"Function descriptor header scope"); "Function descriptor header scope");
innerScope.addLabeledDeclaration(functionDescriptor); innerScope.addLabeledDeclaration(functionDescriptor);
@@ -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);
}
}
@@ -22,6 +22,8 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns; import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor; 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.FqName;
import org.jetbrains.kotlin.name.FqNameUnsafe; import org.jetbrains.kotlin.name.FqNameUnsafe;
import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.name.Name;
@@ -236,10 +238,21 @@ public class DescriptorUtils {
return false; return false;
} }
public static boolean isFunctionLiteral(@NotNull FunctionDescriptor descriptor) { public static boolean isFunctionLiteral(@Nullable DeclarationDescriptor descriptor) {
return descriptor instanceof AnonymousFunctionDescriptor; 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) { public static boolean isDefaultObject(@Nullable DeclarationDescriptor descriptor) {
return isKindOf(descriptor, ClassKind.OBJECT) && ((ClassDescriptor) descriptor).isDefaultObject(); return isKindOf(descriptor, ClassKind.OBJECT) && ((ClassDescriptor) descriptor).isDefaultObject();
} }