JS backend: refactoring the code for using special implementation of Map/Set for primitives (Int, String etc.) -- made it intrinsic.

Properly implementation for KT-2026.

(cherry picked from commit 6335bc4)
This commit is contained in:
develar
2013-08-06 17:24:48 +04:00
committed by Zalim Bashorov
parent 1fab7346cc
commit bf8d5d797a
2 changed files with 47 additions and 33 deletions
@@ -28,9 +28,12 @@ import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.psi.JetQualifiedExpression;
import org.jetbrains.jet.lang.psi.JetReferenceExpression;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.jet.lang.types.lang.PrimitiveType;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.intrinsic.functions.basic.BuiltInFunctionIntrinsic;
import org.jetbrains.k2js.translate.intrinsic.functions.basic.CallStandardMethodIntrinsic;
@@ -40,6 +43,7 @@ import org.jetbrains.k2js.translate.intrinsic.functions.patterns.NamePredicate;
import org.jetbrains.k2js.translate.reference.CallTranslator;
import org.jetbrains.k2js.translate.utils.AnnotationsUtils;
import org.jetbrains.k2js.translate.utils.BindingUtils;
import org.jetbrains.k2js.translate.utils.JsDescriptorUtils;
import java.util.List;
@@ -182,7 +186,11 @@ public final class TopLevelFIF extends CompositeFIF {
}, new CallParametersAwareFunctionIntrinsic() {
@NotNull
@Override
public JsExpression apply(@NotNull CallTranslator callTranslator, @NotNull List<JsExpression> arguments, @NotNull TranslationContext context) {
public JsExpression apply(
@NotNull CallTranslator callTranslator,
@NotNull List<JsExpression> arguments,
@NotNull TranslationContext context
) {
JsExpression thisExpression = callTranslator.getCallParameters().getThisObject();
if (thisExpression == null) {
return new JsInvocation(callTranslator.getCallParameters().getFunctionReference(), arguments);
@@ -201,5 +209,40 @@ public final class TopLevelFIF extends CompositeFIF {
add(pattern("java", "util", "set").receiverExists(true), NATIVE_MAP_SET);
add(pattern("jet", "Map", "get"), NATIVE_MAP_GET);
add(pattern("java", "util", "HashMap", "get"), NATIVE_MAP_GET);
add(pattern("java", "util", "HashMap", "<init>"), new MapSelectImplementationIntrinsic(false));
add(pattern("java", "util", "HashSet", "<init>"), new MapSelectImplementationIntrinsic(true));
}
private static class MapSelectImplementationIntrinsic extends CallParametersAwareFunctionIntrinsic {
private final boolean isSet;
private MapSelectImplementationIntrinsic(boolean isSet) {
this.isSet = isSet;
}
@NotNull
@Override
public JsExpression apply(
@NotNull CallTranslator callTranslator,
@NotNull List<JsExpression> arguments,
@NotNull TranslationContext context
) {
JetType keyType = callTranslator.getResolvedCall().getTypeArguments().values().iterator().next();
Name keyTypeName = JsDescriptorUtils.getNameIfStandardType(keyType);
String collectionClassName;
if (keyTypeName != null &&
(NamePredicate.PRIMITIVE_NUMBERS.apply(keyTypeName) ||
keyTypeName.asString().equals("String") ||
PrimitiveType.BOOLEAN.getTypeName().equals(keyTypeName))) {
collectionClassName = isSet ? "PrimitiveHashSet" : "PrimitiveHashMap";
}
else {
collectionClassName = isSet ? "ComplexHashSet" : "ComplexHashMap";
}
return callTranslator.createConstructorCallExpression(context.namer().kotlin(collectionClassName));
}
}
}
@@ -16,6 +16,7 @@
package org.jetbrains.k2js.translate.reference;
import com.google.dart.compiler.backend.js.ast.HasArguments;
import com.google.dart.compiler.backend.js.ast.JsExpression;
import com.google.dart.compiler.backend.js.ast.JsInvocation;
import com.google.dart.compiler.backend.js.ast.JsNew;
@@ -25,15 +26,11 @@ import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
import org.jetbrains.jet.lang.resolve.calls.model.VariableAsFunctionResolvedCall;
import org.jetbrains.jet.lang.resolve.calls.util.ExpressionAsFunctionDescriptor;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.general.AbstractTranslator;
import org.jetbrains.k2js.translate.intrinsic.functions.basic.FunctionIntrinsic;
import org.jetbrains.k2js.translate.intrinsic.functions.patterns.NamePredicate;
import org.jetbrains.k2js.translate.utils.AnnotationsUtils;
import org.jetbrains.k2js.translate.utils.ErrorReportingUtils;
import org.jetbrains.k2js.translate.utils.JsDescriptorUtils;
import org.jetbrains.k2js.translate.utils.TranslationUtils;
import java.util.List;
@@ -88,7 +85,7 @@ public final class CallTranslator extends AbstractTranslator {
return result;
}
if (isConstructor()) {
return constructorCall();
return createConstructorCallExpression(translateAsFunctionWithNoThisObject(descriptor));
}
if (resolvedCall.getReceiverArgument().exists()) {
if (AnnotationsUtils.isNativeObject(descriptor)) {
@@ -133,33 +130,7 @@ public final class CallTranslator extends AbstractTranslator {
}
@NotNull
private JsExpression constructorCall() {
JsExpression constructorReference;
ClassDescriptor classDescriptor = (ClassDescriptor) descriptor.getContainingDeclaration();
boolean isSet = false;
if (AnnotationsUtils.isLibraryObject(classDescriptor) &&
(classDescriptor.getName().asString().equals("HashMap") || (isSet = classDescriptor.getName().asString().equals("HashSet")))) {
JetType keyType = resolvedCall.getTypeArguments().values().iterator().next();
Name keyTypeName = JsDescriptorUtils.getNameIfStandardType(keyType);
String collectionClassName;
if (keyTypeName != null && (NamePredicate.PRIMITIVE_NUMBERS.apply(keyTypeName) || keyTypeName.asString().equals("String"))) {
collectionClassName = isSet ? "PrimitiveHashSet" : "PrimitiveHashMap";
}
else {
collectionClassName = isSet ? "ComplexHashSet" : "ComplexHashMap";
}
constructorReference = context().namer().kotlin(collectionClassName);
}
else {
constructorReference = translateAsFunctionWithNoThisObject(descriptor);
}
return createConstructorCallExpression(constructorReference);
}
@NotNull
private JsExpression createConstructorCallExpression(@NotNull JsExpression constructorReference) {
public HasArguments createConstructorCallExpression(@NotNull JsExpression constructorReference) {
if (context().isEcma5() && !AnnotationsUtils.isNativeObject(resolvedCall.getCandidateDescriptor())) {
return new JsInvocation(constructorReference, arguments);
}