From 4a2fac6f40b61868a5cec6fc3fb2c9e3602c6637 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Wed, 15 Apr 2015 18:52:49 +0300 Subject: [PATCH] Add utility InlineUtil.isInline instead of interface method in SimpleFunctionDescriptor Also fix some warnings and reformat along the way --- .../org/jetbrains/kotlin/codegen/AsmUtil.java | 19 +----- .../kotlin/codegen/ExpressionCodegen.java | 8 +-- .../kotlin/codegen/context/MethodContext.java | 7 +- .../kotlin/codegen/inline/InlineCodegen.java | 11 +-- .../resolve/FunctionAnalyzerExtension.java | 15 ++--- .../kotlin/resolve/InlineDescriptorUtils.java | 4 +- .../resolve/calls/checkers/InlineChecker.java | 47 ++++++------- .../calls/checkers/InlineCheckerWrapper.kt | 9 +-- .../extension/InlineAnalyzerExtension.java | 8 +-- .../jetbrains/kotlin/builtins/InlineUtil.java | 9 +-- .../descriptors/SimpleFunctionDescriptor.java | 5 -- .../impl/SimpleFunctionDescriptorImpl.java | 31 ++++----- .../kotlin/idea/completion/CompletionUtils.kt | 4 +- .../idea/debugger/JetPositionManager.kt | 67 +++++++++---------- .../internal/KotlinBytecodeToolWindow.java | 21 +++--- .../reference/CallExpressionTranslator.java | 6 +- 16 files changed, 113 insertions(+), 158 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java index 1c202339f0c..30720159037 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java @@ -24,6 +24,7 @@ import kotlin.Function1; import kotlin.Unit; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.kotlin.builtins.InlineUtil; import org.jetbrains.kotlin.builtins.KotlinBuiltIns; import org.jetbrains.kotlin.builtins.PrimitiveType; import org.jetbrains.kotlin.codegen.binding.CalculatedClosure; @@ -40,7 +41,6 @@ import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor; import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.resolve.DescriptorUtils; import org.jetbrains.kotlin.resolve.annotations.AnnotationsPackage; -import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall; import org.jetbrains.kotlin.resolve.jvm.JvmClassName; import org.jetbrains.kotlin.resolve.jvm.JvmPackage; import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType; @@ -260,20 +260,7 @@ public class AsmUtil { } public static int getVisibilityAccessFlagForAnonymous(@NotNull ClassDescriptor descriptor) { - if (isDeclarationInsideInlineFunction(descriptor)) { - return ACC_PUBLIC; - } - return NO_FLAG_PACKAGE_PRIVATE; - } - - private static boolean isDeclarationInsideInlineFunction(@NotNull ClassDescriptor descriptor) { - //NB: constructor context couldn't be inline - DeclarationDescriptor parentDeclaration = descriptor.getContainingDeclaration(); - if (parentDeclaration instanceof SimpleFunctionDescriptor && - ((SimpleFunctionDescriptor) parentDeclaration).getInlineStrategy().isInline()) { - return true; - } - return false; + return InlineUtil.isInline(descriptor.getContainingDeclaration()) ? ACC_PUBLIC : NO_FLAG_PACKAGE_PRIVATE; } public static int calculateInnerClassAccessFlags(@NotNull ClassDescriptor innerClass) { @@ -536,7 +523,7 @@ public class AsmUtil { } public static void genAreEqualCall(InstructionAdapter v) { - v.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, "areEqual", "(Ljava/lang/Object;Ljava/lang/Object;)Z"); + v.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, "areEqual", "(Ljava/lang/Object;Ljava/lang/Object;)Z", false); } public static void genIncrement(Type expectedType, int myDelta, InstructionAdapter v) { diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index 237252adcf2..e11525188a4 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -31,6 +31,7 @@ import kotlin.Unit; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.backend.common.CodegenUtil; +import org.jetbrains.kotlin.builtins.InlineUtil; import org.jetbrains.kotlin.builtins.KotlinBuiltIns; import org.jetbrains.kotlin.codegen.binding.CalculatedClosure; import org.jetbrains.kotlin.codegen.context.*; @@ -2377,20 +2378,19 @@ public class ExpressionCodegen extends JetVisitor implem protected CallGenerator getOrCreateCallGenerator( @NotNull CallableDescriptor descriptor, @Nullable JetElement callElement, - @Nullable ReifiedTypeParameterMappings reifierTypeParameterMappings + @Nullable ReifiedTypeParameterMappings reifiedTypeParameterMappings ) { if (callElement == null) return defaultCallGenerator; // We should inline callable containing reified type parameters even if inline is disabled // because they may contain something to reify and straight call will probably fail at runtime boolean isInline = (state.isInlineEnabled() || DescriptorUtils.containsReifiedTypeParameters(descriptor)) && - descriptor instanceof SimpleFunctionDescriptor && - ((SimpleFunctionDescriptor) descriptor).getInlineStrategy().isInline(); + InlineUtil.isInline(descriptor); if (!isInline) return defaultCallGenerator; SimpleFunctionDescriptor original = DescriptorUtils.unwrapFakeOverride((SimpleFunctionDescriptor) descriptor.getOriginal()); - return new InlineCodegen(this, state, original, callElement, reifierTypeParameterMappings); + return new InlineCodegen(this, state, original, callElement, reifiedTypeParameterMappings); } @NotNull diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/context/MethodContext.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/context/MethodContext.java index 9db5cff09be..f3024061d6f 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/context/MethodContext.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/context/MethodContext.java @@ -18,6 +18,7 @@ package org.jetbrains.kotlin.codegen.context; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.kotlin.builtins.InlineUtil; import org.jetbrains.kotlin.codegen.AsmUtil; import org.jetbrains.kotlin.codegen.JvmCodegenUtil; import org.jetbrains.kotlin.codegen.OwnerKind; @@ -112,11 +113,7 @@ public class MethodContext extends CodegenContext { } public boolean isInlineFunction() { - DeclarationDescriptor descriptor = getContextDescriptor(); - if (descriptor instanceof SimpleFunctionDescriptor) { - return ((SimpleFunctionDescriptor) descriptor).getInlineStrategy().isInline(); - } - return false; + return InlineUtil.isInline(getContextDescriptor()); } public boolean isInliningLambda() { 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 01f32cfa384..5eb5c289218 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.java @@ -55,7 +55,10 @@ import org.jetbrains.org.objectweb.asm.tree.MethodNode; import org.jetbrains.org.objectweb.asm.tree.TryCatchBlockNode; import java.io.IOException; -import java.util.*; +import java.util.HashMap; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; import static org.jetbrains.kotlin.codegen.AsmUtil.getMethodAsmFlags; import static org.jetbrains.kotlin.codegen.AsmUtil.isPrimitive; @@ -94,7 +97,7 @@ public class InlineCodegen extends CallGenerator { @NotNull JetElement callElement, @Nullable ReifiedTypeParameterMappings typeParameterMappings ) { - assert functionDescriptor.getInlineStrategy().isInline() : "InlineCodegen could inline only inline function but " + functionDescriptor; + assert InlineUtil.isInline(functionDescriptor) : "InlineCodegen could inline only inline function: " + functionDescriptor; this.state = state; this.typeMapper = state.getTypeMapper(); @@ -109,8 +112,8 @@ public class InlineCodegen extends CallGenerator { context = (MethodContext) getContext(functionDescriptor, state); jvmSignature = typeMapper.mapSignature(functionDescriptor, context.getContextKind()); - InlineStrategy inlineStrategy = - codegen.getContext().isInlineFunction() ? InlineStrategy.IN_PLACE : functionDescriptor.getInlineStrategy(); + // TODO: implement AS_FUNCTION inline strategy + InlineStrategy inlineStrategy = InlineUtil.getInlineType(functionDescriptor); this.asFunctionInline = false; isSameModule = JvmCodegenUtil.isCallInsideSameModuleAsDeclared(functionDescriptor, codegen.getContext(), state.getOutDirectory()); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/FunctionAnalyzerExtension.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/FunctionAnalyzerExtension.java index 0ed46da49f2..b2f34ca1ed0 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/FunctionAnalyzerExtension.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/FunctionAnalyzerExtension.java @@ -17,13 +17,14 @@ package org.jetbrains.kotlin.resolve; import org.jetbrains.annotations.NotNull; +import org.jetbrains.kotlin.builtins.InlineUtil; import org.jetbrains.kotlin.descriptors.FunctionDescriptor; import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor; import org.jetbrains.kotlin.psi.JetNamedFunction; import org.jetbrains.kotlin.resolve.extension.InlineAnalyzerExtension; import javax.inject.Inject; -import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Map; @@ -45,8 +46,7 @@ public class FunctionAnalyzerExtension { JetNamedFunction function = entry.getKey(); SimpleFunctionDescriptor functionDescriptor = entry.getValue(); - List extensions = getExtensions(functionDescriptor); - for (AnalyzerExtension extension : extensions) { + for (AnalyzerExtension extension : getExtensions(functionDescriptor)) { extension.process(functionDescriptor, function, trace); } } @@ -54,12 +54,9 @@ public class FunctionAnalyzerExtension { @NotNull private static List getExtensions(@NotNull FunctionDescriptor functionDescriptor) { - List list = new ArrayList(); - if (functionDescriptor instanceof SimpleFunctionDescriptor && - ((SimpleFunctionDescriptor) functionDescriptor).getInlineStrategy().isInline()) { - list.add(InlineAnalyzerExtension.INSTANCE); + if (InlineUtil.isInline(functionDescriptor)) { + return Collections.singletonList(InlineAnalyzerExtension.INSTANCE); } - return list; + return Collections.emptyList(); } - } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/InlineDescriptorUtils.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/InlineDescriptorUtils.java index 459dcbeb629..6c33ddaf22c 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/InlineDescriptorUtils.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/InlineDescriptorUtils.java @@ -68,9 +68,7 @@ public class InlineDescriptorUtils { JetExpression call = JetPsiUtil.getParentCallIfPresent(lambdaExpression); if (call != null) { ResolvedCall resolvedCall = CallUtilPackage.getResolvedCall(call, bindingContext); - CallableDescriptor resultingDescriptor = resolvedCall == null ? null : resolvedCall.getResultingDescriptor(); - if (resultingDescriptor instanceof SimpleFunctionDescriptor && - ((SimpleFunctionDescriptor) resultingDescriptor).getInlineStrategy().isInline()) { + if (resolvedCall != null && InlineUtil.isInline(resolvedCall.getResultingDescriptor())) { ValueArgument argument = CallUtilPackage.getValueArgumentForExpression(resolvedCall.getCall(), lambdaExpression); if (argument != null) { ArgumentMapping mapping = resolvedCall.getArgumentMapping(argument); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/InlineChecker.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/InlineChecker.java index 2c30aaf0a76..14dfd43a04a 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/InlineChecker.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/InlineChecker.java @@ -16,8 +16,6 @@ package org.jetbrains.kotlin.resolve.calls.checkers; -import com.intellij.psi.PsiElement; -import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.builtins.InlineUtil; @@ -39,24 +37,23 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver; import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue; import org.jetbrains.kotlin.types.JetType; -import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; +import static org.jetbrains.kotlin.diagnostics.Errors.NON_LOCAL_RETURN_NOT_ALLOWED; +import static org.jetbrains.kotlin.diagnostics.Errors.USAGE_IS_NOT_INLINABLE; import static org.jetbrains.kotlin.resolve.InlineDescriptorUtils.allowsNonLocalReturns; import static org.jetbrains.kotlin.resolve.InlineDescriptorUtils.checkNonLocalReturnUsage; import static org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilPackage.getIsEffectivelyPublicApi; class InlineChecker implements CallChecker { - private final SimpleFunctionDescriptor descriptor; - - private final Set inlinableParameters = new HashSet(); - + private final Set inlinableParameters = new LinkedHashSet(); private final boolean isEffectivelyPublicApiFunction; public InlineChecker(@NotNull SimpleFunctionDescriptor descriptor) { - assert descriptor.getInlineStrategy().isInline() : "This extension should be created only for inline functions but not " + descriptor; + assert InlineUtil.isInline(descriptor) : "This extension should be created only for inline functions: " + descriptor; this.descriptor = descriptor; this.isEffectivelyPublicApiFunction = getIsEffectivelyPublicApi(descriptor); @@ -89,7 +86,7 @@ class InlineChecker implements CallChecker { if (inlinableParameters.contains(targetDescriptor)) { if (!isInsideCall(expression)) { - context.trace.report(Errors.USAGE_IS_NOT_INLINABLE.on(expression, expression, descriptor)); + context.trace.report(USAGE_IS_NOT_INLINABLE.on(expression, expression, descriptor)); } } @@ -135,18 +132,19 @@ class InlineChecker implements CallChecker { CallableDescriptor argumentCallee = getCalleeDescriptor(context, argumentExpression, false); if (argumentCallee != null && inlinableParameters.contains(argumentCallee)) { - boolean isTargetInlineFunction = targetDescriptor instanceof SimpleFunctionDescriptor && - ((SimpleFunctionDescriptor) targetDescriptor).getInlineStrategy().isInline(); - - if (!isTargetInlineFunction || !isInlinableParameter(targetParameterDescriptor)) { - context.trace.report(Errors.USAGE_IS_NOT_INLINABLE.on(argumentExpression, argumentExpression, descriptor)); - } else { + if (InlineUtil.isInline(targetDescriptor) && isInlinableParameter(targetParameterDescriptor)) { if (allowsNonLocalReturns(argumentCallee) && !allowsNonLocalReturns(targetParameterDescriptor)) { - context.trace.report(Errors.NON_LOCAL_RETURN_NOT_ALLOWED.on(argumentExpression, argumentExpression, argumentCallee, descriptor)); - } else { + context.trace.report( + NON_LOCAL_RETURN_NOT_ALLOWED.on(argumentExpression, argumentExpression, argumentCallee, descriptor) + ); + } + else { checkNonLocalReturn(context, argumentCallee, argumentExpression); } } + else { + context.trace.report(USAGE_IS_NOT_INLINABLE.on(argumentExpression, argumentExpression, descriptor)); + } } } @@ -199,13 +197,14 @@ class InlineChecker implements CallChecker { @NotNull BasicCallResolutionContext context, @NotNull CallableDescriptor lambdaDescriptor, @NotNull CallableDescriptor callDescriptor, - @NotNull JetExpression receiverExpresssion + @NotNull JetExpression receiverExpression ) { boolean inlinableCall = isInvokeOrInlineExtension(callDescriptor); if (!inlinableCall) { - context.trace.report(Errors.USAGE_IS_NOT_INLINABLE.on(receiverExpresssion, receiverExpresssion, descriptor)); - } else { - checkNonLocalReturn(context, lambdaDescriptor, receiverExpresssion); + context.trace.report(USAGE_IS_NOT_INLINABLE.on(receiverExpression, receiverExpression, descriptor)); + } + else { + checkNonLocalReturn(context, lambdaDescriptor, receiverExpression); } } @@ -236,9 +235,7 @@ class InlineChecker implements CallChecker { containingDeclaration instanceof ClassDescriptor && KotlinBuiltIns.isExactFunctionOrExtensionFunctionType(((ClassDescriptor) containingDeclaration).getDefaultType()); - return isInvoke || - //or inline extension - ((SimpleFunctionDescriptor) descriptor).getInlineStrategy().isInline(); + return isInvoke || InlineUtil.isInline(descriptor); } private void checkVisibility(@NotNull CallableDescriptor declarationDescriptor, @NotNull JetElement expression, @NotNull BasicCallResolutionContext context){ @@ -268,7 +265,7 @@ class InlineChecker implements CallChecker { if (!allowsNonLocalReturns(inlinableParameterDescriptor)) return; if (!checkNonLocalReturnUsage(descriptor, parameterUsage, context.trace)) { - context.trace.report(Errors.NON_LOCAL_RETURN_NOT_ALLOWED.on(parameterUsage, parameterUsage, inlinableParameterDescriptor, descriptor)); + context.trace.report(NON_LOCAL_RETURN_NOT_ALLOWED.on(parameterUsage, parameterUsage, inlinableParameterDescriptor, descriptor)); } } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/InlineCheckerWrapper.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/InlineCheckerWrapper.kt index 7ac15052441..0436f1171e9 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/InlineCheckerWrapper.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/InlineCheckerWrapper.kt @@ -16,11 +16,12 @@ package org.jetbrains.kotlin.resolve.calls.checkers +import org.jetbrains.kotlin.builtins.InlineUtil import org.jetbrains.kotlin.descriptors.CallableDescriptor -import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall -import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor +import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext +import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import java.lang.ref.WeakReference public class InlineCheckerWrapper : CallChecker { @@ -34,8 +35,8 @@ public class InlineCheckerWrapper : CallChecker { while (parentDescriptor != null) { val descriptor = parentDescriptor!! - if (descriptor is SimpleFunctionDescriptor && descriptor.getInlineStrategy().isInline()) { - val checker = getChecker(descriptor) + if (InlineUtil.isInline(descriptor)) { + val checker = getChecker(descriptor as SimpleFunctionDescriptor) checker.check(resolvedCall, context) } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/extension/InlineAnalyzerExtension.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/extension/InlineAnalyzerExtension.java index 77e4c3e3bba..a6acee91655 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/extension/InlineAnalyzerExtension.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/extension/InlineAnalyzerExtension.java @@ -19,7 +19,6 @@ package org.jetbrains.kotlin.resolve.extension; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.builtins.InlineUtil; -import org.jetbrains.kotlin.builtins.KotlinBuiltIns; import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.diagnostics.Errors; import org.jetbrains.kotlin.psi.*; @@ -35,22 +34,19 @@ public class InlineAnalyzerExtension implements FunctionAnalyzerExtension.Analyz public static final InlineAnalyzerExtension INSTANCE = new InlineAnalyzerExtension(); private InlineAnalyzerExtension() { - } @Override public void process( @NotNull final FunctionDescriptor descriptor, @NotNull JetNamedFunction function, @NotNull final BindingTrace trace ) { - assert descriptor instanceof SimpleFunctionDescriptor && ((SimpleFunctionDescriptor) descriptor).getInlineStrategy().isInline() : - "This method should be invoced on inline function: " + descriptor; + assert InlineUtil.isInline(descriptor) : "This method should be invoked on inline function: " + descriptor; checkDefaults(descriptor, function, trace); checkNotVirtual(descriptor, function, trace); checkHasInlinableAndNullability(descriptor, function, trace); JetVisitorVoid visitor = new JetVisitorVoid() { - @Override public void visitJetElement(@NotNull JetElement element) { super.visitJetElement(element); @@ -85,7 +81,7 @@ public class InlineAnalyzerExtension implements FunctionAnalyzerExtension.Analyz for (ValueParameterDescriptor parameter : functionDescriptor.getValueParameters()) { if (parameter.hasDefaultValue()) { JetParameter jetParameter = jetParameters.get(index); - //report not supported default only on inlinable lambda and on parameter with inherited dafault (there is some problems to inline it) + //report not supported default only on inlinable lambda and on parameter with inherited default (there is some problems to inline it) if (checkInlinableParameter(parameter, jetParameter, functionDescriptor, null) || !parameter.declaresDefaultValue()) { trace.report(Errors.NOT_YET_SUPPORTED_IN_INLINE.on(jetParameter, jetParameter, functionDescriptor)); } diff --git a/core/descriptors/src/org/jetbrains/kotlin/builtins/InlineUtil.java b/core/descriptors/src/org/jetbrains/kotlin/builtins/InlineUtil.java index a4e20be15c8..10d13278e16 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/builtins/InlineUtil.java +++ b/core/descriptors/src/org/jetbrains/kotlin/builtins/InlineUtil.java @@ -19,10 +19,7 @@ package org.jetbrains.kotlin.builtins; import kotlin.KotlinPackage; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.kotlin.descriptors.CallableDescriptor; -import org.jetbrains.kotlin.descriptors.ClassDescriptor; -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor; -import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor; +import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.annotations.Annotated; import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.kotlin.resolve.DescriptorUtils; @@ -46,6 +43,10 @@ public class InlineUtil { KotlinBuiltIns.isExactFunctionOrExtensionFunctionType(type); } + public static boolean isInline(@Nullable DeclarationDescriptor descriptor) { + return descriptor instanceof SimpleFunctionDescriptor && getInlineType(descriptor).isInline(); + } + @NotNull public static InlineStrategy getInlineType(@NotNull DeclarationDescriptor descriptor) { ClassDescriptor inlineAnnotation = KotlinBuiltIns.getInstance().getInlineClassAnnotation(); diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/SimpleFunctionDescriptor.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/SimpleFunctionDescriptor.java index 484cb78c39b..426c35fc462 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/SimpleFunctionDescriptor.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/SimpleFunctionDescriptor.java @@ -17,13 +17,11 @@ package org.jetbrains.kotlin.descriptors; import org.jetbrains.annotations.NotNull; -import org.jetbrains.kotlin.builtins.InlineStrategy; /** * Simple functions are the ones with 'fun' keyword and function literals */ public interface SimpleFunctionDescriptor extends FunctionDescriptor { - @NotNull @Override SimpleFunctionDescriptor copy(DeclarationDescriptor newOwner, Modality modality, Visibility visibility, Kind kind, boolean copyOverrides); @@ -31,7 +29,4 @@ public interface SimpleFunctionDescriptor extends FunctionDescriptor { @NotNull @Override SimpleFunctionDescriptor getOriginal(); - - @NotNull - InlineStrategy getInlineStrategy(); } diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/SimpleFunctionDescriptorImpl.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/SimpleFunctionDescriptorImpl.java index ba91412ea76..4239799a2bf 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/SimpleFunctionDescriptorImpl.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/SimpleFunctionDescriptorImpl.java @@ -23,15 +23,10 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations; import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.types.JetType; import org.jetbrains.kotlin.types.TypeSubstitutor; -import org.jetbrains.kotlin.builtins.InlineStrategy; -import org.jetbrains.kotlin.builtins.InlineUtil; import java.util.List; public class SimpleFunctionDescriptorImpl extends FunctionDescriptorImpl implements SimpleFunctionDescriptor { - - private InlineStrategy inlineStrategy; - protected SimpleFunctionDescriptorImpl( @NotNull DeclarationDescriptor containingDeclaration, @Nullable SimpleFunctionDescriptor original, @@ -54,7 +49,6 @@ public class SimpleFunctionDescriptorImpl extends FunctionDescriptorImpl impleme return new SimpleFunctionDescriptorImpl(containingDeclaration, null, annotations, name, kind, source); } - @NotNull @Override public SimpleFunctionDescriptorImpl initialize( @@ -66,9 +60,8 @@ public class SimpleFunctionDescriptorImpl extends FunctionDescriptorImpl impleme @Nullable Modality modality, @NotNull Visibility visibility ) { - super.initialize(receiverParameterType, dispatchReceiverParameter, typeParameters, unsubstitutedValueParameters, unsubstitutedReturnType, - modality, visibility); - this.inlineStrategy = InlineUtil.getInlineType(this); + super.initialize(receiverParameterType, dispatchReceiverParameter, typeParameters, unsubstitutedValueParameters, + unsubstitutedReturnType, modality, visibility); return this; } @@ -93,18 +86,20 @@ public class SimpleFunctionDescriptorImpl extends FunctionDescriptorImpl impleme getName(), kind, SourceElement.NO_SOURCE - ); + ); } @NotNull @Override - public SimpleFunctionDescriptor copy(DeclarationDescriptor newOwner, Modality modality, Visibility visibility, Kind kind, boolean copyOverrides) { - return (SimpleFunctionDescriptorImpl)doSubstitute(TypeSubstitutor.EMPTY, newOwner, modality, visibility, null, copyOverrides, kind); - } - - @NotNull - @Override - public InlineStrategy getInlineStrategy() { - return inlineStrategy; + public SimpleFunctionDescriptor copy( + DeclarationDescriptor newOwner, + Modality modality, + Visibility visibility, + Kind kind, + boolean copyOverrides + ) { + return (SimpleFunctionDescriptorImpl) doSubstitute( + TypeSubstitutor.EMPTY, newOwner, modality, visibility, null, copyOverrides, kind + ); } } diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/CompletionUtils.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/CompletionUtils.kt index 070c01eceb0..a414cc3d050 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/CompletionUtils.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/CompletionUtils.kt @@ -23,6 +23,7 @@ import com.intellij.openapi.util.Key import com.intellij.patterns.ElementPattern import com.intellij.patterns.StandardPatterns import com.intellij.util.PlatformIcons +import org.jetbrains.kotlin.builtins.InlineUtil import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.idea.caches.resolve.ResolutionFacade @@ -252,8 +253,7 @@ fun returnExpressionItems(bindingContext: BindingContext, position: JetElement): // check if the current function literal is inlined and stop processing outer declarations if it's not val callee = call?.getCalleeExpression() as? JetReferenceExpression ?: break // not inlined - val target = bindingContext[BindingContext.REFERENCE_TARGET, callee] as? SimpleFunctionDescriptor ?: break // not inlined - if (!target.getInlineStrategy().isInline()) break // not inlined + if (!InlineUtil.isInline(bindingContext[BindingContext.REFERENCE_TARGET, callee])) break // not inlined } else { if (parent.hasBlockBody()) { diff --git a/idea/src/org/jetbrains/kotlin/idea/debugger/JetPositionManager.kt b/idea/src/org/jetbrains/kotlin/idea/debugger/JetPositionManager.kt index 9d3b367e9aa..05d175614e8 100644 --- a/idea/src/org/jetbrains/kotlin/idea/debugger/JetPositionManager.kt +++ b/idea/src/org/jetbrains/kotlin/idea/debugger/JetPositionManager.kt @@ -16,13 +16,14 @@ package org.jetbrains.kotlin.idea.debugger +import com.intellij.debugger.MultiRequestPositionManager import com.intellij.debugger.NoDataException import com.intellij.debugger.SourcePosition import com.intellij.debugger.engine.DebugProcess import com.intellij.debugger.requests.ClassPrepareRequestor +import com.intellij.find.findUsages.FindUsagesOptions import com.intellij.openapi.project.DumbService import com.intellij.openapi.roots.libraries.LibraryUtil -import com.intellij.openapi.util.Pair import com.intellij.psi.PsiElement import com.intellij.psi.PsiFile import com.intellij.psi.search.GlobalSearchScope @@ -32,35 +33,31 @@ import com.sun.jdi.Location import com.sun.jdi.ReferenceType import com.sun.jdi.request.ClassPrepareRequest import org.jetbrains.annotations.TestOnly +import org.jetbrains.kotlin.builtins.InlineUtil import org.jetbrains.kotlin.codegen.AsmUtil import org.jetbrains.kotlin.codegen.ClassBuilderFactories +import org.jetbrains.kotlin.codegen.binding.CodegenBinding import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.codegen.state.JetTypeMapper import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.PropertyDescriptor -import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.resolve.BindingContext -import org.jetbrains.kotlin.resolve.calls.callUtil.* -import org.jetbrains.kotlin.resolve.extension.InlineAnalyzerExtension -import org.jetbrains.kotlin.resolve.jvm.JvmClassName +import org.jetbrains.kotlin.idea.caches.resolve.analyzeAndGetResult +import org.jetbrains.kotlin.idea.caches.resolve.analyzeFullyAndGetResult +import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils +import org.jetbrains.kotlin.idea.findUsages.toSearchTarget +import org.jetbrains.kotlin.idea.search.usagesSearch.DefaultSearchHelper +import org.jetbrains.kotlin.idea.search.usagesSearch.search +import org.jetbrains.kotlin.idea.util.DebuggerUtils +import org.jetbrains.kotlin.idea.util.application.runReadAction import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.builtins.InlineUtil -import org.jetbrains.kotlin.idea.caches.resolve.* -import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils -import org.jetbrains.kotlin.idea.util.DebuggerUtils -import org.jetbrains.kotlin.idea.search.usagesSearch.DefaultSearchHelper -import com.intellij.find.findUsages.FindUsagesOptions -import org.jetbrains.kotlin.idea.findUsages.toSearchTarget -import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor -import org.jetbrains.kotlin.idea.search.usagesSearch.search -import java.util.WeakHashMap -import org.jetbrains.kotlin.idea.util.application.runReadAction -import org.jetbrains.kotlin.idea.stubindex.PackageIndexUtil +import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall +import org.jetbrains.kotlin.resolve.extension.InlineAnalyzerExtension +import org.jetbrains.kotlin.resolve.jvm.JvmClassName import java.util.ArrayList -import org.jetbrains.kotlin.codegen.binding.CodegenBinding -import com.intellij.debugger.MultiRequestPositionManager -import java.util.Collections +import java.util.WeakHashMap class PositionedElement(val className: String?, val element: PsiElement?) @@ -439,22 +436,20 @@ public class JetPositionManager(private val myDebugProcess: DebugProcess) : Mult val typeMapper = if (!isInLibrary) prepareTypeMapper(jetFile) else createTypeMapperForLibraryFile(element, jetFile) val psiElement = getInternalClassNameForElement(element, typeMapper, jetFile, isInLibrary).element; - if (psiElement is JetNamedFunction) { - val descriptor = typeMapper.getBindingContext().get(BindingContext.DECLARATION_TO_DESCRIPTOR, psiElement) + if (psiElement is JetNamedFunction && + InlineUtil.isInline(typeMapper.getBindingContext().get(BindingContext.DECLARATION_TO_DESCRIPTOR, psiElement)) + ) { + val project = myDebugProcess.getProject() + val usagesSearchTarget = FindUsagesOptions(project).toSearchTarget(psiElement, true) - if (descriptor is SimpleFunctionDescriptor && descriptor.getInlineStrategy().isInline()) { - val project = myDebugProcess.getProject() - val usagesSearchTarget = FindUsagesOptions(project).toSearchTarget(psiElement, true) - - val usagesSearchRequest = DefaultSearchHelper(true).newRequest(usagesSearchTarget) - usagesSearchRequest.search().forEach { - val psiElement = it.getElement() - if (psiElement is JetElement) { - //TODO recursive search - val name = classNameForPosition(psiElement) - if (name != null) { - result.add(name) - } + val usagesSearchRequest = DefaultSearchHelper(true).newRequest(usagesSearchTarget) + usagesSearchRequest.search().forEach { + val psiElement = it.getElement() + if (psiElement is JetElement) { + //TODO recursive search + val name = classNameForPosition(psiElement) + if (name != null) { + result.add(name) } } } diff --git a/idea/src/org/jetbrains/kotlin/idea/internal/KotlinBytecodeToolWindow.java b/idea/src/org/jetbrains/kotlin/idea/internal/KotlinBytecodeToolWindow.java index 7eed2397787..c603a2c23b4 100644 --- a/idea/src/org/jetbrains/kotlin/idea/internal/KotlinBytecodeToolWindow.java +++ b/idea/src/org/jetbrains/kotlin/idea/internal/KotlinBytecodeToolWindow.java @@ -40,13 +40,13 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.analyzer.AnalysisResult; import org.jetbrains.kotlin.backend.common.output.OutputFile; import org.jetbrains.kotlin.backend.common.output.OutputFileCollection; +import org.jetbrains.kotlin.builtins.InlineUtil; import org.jetbrains.kotlin.codegen.ClassBuilderFactories; import org.jetbrains.kotlin.codegen.CompilationErrorHandler; import org.jetbrains.kotlin.codegen.KotlinCodegenFacade; import org.jetbrains.kotlin.codegen.state.GenerationState; import org.jetbrains.kotlin.codegen.state.Progress; import org.jetbrains.kotlin.descriptors.CallableDescriptor; -import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor; import org.jetbrains.kotlin.diagnostics.DiagnosticSink; import org.jetbrains.kotlin.idea.caches.resolve.KotlinCacheService; import org.jetbrains.kotlin.idea.caches.resolve.ResolvePackage; @@ -116,7 +116,7 @@ public class KotlinBytecodeToolWindow extends JPanel implements Disposable { try { AnalysisResult result = ResolvePackage.analyzeFullyAndGetResult(jetFile); boolean disableInline = !enableInline.isSelected(); - Ref> ref = new Ref(); + Ref> ref = Ref.create(); if (!disableInline) { result = processInlinedDeclarations(jetFile.getProject(), result, Collections.singleton(jetFile), 1, ref); } @@ -199,17 +199,12 @@ public class KotlinBytecodeToolWindow extends JPanel implements Disposable { Set collectedElements = new HashSet(); collectedElements.addAll(originalElements); Map> contents = result.getBindingContext().getSliceContents(BindingContext.RESOLVED_CALL); - Collection> values = contents.values(); - for (ResolvedCall call : values) { + for (ResolvedCall call : contents.values()) { CallableDescriptor descriptor = call.getResultingDescriptor(); - if (!(descriptor instanceof DeserializedSimpleFunctionDescriptor)) { - if (descriptor instanceof SimpleFunctionDescriptor && - ((SimpleFunctionDescriptor) descriptor).getInlineStrategy().isInline()) { - PsiElement declaration = - DescriptorToSourceUtilsIde.INSTANCE$.getAnyDeclaration(project, descriptor); - if (declaration != null && declaration instanceof JetElement) { - collectedElements.add((JetElement) declaration); - } + if (!(descriptor instanceof DeserializedSimpleFunctionDescriptor) && InlineUtil.isInline(descriptor)) { + PsiElement declaration = DescriptorToSourceUtilsIde.INSTANCE$.getAnyDeclaration(project, descriptor); + if (declaration != null && declaration instanceof JetElement) { + collectedElements.add((JetElement) declaration); } } } @@ -381,7 +376,7 @@ public class KotlinBytecodeToolWindow extends JPanel implements Disposable { public static class Factory implements ToolWindowFactory { @Override - public void createToolWindowContent(Project project, ToolWindow toolWindow) { + public void createToolWindowContent(@NotNull Project project, @NotNull ToolWindow toolWindow) { ContentManager contentManager = toolWindow.getContentManager(); ContentFactory contentFactory = ContentFactory.SERVICE.getInstance(); contentManager.addContent(contentFactory.createContent( diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/CallExpressionTranslator.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/CallExpressionTranslator.java index 46538fcb112..c78640d438e 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/CallExpressionTranslator.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/CallExpressionTranslator.java @@ -37,14 +37,12 @@ import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant; import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator; import org.jetbrains.kotlin.types.JetType; -import java.io.IOException; -import java.util.ArrayList; import java.util.List; +import static org.jetbrains.kotlin.js.resolve.diagnostics.JsCallChecker.isJsCall; import static org.jetbrains.kotlin.js.translate.utils.PsiUtils.getFunctionDescriptor; import static org.jetbrains.kotlin.js.translate.utils.UtilsPackage.setInlineCallMetadata; import static org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilPackage.getFunctionResolvedCallWithAssert; -import static org.jetbrains.kotlin.js.resolve.diagnostics.JsCallChecker.isJsCall; public final class CallExpressionTranslator extends AbstractCallExpressionTranslator { @@ -78,7 +76,7 @@ public final class CallExpressionTranslator extends AbstractCallExpressionTransl public static boolean shouldBeInlined(@NotNull CallableDescriptor descriptor) { if (descriptor instanceof SimpleFunctionDescriptor) { - return ((SimpleFunctionDescriptor) descriptor).getInlineStrategy().isInline(); + return InlineUtil.isInline(descriptor); } if (descriptor instanceof ValueParameterDescriptor) {