Add constant "invoke" to OperatorConventions

This commit is contained in:
Alexander Udalov
2015-04-07 21:29:14 +03:00
parent 94eac98500
commit 167942f4bb
15 changed files with 77 additions and 73 deletions
@@ -32,11 +32,11 @@ import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl; import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl;
import org.jetbrains.kotlin.load.java.JvmAbi; import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.psi.JetElement; import org.jetbrains.kotlin.psi.JetElement;
import org.jetbrains.kotlin.resolve.BindingContext; import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.DescriptorUtils; import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.types.JetType; import org.jetbrains.kotlin.types.JetType;
import org.jetbrains.kotlin.types.expressions.OperatorConventions;
import org.jetbrains.org.objectweb.asm.MethodVisitor; import org.jetbrains.org.objectweb.asm.MethodVisitor;
import org.jetbrains.org.objectweb.asm.Type; import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter; import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
@@ -48,7 +48,8 @@ import java.util.List;
import static org.jetbrains.kotlin.codegen.AsmUtil.*; import static org.jetbrains.kotlin.codegen.AsmUtil.*;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isConst; import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isConst;
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.*; import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.CLOSURE;
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.asmTypeForAnonymousClass;
import static org.jetbrains.kotlin.load.java.JvmAnnotationNames.KotlinSyntheticClass; import static org.jetbrains.kotlin.load.java.JvmAnnotationNames.KotlinSyntheticClass;
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.DiagnosticsPackage.OtherOrigin; import static org.jetbrains.kotlin.resolve.jvm.diagnostics.DiagnosticsPackage.OtherOrigin;
import static org.jetbrains.org.objectweb.asm.Opcodes.*; import static org.jetbrains.org.objectweb.asm.Opcodes.*;
@@ -365,6 +366,6 @@ public class ClosureCodegen extends MemberCodegen<JetElement> {
ClassDescriptor elementClass = elementDescriptor.getExtensionReceiverParameter() == null ClassDescriptor elementClass = elementDescriptor.getExtensionReceiverParameter() == null
? KotlinBuiltIns.getInstance().getFunction(arity) ? KotlinBuiltIns.getInstance().getFunction(arity)
: KotlinBuiltIns.getInstance().getExtensionFunction(arity); : KotlinBuiltIns.getInstance().getExtensionFunction(arity);
return elementClass.getDefaultType().getMemberScope().getFunctions(Name.identifier("invoke")).iterator().next(); return elementClass.getDefaultType().getMemberScope().getFunctions(OperatorConventions.INVOKE).iterator().next();
} }
} }
@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.psi.JetFile; import org.jetbrains.kotlin.psi.JetFile;
import org.jetbrains.kotlin.resolve.DescriptorUtils; import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.types.JetType; import org.jetbrains.kotlin.types.JetType;
import org.jetbrains.kotlin.types.expressions.OperatorConventions;
import org.jetbrains.org.objectweb.asm.MethodVisitor; import org.jetbrains.org.objectweb.asm.MethodVisitor;
import org.jetbrains.org.objectweb.asm.Type; import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter; import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
@@ -146,8 +147,8 @@ public class SamWrapperCodegen {
FunctionCodegen codegen = new FunctionCodegen(CodegenContext.STATIC.intoClass( FunctionCodegen codegen = new FunctionCodegen(CodegenContext.STATIC.intoClass(
(ClassDescriptor) erasedInterfaceFunction.getContainingDeclaration(), OwnerKind.IMPLEMENTATION, state), cv, state, parentCodegen); (ClassDescriptor) erasedInterfaceFunction.getContainingDeclaration(), OwnerKind.IMPLEMENTATION, state), cv, state, parentCodegen);
FunctionDescriptor invokeFunction = functionJetType.getMemberScope() FunctionDescriptor invokeFunction =
.getFunctions(Name.identifier("invoke")).iterator().next().getOriginal(); functionJetType.getMemberScope().getFunctions(OperatorConventions.INVOKE).iterator().next().getOriginal();
StackValue functionField = StackValue.field(functionType, ownerType, FUNCTION_FIELD_NAME, false, StackValue.none()); StackValue functionField = StackValue.field(functionType, ownerType, FUNCTION_FIELD_NAME, false, StackValue.none());
codegen.genDelegate(erasedInterfaceFunction, invokeFunction, functionField); codegen.genDelegate(erasedInterfaceFunction, invokeFunction, functionField);
@@ -48,6 +48,7 @@ import org.jetbrains.kotlin.resolve.jvm.JvmClassName;
import org.jetbrains.kotlin.serialization.ProtoBuf; import org.jetbrains.kotlin.serialization.ProtoBuf;
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor; import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor;
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf; import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf;
import org.jetbrains.kotlin.types.expressions.OperatorConventions;
import org.jetbrains.org.objectweb.asm.*; import org.jetbrains.org.objectweb.asm.*;
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter; import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
import org.jetbrains.org.objectweb.asm.tree.*; import org.jetbrains.org.objectweb.asm.tree.*;
@@ -67,7 +68,6 @@ import static org.jetbrains.kotlin.resolve.DescriptorUtils.isTrait;
public class InlineCodegenUtil { public class InlineCodegenUtil {
public static final boolean GENERATE_SMAP = true; public static final boolean GENERATE_SMAP = true;
public static final int API = Opcodes.ASM5; public static final int API = Opcodes.ASM5;
public static final String INVOKE = "invoke";
public static final String CAPTURED_FIELD_PREFIX = "$"; public static final String CAPTURED_FIELD_PREFIX = "$";
@@ -115,9 +115,8 @@ public class InlineCodegenUtil {
) { ) {
if (methodName.equals(name) && methodDescriptor.equals(desc)) { if (methodName.equals(name) && methodDescriptor.equals(desc)) {
node[0] = new MethodNode(API, access, name, desc, signature, exceptions) { node[0] = new MethodNode(API, access, name, desc, signature, exceptions) {
@Override @Override
public void visitLineNumber(int line, Label start) { public void visitLineNumber(int line, @NotNull Label start) {
super.visitLineNumber(line, start); super.visitLineNumber(line, start);
lines[0] = Math.min(lines[0], line); lines[0] = Math.min(lines[0], line);
lines[1] = Math.max(lines[1], line); lines[1] = Math.max(lines[1], line);
@@ -252,9 +251,8 @@ public class InlineCodegenUtil {
return getInlineName(codegenContext, currentDescriptor.getContainingDeclaration(), typeMapper) + "$" + suffix; return getInlineName(codegenContext, currentDescriptor.getContainingDeclaration(), typeMapper) + "$" + suffix;
} }
public static boolean isInvokeOnLambda(String owner, String name) { public static boolean isInvokeOnLambda(String owner, String name) {
if (!INVOKE.equals(name)) { if (!OperatorConventions.INVOKE.asString().equals(name)) {
return false; return false;
} }
@@ -58,6 +58,7 @@ import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature; import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor; import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor;
import org.jetbrains.kotlin.types.*; import org.jetbrains.kotlin.types.*;
import org.jetbrains.kotlin.types.expressions.OperatorConventions;
import org.jetbrains.org.objectweb.asm.Type; import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.commons.Method; import org.jetbrains.org.objectweb.asm.commons.Method;
@@ -682,10 +683,10 @@ public class JetTypeMapper {
} }
} }
return "invoke"; return OperatorConventions.INVOKE.asString();
} }
else if (isLocalFunction(descriptor) || isFunctionExpression(descriptor)) { else if (isLocalFunction(descriptor) || isFunctionExpression(descriptor)) {
return "invoke"; return OperatorConventions.INVOKE.asString();
} }
else { else {
return descriptor.getName().asString(); return descriptor.getName().asString();
@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.renderer.MultiRenderer;
import org.jetbrains.kotlin.renderer.Renderer; import org.jetbrains.kotlin.renderer.Renderer;
import org.jetbrains.kotlin.resolve.varianceChecker.VarianceChecker.VarianceConflictDiagnosticData; import org.jetbrains.kotlin.resolve.varianceChecker.VarianceChecker.VarianceConflictDiagnosticData;
import org.jetbrains.kotlin.types.JetType; import org.jetbrains.kotlin.types.JetType;
import org.jetbrains.kotlin.types.expressions.OperatorConventions;
import org.jetbrains.kotlin.util.MappedExtensionProvider; import org.jetbrains.kotlin.util.MappedExtensionProvider;
import java.lang.reflect.Field; import java.lang.reflect.Field;
@@ -500,15 +501,17 @@ public class DefaultErrorMessages {
MAP.put(CONFLICTING_OVERLOADS, "''{0}'' is already defined in {1}", COMPACT_WITH_MODIFIERS, STRING); MAP.put(CONFLICTING_OVERLOADS, "''{0}'' is already defined in {1}", COMPACT_WITH_MODIFIERS, STRING);
MAP.put(ILLEGAL_PLATFORM_NAME, "Illegal platform name: ''{0}''", STRING); MAP.put(ILLEGAL_PLATFORM_NAME, "Illegal platform name: ''{0}''", STRING);
MAP.put(FUNCTION_EXPECTED, "Expression ''{0}''{1} cannot be invoked as a function. The function 'invoke()' is not found", ELEMENT_TEXT, new Renderer<JetType>() { MAP.put(FUNCTION_EXPECTED, "Expression ''{0}''{1} cannot be invoked as a function. " +
@NotNull "The function '" + OperatorConventions.INVOKE.asString() + "()' is not found",
@Override ELEMENT_TEXT, new Renderer<JetType>() {
public String render(@NotNull JetType type) { @NotNull
if (type.isError()) return ""; @Override
return " of type '" + RENDER_TYPE.render(type) + "'"; public String render(@NotNull JetType type) {
} if (type.isError()) return "";
}); return " of type '" + RENDER_TYPE.render(type) + "'";
MAP.put(FUNCTION_CALL_EXPECTED, "Function invocation ''{0}({1})'' expected", ELEMENT_TEXT,new Renderer<Boolean>() { }
});
MAP.put(FUNCTION_CALL_EXPECTED, "Function invocation ''{0}({1})'' expected", ELEMENT_TEXT, new Renderer<Boolean>() {
@NotNull @NotNull
@Override @Override
public String render(@NotNull Boolean hasValueParameters) { public String render(@NotNull Boolean hasValueParameters) {
@@ -48,6 +48,7 @@ import org.jetbrains.kotlin.types.JetType;
import org.jetbrains.kotlin.types.TypeSubstitutor; import org.jetbrains.kotlin.types.TypeSubstitutor;
import org.jetbrains.kotlin.types.expressions.ExpressionTypingContext; import org.jetbrains.kotlin.types.expressions.ExpressionTypingContext;
import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices; import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices;
import org.jetbrains.kotlin.types.expressions.OperatorConventions;
import javax.inject.Inject; import javax.inject.Inject;
import java.util.Collection; import java.util.Collection;
@@ -154,7 +155,7 @@ public class CallResolver {
@NotNull TracingStrategy tracing @NotNull TracingStrategy tracing
) { ) {
return computeTasksAndResolveCall( return computeTasksAndResolveCall(
context, Name.identifier("invoke"), tracing, context, OperatorConventions.INVOKE, tracing,
CallableDescriptorCollectors.FUNCTIONS, CallTransformer.FUNCTION_CALL_TRANSFORMER); CallableDescriptorCollectors.FUNCTIONS, CallTransformer.FUNCTION_CALL_TRANSFORMER);
} }
@@ -45,6 +45,7 @@ import org.jetbrains.kotlin.resolve.calls.util.DelegatingCall;
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver; import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver;
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue; import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.kotlin.types.JetType; import org.jetbrains.kotlin.types.JetType;
import org.jetbrains.kotlin.types.expressions.OperatorConventions;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
@@ -267,7 +268,8 @@ public class CallTransformer<D extends CallableDescriptor, F extends D> {
this.outerCall = call; this.outerCall = call;
this.explicitExtensionReceiver = explicitExtensionReceiver; this.explicitExtensionReceiver = explicitExtensionReceiver;
this.calleeExpressionAsDispatchReceiver = calleeExpressionAsDispatchReceiver; this.calleeExpressionAsDispatchReceiver = calleeExpressionAsDispatchReceiver;
this.fakeInvokeExpression = (JetSimpleNameExpression) JetPsiFactory(call.getCallElement()).createExpression( "invoke"); this.fakeInvokeExpression =
(JetSimpleNameExpression) JetPsiFactory(call.getCallElement()).createExpression(OperatorConventions.INVOKE.asString());
} }
@Nullable @Nullable
@@ -36,6 +36,7 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver;
import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver; import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver;
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue; import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.kotlin.types.JetType; import org.jetbrains.kotlin.types.JetType;
import org.jetbrains.kotlin.types.expressions.OperatorConventions;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.Map; import java.util.Map;
@@ -228,7 +229,7 @@ class InlineChecker implements CallChecker {
} }
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration(); DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
boolean isInvoke = descriptor.getName().asString().equals("invoke") && boolean isInvoke = descriptor.getName().equals(OperatorConventions.INVOKE) &&
containingDeclaration instanceof ClassDescriptor && containingDeclaration instanceof ClassDescriptor &&
KotlinBuiltIns.isExactFunctionOrExtensionFunctionType(((ClassDescriptor) containingDeclaration).getDefaultType()); KotlinBuiltIns.isExactFunctionOrExtensionFunctionType(((ClassDescriptor) containingDeclaration).getDefaultType());
@@ -20,9 +20,9 @@ import com.google.common.collect.ImmutableBiMap;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.lexer.JetToken; import org.jetbrains.kotlin.lexer.JetToken;
import org.jetbrains.kotlin.lexer.JetTokens; import org.jetbrains.kotlin.lexer.JetTokens;
import org.jetbrains.kotlin.name.Name;
public class OperatorConventions { public class OperatorConventions {
@@ -30,6 +30,7 @@ public class OperatorConventions {
public static final Name IDENTITY_EQUALS = Name.identifier("identityEquals"); public static final Name IDENTITY_EQUALS = Name.identifier("identityEquals");
public static final Name COMPARE_TO = Name.identifier("compareTo"); public static final Name COMPARE_TO = Name.identifier("compareTo");
public static final Name CONTAINS = Name.identifier("contains"); public static final Name CONTAINS = Name.identifier("contains");
public static final Name INVOKE = Name.identifier("invoke");
private OperatorConventions() {} private OperatorConventions() {}
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.lexer.JetTokens
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.types.expressions.OperatorConventions
public class OperatorToFunctionIntention : JetSelfTargetingIntention<JetExpression>(javaClass(), "Replace overloaded operator with function call") { public class OperatorToFunctionIntention : JetSelfTargetingIntention<JetExpression>(javaClass(), "Replace overloaded operator with function call") {
companion object { companion object {
@@ -69,10 +70,10 @@ public class OperatorToFunctionIntention : JetSelfTargetingIntention<JetExpressi
val resolvedCall = element.getResolvedCall(element.analyze()) val resolvedCall = element.getResolvedCall(element.analyze())
val descriptor = resolvedCall?.getResultingDescriptor() val descriptor = resolvedCall?.getResultingDescriptor()
if (descriptor is FunctionDescriptor && descriptor.getName().asString() == "invoke") { if (descriptor is FunctionDescriptor && descriptor.getName() == OperatorConventions.INVOKE) {
val parent = element.getParent() if (element.getParent() is JetDotQualifiedExpression &&
if (parent is JetDotQualifiedExpression && element.getCalleeExpression()?.getText() == "invoke") return false element.getCalleeExpression()?.getText() == OperatorConventions.INVOKE.asString()) return false
return !(element.getValueArgumentList() == null && element.getFunctionLiteralArguments().isEmpty()) return element.getValueArgumentList() != null || element.getFunctionLiteralArguments().isNotEmpty()
} }
return false return false
} }
@@ -186,7 +187,8 @@ public class OperatorToFunctionIntention : JetSelfTargetingIntention<JetExpressi
val argumentString = arguments?.getText()?.trim("(", ")") val argumentString = arguments?.getText()?.trim("(", ")")
val funcLitArgs = element.getFunctionLiteralArguments() val funcLitArgs = element.getFunctionLiteralArguments()
val calleeText = callee.getText() val calleeText = callee.getText()
val transformation = if (argumentString == null) "$calleeText.invoke" else "$calleeText.invoke($argumentString)" val transformation = "$calleeText.${OperatorConventions.INVOKE.asString()}" +
(if (argumentString == null) "" else "($argumentString)")
val transformed = JetPsiFactory(element).createExpression(transformation) val transformed = JetPsiFactory(element).createExpression(transformation)
funcLitArgs.forEach { transformed.add(it) } funcLitArgs.forEach { transformed.add(it) }
return callee.getParent()!!.replace(transformed) as JetExpression return callee.getParent()!!.replace(transformed) as JetExpression
@@ -16,14 +16,14 @@
package org.jetbrains.kotlin.idea.search.usagesSearch package org.jetbrains.kotlin.idea.search.usagesSearch
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.lexer.JetToken
import org.jetbrains.kotlin.types.expressions.OperatorConventions.*
import com.google.common.collect.ImmutableSet import com.google.common.collect.ImmutableSet
import org.jetbrains.kotlin.lexer.JetTokens
import org.jetbrains.kotlin.lexer.JetSingleValueToken import org.jetbrains.kotlin.lexer.JetSingleValueToken
import org.jetbrains.kotlin.lexer.JetToken
import org.jetbrains.kotlin.lexer.JetTokens
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DelegatedPropertyResolver
import org.jetbrains.kotlin.resolve.dataClassUtils.isComponentLike import org.jetbrains.kotlin.resolve.dataClassUtils.isComponentLike
import org.jetbrains.kotlin.resolve.* import org.jetbrains.kotlin.types.expressions.OperatorConventions.*
public val ALL_SEARCHABLE_OPERATIONS: ImmutableSet<JetToken> = ImmutableSet public val ALL_SEARCHABLE_OPERATIONS: ImmutableSet<JetToken> = ImmutableSet
.builder<JetToken>() .builder<JetToken>()
@@ -45,8 +45,6 @@ public val ALL_SEARCHABLE_OPERATION_PATTERNS: Set<String> =
public val INDEXING_OPERATION_NAMES: ImmutableSet<Name> = public val INDEXING_OPERATION_NAMES: ImmutableSet<Name> =
ImmutableSet.of(Name.identifier("get"), Name.identifier("set")) ImmutableSet.of(Name.identifier("get"), Name.identifier("set"))
public val INVOKE_OPERATION_NAME: Name = Name.identifier("invoke")
public val ITERATOR_OPERATION_NAME: Name = Name.identifier("iterator") public val ITERATOR_OPERATION_NAME: Name = Name.identifier("iterator")
public val IN_OPERATIONS_TO_SEARCH: ImmutableSet<JetToken> = ImmutableSet.of(JetTokens.IN_KEYWORD) public val IN_OPERATIONS_TO_SEARCH: ImmutableSet<JetToken> = ImmutableSet.of(JetTokens.IN_KEYWORD)
@@ -44,6 +44,7 @@ import org.jetbrains.kotlin.lexer.JetTokens
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext
import org.jetbrains.kotlin.psi.psiUtil.isAncestor import org.jetbrains.kotlin.psi.psiUtil.isAncestor
import org.jetbrains.kotlin.types.expressions.OperatorConventions
import org.jetbrains.kotlin.utils.singletonOrEmptyList import org.jetbrains.kotlin.utils.singletonOrEmptyList
import java.awt.GridBagConstraints import java.awt.GridBagConstraints
import java.awt.GridBagLayout import java.awt.GridBagLayout
@@ -156,7 +157,7 @@ public class UnusedSymbolInspection : AbstractKotlinInspection() {
private fun isConventionalName(namedDeclaration: JetNamedDeclaration): Boolean { private fun isConventionalName(namedDeclaration: JetNamedDeclaration): Boolean {
val name = namedDeclaration.getNameAsName() val name = namedDeclaration.getNameAsName()
return name.getOperationSymbolsToSearch().isNotEmpty() || name == INVOKE_OPERATION_NAME return name.getOperationSymbolsToSearch().isNotEmpty() || name == OperatorConventions.INVOKE
} }
private fun hasNonTrivialUsages(declaration: JetNamedDeclaration): Boolean { private fun hasNonTrivialUsages(declaration: JetNamedDeclaration): Boolean {
@@ -18,11 +18,12 @@ package org.jetbrains.kotlin.idea.intentions.attributeCallReplacements
import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.Editor
import org.jetbrains.kotlin.psi.JetPsiFactory import org.jetbrains.kotlin.psi.JetPsiFactory
import org.jetbrains.kotlin.types.expressions.OperatorConventions
public open class ReplaceInvokeIntention : AttributeCallReplacementIntention("replace.invoke.with.call") { public open class ReplaceInvokeIntention : AttributeCallReplacementIntention("replace.invoke.with.call") {
override fun isApplicableToCall(call: CallDescription): Boolean { override fun isApplicableToCall(call: CallDescription): Boolean {
return call.functionName == "invoke" return call.functionName == OperatorConventions.INVOKE.asString()
} }
override fun replaceCall(call: CallDescription, editor: Editor) { override fun replaceCall(call: CallDescription, editor: Editor) {
@@ -16,15 +16,17 @@
package org.jetbrains.kotlin.idea.quickfix.createFromUsage.createCallable package org.jetbrains.kotlin.idea.quickfix.createFromUsage.createCallable
import org.jetbrains.kotlin.diagnostics.Diagnostic
import com.intellij.codeInsight.intention.IntentionAction import com.intellij.codeInsight.intention.IntentionAction
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.psi.JetCallExpression
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.*
import java.util.Collections
import org.jetbrains.kotlin.idea.quickfix.JetIntentionActionsFactory import org.jetbrains.kotlin.idea.quickfix.JetIntentionActionsFactory
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.FunctionInfo
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.ParameterInfo
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.TypeInfo
import org.jetbrains.kotlin.psi.JetCallExpression
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.expressions.OperatorConventions
object CreateInvokeFunctionActionFactory : JetIntentionActionsFactory() { object CreateInvokeFunctionActionFactory : JetIntentionActionsFactory() {
override fun doCreateActions(diagnostic: Diagnostic): List<IntentionAction>? { override fun doCreateActions(diagnostic: Diagnostic): List<IntentionAction>? {
@@ -44,6 +46,9 @@ object CreateInvokeFunctionActionFactory : JetIntentionActionsFactory() {
} }
val returnType = TypeInfo(callExpr, Variance.OUT_VARIANCE) val returnType = TypeInfo(callExpr, Variance.OUT_VARIANCE)
return CreateCallableFromUsageFixes(callExpr, FunctionInfo("invoke", receiverType, returnType, Collections.emptyList(), parameters)) return CreateCallableFromUsageFixes(
callExpr,
FunctionInfo(OperatorConventions.INVOKE.asString(), receiverType, returnType, emptyList(), parameters)
)
} }
} }
@@ -16,37 +16,25 @@
package org.jetbrains.kotlin.js.translate.callTranslator package org.jetbrains.kotlin.js.translate.callTranslator
import com.google.dart.compiler.backend.js.ast.JsExpression import com.google.dart.compiler.backend.js.ast.*
import com.google.dart.compiler.backend.js.ast.JsNameRef
import com.google.dart.compiler.backend.js.ast.JsInvocation
import java.util.ArrayList
import org.jetbrains.kotlin.js.translate.context.Namer
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import com.google.dart.compiler.backend.js.ast.JsNew
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import com.google.dart.compiler.backend.js.ast.JsLiteral
import com.google.dart.compiler.backend.js.ast.JsName
import org.jetbrains.kotlin.js.translate.context.TranslationContext
import org.jetbrains.kotlin.js.translate.reference.CallArgumentTranslator
import org.jetbrains.kotlin.descriptors.Visibilities
import com.intellij.util.SmartList import com.intellij.util.SmartList
import com.google.dart.compiler.backend.js.ast.JsArrayAccess import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.js.PredefinedAnnotation import org.jetbrains.kotlin.js.PredefinedAnnotation
import org.jetbrains.kotlin.resolve.calls.tasks.isDynamic import org.jetbrains.kotlin.js.translate.context.Namer
import org.jetbrains.kotlin.psi.Call import org.jetbrains.kotlin.js.translate.context.TranslationContext
import org.jetbrains.kotlin.js.translate.operation.OperatorTable import org.jetbrains.kotlin.js.translate.operation.OperatorTable
import com.google.dart.compiler.backend.js.ast.JsBinaryOperation import org.jetbrains.kotlin.js.translate.reference.CallArgumentTranslator
import org.jetbrains.kotlin.psi.JetPrefixExpression import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils
import com.google.dart.compiler.backend.js.ast.JsPrefixOperation import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
import org.jetbrains.kotlin.psi.JetPostfixExpression
import com.google.dart.compiler.backend.js.ast.JsPostfixOperation
import org.jetbrains.kotlin.psi.JetBinaryExpression
import org.jetbrains.kotlin.lexer.JetTokens
import org.jetbrains.kotlin.psi.JetOperationExpression
import org.jetbrains.kotlin.js.translate.utils.PsiUtils import org.jetbrains.kotlin.js.translate.utils.PsiUtils
import org.jetbrains.kotlin.lexer.JetTokens
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.calls.tasks.isDynamic
import org.jetbrains.kotlin.types.expressions.OperatorConventions
import java.util.ArrayList
public fun addReceiverToArgs(receiver: JsExpression, arguments: List<JsExpression>): List<JsExpression> { public fun addReceiverToArgs(receiver: JsExpression, arguments: List<JsExpression>): List<JsExpression> {
if (arguments.isEmpty()) if (arguments.isEmpty())
@@ -178,7 +166,7 @@ object NativeSetterCallCase : AnnotatedAsNativeXCallCase(PredefinedAnnotation.NA
object InvokeIntrinsic : FunctionCallCase { object InvokeIntrinsic : FunctionCallCase {
fun canApply(callInfo: FunctionCallInfo): Boolean { fun canApply(callInfo: FunctionCallInfo): Boolean {
if (!callInfo.callableDescriptor.getName().asString().equals("invoke")) if (callInfo.callableDescriptor.getName() != OperatorConventions.INVOKE)
return false return false
val parameterCount = callInfo.callableDescriptor.getValueParameters().size() val parameterCount = callInfo.callableDescriptor.getValueParameters().size()
val funDeclaration = callInfo.callableDescriptor.getContainingDeclaration() val funDeclaration = callInfo.callableDescriptor.getContainingDeclaration()