JS backend: don't aliasing captured variable foo as foo.v.
Moved isVarCapturedInClosure from CodegenBinding to BindingContextUtils.
This commit is contained in:
@@ -47,6 +47,7 @@ import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils;
|
|||||||
import org.jetbrains.jet.lang.evaluate.EvaluatePackage;
|
import org.jetbrains.jet.lang.evaluate.EvaluatePackage;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
|
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
|
||||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.model.*;
|
import org.jetbrains.jet.lang.resolve.calls.model.*;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.util.CallMaker;
|
import org.jetbrains.jet.lang.resolve.calls.util.CallMaker;
|
||||||
@@ -75,6 +76,7 @@ import static org.jetbrains.jet.codegen.FunctionTypesUtil.getFunctionImplType;
|
|||||||
import static org.jetbrains.jet.codegen.binding.CodegenBinding.*;
|
import static org.jetbrains.jet.codegen.binding.CodegenBinding.*;
|
||||||
import static org.jetbrains.jet.lang.resolve.BindingContext.*;
|
import static org.jetbrains.jet.lang.resolve.BindingContext.*;
|
||||||
import static org.jetbrains.jet.lang.resolve.BindingContextUtils.getNotNull;
|
import static org.jetbrains.jet.lang.resolve.BindingContextUtils.getNotNull;
|
||||||
|
import static org.jetbrains.jet.lang.resolve.BindingContextUtils.isVarCapturedInClosure;
|
||||||
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.*;
|
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.*;
|
||||||
import static org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames.KotlinSyntheticClass;
|
import static org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames.KotlinSyntheticClass;
|
||||||
import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue.NO_RECEIVER;
|
import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue.NO_RECEIVER;
|
||||||
|
|||||||
@@ -319,12 +319,6 @@ public class CodegenBinding {
|
|||||||
return containerInternalName + "$" + klass.getName().getIdentifier();
|
return containerInternalName + "$" + klass.getName().getIdentifier();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isVarCapturedInClosure(BindingContext bindingContext, DeclarationDescriptor descriptor) {
|
|
||||||
if (!(descriptor instanceof VariableDescriptor) || descriptor instanceof PropertyDescriptor) return false;
|
|
||||||
VariableDescriptor variableDescriptor = (VariableDescriptor) descriptor;
|
|
||||||
return bindingContext.get(CAPTURED_IN_CLOSURE, variableDescriptor) != null && variableDescriptor.isVar();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean hasThis0(BindingContext bindingContext, ClassDescriptor classDescriptor) {
|
public static boolean hasThis0(BindingContext bindingContext, ClassDescriptor classDescriptor) {
|
||||||
//noinspection SuspiciousMethodCalls
|
//noinspection SuspiciousMethodCalls
|
||||||
CalculatedClosure closure = bindingContext.get(CLOSURE, classDescriptor);
|
CalculatedClosure closure = bindingContext.get(CLOSURE, classDescriptor);
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ import static org.jetbrains.jet.codegen.AsmUtil.getTraitImplThisParameterType;
|
|||||||
import static org.jetbrains.jet.codegen.CodegenUtil.*;
|
import static org.jetbrains.jet.codegen.CodegenUtil.*;
|
||||||
import static org.jetbrains.jet.codegen.FunctionTypesUtil.getFunctionTraitClassName;
|
import static org.jetbrains.jet.codegen.FunctionTypesUtil.getFunctionTraitClassName;
|
||||||
import static org.jetbrains.jet.codegen.binding.CodegenBinding.*;
|
import static org.jetbrains.jet.codegen.binding.CodegenBinding.*;
|
||||||
|
import static org.jetbrains.jet.lang.resolve.BindingContextUtils.isVarCapturedInClosure;
|
||||||
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.*;
|
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.*;
|
||||||
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.OBJECT_TYPE;
|
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.OBJECT_TYPE;
|
||||||
|
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ import java.util.*;
|
|||||||
import static org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor.Kind.*;
|
import static org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor.Kind.*;
|
||||||
import static org.jetbrains.jet.lang.diagnostics.Errors.AMBIGUOUS_LABEL;
|
import static org.jetbrains.jet.lang.diagnostics.Errors.AMBIGUOUS_LABEL;
|
||||||
import static org.jetbrains.jet.lang.resolve.BindingContext.AMBIGUOUS_LABEL_TARGET;
|
import static org.jetbrains.jet.lang.resolve.BindingContext.AMBIGUOUS_LABEL_TARGET;
|
||||||
|
import static org.jetbrains.jet.lang.resolve.BindingContext.CAPTURED_IN_CLOSURE;
|
||||||
import static org.jetbrains.jet.lang.resolve.BindingContext.DECLARATION_TO_DESCRIPTOR;
|
import static org.jetbrains.jet.lang.resolve.BindingContext.DECLARATION_TO_DESCRIPTOR;
|
||||||
|
|
||||||
public class BindingContextUtils {
|
public class BindingContextUtils {
|
||||||
@@ -363,4 +364,10 @@ public class BindingContextUtils {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isVarCapturedInClosure(BindingContext bindingContext, DeclarationDescriptor descriptor) {
|
||||||
|
if (!(descriptor instanceof VariableDescriptor) || descriptor instanceof PropertyDescriptor) return false;
|
||||||
|
VariableDescriptor variableDescriptor = (VariableDescriptor) descriptor;
|
||||||
|
return bindingContext.get(CAPTURED_IN_CLOSURE, variableDescriptor) != null && variableDescriptor.isVar();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-6
@@ -19,14 +19,12 @@ package org.jetbrains.k2js.translate.callTranslator
|
|||||||
import com.google.dart.compiler.backend.js.ast.JsExpression
|
import com.google.dart.compiler.backend.js.ast.JsExpression
|
||||||
import com.google.dart.compiler.backend.js.ast.JsNameRef
|
import com.google.dart.compiler.backend.js.ast.JsNameRef
|
||||||
import com.google.dart.compiler.backend.js.ast.JsLiteral
|
import com.google.dart.compiler.backend.js.ast.JsLiteral
|
||||||
import org.jetbrains.k2js.translate.utils.JsAstUtils
|
|
||||||
import com.google.dart.compiler.backend.js.ast.JsInvocation
|
import com.google.dart.compiler.backend.js.ast.JsInvocation
|
||||||
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor
|
|
||||||
import org.jetbrains.jet.lang.descriptors.CallableDescriptor
|
import org.jetbrains.jet.lang.descriptors.CallableDescriptor
|
||||||
import java.util.Collections
|
import java.util.Collections
|
||||||
import org.jetbrains.jet.lang.descriptors.impl.PropertyDescriptorImpl
|
|
||||||
import org.jetbrains.jet.lang.resolve.DescriptorFactory
|
|
||||||
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor
|
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor
|
||||||
|
import org.jetbrains.jet.lang.resolve.BindingContextUtils.isVarCapturedInClosure
|
||||||
|
import org.jetbrains.k2js.translate.context.Namer.getCapturedVarAccessor
|
||||||
|
|
||||||
|
|
||||||
object NativeVariableAccessCase : VariableAccessCase {
|
object NativeVariableAccessCase : VariableAccessCase {
|
||||||
@@ -39,7 +37,7 @@ object NativeVariableAccessCase : VariableAccessCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun VariableAccessInfo.noReceivers(): JsExpression {
|
override fun VariableAccessInfo.noReceivers(): JsExpression {
|
||||||
return constructAccessExpression(variableName.makeRef()!!)
|
return constructAccessExpression(variableName.makeRef())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,7 +46,15 @@ object DefaultVariableAccessCase : VariableAccessCase {
|
|||||||
val functionRef = context.aliasOrValue(callableDescriptor) {
|
val functionRef = context.aliasOrValue(callableDescriptor) {
|
||||||
context.getQualifiedReference(variableDescriptor)
|
context.getQualifiedReference(variableDescriptor)
|
||||||
}
|
}
|
||||||
return constructAccessExpression(functionRef)
|
|
||||||
|
val ref =
|
||||||
|
if (isVarCapturedInClosure(context.bindingContext(), callableDescriptor)) {
|
||||||
|
getCapturedVarAccessor(functionRef)
|
||||||
|
} else {
|
||||||
|
functionRef
|
||||||
|
}
|
||||||
|
|
||||||
|
return constructAccessExpression(ref)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun VariableAccessInfo.thisObject(): JsExpression {
|
override fun VariableAccessInfo.thisObject(): JsExpression {
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ public final class Namer {
|
|||||||
private static final String CLASS_OBJECT_GETTER = "object";
|
private static final String CLASS_OBJECT_GETTER = "object";
|
||||||
private static final String CLASS_OBJECT_INITIALIZER = "object_initializer$";
|
private static final String CLASS_OBJECT_INITIALIZER = "object_initializer$";
|
||||||
private static final String PROTOTYPE_NAME = "prototype";
|
private static final String PROTOTYPE_NAME = "prototype";
|
||||||
|
public static final String CAPTURED_VAR_FIELD = "v";
|
||||||
|
|
||||||
|
|
||||||
private static final String DELEGATE_POSTFIX = "$delegate";
|
private static final String DELEGATE_POSTFIX = "$delegate";
|
||||||
@@ -144,6 +145,11 @@ public final class Namer {
|
|||||||
return new JsNameRef(APPLY_FUNCTION, functionExpression);
|
return new JsNameRef(APPLY_FUNCTION, functionExpression);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static JsNameRef getCapturedVarAccessor(@NotNull JsExpression ref) {
|
||||||
|
return new JsNameRef(CAPTURED_VAR_FIELD, ref);
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static Namer newInstance(@NotNull JsScope rootScope) {
|
public static Namer newInstance(@NotNull JsScope rootScope) {
|
||||||
return new Namer(rootScope);
|
return new Namer(rootScope);
|
||||||
|
|||||||
+10
-6
@@ -21,6 +21,7 @@ import com.intellij.psi.tree.IElementType;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.JetNodeTypes;
|
import org.jetbrains.jet.JetNodeTypes;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
|
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
@@ -37,7 +38,10 @@ import org.jetbrains.k2js.translate.general.Translation;
|
|||||||
import org.jetbrains.k2js.translate.general.TranslatorVisitor;
|
import org.jetbrains.k2js.translate.general.TranslatorVisitor;
|
||||||
import org.jetbrains.k2js.translate.operation.BinaryOperationTranslator;
|
import org.jetbrains.k2js.translate.operation.BinaryOperationTranslator;
|
||||||
import org.jetbrains.k2js.translate.operation.UnaryOperationTranslator;
|
import org.jetbrains.k2js.translate.operation.UnaryOperationTranslator;
|
||||||
import org.jetbrains.k2js.translate.reference.*;
|
import org.jetbrains.k2js.translate.reference.AccessTranslationUtils;
|
||||||
|
import org.jetbrains.k2js.translate.reference.CallExpressionTranslator;
|
||||||
|
import org.jetbrains.k2js.translate.reference.QualifiedExpressionTranslator;
|
||||||
|
import org.jetbrains.k2js.translate.reference.ReferenceTranslator;
|
||||||
import org.jetbrains.k2js.translate.utils.BindingUtils;
|
import org.jetbrains.k2js.translate.utils.BindingUtils;
|
||||||
import org.jetbrains.k2js.translate.utils.JsAstUtils;
|
import org.jetbrains.k2js.translate.utils.JsAstUtils;
|
||||||
import org.jetbrains.k2js.translate.utils.TranslationUtils;
|
import org.jetbrains.k2js.translate.utils.TranslationUtils;
|
||||||
@@ -45,6 +49,8 @@ import org.jetbrains.k2js.translate.utils.mutator.AssignToExpressionMutator;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.jetbrains.jet.lang.resolve.BindingContextUtils.isVarCapturedInClosure;
|
||||||
|
import static org.jetbrains.k2js.translate.context.Namer.getCapturedVarAccessor;
|
||||||
import static org.jetbrains.k2js.translate.general.Translation.translateAsExpression;
|
import static org.jetbrains.k2js.translate.general.Translation.translateAsExpression;
|
||||||
import static org.jetbrains.k2js.translate.reference.ReferenceTranslator.translateAsFQReference;
|
import static org.jetbrains.k2js.translate.reference.ReferenceTranslator.translateAsFQReference;
|
||||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.*;
|
import static org.jetbrains.k2js.translate.utils.BindingUtils.*;
|
||||||
@@ -121,7 +127,7 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JsNode visitMultiDeclaration(@NotNull JetMultiDeclaration multiDeclaration, @NotNull TranslationContext context) {
|
public JsNode visitMultiDeclaration(@NotNull JetMultiDeclaration multiDeclaration, @NotNull TranslationContext context) {
|
||||||
JetExpression jetInitializer = multiDeclaration.getInitializer();
|
JetExpression jetInitializer = multiDeclaration.getInitializer();
|
||||||
assert jetInitializer != null : "Initializer for multi declaration must be not null";
|
assert jetInitializer != null : "Initializer for multi declaration must be not null";
|
||||||
JsExpression initializer = Translation.translateAsExpression(jetInitializer, context);
|
JsExpression initializer = Translation.translateAsExpression(jetInitializer, context);
|
||||||
@@ -164,11 +170,9 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
|
|||||||
VariableDescriptor descriptor = BindingContextUtils.getNotNull(context.bindingContext(), BindingContext.VARIABLE, expression);
|
VariableDescriptor descriptor = BindingContextUtils.getNotNull(context.bindingContext(), BindingContext.VARIABLE, expression);
|
||||||
JsExpression initializer = translateInitializerForProperty(expression, context);
|
JsExpression initializer = translateInitializerForProperty(expression, context);
|
||||||
JsName name = context.getNameForDescriptor(descriptor);
|
JsName name = context.getNameForDescriptor(descriptor);
|
||||||
if (descriptor.isVar() && context.bindingContext().get(BindingContext.CAPTURED_IN_CLOSURE, descriptor) != null) {
|
if (isVarCapturedInClosure(context.bindingContext(), descriptor)) {
|
||||||
// well, wrap it
|
JsNameRef alias = getCapturedVarAccessor(name.makeRef());
|
||||||
JsNameRef alias = new JsNameRef("v", new JsNameRef(name));
|
|
||||||
initializer = JsAstUtils.wrapValue(alias, initializer == null ? JsLiteral.NULL : initializer);
|
initializer = JsAstUtils.wrapValue(alias, initializer == null ? JsLiteral.NULL : initializer);
|
||||||
context.aliasingContext().registerAlias(descriptor, alias);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return newVar(name, initializer).source(expression);
|
return newVar(name, initializer).source(expression);
|
||||||
|
|||||||
+8
-3
@@ -21,7 +21,7 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
|
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
|
||||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||||
import org.jetbrains.jet.lang.psi.JetQualifiedExpression;
|
import org.jetbrains.jet.lang.psi.JetQualifiedExpression;
|
||||||
@@ -92,8 +92,13 @@ public final class ReferenceTranslator {
|
|||||||
else if (expression instanceof JetSimpleNameExpression) {
|
else if (expression instanceof JetSimpleNameExpression) {
|
||||||
simpleNameExpression = (JetSimpleNameExpression) expression;
|
simpleNameExpression = (JetSimpleNameExpression) expression;
|
||||||
}
|
}
|
||||||
return simpleNameExpression != null &&
|
|
||||||
(getDescriptorForReferenceExpression(context.bindingContext(), simpleNameExpression) instanceof PropertyDescriptor);
|
if (simpleNameExpression == null) return false;
|
||||||
|
|
||||||
|
DeclarationDescriptor descriptor = getDescriptorForReferenceExpression(context.bindingContext(), simpleNameExpression);
|
||||||
|
|
||||||
|
// Skip ValueParameterDescriptor because sometime we can miss resolved call for it, e.g. when set something to delegated property.
|
||||||
|
return descriptor instanceof VariableDescriptor && !(descriptor instanceof ValueParameterDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ public final class BindingUtils {
|
|||||||
public static ResolvedCall<?> getResolvedCallForProperty(@NotNull BindingContext context,
|
public static ResolvedCall<?> getResolvedCallForProperty(@NotNull BindingContext context,
|
||||||
@NotNull JetExpression expression) {
|
@NotNull JetExpression expression) {
|
||||||
ResolvedCall<? extends CallableDescriptor> resolvedCall = context.get(BindingContext.RESOLVED_CALL, expression);
|
ResolvedCall<? extends CallableDescriptor> resolvedCall = context.get(BindingContext.RESOLVED_CALL, expression);
|
||||||
assert resolvedCall != null : message(expression, expression.getText() + "must resolve to a call");
|
assert resolvedCall != null : message(expression, expression.getText() + " must resolve to a call");
|
||||||
if (resolvedCall instanceof VariableAsFunctionResolvedCall) {
|
if (resolvedCall instanceof VariableAsFunctionResolvedCall) {
|
||||||
return ((VariableAsFunctionResolvedCall) resolvedCall).getVariableCall();
|
return ((VariableAsFunctionResolvedCall) resolvedCall).getVariableCall();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user