JS backend: made as intrinsic map accessing methods and fixed accessing to native map.

This commit is contained in:
develar
2013-08-06 17:24:48 +04:00
committed by Zalim Bashorov
parent be4e1b7599
commit 678f6601dd
5 changed files with 141 additions and 11 deletions
@@ -80,4 +80,8 @@ public final class NativeInteropTest extends SingleFileTranslationTest {
public void testKt_2388() throws Exception {
fooBoxTest();
}
public void testKt2323() throws Exception {
fooBoxTest();
}
}
@@ -99,7 +99,7 @@ public final class ArrayFIF extends CompositeFIF {
};
@NotNull
private static final FunctionIntrinsic GET_INTRINSIC = new FunctionIntrinsic() {
public static final FunctionIntrinsic GET_INTRINSIC = new FunctionIntrinsic() {
@NotNull
@Override
public JsExpression apply(@Nullable JsExpression receiver,
@@ -113,7 +113,7 @@ public final class ArrayFIF extends CompositeFIF {
};
@NotNull
private static final FunctionIntrinsic SET_INTRINSIC = new FunctionIntrinsic() {
public static final FunctionIntrinsic SET_INTRINSIC = new FunctionIntrinsic() {
@NotNull
@Override
public JsExpression apply(@Nullable JsExpression receiver,
@@ -23,6 +23,13 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
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.scopes.receivers.ExpressionReceiver;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.intrinsic.functions.basic.BuiltInFunctionIntrinsic;
@@ -31,6 +38,8 @@ import org.jetbrains.k2js.translate.intrinsic.functions.basic.FunctionIntrinsic;
import org.jetbrains.k2js.translate.intrinsic.functions.patterns.DescriptorPredicate;
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 java.util.List;
@@ -54,6 +63,100 @@ public final class TopLevelFIF extends CompositeFIF {
return receiver;
}
};
private static final FunctionIntrinsic NATIVE_MAP_GET = new NativeMapGetSet() {
@NotNull
@Override
protected String operation() {
return "get";
}
@Nullable
@Override
protected ExpressionReceiver getExpressionReceiver(@NotNull ResolvedCall<?> resolvedCall) {
ReceiverValue result = resolvedCall.getThisObject();
return result instanceof ExpressionReceiver ? (ExpressionReceiver) result : null;
}
@Override
protected JsExpression asArrayAccess(
@NotNull JsExpression receiver,
@NotNull List<JsExpression> arguments,
@NotNull TranslationContext context
) {
return ArrayFIF.GET_INTRINSIC.apply(receiver, arguments, context);
}
};
private static final FunctionIntrinsic NATIVE_MAP_SET = new NativeMapGetSet() {
@NotNull
@Override
protected String operation() {
return "put";
}
@Nullable
@Override
protected ExpressionReceiver getExpressionReceiver(@NotNull ResolvedCall<?> resolvedCall) {
ReceiverValue result = resolvedCall.getReceiverArgument();
return result instanceof ExpressionReceiver ? (ExpressionReceiver) result : null;
}
@Override
protected JsExpression asArrayAccess(
@NotNull JsExpression receiver,
@NotNull List<JsExpression> arguments,
@NotNull TranslationContext context
) {
return ArrayFIF.SET_INTRINSIC.apply(receiver, arguments, context);
}
};
private abstract static class NativeMapGetSet extends CallParametersAwareFunctionIntrinsic {
@NotNull
protected abstract String operation();
@Nullable
protected abstract ExpressionReceiver getExpressionReceiver(@NotNull ResolvedCall<?> resolvedCall);
protected abstract JsExpression asArrayAccess(
@NotNull JsExpression receiver,
@NotNull List<JsExpression> arguments,
@NotNull TranslationContext context
);
@NotNull
@Override
public JsExpression apply(@NotNull CallTranslator callTranslator, @NotNull List<JsExpression> arguments, @NotNull TranslationContext context) {
ExpressionReceiver expressionReceiver = getExpressionReceiver(callTranslator.getResolvedCall());
JsExpression thisOrReceiver = callTranslator.getCallParameters().getThisOrReceiverOrNull();
assert thisOrReceiver != null;
if (expressionReceiver != null) {
JetExpression expression = expressionReceiver.getExpression();
JetReferenceExpression referenceExpression = null;
if (expression instanceof JetReferenceExpression) {
referenceExpression = (JetReferenceExpression) expression;
}
else if (expression instanceof JetQualifiedExpression) {
JetExpression candidate = ((JetQualifiedExpression) expression).getReceiverExpression();
if (candidate instanceof JetReferenceExpression) {
referenceExpression = (JetReferenceExpression) candidate;
}
}
if (referenceExpression != null) {
DeclarationDescriptor candidate = BindingUtils.getDescriptorForReferenceExpression(context.bindingContext(),
referenceExpression);
if (candidate instanceof PropertyDescriptor && AnnotationsUtils.isNativeObject(candidate)) {
return asArrayAccess(thisOrReceiver, arguments, context);
}
}
}
return new JsInvocation(new JsNameRef(operation(), thisOrReceiver), arguments);
}
}
@NotNull
public static final FunctionIntrinsicFactory INSTANCE = new TopLevelFIF();
@@ -95,14 +198,8 @@ public final class TopLevelFIF extends CompositeFIF {
}
);
add(pattern("java", "util", "set").receiverExists(true), new FunctionIntrinsic() {
@NotNull
@Override
public JsExpression apply(
@Nullable JsExpression receiver, @NotNull List<JsExpression> arguments, @NotNull TranslationContext context
) {
return new JsInvocation(new JsNameRef("put", receiver), arguments);
}
});
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);
}
}
@@ -0,0 +1,13 @@
package foo
import java.util.*
native
val classes: Map<String, Any> = noImpl
native
val classesMutable: HashMap<String, String> = noImpl
fun box(): Boolean {
classesMutable["why"] = "?"
return classes["answer"] == 42 && classesMutable["why"] == "?"
}
@@ -0,0 +1,16 @@
/*
* Copyright 2010-2013 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.
*/
var classes = {"answer": 42}, classesMutable = {};