Automatically put 'operator' modifier on appropriate Java methods
This commit is contained in:
+1
-3
@@ -109,9 +109,7 @@ public class JavaConstructorDescriptor extends ConstructorDescriptorImpl impleme
|
||||
DescriptorsPackage.createEnhancedValueParameters(enhancedValueParametersTypes, getValueParameters(), enhanced),
|
||||
enhancedReturnType,
|
||||
getModality(),
|
||||
getVisibility(),
|
||||
false,
|
||||
false
|
||||
getVisibility()
|
||||
);
|
||||
|
||||
return enhanced;
|
||||
|
||||
+20
-1
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.types.JetType;
|
||||
import org.jetbrains.kotlin.types.TypeSubstitutor;
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -73,6 +74,24 @@ public class JavaMethodDescriptor extends SimpleFunctionDescriptorImpl implement
|
||||
return new JavaMethodDescriptor(containingDeclaration, null, annotations, name, Kind.DECLARATION, source);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public SimpleFunctionDescriptorImpl initialize(
|
||||
@Nullable JetType receiverParameterType,
|
||||
@Nullable ReceiverParameterDescriptor dispatchReceiverParameter,
|
||||
@NotNull List<? extends TypeParameterDescriptor> typeParameters,
|
||||
@NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters,
|
||||
@Nullable JetType unsubstitutedReturnType,
|
||||
@Nullable Modality modality,
|
||||
@NotNull Visibility visibility
|
||||
) {
|
||||
SimpleFunctionDescriptorImpl descriptor = super.initialize(
|
||||
receiverParameterType, dispatchReceiverParameter, typeParameters, unsubstitutedValueParameters,
|
||||
unsubstitutedReturnType, modality, visibility);
|
||||
setOperator(OperatorNameConventions.INSTANCE$.canBeOperator(descriptor));
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasStableParameterNames() {
|
||||
assert parameterNamesStatus != null : "Parameter names status was not set: " + this;
|
||||
@@ -122,7 +141,7 @@ public class JavaMethodDescriptor extends SimpleFunctionDescriptorImpl implement
|
||||
// 1. creates full copy of descriptor
|
||||
// 2. copies method's type parameters (with new containing declaration) and properly substitute to them in value parameters, return type and etc.
|
||||
JavaMethodDescriptor enhancedMethod = (JavaMethodDescriptor) doSubstitute(
|
||||
TypeSubstitutor.EMPTY, getContainingDeclaration(), getModality(), getVisibility(), false, false, getOriginal(),
|
||||
TypeSubstitutor.EMPTY, getContainingDeclaration(), getModality(), getVisibility(), isOperator(), isInfix(), getOriginal(),
|
||||
/* copyOverrides = */ true, getKind(),
|
||||
enhancedValueParameters, enhancedReceiverType, enhancedReturnType
|
||||
);
|
||||
|
||||
+1
-3
@@ -131,9 +131,7 @@ public abstract class LazyJavaScope(
|
||||
effectiveSignature.getValueParameters(),
|
||||
effectiveSignature.getReturnType(),
|
||||
Modality.convertFromFlags(method.isAbstract(), !method.isFinal()),
|
||||
method.getVisibility(),
|
||||
false,
|
||||
false
|
||||
method.getVisibility()
|
||||
)
|
||||
|
||||
functionDescriptorImpl.setParameterNamesStatus(effectiveSignature.hasStableParameterNames(), valueParameters.hasSynthesizedNames)
|
||||
|
||||
+2
-3
@@ -60,10 +60,9 @@ public class FunctionInvokeDescriptor private constructor(
|
||||
.map { createValueParameter(result, it.index, it.value) },
|
||||
typeParameters.last().getDefaultType(),
|
||||
Modality.ABSTRACT,
|
||||
Visibilities.PUBLIC,
|
||||
true,
|
||||
false
|
||||
Visibilities.PUBLIC
|
||||
)
|
||||
result.isOperator = true
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -60,7 +60,7 @@ public class ConstructorDescriptorImpl extends FunctionDescriptorImpl implements
|
||||
@NotNull Visibility visibility
|
||||
) {
|
||||
super.initialize(null, calculateDispatchReceiverParameter(), typeParameters, unsubstitutedValueParameters, null,
|
||||
Modality.FINAL, visibility, false, false);
|
||||
Modality.FINAL, visibility);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
+14
-10
@@ -42,8 +42,8 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo
|
||||
private ReceiverParameterDescriptor dispatchReceiverParameter;
|
||||
private Modality modality;
|
||||
private Visibility visibility = Visibilities.UNKNOWN;
|
||||
private boolean isOperator;
|
||||
private boolean isInfix;
|
||||
private boolean isOperator = false;
|
||||
private boolean isInfix = false;
|
||||
private final Set<FunctionDescriptor> overriddenFunctions = SmartSet.create();
|
||||
private final FunctionDescriptor original;
|
||||
private final Kind kind;
|
||||
@@ -69,17 +69,13 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo
|
||||
@NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters,
|
||||
@Nullable JetType unsubstitutedReturnType,
|
||||
@Nullable Modality modality,
|
||||
@NotNull Visibility visibility,
|
||||
boolean isOperator,
|
||||
boolean isInfix
|
||||
@NotNull Visibility visibility
|
||||
) {
|
||||
this.typeParameters = UtilsPackage.toReadOnlyList(typeParameters);
|
||||
this.unsubstitutedValueParameters = unsubstitutedValueParameters;
|
||||
this.unsubstitutedReturnType = unsubstitutedReturnType;
|
||||
this.modality = modality;
|
||||
this.visibility = visibility;
|
||||
this.isOperator = isOperator;
|
||||
this.isInfix = isInfix;
|
||||
this.extensionReceiverParameter = DescriptorFactory.createExtensionReceiverParameterForCallable(this, receiverParameterType);
|
||||
this.dispatchReceiverParameter = dispatchReceiverParameter;
|
||||
|
||||
@@ -106,6 +102,14 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo
|
||||
this.visibility = visibility;
|
||||
}
|
||||
|
||||
public void setOperator(boolean isOperator) {
|
||||
this.isOperator = isOperator;
|
||||
}
|
||||
|
||||
public void setInfix(boolean isInfix) {
|
||||
this.isInfix = isInfix;
|
||||
}
|
||||
|
||||
public void setReturnType(@NotNull JetType unsubstitutedReturnType) {
|
||||
if (this.unsubstitutedReturnType != null) {
|
||||
// TODO: uncomment and fix tests
|
||||
@@ -309,10 +313,10 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo
|
||||
substitutedValueParameters,
|
||||
substitutedReturnType,
|
||||
newModality,
|
||||
newVisibility,
|
||||
isOperator,
|
||||
isInfix
|
||||
newVisibility
|
||||
);
|
||||
substitutedDescriptor.setOperator(isOperator);
|
||||
substitutedDescriptor.setInfix(isInfix);
|
||||
|
||||
if (copyOverrides) {
|
||||
for (FunctionDescriptor overriddenFunction : overriddenFunctions) {
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ public class ScriptCodeDescriptor extends FunctionDescriptorImpl {
|
||||
@NotNull List<ValueParameterDescriptor> valueParameters,
|
||||
@NotNull JetType returnType) {
|
||||
super.initialize(null, dispatchReceiverParameter, Collections.<TypeParameterDescriptor>emptyList(), valueParameters, returnType,
|
||||
Modality.FINAL, Visibilities.INTERNAL, false, false);
|
||||
Modality.FINAL, Visibilities.INTERNAL);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+2
-4
@@ -58,12 +58,10 @@ public class SimpleFunctionDescriptorImpl extends FunctionDescriptorImpl impleme
|
||||
@NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters,
|
||||
@Nullable JetType unsubstitutedReturnType,
|
||||
@Nullable Modality modality,
|
||||
@NotNull Visibility visibility,
|
||||
boolean isOperator,
|
||||
boolean isInfix
|
||||
@NotNull Visibility visibility
|
||||
) {
|
||||
super.initialize(receiverParameterType, dispatchReceiverParameter, typeParameters, unsubstitutedValueParameters,
|
||||
unsubstitutedReturnType, modality, visibility, isOperator, isInfix);
|
||||
unsubstitutedReturnType, modality, visibility);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ public class DescriptorFactory {
|
||||
return values.initialize(null, null, Collections.<TypeParameterDescriptor>emptyList(),
|
||||
Collections.<ValueParameterDescriptor>emptyList(),
|
||||
getBuiltIns(enumClass).getArrayType(Variance.INVARIANT, enumClass.getDefaultType()),
|
||||
Modality.FINAL, Visibilities.PUBLIC, false, false);
|
||||
Modality.FINAL, Visibilities.PUBLIC);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -117,7 +117,7 @@ public class DescriptorFactory {
|
||||
);
|
||||
return valueOf.initialize(null, null, Collections.<TypeParameterDescriptor>emptyList(),
|
||||
Collections.singletonList(parameterDescriptor), enumClass.getDefaultType(),
|
||||
Modality.FINAL, Visibilities.PUBLIC, false, false);
|
||||
Modality.FINAL, Visibilities.PUBLIC);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -499,9 +499,7 @@ public class ErrorUtils {
|
||||
Collections.<ValueParameterDescriptor>emptyList(), // TODO
|
||||
createErrorType("<ERROR FUNCTION RETURN TYPE>"),
|
||||
Modality.OPEN,
|
||||
Visibilities.INTERNAL,
|
||||
false,
|
||||
false
|
||||
Visibilities.INTERNAL
|
||||
);
|
||||
return function;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* 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.util
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import kotlin.text.Regex
|
||||
|
||||
object OperatorNameConventions {
|
||||
|
||||
val EQUALS = Name.identifier("equals")
|
||||
val IDENTITY_EQUALS = Name.identifier("identityEquals");
|
||||
val COMPARE_TO = Name.identifier("compareTo")
|
||||
val CONTAINS = Name.identifier("contains")
|
||||
val INVOKE = Name.identifier("invoke")
|
||||
val ITERATOR = Name.identifier("iterator")
|
||||
val GET = Name.identifier("get")
|
||||
val SET = Name.identifier("set")
|
||||
val NEXT = Name.identifier("next")
|
||||
val HAS_NEXT = Name.identifier("hasNext")
|
||||
|
||||
val COMPONENT_REGEX = Regex("component\\d+")
|
||||
|
||||
val AND = Name.identifier("and")
|
||||
val OR = Name.identifier("or")
|
||||
|
||||
val INC = Name.identifier("inc")
|
||||
val DEC = Name.identifier("dec")
|
||||
val PLUS = Name.identifier("plus")
|
||||
val MINUS = Name.identifier("minus")
|
||||
val NOT = Name.identifier("not")
|
||||
|
||||
val TIMES = Name.identifier("times")
|
||||
val DIV = Name.identifier("div")
|
||||
val MOD = Name.identifier("mod")
|
||||
val RANGE_TO = Name.identifier("rangeTo")
|
||||
|
||||
val TIMES_ASSIGN = Name.identifier("timesAssign")
|
||||
val DIV_ASSIGN = Name.identifier("divAssign")
|
||||
val MOD_ASSIGN = Name.identifier("modAssign")
|
||||
val PLUS_ASSIGN = Name.identifier("plusAssign")
|
||||
val MINUS_ASSIGN = Name.identifier("minusAssign")
|
||||
|
||||
// If you add new unary, binary or assignment operators, add it to OperatorConventions as well
|
||||
|
||||
private val UNARY_OPERATION_NAMES = setOf(INC, DEC, PLUS, MINUS, NOT)
|
||||
private val BINARY_OPERATION_NAMES = setOf(TIMES, PLUS, MINUS, DIV, MOD, RANGE_TO)
|
||||
private val ASSIGNMENT_OPERATIONS = setOf(TIMES_ASSIGN, DIV_ASSIGN, MOD_ASSIGN, PLUS_ASSIGN, MINUS_ASSIGN)
|
||||
|
||||
fun canBeOperator(functionDescriptor: FunctionDescriptor): Boolean {
|
||||
val name = functionDescriptor.name
|
||||
|
||||
return when {
|
||||
GET == name -> true
|
||||
SET == name -> true
|
||||
INVOKE == name -> true
|
||||
CONTAINS == name -> true
|
||||
ITERATOR == name -> true
|
||||
NEXT == name -> true
|
||||
HAS_NEXT == name -> true
|
||||
EQUALS == name -> true
|
||||
COMPARE_TO == name -> true
|
||||
UNARY_OPERATION_NAMES.any { it == name } && functionDescriptor.valueParameters.isEmpty() -> true
|
||||
BINARY_OPERATION_NAMES.any { it == name } && functionDescriptor.valueParameters.size() == 1 -> true
|
||||
ASSIGNMENT_OPERATIONS.any { it == name } -> true
|
||||
name.asString().matches(COMPONENT_REGEX) -> true
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+3
-3
@@ -151,10 +151,10 @@ public class MemberDeserializer(private val c: DeserializationContext) {
|
||||
local.memberDeserializer.valueParameters(proto, AnnotatedCallableKind.FUNCTION),
|
||||
local.typeDeserializer.type(proto.returnType),
|
||||
Deserialization.modality(Flags.MODALITY.get(proto.flags)),
|
||||
Deserialization.visibility(Flags.VISIBILITY.get(proto.flags)),
|
||||
Flags.OLD_IS_OPERATOR.get(proto.flags),
|
||||
Flags.OLD_IS_INFIX.get(proto.flags)
|
||||
Deserialization.visibility(Flags.VISIBILITY.get(proto.flags))
|
||||
)
|
||||
function.isOperator = Flags.OLD_IS_OPERATOR.get(proto.flags)
|
||||
function.isInfix = Flags.OLD_IS_INFIX.get(proto.flags)
|
||||
return function
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user