JS backend: move mangling functions to separate util class.
This commit is contained in:
@@ -25,7 +25,7 @@ import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||
import org.jetbrains.jet.plugin.JetLanguage;
|
||||
|
||||
import static com.google.dart.compiler.backend.js.ast.AstPackage.JsObjectScope;
|
||||
import static org.jetbrains.k2js.translate.utils.TranslationUtils.getStableMangledNameForDescriptor;
|
||||
import static org.jetbrains.k2js.translate.utils.ManglingUtils.getStableMangledNameForDescriptor;
|
||||
|
||||
/**
|
||||
* Encapuslates different types of constants and naming conventions.
|
||||
|
||||
@@ -41,8 +41,8 @@ import java.util.Map;
|
||||
import static org.jetbrains.jet.lang.resolve.DescriptorToSourceUtils.descriptorToDeclaration;
|
||||
import static org.jetbrains.k2js.translate.utils.AnnotationsUtils.*;
|
||||
import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.*;
|
||||
import static org.jetbrains.k2js.translate.utils.TranslationUtils.getMangledName;
|
||||
import static org.jetbrains.k2js.translate.utils.TranslationUtils.getSuggestedName;
|
||||
import static org.jetbrains.k2js.translate.utils.ManglingUtils.getMangledName;
|
||||
import static org.jetbrains.k2js.translate.utils.ManglingUtils.getSuggestedName;
|
||||
|
||||
/**
|
||||
* Aggregates all the static parts of the context.
|
||||
|
||||
@@ -19,7 +19,7 @@ package org.jetbrains.k2js.translate.context
|
||||
import org.jetbrains.jet.lang.descriptors.*
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils.isAncestor
|
||||
import com.google.dart.compiler.backend.js.ast.JsName
|
||||
import org.jetbrains.k2js.translate.utils.TranslationUtils.getSuggestedName
|
||||
import org.jetbrains.k2js.translate.utils.ManglingUtils.getSuggestedName
|
||||
import com.google.dart.compiler.backend.js.ast.JsFunctionScope
|
||||
|
||||
private val CAPTURED_RECEIVER_NAME_PREFIX : String = "this$"
|
||||
|
||||
+1
-1
@@ -33,8 +33,8 @@ import org.jetbrains.k2js.translate.utils.TranslationUtils.*
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils
|
||||
import org.jetbrains.jet.backend.common.CodegenUtil
|
||||
import java.util.HashMap
|
||||
import com.google.dart.compiler.backend.js.ast.JsLiteral
|
||||
import org.jetbrains.k2js.translate.declaration.propertyTranslator.addGetterAndSetter
|
||||
import org.jetbrains.k2js.translate.utils.ManglingUtils.getMangledMemberNameForExplicitDelegation
|
||||
|
||||
public class DelegationTranslator(
|
||||
private val classDeclaration: JetClassOrObject,
|
||||
|
||||
-1
@@ -26,7 +26,6 @@ import org.jetbrains.k2js.translate.context.*
|
||||
import org.jetbrains.k2js.translate.general.AbstractTranslator
|
||||
import org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptor
|
||||
import org.jetbrains.k2js.translate.utils.FunctionBodyTranslator.translateFunctionBody
|
||||
import org.jetbrains.k2js.translate.utils.TranslationUtils.getSuggestedName
|
||||
import org.jetbrains.k2js.translate.utils.TranslationUtils.simpleReturnFunction
|
||||
import org.jetbrains.jet.lang.descriptors.MemberDescriptor
|
||||
import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor
|
||||
|
||||
+1
-1
@@ -45,7 +45,7 @@ import java.util.List;
|
||||
|
||||
import static org.jetbrains.k2js.translate.intrinsic.functions.basic.FunctionIntrinsic.CallParametersAwareFunctionIntrinsic;
|
||||
import static org.jetbrains.k2js.translate.intrinsic.functions.patterns.PatternBuilder.pattern;
|
||||
import static org.jetbrains.k2js.translate.utils.TranslationUtils.getStableMangledNameForDescriptor;
|
||||
import static org.jetbrains.k2js.translate.utils.ManglingUtils.getStableMangledNameForDescriptor;
|
||||
|
||||
public final class TopLevelFIF extends CompositeFIF {
|
||||
public static final DescriptorPredicate EQUALS_IN_ANY = pattern("kotlin", "Any", "equals");
|
||||
|
||||
@@ -0,0 +1,246 @@
|
||||
/*
|
||||
* Copyright 2010-2014 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.k2js.translate.utils;
|
||||
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.backend.common.CodegenUtil;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.resolve.OverrideResolver;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.getFqName;
|
||||
|
||||
public class ManglingUtils {
|
||||
private ManglingUtils() {}
|
||||
|
||||
public static final Comparator<FunctionDescriptor> OVERLOADED_FUNCTION_COMPARATOR = new OverloadedFunctionComparator();
|
||||
|
||||
@NotNull
|
||||
public static String getMangledName(@NotNull PropertyDescriptor descriptor, @NotNull String suggestedName) {
|
||||
return getStableMangledName(suggestedName, getFqName(descriptor).asString());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String getSuggestedName(@NotNull DeclarationDescriptor descriptor) {
|
||||
String suggestedName = descriptor.getName().asString();
|
||||
|
||||
if (descriptor instanceof FunctionDescriptor) {
|
||||
suggestedName = getMangledName((FunctionDescriptor) descriptor);
|
||||
}
|
||||
|
||||
return suggestedName;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String getMangledName(@NotNull FunctionDescriptor descriptor) {
|
||||
if (needsStableMangling(descriptor)) {
|
||||
return getStableMangledName(descriptor);
|
||||
}
|
||||
|
||||
return getSimpleMangledName(descriptor);
|
||||
}
|
||||
|
||||
//TODO extend logic for nested/inner declarations
|
||||
private static boolean needsStableMangling(FunctionDescriptor descriptor) {
|
||||
// Use stable mangling for overrides because we use stable mangling when any function inside a overridable declaration
|
||||
// for avoid clashing names when inheritance.
|
||||
if (JsDescriptorUtils.isOverride(descriptor)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
|
||||
|
||||
if (containingDeclaration instanceof PackageFragmentDescriptor) {
|
||||
return descriptor.getVisibility().isPublicAPI();
|
||||
}
|
||||
else if (containingDeclaration instanceof ClassDescriptor) {
|
||||
ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration;
|
||||
|
||||
// Use stable mangling when it's inside an overridable declaration to avoid clashing names on inheritance.
|
||||
if (classDescriptor.getModality().isOverridable()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// valueOf() is created in the library with a mangled name for every enum class
|
||||
if (CodegenUtil.isEnumValueOfMethod(descriptor)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Don't use stable mangling when it inside a non-public API declaration.
|
||||
if (!classDescriptor.getVisibility().isPublicAPI()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Ignore the `protected` visibility because it can be use outside a containing declaration
|
||||
// only when the containing declaration is overridable.
|
||||
if (descriptor.getVisibility() == Visibilities.PUBLIC) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
assert containingDeclaration instanceof CallableMemberDescriptor :
|
||||
"containingDeclaration for descriptor have unsupported type for mangling, " +
|
||||
"descriptor: " + descriptor + ", containingDeclaration: " + containingDeclaration;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String getMangledMemberNameForExplicitDelegation(@NotNull String suggestedName, FqName classFqName, FqName typeFqName) {
|
||||
String forCalculateId = classFqName.asString() + ":" + typeFqName.asString();
|
||||
return getStableMangledName(suggestedName, forCalculateId);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String getStableMangledName(@NotNull String suggestedName, String forCalculateId) {
|
||||
int absHashCode = Math.abs(forCalculateId.hashCode());
|
||||
String suffix = absHashCode == 0 ? "" : ("_" + Integer.toString(absHashCode, Character.MAX_RADIX) + "$");
|
||||
return suggestedName + suffix;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String getStableMangledName(@NotNull FunctionDescriptor descriptor) {
|
||||
return getStableMangledName(descriptor.getName().asString(), getArgumentTypesAsString(descriptor));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String getSimpleMangledName(@NotNull final FunctionDescriptor descriptor) {
|
||||
DeclarationDescriptor declaration = descriptor.getContainingDeclaration();
|
||||
|
||||
JetScope jetScope = null;
|
||||
if (declaration instanceof PackageFragmentDescriptor) {
|
||||
jetScope = ((PackageFragmentDescriptor) declaration).getMemberScope();
|
||||
}
|
||||
else if (declaration instanceof ClassDescriptor) {
|
||||
jetScope = ((ClassDescriptor) declaration).getDefaultType().getMemberScope();
|
||||
}
|
||||
|
||||
int counter = 0;
|
||||
|
||||
if (jetScope != null) {
|
||||
Collection<DeclarationDescriptor> declarations = jetScope.getAllDescriptors();
|
||||
List<FunctionDescriptor>
|
||||
overloadedFunctions = ContainerUtil.mapNotNull(declarations, new Function<DeclarationDescriptor, FunctionDescriptor>() {
|
||||
@Override
|
||||
public FunctionDescriptor fun(DeclarationDescriptor declarationDescriptor) {
|
||||
if (!(declarationDescriptor instanceof FunctionDescriptor)) return null;
|
||||
|
||||
FunctionDescriptor functionDescriptor = (FunctionDescriptor) declarationDescriptor;
|
||||
|
||||
String name = AnnotationsUtils.getNameForAnnotatedObjectWithOverrides(functionDescriptor);
|
||||
|
||||
// when name == null it's mean that it's not native.
|
||||
if (name == null) {
|
||||
// skip functions without arguments, because we don't use mangling for them
|
||||
if (needsStableMangling(functionDescriptor) && !functionDescriptor.getValueParameters().isEmpty()) return null;
|
||||
|
||||
name = declarationDescriptor.getName().asString();
|
||||
}
|
||||
|
||||
return descriptor.getName().asString().equals(name) ? functionDescriptor : null;
|
||||
}
|
||||
});
|
||||
|
||||
if (overloadedFunctions.size() > 1) {
|
||||
Collections.sort(overloadedFunctions, OVERLOADED_FUNCTION_COMPARATOR);
|
||||
counter = ContainerUtil.indexOfIdentity(overloadedFunctions, descriptor);
|
||||
assert counter >= 0;
|
||||
}
|
||||
}
|
||||
|
||||
String name = descriptor.getName().asString();
|
||||
return counter == 0 ? name : name + '_' + counter;
|
||||
}
|
||||
|
||||
private static String getArgumentTypesAsString(FunctionDescriptor descriptor) {
|
||||
StringBuilder argTypes = new StringBuilder();
|
||||
|
||||
ReceiverParameterDescriptor receiverParameter = descriptor.getExtensionReceiverParameter();
|
||||
if (receiverParameter != null) {
|
||||
argTypes.append(TranslationUtils.getJetTypeFqName(receiverParameter.getType())).append(".");
|
||||
}
|
||||
|
||||
argTypes.append(StringUtil.join(descriptor.getValueParameters(), new Function<ValueParameterDescriptor, String>() {
|
||||
@Override
|
||||
public String fun(ValueParameterDescriptor descriptor) {
|
||||
return TranslationUtils.getJetTypeFqName(descriptor.getType());
|
||||
}
|
||||
}, ","));
|
||||
|
||||
return argTypes.toString();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String getStableMangledNameForDescriptor(@NotNull ClassDescriptor descriptor, @NotNull String functionName) {
|
||||
Collection<FunctionDescriptor> functions = descriptor.getDefaultType().getMemberScope().getFunctions(Name.identifier(functionName));
|
||||
assert functions.size() == 1 : "Can't select a single function: " + functionName + " in " + descriptor;
|
||||
return getSuggestedName(functions.iterator().next());
|
||||
}
|
||||
|
||||
private static class OverloadedFunctionComparator implements Comparator<FunctionDescriptor> {
|
||||
@Override
|
||||
public int compare(@NotNull FunctionDescriptor a, @NotNull FunctionDescriptor b) {
|
||||
// native functions first
|
||||
if (isNativeOrOverrideNative(a)) {
|
||||
if (!isNativeOrOverrideNative(b)) return -1;
|
||||
}
|
||||
else if (isNativeOrOverrideNative(b)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// be visibility
|
||||
// Actually "internal" > "private", but we want to have less number for "internal", so compare b with a instead of a with b.
|
||||
Integer result = Visibilities.compare(b.getVisibility(), a.getVisibility());
|
||||
if (result != null && result != 0) return result;
|
||||
|
||||
// by arity
|
||||
int aArity = arity(a);
|
||||
int bArity = arity(b);
|
||||
if (aArity != bArity) return aArity - bArity;
|
||||
|
||||
// by stringify argument types
|
||||
String aArguments = getArgumentTypesAsString(a);
|
||||
String bArguments = getArgumentTypesAsString(b);
|
||||
assert aArguments != bArguments;
|
||||
|
||||
return aArguments.compareTo(bArguments);
|
||||
}
|
||||
|
||||
private static int arity(FunctionDescriptor descriptor) {
|
||||
return descriptor.getValueParameters().size() + (descriptor.getExtensionReceiverParameter() == null ? 0 : 1);
|
||||
}
|
||||
|
||||
private static boolean isNativeOrOverrideNative(FunctionDescriptor descriptor) {
|
||||
if (AnnotationsUtils.isNativeObject(descriptor)) return true;
|
||||
|
||||
Set<FunctionDescriptor> declarations = OverrideResolver.getAllOverriddenDeclarations(descriptor);
|
||||
for (FunctionDescriptor memberDescriptor : declarations) {
|
||||
if (AnnotationsUtils.isNativeObject(memberDescriptor)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,26 +17,20 @@
|
||||
package org.jetbrains.k2js.translate.utils;
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.*;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.backend.common.CodegenUtil;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.descriptors.impl.AnonymousFunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.OverrideResolver;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||
import org.jetbrains.k2js.translate.context.TemporaryConstVariable;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.general.Translation;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static com.google.dart.compiler.backend.js.ast.JsBinaryOperator.*;
|
||||
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.getFqName;
|
||||
@@ -45,9 +39,9 @@ import static org.jetbrains.k2js.translate.context.Namer.getKotlinBackingFieldNa
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getCallableDescriptorForOperationExpression;
|
||||
import static org.jetbrains.k2js.translate.utils.JsAstUtils.assignment;
|
||||
import static org.jetbrains.k2js.translate.utils.JsAstUtils.createDataDescriptor;
|
||||
import static org.jetbrains.k2js.translate.utils.ManglingUtils.getMangledName;
|
||||
|
||||
public final class TranslationUtils {
|
||||
public static final Comparator<FunctionDescriptor> OVERLOADED_FUNCTION_COMPARATOR = new OverloadedFunctionComparator();
|
||||
|
||||
private TranslationUtils() {
|
||||
}
|
||||
@@ -139,162 +133,6 @@ public final class TranslationUtils {
|
||||
return new JsConditional(testExpression, thenExpression, elseExpression);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String getMangledName(@NotNull PropertyDescriptor descriptor, @NotNull String suggestedName) {
|
||||
return getStableMangledName(suggestedName, getFqName(descriptor).asString());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String getSuggestedName(@NotNull DeclarationDescriptor descriptor) {
|
||||
String suggestedName = descriptor.getName().asString();
|
||||
|
||||
if (descriptor instanceof FunctionDescriptor) {
|
||||
suggestedName = getMangledName((FunctionDescriptor) descriptor);
|
||||
}
|
||||
|
||||
return suggestedName;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String getMangledName(@NotNull FunctionDescriptor descriptor) {
|
||||
if (needsStableMangling(descriptor)) {
|
||||
return getStableMangledName(descriptor);
|
||||
}
|
||||
|
||||
return getSimpleMangledName(descriptor);
|
||||
}
|
||||
|
||||
//TODO extend logic for nested/inner declarations
|
||||
private static boolean needsStableMangling(FunctionDescriptor descriptor) {
|
||||
// Use stable mangling for overrides because we use stable mangling when any function inside a overridable declaration
|
||||
// for avoid clashing names when inheritance.
|
||||
if (JsDescriptorUtils.isOverride(descriptor)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
|
||||
|
||||
if (containingDeclaration instanceof PackageFragmentDescriptor) {
|
||||
return descriptor.getVisibility().isPublicAPI();
|
||||
}
|
||||
else if (containingDeclaration instanceof ClassDescriptor) {
|
||||
ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration;
|
||||
|
||||
// Use stable mangling when it's inside an overridable declaration to avoid clashing names on inheritance.
|
||||
if (classDescriptor.getModality().isOverridable()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// valueOf() is created in the library with a mangled name for every enum class
|
||||
if (CodegenUtil.isEnumValueOfMethod(descriptor)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Don't use stable mangling when it inside a non-public API declaration.
|
||||
if (!classDescriptor.getVisibility().isPublicAPI()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Ignore the `protected` visibility because it can be use outside a containing declaration
|
||||
// only when the containing declaration is overridable.
|
||||
if (descriptor.getVisibility() == Visibilities.PUBLIC) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
assert containingDeclaration instanceof CallableMemberDescriptor :
|
||||
"containingDeclaration for descriptor have unsupported type for mangling, " +
|
||||
"descriptor: " + descriptor + ", containingDeclaration: " + containingDeclaration;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String getMangledMemberNameForExplicitDelegation(@NotNull String suggestedName, FqName classFqName, FqName typeFqName) {
|
||||
String forCalculateId = classFqName.asString() + ":" + typeFqName.asString();
|
||||
return getStableMangledName(suggestedName, forCalculateId);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String getStableMangledName(@NotNull String suggestedName, String forCalculateId) {
|
||||
int absHashCode = Math.abs(forCalculateId.hashCode());
|
||||
String suffix = absHashCode == 0 ? "" : ("_" + Integer.toString(absHashCode, Character.MAX_RADIX) + "$");
|
||||
return suggestedName + suffix;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String getStableMangledName(@NotNull FunctionDescriptor descriptor) {
|
||||
return getStableMangledName(descriptor.getName().asString(), getArgumentTypesAsString(descriptor));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String getSimpleMangledName(@NotNull final FunctionDescriptor descriptor) {
|
||||
DeclarationDescriptor declaration = descriptor.getContainingDeclaration();
|
||||
|
||||
JetScope jetScope = null;
|
||||
if (declaration instanceof PackageFragmentDescriptor) {
|
||||
jetScope = ((PackageFragmentDescriptor) declaration).getMemberScope();
|
||||
}
|
||||
else if (declaration instanceof ClassDescriptor) {
|
||||
jetScope = ((ClassDescriptor) declaration).getDefaultType().getMemberScope();
|
||||
}
|
||||
|
||||
int counter = 0;
|
||||
|
||||
if (jetScope != null) {
|
||||
Collection<DeclarationDescriptor> declarations = jetScope.getAllDescriptors();
|
||||
List<FunctionDescriptor> overloadedFunctions = ContainerUtil.mapNotNull(declarations, new Function<DeclarationDescriptor, FunctionDescriptor>() {
|
||||
@Override
|
||||
public FunctionDescriptor fun(DeclarationDescriptor declarationDescriptor) {
|
||||
if (!(declarationDescriptor instanceof FunctionDescriptor)) return null;
|
||||
|
||||
FunctionDescriptor functionDescriptor = (FunctionDescriptor) declarationDescriptor;
|
||||
|
||||
String name = AnnotationsUtils.getNameForAnnotatedObjectWithOverrides(functionDescriptor);
|
||||
|
||||
// when name == null it's mean that it's not native.
|
||||
if (name == null) {
|
||||
// skip functions without arguments, because we don't use mangling for them
|
||||
if (needsStableMangling(functionDescriptor) && !functionDescriptor.getValueParameters().isEmpty()) return null;
|
||||
|
||||
name = declarationDescriptor.getName().asString();
|
||||
}
|
||||
|
||||
return descriptor.getName().asString().equals(name) ? functionDescriptor : null;
|
||||
}
|
||||
});
|
||||
|
||||
if (overloadedFunctions.size() > 1) {
|
||||
Collections.sort(overloadedFunctions, OVERLOADED_FUNCTION_COMPARATOR);
|
||||
counter = ContainerUtil.indexOfIdentity(overloadedFunctions, descriptor);
|
||||
assert counter >= 0;
|
||||
}
|
||||
}
|
||||
|
||||
String name = descriptor.getName().asString();
|
||||
return counter == 0 ? name : name + '_' + counter;
|
||||
}
|
||||
|
||||
private static String getArgumentTypesAsString(FunctionDescriptor descriptor) {
|
||||
StringBuilder argTypes = new StringBuilder();
|
||||
|
||||
ReceiverParameterDescriptor receiverParameter = descriptor.getExtensionReceiverParameter();
|
||||
if (receiverParameter != null) {
|
||||
argTypes.append(getJetTypeFqName(receiverParameter.getType())).append(".");
|
||||
}
|
||||
|
||||
argTypes.append(StringUtil.join(descriptor.getValueParameters(), new Function<ValueParameterDescriptor, String>() {
|
||||
@Override
|
||||
public String fun(ValueParameterDescriptor descriptor) {
|
||||
return getJetTypeFqName(descriptor.getType());
|
||||
}
|
||||
}, ","));
|
||||
|
||||
return argTypes.toString();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String getJetTypeFqName(@NotNull JetType jetType) {
|
||||
ClassifierDescriptor declaration = jetType.getConstructor().getDeclarationDescriptor();
|
||||
@@ -430,13 +268,6 @@ public final class TranslationUtils {
|
||||
return ensureNotNull;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String getStableMangledNameForDescriptor(@NotNull ClassDescriptor descriptor, @NotNull String functionName) {
|
||||
Collection<FunctionDescriptor> functions = descriptor.getDefaultType().getMemberScope().getFunctions(Name.identifier(functionName));
|
||||
assert functions.size() == 1 : "Can't select a single function: " + functionName + " in " + descriptor;
|
||||
return getSuggestedName(functions.iterator().next());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String getSuggestedNameForInnerDeclaration(TranslationContext context, DeclarationDescriptor descriptor) {
|
||||
String suggestedName = "";
|
||||
@@ -461,48 +292,4 @@ public final class TranslationUtils {
|
||||
}
|
||||
return suggestedName;
|
||||
}
|
||||
|
||||
private static class OverloadedFunctionComparator implements Comparator<FunctionDescriptor> {
|
||||
@Override
|
||||
public int compare(@NotNull FunctionDescriptor a, @NotNull FunctionDescriptor b) {
|
||||
// native functions first
|
||||
if (isNativeOrOverrideNative(a)) {
|
||||
if (!isNativeOrOverrideNative(b)) return -1;
|
||||
}
|
||||
else if (isNativeOrOverrideNative(b)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// be visibility
|
||||
// Actually "internal" > "private", but we want to have less number for "internal", so compare b with a instead of a with b.
|
||||
Integer result = Visibilities.compare(b.getVisibility(), a.getVisibility());
|
||||
if (result != null && result != 0) return result;
|
||||
|
||||
// by arity
|
||||
int aArity = arity(a);
|
||||
int bArity = arity(b);
|
||||
if (aArity != bArity) return aArity - bArity;
|
||||
|
||||
// by stringify argument types
|
||||
String aArguments = getArgumentTypesAsString(a);
|
||||
String bArguments = getArgumentTypesAsString(b);
|
||||
assert aArguments != bArguments;
|
||||
|
||||
return aArguments.compareTo(bArguments);
|
||||
}
|
||||
|
||||
private static int arity(FunctionDescriptor descriptor) {
|
||||
return descriptor.getValueParameters().size() + (descriptor.getExtensionReceiverParameter() == null ? 0 : 1);
|
||||
}
|
||||
|
||||
private static boolean isNativeOrOverrideNative(FunctionDescriptor descriptor) {
|
||||
if (AnnotationsUtils.isNativeObject(descriptor)) return true;
|
||||
|
||||
Set<FunctionDescriptor> declarations = OverrideResolver.getAllOverriddenDeclarations(descriptor);
|
||||
for (FunctionDescriptor memberDescriptor : declarations) {
|
||||
if (AnnotationsUtils.isNativeObject(memberDescriptor)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user