Fixed bug where standard methods names may become obfuscated.
This commit is contained in:
@@ -5,6 +5,8 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import static org.jetbrains.k2js.translate.utils.DescriptorUtils.getNameForNamespace;
|
||||
import static org.jetbrains.k2js.translate.utils.DescriptorUtils.getOwnDeclarations;
|
||||
|
||||
@@ -41,6 +43,7 @@ public final class DeclarationVisitor extends DeclarationDescriptorVisitor<Void,
|
||||
private JsName declareName(@NotNull DeclarationDescriptor descriptor, @NotNull DeclarationContext context,
|
||||
@NotNull String name) {
|
||||
JsName jsName = context.getScope().declareVariable(descriptor, name, shouldObfuscate);
|
||||
jsName.setObfuscatable(false);
|
||||
declarations.putName(descriptor, jsName);
|
||||
declarations.putQualifier(descriptor, context.getQualifier());
|
||||
return jsName;
|
||||
@@ -85,11 +88,27 @@ public final class DeclarationVisitor extends DeclarationDescriptorVisitor<Void,
|
||||
|
||||
@Override
|
||||
public Void visitFunctionDescriptor(@NotNull FunctionDescriptor descriptor, @NotNull DeclarationContext context) {
|
||||
boolean overridesDeclaredDescriptor = declareAsOverridden(descriptor, context);
|
||||
if (overridesDeclaredDescriptor) {
|
||||
return null;
|
||||
}
|
||||
declareName(descriptor, context);
|
||||
declareScope(descriptor, context, "function " + descriptor.getName());
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean declareAsOverridden(@NotNull FunctionDescriptor descriptor, @NotNull DeclarationContext context) {
|
||||
Set<? extends FunctionDescriptor> overriddenDescriptors = descriptor.getOverriddenDescriptors();
|
||||
for (FunctionDescriptor overriddenDescriptor : overriddenDescriptors) {
|
||||
if (declarations.hasDeclaredName(overriddenDescriptor)) {
|
||||
declarations.putName(descriptor, declarations.getName(overriddenDescriptor));
|
||||
declareScope(descriptor, context, "function " + descriptor.getName());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitPropertyDescriptor(@NotNull PropertyDescriptor descriptor, @NotNull DeclarationContext context) {
|
||||
String propertyName = descriptor.getName();
|
||||
|
||||
@@ -33,9 +33,16 @@ public final class StandardClasses {
|
||||
declareJavaArrayList(standardClasses);
|
||||
declareJavaSystem(standardClasses);
|
||||
declareJavaInteger(standardClasses);
|
||||
declareJavaUtilIterator(standardClasses);
|
||||
return standardClasses;
|
||||
}
|
||||
|
||||
private static void declareJavaUtilIterator(@NotNull StandardClasses standardClasses) {
|
||||
String iteratorFQName = "<java_root>.java.util.Iterator";
|
||||
standardClasses.declareStandardTopLevelObject(iteratorFQName, "Iterator");
|
||||
declareMethods(standardClasses, iteratorFQName, "next", "hasNext");
|
||||
}
|
||||
|
||||
private static void declareString(@NotNull StandardClasses standardClasses) {
|
||||
String stringFQName = "jet.String";
|
||||
standardClasses.declareStandardTopLevelObject(stringFQName, "String");
|
||||
|
||||
@@ -119,9 +119,7 @@ public class StaticContext {
|
||||
|
||||
@NotNull
|
||||
public JsName getGlobalName(@NotNull DeclarationDescriptor descriptor) {
|
||||
JsName nameToDeclare = declarations.getName(descriptor);
|
||||
//nameToDeclare.setObfuscatable(false);
|
||||
return nameToDeclare;
|
||||
return declarations.getName(descriptor);
|
||||
}
|
||||
|
||||
public boolean isDeclared(@NotNull DeclarationDescriptor descriptor) {
|
||||
|
||||
@@ -3,6 +3,8 @@ package org.jetbrains.k2js.translate.expression;
|
||||
import com.google.dart.compiler.backend.js.ast.*;
|
||||
import com.google.dart.compiler.util.AstUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetForExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetParameter;
|
||||
@@ -10,7 +12,9 @@ import org.jetbrains.k2js.translate.context.TemporaryVariable;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.general.AbstractTranslator;
|
||||
import org.jetbrains.k2js.translate.general.Translation;
|
||||
import org.jetbrains.k2js.translate.reference.CallTranslator;
|
||||
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.*;
|
||||
import static org.jetbrains.k2js.translate.utils.PsiUtils.getLoopBody;
|
||||
import static org.jetbrains.k2js.translate.utils.PsiUtils.getLoopParameter;
|
||||
|
||||
@@ -58,28 +62,22 @@ public final class ForTranslator extends AbstractTranslator {
|
||||
|
||||
@NotNull
|
||||
private JsExpression nextMethodInvocation(@NotNull TemporaryVariable iterator) {
|
||||
return callStandardMethodOnExpression("next", iterator.nameReference());
|
||||
FunctionDescriptor nextFunction = getNextFunction(context().bindingContext(), getLoopRange());
|
||||
return CallTranslator.translate(iterator.nameReference(), nextFunction, context());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsExpression hasNextMethodInvocation(@NotNull TemporaryVariable iterator) {
|
||||
return callStandardMethodOnExpression("hasNext", iterator.nameReference());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsExpression callStandardMethodOnExpression(@NotNull String methodName, @NotNull JsNameRef expression) {
|
||||
JsNameRef hasNext = AstUtil.newQualifiedNameRef(methodName);
|
||||
AstUtil.setQualifier(hasNext, expression);
|
||||
return AstUtil.newInvocation(hasNext);
|
||||
CallableDescriptor hasNextFunction = getHasNextCallable(context().bindingContext(), getLoopRange());
|
||||
return CallTranslator.translate(iterator.nameReference(), hasNextFunction, context());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsExpression iteratorMethodInvocation() {
|
||||
JetExpression rangeExpression = getLoopRange();
|
||||
JsExpression range = Translation.translateAsExpression(rangeExpression, context());
|
||||
JsNameRef iteratorMethodReference = AstUtil.newQualifiedNameRef("iterator");
|
||||
AstUtil.setQualifier(iteratorMethodReference, range);
|
||||
return AstUtil.newInvocation(iteratorMethodReference);
|
||||
FunctionDescriptor iteratorFunction = getIteratorFunction(context().bindingContext(), rangeExpression);
|
||||
return CallTranslator.translate(range, iteratorFunction, context());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -126,6 +126,12 @@ public final class CallTranslator extends AbstractTranslator {
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsExpression translate(@NotNull JsExpression receiver, @NotNull CallableDescriptor functionDescriptor,
|
||||
@NotNull TranslationContext context) {
|
||||
return (new CallTranslator(receiver, Collections.<JsExpression>emptyList(), functionDescriptor, context)).translate();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsExpression translate(@NotNull JetUnaryExpression unaryExpression,
|
||||
@NotNull TranslationContext context) {
|
||||
@@ -173,14 +179,14 @@ public final class CallTranslator extends AbstractTranslator {
|
||||
private final List<JsExpression> arguments;
|
||||
|
||||
@NotNull
|
||||
private final FunctionDescriptor functionDescriptor;
|
||||
private final CallableDescriptor descriptor;
|
||||
|
||||
private CallTranslator(@Nullable JsExpression receiver, @NotNull List<JsExpression> arguments,
|
||||
@NotNull FunctionDescriptor descriptor, @NotNull TranslationContext context) {
|
||||
@NotNull CallableDescriptor descriptor, @NotNull TranslationContext context) {
|
||||
super(context);
|
||||
this.receiver = receiver;
|
||||
this.arguments = arguments;
|
||||
this.functionDescriptor = descriptor;
|
||||
this.descriptor = descriptor;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -206,12 +212,14 @@ public final class CallTranslator extends AbstractTranslator {
|
||||
}
|
||||
|
||||
private boolean isExtensionFunction() {
|
||||
return DescriptorUtils.isExtensionFunction(functionDescriptor);
|
||||
return DescriptorUtils.isExtensionFunction(descriptor);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsExpression intrinsicInvocation() {
|
||||
FunctionIntrinsic functionIntrinsic = context().intrinsics().getFunctionIntrinsic(functionDescriptor);
|
||||
assert descriptor instanceof FunctionDescriptor;
|
||||
FunctionIntrinsic functionIntrinsic =
|
||||
context().intrinsics().getFunctionIntrinsic((FunctionDescriptor) descriptor);
|
||||
assert receiver != null : "Functions that have functionIntrinsic implementation should have a receiver.";
|
||||
return functionIntrinsic.apply(receiver, arguments, context());
|
||||
}
|
||||
@@ -222,25 +230,25 @@ public final class CallTranslator extends AbstractTranslator {
|
||||
}
|
||||
|
||||
private boolean isConstructor() {
|
||||
return isConstructorDescriptor(functionDescriptor);
|
||||
return isConstructorDescriptor(descriptor);
|
||||
}
|
||||
|
||||
private boolean isIntrinsic() {
|
||||
return context().intrinsics().isIntrinsic(functionDescriptor);
|
||||
return context().intrinsics().isIntrinsic(descriptor);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsExpression calleeReference() {
|
||||
if (DescriptorUtils.isVariableDescriptor(functionDescriptor)) {
|
||||
if (DescriptorUtils.isVariableDescriptor(descriptor)) {
|
||||
//TODO: write tests on this cases
|
||||
VariableDescriptor variableDescriptor =
|
||||
getVariableDescriptorForVariableAsFunction((VariableAsFunctionDescriptor) functionDescriptor);
|
||||
getVariableDescriptorForVariableAsFunction((VariableAsFunctionDescriptor) descriptor);
|
||||
if (variableDescriptor instanceof PropertyDescriptor) {
|
||||
return getterCall((PropertyDescriptor) variableDescriptor);
|
||||
}
|
||||
return qualifiedMethodReference(variableDescriptor);
|
||||
}
|
||||
return qualifiedMethodReference(functionDescriptor);
|
||||
return qualifiedMethodReference(descriptor);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -261,7 +269,7 @@ public final class CallTranslator extends AbstractTranslator {
|
||||
|
||||
@NotNull
|
||||
private JsExpression extensionFunctionReference(@NotNull JsExpression methodReference) {
|
||||
JsExpression qualifier = TranslationUtils.getExtensionFunctionImplicitReceiver(context(), functionDescriptor);
|
||||
JsExpression qualifier = TranslationUtils.getExtensionFunctionImplicitReceiver(context(), descriptor);
|
||||
if (qualifier != null) {
|
||||
AstUtil.setQualifier(methodReference, qualifier);
|
||||
}
|
||||
@@ -270,7 +278,7 @@ public final class CallTranslator extends AbstractTranslator {
|
||||
|
||||
@NotNull
|
||||
private JsExpression constructorCall() {
|
||||
JsNew constructorCall = new JsNew(qualifiedMethodReference(functionDescriptor));
|
||||
JsNew constructorCall = new JsNew(qualifiedMethodReference(descriptor));
|
||||
constructorCall.setArguments(arguments);
|
||||
return constructorCall;
|
||||
}
|
||||
|
||||
@@ -22,13 +22,13 @@ import static org.jetbrains.k2js.translate.utils.DescriptorUtils.isVariableDescr
|
||||
* @author Pavel Talanov
|
||||
* <p/>
|
||||
* This class contains some code related to BindingContext use. Intention is not to pollute other classes.
|
||||
* Every call to BindingContext.get() is supposed to be wrapped by this utility class.
|
||||
*/
|
||||
public final class BindingUtils {
|
||||
|
||||
private BindingUtils() {
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
static private <E extends PsiElement, D extends DeclarationDescriptor>
|
||||
D getDescriptorForExpression(@NotNull BindingContext context, @NotNull E expression, Class<D> descriptorClass) {
|
||||
@@ -298,4 +298,36 @@ public final class BindingUtils {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JetType getTypeForExpression(@NotNull BindingContext context,
|
||||
@NotNull JetExpression expression) {
|
||||
JetType jetType = context.get(BindingContext.EXPRESSION_TYPE, expression);
|
||||
assert jetType != null : "Expression must have a type.";
|
||||
return jetType;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static FunctionDescriptor getIteratorFunction(@NotNull BindingContext context,
|
||||
@NotNull JetExpression rangeExpression) {
|
||||
FunctionDescriptor functionDescriptor = context.get(BindingContext.LOOP_RANGE_ITERATOR, rangeExpression);
|
||||
assert functionDescriptor != null : "Range expression must have a descriptor for iterator function.";
|
||||
return functionDescriptor;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static FunctionDescriptor getNextFunction(@NotNull BindingContext context,
|
||||
@NotNull JetExpression rangeExpression) {
|
||||
FunctionDescriptor functionDescriptor = context.get(BindingContext.LOOP_RANGE_NEXT, rangeExpression);
|
||||
assert functionDescriptor != null : "Range expression must have a descriptor for next function.";
|
||||
return functionDescriptor;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static CallableDescriptor getHasNextCallable(@NotNull BindingContext context,
|
||||
@NotNull JetExpression rangeExpression) {
|
||||
CallableDescriptor hasNextDescriptor = context.get(BindingContext.LOOP_RANGE_HAS_NEXT, rangeExpression);
|
||||
assert hasNextDescriptor != null : "Range expression must have a descriptor for hasNext function or property.";
|
||||
return hasNextDescriptor;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ public final class DescriptorUtils {
|
||||
return (functionDescriptor.getName().equals(OperatorConventions.COMPARE_TO));
|
||||
}
|
||||
|
||||
public static boolean isConstructorDescriptor(@NotNull FunctionDescriptor descriptor) {
|
||||
public static boolean isConstructorDescriptor(@NotNull CallableDescriptor descriptor) {
|
||||
return (descriptor instanceof ConstructorDescriptor);
|
||||
}
|
||||
|
||||
@@ -71,7 +71,8 @@ public final class DescriptorUtils {
|
||||
@NotNull String name) {
|
||||
Set<FunctionDescriptor> functionDescriptors = scope.getFunctions(name);
|
||||
assert functionDescriptors.size() == 1 :
|
||||
"In scope " + scope + " supposed to be exactly one " + name + " function.";
|
||||
"In scope " + scope + " supposed to be exactly one " + name + " function.\n" +
|
||||
"Found: " + functionDescriptors.size();
|
||||
//noinspection LoopStatementThatDoesntLoop
|
||||
for (FunctionDescriptor descriptor : functionDescriptors) {
|
||||
return descriptor;
|
||||
@@ -122,7 +123,7 @@ public final class DescriptorUtils {
|
||||
return containing;
|
||||
}
|
||||
|
||||
public static boolean isExtensionFunction(@NotNull FunctionDescriptor functionDescriptor) {
|
||||
public static boolean isExtensionFunction(@NotNull CallableDescriptor functionDescriptor) {
|
||||
return (functionDescriptor.getReceiverParameter().exists());
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.google.dart.compiler.backend.js.ast.*;
|
||||
import com.google.dart.compiler.util.AstUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
||||
@@ -210,7 +211,7 @@ public final class TranslationUtils {
|
||||
|
||||
@Nullable
|
||||
public static JsExpression getExtensionFunctionImplicitReceiver(@NotNull TranslationContext context,
|
||||
@NotNull FunctionDescriptor descriptor) {
|
||||
@NotNull CallableDescriptor descriptor) {
|
||||
return getImplicitReceiverBasedOnOwner(context, descriptor);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@ function $A(iterable) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
function keys(object) {
|
||||
if (Type(object) !== OBJECT_TYPE) {
|
||||
throw new TypeError();
|
||||
@@ -284,7 +283,7 @@ Kotlin.Array = Class.create({
|
||||
iterator:function () {
|
||||
return new Kotlin.ArrayIterator(this);
|
||||
},
|
||||
indices:function() {
|
||||
indices:function () {
|
||||
return new Kotlin.NumberRange(0, this.size(), false);
|
||||
}
|
||||
});
|
||||
@@ -398,8 +397,20 @@ Kotlin.System = function () {
|
||||
};
|
||||
}();
|
||||
|
||||
Kotlin.AbstractFunctionInvokationError = Class.create();
|
||||
|
||||
Kotlin.ArrayIterator = Class.create({
|
||||
Kotlin.Iterator = Class.create({
|
||||
initialize:function () {
|
||||
},
|
||||
next:function () {
|
||||
throw new Kotlin.AbstractFunctionInvokationError();
|
||||
},
|
||||
hasNext:function () {
|
||||
throw new Kotlin.AbstractFunctionInvokationError();
|
||||
}
|
||||
});
|
||||
|
||||
Kotlin.ArrayIterator = Class.create(Kotlin.Iterator, {
|
||||
initialize:function (array) {
|
||||
this.array = array;
|
||||
this.index = 0;
|
||||
@@ -412,36 +423,37 @@ Kotlin.ArrayIterator = Class.create({
|
||||
}
|
||||
});
|
||||
|
||||
Kotlin.RangeIterator = Kotlin.Class.create({initialize:function (start, count, reversed) {
|
||||
this.$start = start;
|
||||
this.$count = count;
|
||||
this.$reversed = reversed;
|
||||
this.$i = this.get_start();
|
||||
}, get_start:function () {
|
||||
return this.$start;
|
||||
}, get_count:function () {
|
||||
return this.$count;
|
||||
}, set_count:function (tmp$0) {
|
||||
this.$count = tmp$0;
|
||||
}, get_reversed:function () {
|
||||
return this.$reversed;
|
||||
}, get_i:function () {
|
||||
return this.$i;
|
||||
}, set_i:function (tmp$0) {
|
||||
this.$i = tmp$0;
|
||||
}, next:function () {
|
||||
this.set_count(this.get_count() - 1);
|
||||
if (this.get_reversed()) {
|
||||
this.set_i(this.get_i() - 1);
|
||||
return this.get_i() + 1;
|
||||
Kotlin.RangeIterator = Kotlin.Class.create(Kotlin.Iterator, {
|
||||
initialize:function (start, count, reversed) {
|
||||
this.$start = start;
|
||||
this.$count = count;
|
||||
this.$reversed = reversed;
|
||||
this.$i = this.get_start();
|
||||
}, get_start:function () {
|
||||
return this.$start;
|
||||
}, get_count:function () {
|
||||
return this.$count;
|
||||
}, set_count:function (tmp$0) {
|
||||
this.$count = tmp$0;
|
||||
}, get_reversed:function () {
|
||||
return this.$reversed;
|
||||
}, get_i:function () {
|
||||
return this.$i;
|
||||
}, set_i:function (tmp$0) {
|
||||
this.$i = tmp$0;
|
||||
}, next:function () {
|
||||
this.set_count(this.get_count() - 1);
|
||||
if (this.get_reversed()) {
|
||||
this.set_i(this.get_i() - 1);
|
||||
return this.get_i() + 1;
|
||||
}
|
||||
else {
|
||||
this.set_i(this.get_i() + 1);
|
||||
return this.get_i() - 1;
|
||||
}
|
||||
}, hasNext:function () {
|
||||
return this.get_count() > 0;
|
||||
}
|
||||
else {
|
||||
this.set_i(this.get_i() + 1);
|
||||
return this.get_i() - 1;
|
||||
}
|
||||
}, hasNext:function () {
|
||||
return this.get_count() > 0;
|
||||
}
|
||||
});
|
||||
|
||||
Kotlin.NumberRange = Kotlin.Class.create({initialize:function (start, size, reversed) {
|
||||
|
||||
Reference in New Issue
Block a user