Refactoring: refactor Aliaser into aliasing context. A very rough draft but test pass.
This commit is contained in:
@@ -1,100 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2012 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.context;
|
|
||||||
|
|
||||||
import com.google.dart.compiler.backend.js.ast.JsName;
|
|
||||||
import com.google.dart.compiler.backend.js.ast.JsNameRef;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Stack;
|
|
||||||
|
|
||||||
public class Aliaser {
|
|
||||||
|
|
||||||
public static Aliaser newInstance() {
|
|
||||||
return new Aliaser();
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private final Map<DeclarationDescriptor, JsName> aliasesForDescriptors = new HashMap<DeclarationDescriptor, JsName>();
|
|
||||||
@NotNull
|
|
||||||
private final Map<DeclarationDescriptor, Stack<JsName>> aliasesForThis
|
|
||||||
= new HashMap<DeclarationDescriptor, Stack<JsName>>();
|
|
||||||
|
|
||||||
private Aliaser() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public JsNameRef getAliasForThis(@NotNull DeclarationDescriptor descriptor) {
|
|
||||||
Stack<JsName> aliasStack = aliasesForThis.get(descriptor.getOriginal());
|
|
||||||
assert !aliasStack.empty();
|
|
||||||
JsName aliasName = aliasStack.peek();
|
|
||||||
assert aliasName != null : "This " + descriptor.getOriginal() + " doesn't have an alias.";
|
|
||||||
return aliasName.makeRef();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAliasForThis(@NotNull DeclarationDescriptor descriptor, @NotNull JsName alias) {
|
|
||||||
Stack<JsName> aliasStack = aliasesForThis.get(descriptor.getOriginal());
|
|
||||||
if (aliasStack == null) {
|
|
||||||
aliasStack = new Stack<JsName>();
|
|
||||||
aliasesForThis.put(descriptor, aliasStack);
|
|
||||||
}
|
|
||||||
aliasStack.push(alias);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeAliasForThis(@NotNull DeclarationDescriptor descriptor) {
|
|
||||||
Stack<JsName> aliasStack = aliasesForThis.get(descriptor.getOriginal());
|
|
||||||
assert !aliasStack.empty();
|
|
||||||
aliasStack.pop();
|
|
||||||
if (aliasStack.empty()) {
|
|
||||||
aliasesForThis.put(descriptor, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasAliasForThis(@NotNull DeclarationDescriptor descriptor) {
|
|
||||||
Stack<JsName> aliasStack = aliasesForThis.get(descriptor.getOriginal());
|
|
||||||
if (aliasStack == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return (!aliasStack.empty());
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public JsName getAliasForDeclaration(@NotNull DeclarationDescriptor declaration) {
|
|
||||||
JsName alias = aliasesForDescriptors.get(declaration.getOriginal());
|
|
||||||
assert alias != null : "Use has alias for declaration to check.";
|
|
||||||
return alias;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAliasForDescriptor(@NotNull DeclarationDescriptor declaration, @NotNull JsName alias) {
|
|
||||||
assert (!hasAliasForDeclaration(declaration.getOriginal())) : "This declaration already has an alias!";
|
|
||||||
aliasesForDescriptors.put(declaration.getOriginal(), alias);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeAliasForDescriptor(@NotNull DeclarationDescriptor declaration) {
|
|
||||||
assert (hasAliasForDeclaration(declaration.getOriginal())) : "This declaration does not has an alias!";
|
|
||||||
aliasesForDescriptors.remove(declaration.getOriginal());
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasAliasForDeclaration(@NotNull DeclarationDescriptor declaration) {
|
|
||||||
return aliasesForDescriptors.containsKey(declaration.getOriginal());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2012 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.context;
|
||||||
|
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import com.google.dart.compiler.backend.js.ast.JsName;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Pavel Talanov
|
||||||
|
*/
|
||||||
|
public class AliasingContext {
|
||||||
|
|
||||||
|
private static AliasingContext ROOT = new AliasingContext(null) {
|
||||||
|
@Override
|
||||||
|
public JsName getAliasForThis(@NotNull DeclarationDescriptor descriptor) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsName getAliasForDescriptor(@NotNull DeclarationDescriptor descriptor) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public static AliasingContext getCleanContext() {
|
||||||
|
return new AliasingContext(ROOT);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private final Map<DeclarationDescriptor, JsName> aliasesForDescriptors = Maps.newHashMap();
|
||||||
|
@NotNull
|
||||||
|
private final Map<DeclarationDescriptor, JsName> aliasesForThis = Maps.newHashMap();
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private final AliasingContext parent;
|
||||||
|
|
||||||
|
private AliasingContext(@Nullable AliasingContext parent) {
|
||||||
|
this.parent = parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public AliasingContext withThisAliased(@NotNull DeclarationDescriptor correspondingDescriptor, @NotNull JsName alias) {
|
||||||
|
AliasingContext newContext = new AliasingContext(this);
|
||||||
|
assert !newContext.aliasesForThis.containsKey(correspondingDescriptor);
|
||||||
|
newContext.aliasesForThis.put(correspondingDescriptor, alias);
|
||||||
|
return newContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private AliasingContext getParent() {
|
||||||
|
assert parent != null;
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public JsName getAliasForThis(@NotNull DeclarationDescriptor descriptor) {
|
||||||
|
JsName alias = aliasesForThis.get(descriptor.getOriginal());
|
||||||
|
if (alias != null) {
|
||||||
|
return alias;
|
||||||
|
}
|
||||||
|
return getParent().getAliasForThis(descriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public JsName getAliasForDescriptor(@NotNull DeclarationDescriptor descriptor) {
|
||||||
|
JsName alias = aliasesForDescriptors.get(descriptor.getOriginal());
|
||||||
|
if (alias != null) {
|
||||||
|
return alias;
|
||||||
|
}
|
||||||
|
return getParent().getAliasForDescriptor(descriptor);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -48,13 +48,11 @@ public final class StaticContext {
|
|||||||
JsProgram program = new JsProgram("main");
|
JsProgram program = new JsProgram("main");
|
||||||
JsRootScope jsRootScope = program.getRootScope();
|
JsRootScope jsRootScope = program.getRootScope();
|
||||||
Namer namer = Namer.newInstance(jsRootScope);
|
Namer namer = Namer.newInstance(jsRootScope);
|
||||||
Aliaser aliaser = Aliaser.newInstance();
|
|
||||||
NamingScope scope = NamingScope.rootScope(jsRootScope);
|
NamingScope scope = NamingScope.rootScope(jsRootScope);
|
||||||
Intrinsics intrinsics = Intrinsics.standardLibraryIntrinsics(library);
|
Intrinsics intrinsics = Intrinsics.standardLibraryIntrinsics(library);
|
||||||
StandardClasses standardClasses =
|
StandardClasses standardClasses =
|
||||||
StandardClasses.bindImplementations(namer.getKotlinScope());
|
StandardClasses.bindImplementations(namer.getKotlinScope());
|
||||||
return new StaticContext(program, bindingContext, aliaser,
|
return new StaticContext(program, bindingContext, namer, intrinsics, standardClasses, scope);
|
||||||
namer, intrinsics, standardClasses, scope);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -62,10 +60,6 @@ public final class StaticContext {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private final BindingContext bindingContext;
|
private final BindingContext bindingContext;
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private final Aliaser aliaser;
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private final Namer namer;
|
private final Namer namer;
|
||||||
|
|
||||||
@@ -90,14 +84,12 @@ public final class StaticContext {
|
|||||||
private final Map<NamingScope, JsFunction> scopeToFunction = Maps.newHashMap();
|
private final Map<NamingScope, JsFunction> scopeToFunction = Maps.newHashMap();
|
||||||
|
|
||||||
|
|
||||||
//qTODO: too many parameters in constructor
|
//TODO: too many parameters in constructor
|
||||||
private StaticContext(@NotNull JsProgram program, @NotNull BindingContext bindingContext,
|
private StaticContext(@NotNull JsProgram program, @NotNull BindingContext bindingContext,
|
||||||
@NotNull Aliaser aliaser,
|
|
||||||
@NotNull Namer namer, @NotNull Intrinsics intrinsics,
|
@NotNull Namer namer, @NotNull Intrinsics intrinsics,
|
||||||
@NotNull StandardClasses standardClasses, @NotNull NamingScope rootScope) {
|
@NotNull StandardClasses standardClasses, @NotNull NamingScope rootScope) {
|
||||||
this.program = program;
|
this.program = program;
|
||||||
this.bindingContext = bindingContext;
|
this.bindingContext = bindingContext;
|
||||||
this.aliaser = aliaser;
|
|
||||||
this.namer = namer;
|
this.namer = namer;
|
||||||
this.intrinsics = intrinsics;
|
this.intrinsics = intrinsics;
|
||||||
this.rootScope = rootScope;
|
this.rootScope = rootScope;
|
||||||
@@ -114,11 +106,6 @@ public final class StaticContext {
|
|||||||
return bindingContext;
|
return bindingContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public Aliaser getAliaser() {
|
|
||||||
return aliaser;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public Intrinsics getIntrinsics() {
|
public Intrinsics getIntrinsics() {
|
||||||
return intrinsics;
|
return intrinsics;
|
||||||
|
|||||||
@@ -38,28 +38,35 @@ public final class TranslationContext {
|
|||||||
private final DynamicContext dynamicContext;
|
private final DynamicContext dynamicContext;
|
||||||
@NotNull
|
@NotNull
|
||||||
private final StaticContext staticContext;
|
private final StaticContext staticContext;
|
||||||
|
@NotNull
|
||||||
|
private final AliasingContext aliasingContext;
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static TranslationContext rootContext(@NotNull StaticContext staticContext) {
|
public static TranslationContext rootContext(@NotNull StaticContext staticContext) {
|
||||||
JsProgram program = staticContext.getProgram();
|
JsProgram program = staticContext.getProgram();
|
||||||
JsBlock globalBlock = program.getGlobalBlock();
|
JsBlock globalBlock = program.getGlobalBlock();
|
||||||
|
DynamicContext rootDynamicContext = DynamicContext.rootContext(staticContext.getRootScope(), globalBlock);
|
||||||
|
AliasingContext rootAliasingContext = AliasingContext.getCleanContext();
|
||||||
return new TranslationContext(staticContext,
|
return new TranslationContext(staticContext,
|
||||||
DynamicContext.rootContext(staticContext.getRootScope(), globalBlock));
|
rootDynamicContext, rootAliasingContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
private TranslationContext(@NotNull StaticContext staticContext, @NotNull DynamicContext dynamicContext) {
|
private TranslationContext(@NotNull StaticContext staticContext,
|
||||||
|
@NotNull DynamicContext dynamicContext,
|
||||||
|
@NotNull AliasingContext context) {
|
||||||
this.dynamicContext = dynamicContext;
|
this.dynamicContext = dynamicContext;
|
||||||
this.staticContext = staticContext;
|
this.staticContext = staticContext;
|
||||||
|
aliasingContext = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public TranslationContext contextWithScope(@NotNull NamingScope newScope, @NotNull JsBlock block) {
|
public TranslationContext contextWithScope(@NotNull NamingScope newScope, @NotNull JsBlock block) {
|
||||||
return new TranslationContext(staticContext, DynamicContext.newContext(newScope, block));
|
return new TranslationContext(staticContext, DynamicContext.newContext(newScope, block), aliasingContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public TranslationContext innerBlock(@NotNull JsBlock block) {
|
public TranslationContext innerBlock(@NotNull JsBlock block) {
|
||||||
return new TranslationContext(staticContext, dynamicContext.innerBlock(block));
|
return new TranslationContext(staticContext, dynamicContext.innerBlock(block), aliasingContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -73,6 +80,11 @@ public final class TranslationContext {
|
|||||||
return contextWithScope(dynamicContext.getScope().innerScope(scope), block);
|
return contextWithScope(dynamicContext.getScope().innerScope(scope), block);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public TranslationContext innerContextWithThisAliased(@NotNull DeclarationDescriptor correspondingDescriptor, @NotNull JsName alias) {
|
||||||
|
return new TranslationContext(staticContext, dynamicContext, aliasingContext.withThisAliased(correspondingDescriptor, alias));
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public JsBlock getBlockForDescriptor(@NotNull DeclarationDescriptor descriptor) {
|
public JsBlock getBlockForDescriptor(@NotNull DeclarationDescriptor descriptor) {
|
||||||
if (descriptor instanceof CallableDescriptor) {
|
if (descriptor instanceof CallableDescriptor) {
|
||||||
@@ -119,11 +131,6 @@ public final class TranslationContext {
|
|||||||
return dynamicContext.declareTemporary(initExpression);
|
return dynamicContext.declareTemporary(initExpression);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public Aliaser aliaser() {
|
|
||||||
return staticContext.getAliaser();
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public Namer namer() {
|
public Namer namer() {
|
||||||
return staticContext.getNamer();
|
return staticContext.getNamer();
|
||||||
@@ -144,6 +151,11 @@ public final class TranslationContext {
|
|||||||
return dynamicContext.jsScope();
|
return dynamicContext.jsScope();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public AliasingContext aliasingContext() {
|
||||||
|
return aliasingContext;
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public JsFunction getFunctionObject(@NotNull CallableDescriptor descriptor) {
|
public JsFunction getFunctionObject(@NotNull CallableDescriptor descriptor) {
|
||||||
return staticContext.getFunctionWithScope(descriptor);
|
return staticContext.getFunctionWithScope(descriptor);
|
||||||
|
|||||||
+6
-15
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package org.jetbrains.k2js.translate.declaration;
|
package org.jetbrains.k2js.translate.declaration;
|
||||||
|
|
||||||
|
import com.google.common.collect.BiMap;
|
||||||
|
import com.google.common.collect.HashBiMap;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.dart.compiler.backend.js.ast.*;
|
import com.google.dart.compiler.backend.js.ast.*;
|
||||||
import com.google.dart.compiler.util.AstUtil;
|
import com.google.dart.compiler.util.AstUtil;
|
||||||
@@ -32,9 +34,7 @@ import org.jetbrains.k2js.translate.utils.BindingUtils;
|
|||||||
import org.jetbrains.k2js.translate.utils.ClassSortingUtils;
|
import org.jetbrains.k2js.translate.utils.ClassSortingUtils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import static org.jetbrains.k2js.translate.utils.DescriptorUtils.getAllClassesDefinedInNamespace;
|
import static org.jetbrains.k2js.translate.utils.DescriptorUtils.getAllClassesDefinedInNamespace;
|
||||||
import static org.jetbrains.k2js.translate.utils.JsAstUtils.*;
|
import static org.jetbrains.k2js.translate.utils.JsAstUtils.*;
|
||||||
@@ -49,7 +49,7 @@ public final class ClassDeclarationTranslator extends AbstractTranslator {
|
|||||||
@NotNull
|
@NotNull
|
||||||
private final List<ClassDescriptor> descriptors;
|
private final List<ClassDescriptor> descriptors;
|
||||||
@NotNull
|
@NotNull
|
||||||
private final Map<JsName, JsName> localToGlobalClassName;
|
private final BiMap<JsName, JsName> localToGlobalClassName;
|
||||||
@NotNull
|
@NotNull
|
||||||
private final JsFunction dummyFunction;
|
private final JsFunction dummyFunction;
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -61,7 +61,7 @@ public final class ClassDeclarationTranslator extends AbstractTranslator {
|
|||||||
@NotNull TranslationContext context) {
|
@NotNull TranslationContext context) {
|
||||||
super(context);
|
super(context);
|
||||||
this.descriptors = descriptors;
|
this.descriptors = descriptors;
|
||||||
this.localToGlobalClassName = new HashMap<JsName, JsName>();
|
this.localToGlobalClassName = HashBiMap.create();
|
||||||
this.dummyFunction = new JsFunction(context.jsScope());
|
this.dummyFunction = new JsFunction(context.jsScope());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,7 +69,7 @@ public final class ClassDeclarationTranslator extends AbstractTranslator {
|
|||||||
declarationsObject = context().jsScope().declareName(Namer.nameForClassesVariable());
|
declarationsObject = context().jsScope().declareName(Namer.nameForClassesVariable());
|
||||||
assert declarationsObject != null;
|
assert declarationsObject != null;
|
||||||
declarationsStatement =
|
declarationsStatement =
|
||||||
newVar(declarationsObject, generateDummyFunctionInvocation());
|
newVar(declarationsObject, generateDummyFunctionInvocation());
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -112,16 +112,9 @@ public final class ClassDeclarationTranslator extends AbstractTranslator {
|
|||||||
for (JetClass jetClass : getClassDeclarations()) {
|
for (JetClass jetClass : getClassDeclarations()) {
|
||||||
classDeclarations.add(generateDeclaration(jetClass));
|
classDeclarations.add(generateDeclaration(jetClass));
|
||||||
}
|
}
|
||||||
removeAliases();
|
|
||||||
return classDeclarations;
|
return classDeclarations;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeAliases() {
|
|
||||||
for (JetClass jetClass : getClassDeclarations()) {
|
|
||||||
ClassDescriptor descriptor = BindingUtils.getClassDescriptor(bindingContext(), jetClass);
|
|
||||||
aliaser().removeAliasForDescriptor(descriptor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private List<JetClass> getClassDeclarations() {
|
private List<JetClass> getClassDeclarations() {
|
||||||
@@ -136,7 +129,7 @@ public final class ClassDeclarationTranslator extends AbstractTranslator {
|
|||||||
private JsStatement generateDeclaration(@NotNull JetClass declaration) {
|
private JsStatement generateDeclaration(@NotNull JetClass declaration) {
|
||||||
JsName localClassName = generateLocalAlias(declaration);
|
JsName localClassName = generateLocalAlias(declaration);
|
||||||
JsInvocation classDeclarationExpression =
|
JsInvocation classDeclarationExpression =
|
||||||
Translation.translateClassDeclaration(declaration, context());
|
Translation.translateClassDeclaration(declaration, localToGlobalClassName.inverse(), context());
|
||||||
return newVar(localClassName, classDeclarationExpression);
|
return newVar(localClassName, classDeclarationExpression);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,8 +138,6 @@ public final class ClassDeclarationTranslator extends AbstractTranslator {
|
|||||||
JsName globalClassName = context().getNameForElement(declaration);
|
JsName globalClassName = context().getNameForElement(declaration);
|
||||||
JsName localAlias = dummyFunction.getScope().declareTemporary();
|
JsName localAlias = dummyFunction.getScope().declareTemporary();
|
||||||
localToGlobalClassName.put(localAlias, globalClassName);
|
localToGlobalClassName.put(localAlias, globalClassName);
|
||||||
ClassDescriptor descriptor = BindingUtils.getClassDescriptor(bindingContext(), declaration);
|
|
||||||
aliaser().setAliasForDescriptor(descriptor, localAlias);
|
|
||||||
return localAlias;
|
return localAlias;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+49
-18
@@ -33,7 +33,9 @@ import org.jetbrains.k2js.translate.general.Translation;
|
|||||||
import org.jetbrains.k2js.translate.utils.JsAstUtils;
|
import org.jetbrains.k2js.translate.utils.JsAstUtils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import static com.google.dart.compiler.util.AstUtil.newSequence;
|
import static com.google.dart.compiler.util.AstUtil.newSequence;
|
||||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getClassDescriptor;
|
import static org.jetbrains.k2js.translate.utils.BindingUtils.getClassDescriptor;
|
||||||
@@ -53,21 +55,31 @@ public final class ClassTranslator extends AbstractTranslator {
|
|||||||
@NotNull
|
@NotNull
|
||||||
public static JsPropertyInitializer translateAsProperty(@NotNull JetClassOrObject classDeclaration,
|
public static JsPropertyInitializer translateAsProperty(@NotNull JetClassOrObject classDeclaration,
|
||||||
@NotNull TranslationContext context) {
|
@NotNull TranslationContext context) {
|
||||||
JsInvocation classCreationExpression = generateClassCreationExpression(classDeclaration, context);
|
JsInvocation classCreationExpression =
|
||||||
|
generateClassCreationExpression(classDeclaration, context);
|
||||||
JsName className = context.getNameForElement(classDeclaration);
|
JsName className = context.getNameForElement(classDeclaration);
|
||||||
return new JsPropertyInitializer(className.makeRef(), classCreationExpression);
|
return new JsPropertyInitializer(className.makeRef(), classCreationExpression);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static JsInvocation generateClassCreationExpression(@NotNull JetClassOrObject classDeclaration,
|
public static JsInvocation generateClassCreationExpression(@NotNull JetClassOrObject classDeclaration,
|
||||||
|
@NotNull Map<JsName, JsName> aliasingMap,
|
||||||
@NotNull TranslationContext context) {
|
@NotNull TranslationContext context) {
|
||||||
return (new ClassTranslator(classDeclaration, context)).translateClassOrObjectCreation();
|
return (new ClassTranslator(classDeclaration, aliasingMap, context)).translateClassOrObjectCreation();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static JsInvocation generateClassCreationExpression(@NotNull JetClassOrObject classDeclaration,
|
||||||
|
|
||||||
|
@NotNull TranslationContext context) {
|
||||||
|
return (new ClassTranslator(classDeclaration, Collections.<JsName, JsName>emptyMap(), context)).translateClassOrObjectCreation();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static JsExpression generateObjectLiteralExpression(@NotNull JetObjectLiteralExpression objectLiteralExpression,
|
public static JsExpression generateObjectLiteralExpression(@NotNull JetObjectLiteralExpression objectLiteralExpression,
|
||||||
@NotNull TranslationContext context) {
|
@NotNull TranslationContext context) {
|
||||||
return (new ClassTranslator(objectLiteralExpression.getObjectDeclaration(), context)).translateObjectLiteralExpression();
|
return (new ClassTranslator(objectLiteralExpression.getObjectDeclaration(), Collections.<JsName, JsName>emptyMap(), context))
|
||||||
|
.translateObjectLiteralExpression();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -76,11 +88,20 @@ public final class ClassTranslator extends AbstractTranslator {
|
|||||||
@NotNull
|
@NotNull
|
||||||
private final JetClassOrObject classDeclaration;
|
private final JetClassOrObject classDeclaration;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private TemporaryVariable aliasForContainingClassThis = null;
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private final ClassDescriptor descriptor;
|
private final ClassDescriptor descriptor;
|
||||||
|
|
||||||
private ClassTranslator(@NotNull JetClassOrObject classDeclaration, @NotNull TranslationContext context) {
|
@NotNull
|
||||||
|
private final Map<JsName, JsName> aliasingMap;
|
||||||
|
|
||||||
|
private ClassTranslator(@NotNull JetClassOrObject classDeclaration,
|
||||||
|
@NotNull Map<JsName, JsName> aliasingMap,
|
||||||
|
@NotNull TranslationContext context) {
|
||||||
super(context.newDeclaration(classDeclaration));
|
super(context.newDeclaration(classDeclaration));
|
||||||
|
this.aliasingMap = aliasingMap;
|
||||||
this.descriptor = getClassDescriptor(context.bindingContext(), classDeclaration);
|
this.descriptor = getClassDescriptor(context.bindingContext(), classDeclaration);
|
||||||
this.classDeclaration = classDeclaration;
|
this.classDeclaration = classDeclaration;
|
||||||
}
|
}
|
||||||
@@ -96,11 +117,8 @@ public final class ClassTranslator extends AbstractTranslator {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private JsExpression translateAsObjectCreationExpressionWithEnclosingThisSaved(@NotNull ClassDescriptor containingClass) {
|
private JsExpression translateAsObjectCreationExpressionWithEnclosingThisSaved(@NotNull ClassDescriptor containingClass) {
|
||||||
TemporaryVariable thisAlias = context().declareTemporary(getThisObject(context(), containingClass));
|
aliasForContainingClassThis = context().declareTemporary(getThisObject(context(), containingClass));
|
||||||
aliaser().setAliasForThis(containingClass, thisAlias.name());
|
return newSequence(aliasForContainingClassThis.assignmentExpression(), translateClassOrObjectCreation());
|
||||||
JsBinaryOperation result = newSequence(thisAlias.assignmentExpression(), translateClassOrObjectCreation());
|
|
||||||
aliaser().removeAliasForThis(containingClass);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -155,7 +173,7 @@ public final class ClassTranslator extends AbstractTranslator {
|
|||||||
private void addTraits(@NotNull List<JsExpression> superclassReferences,
|
private void addTraits(@NotNull List<JsExpression> superclassReferences,
|
||||||
@NotNull List<ClassDescriptor> superclassDescriptors) {
|
@NotNull List<ClassDescriptor> superclassDescriptors) {
|
||||||
for (ClassDescriptor superClassDescriptor :
|
for (ClassDescriptor superClassDescriptor :
|
||||||
superclassDescriptors) {
|
superclassDescriptors) {
|
||||||
assert (superClassDescriptor.getKind() == ClassKind.TRAIT) : "Only traits are expected here";
|
assert (superClassDescriptor.getKind() == ClassKind.TRAIT) : "Only traits are expected here";
|
||||||
superclassReferences.add(getClassReference(superClassDescriptor));
|
superclassReferences.add(getClassReference(superClassDescriptor));
|
||||||
}
|
}
|
||||||
@@ -173,8 +191,10 @@ public final class ClassTranslator extends AbstractTranslator {
|
|||||||
@NotNull
|
@NotNull
|
||||||
private JsExpression getClassReference(@NotNull ClassDescriptor superClassDescriptor) {
|
private JsExpression getClassReference(@NotNull ClassDescriptor superClassDescriptor) {
|
||||||
//NOTE: aliasing here is needed for the declaration generation step
|
//NOTE: aliasing here is needed for the declaration generation step
|
||||||
if (aliaser().hasAliasForDeclaration(superClassDescriptor)) {
|
JsName name = context().getNameForDescriptor(superClassDescriptor);
|
||||||
return aliaser().getAliasForDeclaration(superClassDescriptor).makeRef();
|
JsName alias = aliasingMap.get(name);
|
||||||
|
if (alias != null) {
|
||||||
|
return alias.makeRef();
|
||||||
}
|
}
|
||||||
return getQualifiedReference(context(), superClassDescriptor);
|
return getQualifiedReference(context(), superClassDescriptor);
|
||||||
}
|
}
|
||||||
@@ -188,25 +208,36 @@ public final class ClassTranslator extends AbstractTranslator {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private JsObjectLiteral translateClassDeclarations() {
|
private JsObjectLiteral translateClassDeclarations() {
|
||||||
|
TranslationContext classDeclarationContext = getClassDeclarationContext();
|
||||||
List<JsPropertyInitializer> propertyList = new ArrayList<JsPropertyInitializer>();
|
List<JsPropertyInitializer> propertyList = new ArrayList<JsPropertyInitializer>();
|
||||||
if (!isTrait()) {
|
if (!isTrait()) {
|
||||||
propertyList.add(Translation.generateClassInitializerMethod(classDeclaration, context()));
|
propertyList.add(Translation.generateClassInitializerMethod(classDeclaration, classDeclarationContext));
|
||||||
}
|
}
|
||||||
propertyList.addAll(translatePropertiesAsConstructorParameters());
|
propertyList.addAll(translatePropertiesAsConstructorParameters(classDeclarationContext));
|
||||||
propertyList.addAll(declarationBodyVisitor.traverseClass(classDeclaration, context()));
|
propertyList.addAll(declarationBodyVisitor.traverseClass(classDeclaration, classDeclarationContext));
|
||||||
return JsAstUtils.newObjectLiteral(propertyList);
|
return JsAstUtils.newObjectLiteral(propertyList);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private List<JsPropertyInitializer> translatePropertiesAsConstructorParameters() {
|
private List<JsPropertyInitializer> translatePropertiesAsConstructorParameters(@NotNull TranslationContext classDeclarationContext) {
|
||||||
List<JsPropertyInitializer> result = new ArrayList<JsPropertyInitializer>();
|
List<JsPropertyInitializer> result = new ArrayList<JsPropertyInitializer>();
|
||||||
for (JetParameter parameter : getPrimaryConstructorParameters(classDeclaration)) {
|
for (JetParameter parameter : getPrimaryConstructorParameters(classDeclaration)) {
|
||||||
PropertyDescriptor descriptor =
|
PropertyDescriptor descriptor =
|
||||||
getPropertyDescriptorForConstructorParameter(bindingContext(), parameter);
|
getPropertyDescriptorForConstructorParameter(bindingContext(), parameter);
|
||||||
if (descriptor != null) {
|
if (descriptor != null) {
|
||||||
result.addAll(PropertyTranslator.translateAccessors(descriptor, context()));
|
result.addAll(PropertyTranslator.translateAccessors(descriptor, classDeclarationContext));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private TranslationContext getClassDeclarationContext() {
|
||||||
|
if (aliasForContainingClassThis == null) {
|
||||||
|
return context();
|
||||||
|
}
|
||||||
|
ClassDescriptor containingClass = getContainingClass(descriptor);
|
||||||
|
assert containingClass != null;
|
||||||
|
return context().innerContextWithThisAliased(containingClass, aliasForContainingClassThis.name());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+65
-43
@@ -20,6 +20,7 @@ package org.jetbrains.k2js.translate.expression;
|
|||||||
import com.google.dart.compiler.backend.js.ast.*;
|
import com.google.dart.compiler.backend.js.ast.*;
|
||||||
import com.google.dart.compiler.util.AstUtil;
|
import com.google.dart.compiler.util.AstUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.psi.JetDeclarationWithBody;
|
import org.jetbrains.jet.lang.psi.JetDeclarationWithBody;
|
||||||
import org.jetbrains.jet.lang.psi.JetElement;
|
import org.jetbrains.jet.lang.psi.JetElement;
|
||||||
@@ -34,6 +35,7 @@ import org.jetbrains.k2js.translate.general.AbstractTranslator;
|
|||||||
import org.jetbrains.k2js.translate.general.Translation;
|
import org.jetbrains.k2js.translate.general.Translation;
|
||||||
import org.jetbrains.k2js.translate.reference.ReferenceTranslator;
|
import org.jetbrains.k2js.translate.reference.ReferenceTranslator;
|
||||||
import org.jetbrains.k2js.translate.utils.DescriptorUtils;
|
import org.jetbrains.k2js.translate.utils.DescriptorUtils;
|
||||||
|
import org.jetbrains.k2js.translate.utils.TranslationUtils;
|
||||||
import org.jetbrains.k2js.translate.utils.closure.ClosureContext;
|
import org.jetbrains.k2js.translate.utils.closure.ClosureContext;
|
||||||
import org.jetbrains.k2js.translate.utils.closure.ClosureUtils;
|
import org.jetbrains.k2js.translate.utils.closure.ClosureUtils;
|
||||||
import org.jetbrains.k2js.translate.utils.mutator.Mutator;
|
import org.jetbrains.k2js.translate.utils.mutator.Mutator;
|
||||||
@@ -45,7 +47,6 @@ import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescrip
|
|||||||
import static org.jetbrains.k2js.translate.utils.DescriptorUtils.*;
|
import static org.jetbrains.k2js.translate.utils.DescriptorUtils.*;
|
||||||
import static org.jetbrains.k2js.translate.utils.JsAstUtils.convertToBlock;
|
import static org.jetbrains.k2js.translate.utils.JsAstUtils.convertToBlock;
|
||||||
import static org.jetbrains.k2js.translate.utils.JsAstUtils.setParameters;
|
import static org.jetbrains.k2js.translate.utils.JsAstUtils.setParameters;
|
||||||
import static org.jetbrains.k2js.translate.utils.TranslationUtils.newAliasForThis;
|
|
||||||
import static org.jetbrains.k2js.translate.utils.mutator.LastExpressionMutator.mutateLastExpression;
|
import static org.jetbrains.k2js.translate.utils.mutator.LastExpressionMutator.mutateLastExpression;
|
||||||
|
|
||||||
|
|
||||||
@@ -62,13 +63,15 @@ public final class FunctionTranslator extends AbstractTranslator {
|
|||||||
return new FunctionTranslator(function, context);
|
return new FunctionTranslator(function, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private TemporaryVariable aliasForContaingClassThis = null;
|
||||||
@NotNull
|
@NotNull
|
||||||
private final JetDeclarationWithBody functionDeclaration;
|
private final JetDeclarationWithBody functionDeclaration;
|
||||||
|
@Nullable
|
||||||
|
private JsName extensionFunctionReceiverName = null;
|
||||||
@NotNull
|
@NotNull
|
||||||
private final JsFunction functionObject;
|
private final JsFunction functionObject;
|
||||||
@NotNull
|
@NotNull
|
||||||
private final TranslationContext functionBodyContext;
|
|
||||||
@NotNull
|
|
||||||
private final FunctionDescriptor descriptor;
|
private final FunctionDescriptor descriptor;
|
||||||
// function body needs to be explicitly created here to include it in the context
|
// function body needs to be explicitly created here to include it in the context
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -81,14 +84,49 @@ public final class FunctionTranslator extends AbstractTranslator {
|
|||||||
this.functionDeclaration = functionDeclaration;
|
this.functionDeclaration = functionDeclaration;
|
||||||
this.functionObject = context().getFunctionObject(descriptor);
|
this.functionObject = context().getFunctionObject(descriptor);
|
||||||
this.functionBody = functionObject.getBody();
|
this.functionBody = functionObject.getBody();
|
||||||
this.functionBodyContext = functionBodyContext().innerBlock(functionBody);
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private TranslationContext getFunctionBodyContext() {
|
||||||
|
if (isLiteral()) {
|
||||||
|
return getFunctionBodyContextForLiteral();
|
||||||
|
}
|
||||||
|
if (isExtensionFunction()) {
|
||||||
|
return getFunctionBodyContextForExtensionFunction();
|
||||||
|
}
|
||||||
|
return getContextWithFunctionBodyBlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private TranslationContext getFunctionBodyContextForLiteral() {
|
||||||
|
ClassDescriptor containingClass = getContainingClass(descriptor);
|
||||||
|
if (containingClass == null) {
|
||||||
|
return getContextWithFunctionBodyBlock();
|
||||||
|
}
|
||||||
|
JsExpression thisQualifier = TranslationUtils.getThisObject(context(), containingClass);
|
||||||
|
aliasForContaingClassThis = context().declareTemporary(thisQualifier);
|
||||||
|
return getContextWithFunctionBodyBlock().innerContextWithThisAliased(containingClass, aliasForContaingClassThis.name());
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private TranslationContext getFunctionBodyContextForExtensionFunction() {
|
||||||
|
TranslationContext contextWithFunctionBodyBlock = getContextWithFunctionBodyBlock();
|
||||||
|
extensionFunctionReceiverName = contextWithFunctionBodyBlock.jsScope().declareName(Namer.getReceiverParameterName());
|
||||||
|
DeclarationDescriptor expectedReceiverDescriptor = getExpectedReceiverDescriptor(descriptor);
|
||||||
|
assert expectedReceiverDescriptor != null;
|
||||||
|
return contextWithFunctionBodyBlock.innerContextWithThisAliased(expectedReceiverDescriptor, extensionFunctionReceiverName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private TranslationContext getContextWithFunctionBodyBlock() {
|
||||||
|
return context().newDeclaration(functionDeclaration).innerBlock(functionBody);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public JsFunction translateAsLocalFunction() {
|
public JsFunction translateAsLocalFunction() {
|
||||||
JsName functionName = context().getNameForElement(functionDeclaration);
|
JsName functionName = context().getNameForElement(functionDeclaration);
|
||||||
generateFunctionObject();
|
generateFunctionObject(getFunctionBodyContext());
|
||||||
functionObject.setName(functionName);
|
functionObject.setName(functionName);
|
||||||
return functionObject;
|
return functionObject;
|
||||||
}
|
}
|
||||||
@@ -96,7 +134,7 @@ public final class FunctionTranslator extends AbstractTranslator {
|
|||||||
@NotNull
|
@NotNull
|
||||||
public JsPropertyInitializer translateAsMethod() {
|
public JsPropertyInitializer translateAsMethod() {
|
||||||
JsName functionName = context().getNameForElement(functionDeclaration);
|
JsName functionName = context().getNameForElement(functionDeclaration);
|
||||||
generateFunctionObject();
|
generateFunctionObject(getFunctionBodyContext());
|
||||||
return new JsPropertyInitializer(functionName.makeRef(), functionObject);
|
return new JsPropertyInitializer(functionName.makeRef(), functionObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,17 +146,26 @@ public final class FunctionTranslator extends AbstractTranslator {
|
|||||||
@NotNull
|
@NotNull
|
||||||
private JsExpression doTranslateAsLiteral() {
|
private JsExpression doTranslateAsLiteral() {
|
||||||
assert getExpectedThisDescriptor(descriptor) == null;
|
assert getExpectedThisDescriptor(descriptor) == null;
|
||||||
ClassDescriptor containingClass = getContainingClass(descriptor);
|
generateFunctionObject(getFunctionBodyContext());
|
||||||
if (containingClass == null) {
|
boolean shouldAliasThisObject = shouldAliasThisObject();
|
||||||
generateFunctionObject();
|
if (!shouldAliasThisObject) {
|
||||||
return functionObject;
|
return functionObject;
|
||||||
}
|
}
|
||||||
return generateFunctionObjectWithAliasedThisReference(containingClass);
|
assert aliasForContaingClassThis != null;
|
||||||
|
return AstUtil.newSequence(aliasForContaingClassThis.assignmentExpression(), functionObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean shouldAliasThisObject() {
|
||||||
|
if (!isLiteral()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ClassDescriptor containingClass = getContainingClass(descriptor);
|
||||||
|
return containingClass != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private JsExpression mayBeWrapInClosureCaptureExpression(@NotNull JsExpression wrappedExpression) {
|
private JsExpression mayBeWrapInClosureCaptureExpression(@NotNull JsExpression wrappedExpression) {
|
||||||
ClosureContext closureContext = ClosureUtils.captureClosure(context(), (JetElement) functionDeclaration);
|
ClosureContext closureContext = ClosureUtils.captureClosure(context(), (JetElement)functionDeclaration);
|
||||||
if (closureContext.getDescriptors().isEmpty()) {
|
if (closureContext.getDescriptors().isEmpty()) {
|
||||||
return wrappedExpression;
|
return wrappedExpression;
|
||||||
}
|
}
|
||||||
@@ -138,35 +185,18 @@ public final class FunctionTranslator extends AbstractTranslator {
|
|||||||
return dummyFunctionInvocation;
|
return dummyFunctionInvocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
private void generateFunctionObject(@NotNull TranslationContext context) {
|
||||||
private JsExpression generateFunctionObjectWithAliasedThisReference(@NotNull ClassDescriptor containingClass) {
|
|
||||||
TemporaryVariable aliasForThis = newAliasForThis(context(), containingClass);
|
|
||||||
generateFunctionObject();
|
|
||||||
aliaser().removeAliasForThis(containingClass);
|
|
||||||
return AstUtil.newSequence(aliasForThis.assignmentExpression(), functionObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void generateFunctionObject() {
|
|
||||||
setParameters(functionObject, translateParameters());
|
setParameters(functionObject, translateParameters());
|
||||||
translateBody();
|
translateBody(context);
|
||||||
restoreContext();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void restoreContext() {
|
private void translateBody(@NotNull TranslationContext context) {
|
||||||
if (isExtensionFunction()) {
|
|
||||||
DeclarationDescriptor expectedReceiverDescriptor = getExpectedReceiverDescriptor(descriptor);
|
|
||||||
assert expectedReceiverDescriptor != null : "Extension functions should always have receiver descriptors.";
|
|
||||||
functionBodyContext.aliaser().removeAliasForThis(expectedReceiverDescriptor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void translateBody() {
|
|
||||||
JetExpression jetBodyExpression = functionDeclaration.getBodyExpression();
|
JetExpression jetBodyExpression = functionDeclaration.getBodyExpression();
|
||||||
if (jetBodyExpression == null) {
|
if (jetBodyExpression == null) {
|
||||||
assert descriptor.getModality().equals(Modality.ABSTRACT);
|
assert descriptor.getModality().equals(Modality.ABSTRACT);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
JsNode realBody = Translation.translateExpression(jetBodyExpression, functionBodyContext);
|
JsNode realBody = Translation.translateExpression(jetBodyExpression, context);
|
||||||
functionBody.getStatements().add(wrapWithReturnIfNeeded(realBody, mustAddReturnToGeneratedFunctionBody()));
|
functionBody.getStatements().add(wrapWithReturnIfNeeded(realBody, mustAddReturnToGeneratedFunctionBody()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,16 +222,11 @@ public final class FunctionTranslator extends AbstractTranslator {
|
|||||||
if (!(node instanceof JsExpression)) {
|
if (!(node instanceof JsExpression)) {
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
return new JsReturn((JsExpression) node);
|
return new JsReturn((JsExpression)node);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private TranslationContext functionBodyContext() {
|
|
||||||
return context().newDeclaration(functionDeclaration);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private List<JsParameter> translateParameters() {
|
private List<JsParameter> translateParameters() {
|
||||||
List<JsParameter> jsParameters = new ArrayList<JsParameter>();
|
List<JsParameter> jsParameters = new ArrayList<JsParameter>();
|
||||||
@@ -220,11 +245,8 @@ public final class FunctionTranslator extends AbstractTranslator {
|
|||||||
|
|
||||||
private void mayBeAddThisParameterForExtensionFunction(@NotNull List<JsParameter> jsParameters) {
|
private void mayBeAddThisParameterForExtensionFunction(@NotNull List<JsParameter> jsParameters) {
|
||||||
if (isExtensionFunction()) {
|
if (isExtensionFunction()) {
|
||||||
JsName receiver = functionBodyContext.jsScope().declareName(Namer.getReceiverParameterName());
|
assert extensionFunctionReceiverName != null;
|
||||||
DeclarationDescriptor expectedReceiverDescriptor = getExpectedReceiverDescriptor(descriptor);
|
jsParameters.add(new JsParameter(extensionFunctionReceiverName));
|
||||||
assert expectedReceiverDescriptor != null;
|
|
||||||
aliaser().setAliasForThis(expectedReceiverDescriptor, receiver);
|
|
||||||
jsParameters.add(new JsParameter(receiver));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ package org.jetbrains.k2js.translate.general;
|
|||||||
import com.google.dart.compiler.backend.js.ast.JsProgram;
|
import com.google.dart.compiler.backend.js.ast.JsProgram;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
import org.jetbrains.k2js.translate.context.Aliaser;
|
|
||||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -44,11 +43,6 @@ public abstract class AbstractTranslator {
|
|||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
protected Aliaser aliaser() {
|
|
||||||
return context.aliaser();
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
protected BindingContext bindingContext() {
|
protected BindingContext bindingContext() {
|
||||||
return context.bindingContext();
|
return context.bindingContext();
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ import org.jetbrains.k2js.translate.initializer.ClassInitializerTranslator;
|
|||||||
import org.jetbrains.k2js.translate.initializer.NamespaceInitializerTranslator;
|
import org.jetbrains.k2js.translate.initializer.NamespaceInitializerTranslator;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import static org.jetbrains.k2js.translate.utils.JsAstUtils.convertToExpression;
|
import static org.jetbrains.k2js.translate.utils.JsAstUtils.convertToExpression;
|
||||||
import static org.jetbrains.k2js.translate.utils.JsAstUtils.convertToStatement;
|
import static org.jetbrains.k2js.translate.utils.JsAstUtils.convertToStatement;
|
||||||
@@ -64,8 +65,9 @@ public final class Translation {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static JsInvocation translateClassDeclaration(@NotNull JetClass classDeclaration,
|
public static JsInvocation translateClassDeclaration(@NotNull JetClass classDeclaration,
|
||||||
|
@NotNull Map<JsName, JsName> aliasingMap,
|
||||||
@NotNull TranslationContext context) {
|
@NotNull TranslationContext context) {
|
||||||
return ClassTranslator.generateClassCreationExpression(classDeclaration, context);
|
return ClassTranslator.generateClassCreationExpression(classDeclaration, aliasingMap, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -124,6 +126,4 @@ public final class Translation {
|
|||||||
namer.exec(context.program());
|
namer.exec(context.program());
|
||||||
return context.program();
|
return context.program();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -84,11 +84,11 @@ public final class InitializerVisitor extends TranslatorVisitor<List<JsStatement
|
|||||||
public List<JsStatement> visitObjectDeclarationName(@NotNull JetObjectDeclarationName objectName,
|
public List<JsStatement> visitObjectDeclarationName(@NotNull JetObjectDeclarationName objectName,
|
||||||
@NotNull TranslationContext context) {
|
@NotNull TranslationContext context) {
|
||||||
PropertyDescriptor propertyDescriptorForObjectDeclaration
|
PropertyDescriptor propertyDescriptorForObjectDeclaration
|
||||||
= getPropertyDescriptorForObjectDeclaration(context.bindingContext(), objectName);
|
= getPropertyDescriptorForObjectDeclaration(context.bindingContext(), objectName);
|
||||||
JetObjectDeclaration objectDeclaration = getObjectDeclarationForName(objectName);
|
JetObjectDeclaration objectDeclaration = getObjectDeclarationForName(objectName);
|
||||||
JsInvocation objectValue = ClassTranslator.generateClassCreationExpression(objectDeclaration, context);
|
JsInvocation objectValue = ClassTranslator.generateClassCreationExpression(objectDeclaration, context);
|
||||||
JsExprStmt assignment = assignmentToBackingField(context, propertyDescriptorForObjectDeclaration, objectValue)
|
JsExprStmt assignment = assignmentToBackingField(context, propertyDescriptorForObjectDeclaration, objectValue)
|
||||||
.makeStmt();
|
.makeStmt();
|
||||||
return Collections.<JsStatement>singletonList(assignment);
|
return Collections.<JsStatement>singletonList(assignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.k2js.translate.context.TemporaryVariable;
|
|
||||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||||
import org.jetbrains.k2js.translate.general.Translation;
|
import org.jetbrains.k2js.translate.general.Translation;
|
||||||
import org.jetbrains.k2js.translate.intrinsic.Intrinsic;
|
import org.jetbrains.k2js.translate.intrinsic.Intrinsic;
|
||||||
@@ -117,23 +116,21 @@ public final class TranslationUtils {
|
|||||||
@NotNull
|
@NotNull
|
||||||
public static JsExpression getThisObject(@NotNull TranslationContext context,
|
public static JsExpression getThisObject(@NotNull TranslationContext context,
|
||||||
@NotNull DeclarationDescriptor correspondingDeclaration) {
|
@NotNull DeclarationDescriptor correspondingDeclaration) {
|
||||||
JsExpression thisRef = null;
|
|
||||||
if (correspondingDeclaration instanceof ClassDescriptor) {
|
if (correspondingDeclaration instanceof ClassDescriptor) {
|
||||||
if (context.aliaser().hasAliasForThis(correspondingDeclaration)) {
|
JsName alias = context.aliasingContext().getAliasForThis(correspondingDeclaration);
|
||||||
thisRef = context.aliaser().getAliasForThis(correspondingDeclaration);
|
if (alias != null) {
|
||||||
|
return alias.makeRef();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (correspondingDeclaration instanceof CallableDescriptor) {
|
if (correspondingDeclaration instanceof CallableDescriptor) {
|
||||||
DeclarationDescriptor receiverDescriptor =
|
DeclarationDescriptor receiverDescriptor =
|
||||||
getExpectedReceiverDescriptor((CallableDescriptor) correspondingDeclaration);
|
getExpectedReceiverDescriptor((CallableDescriptor)correspondingDeclaration);
|
||||||
assert receiverDescriptor != null;
|
assert receiverDescriptor != null;
|
||||||
if (context.aliaser().hasAliasForThis(receiverDescriptor)) {
|
JsName alias = context.aliasingContext().getAliasForThis(receiverDescriptor);
|
||||||
thisRef = context.aliaser().getAliasForThis(receiverDescriptor);
|
if (alias != null) {
|
||||||
|
return alias.makeRef();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (thisRef != null) {
|
|
||||||
return thisRef;
|
|
||||||
}
|
|
||||||
return new JsThisRef();
|
return new JsThisRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,7 +168,7 @@ public final class TranslationUtils {
|
|||||||
public static boolean isIntrinsicOperation(@NotNull TranslationContext context,
|
public static boolean isIntrinsicOperation(@NotNull TranslationContext context,
|
||||||
@NotNull JetOperationExpression expression) {
|
@NotNull JetOperationExpression expression) {
|
||||||
FunctionDescriptor operationDescriptor =
|
FunctionDescriptor operationDescriptor =
|
||||||
BindingUtils.getFunctionDescriptorForOperationExpression(context.bindingContext(), expression);
|
BindingUtils.getFunctionDescriptorForOperationExpression(context.bindingContext(), expression);
|
||||||
|
|
||||||
if (operationDescriptor == null) return true;
|
if (operationDescriptor == null) return true;
|
||||||
if (context.intrinsics().isIntrinsic(operationDescriptor)) return true;
|
if (context.intrinsics().isIntrinsic(operationDescriptor)) return true;
|
||||||
@@ -183,7 +180,7 @@ public final class TranslationUtils {
|
|||||||
public static JsNameRef getMethodReferenceForOverloadedOperation(@NotNull TranslationContext context,
|
public static JsNameRef getMethodReferenceForOverloadedOperation(@NotNull TranslationContext context,
|
||||||
@NotNull JetOperationExpression expression) {
|
@NotNull JetOperationExpression expression) {
|
||||||
FunctionDescriptor overloadedOperationDescriptor = getFunctionDescriptorForOperationExpression
|
FunctionDescriptor overloadedOperationDescriptor = getFunctionDescriptorForOperationExpression
|
||||||
(context.bindingContext(), expression);
|
(context.bindingContext(), expression);
|
||||||
assert overloadedOperationDescriptor != null;
|
assert overloadedOperationDescriptor != null;
|
||||||
JsNameRef overloadedOperationReference = context.getNameForDescriptor(overloadedOperationDescriptor).makeRef();
|
JsNameRef overloadedOperationReference = context.getNameForDescriptor(overloadedOperationDescriptor).makeRef();
|
||||||
assert overloadedOperationReference != null;
|
assert overloadedOperationReference != null;
|
||||||
@@ -195,15 +192,6 @@ public final class TranslationUtils {
|
|||||||
return context.program().getNumberLiteral(0);
|
return context.program().getNumberLiteral(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public static TemporaryVariable newAliasForThis(@NotNull TranslationContext context,
|
|
||||||
@NotNull DeclarationDescriptor descriptor) {
|
|
||||||
JsExpression thisQualifier = getThisObject(context, descriptor);
|
|
||||||
TemporaryVariable aliasForThis = context.declareTemporary(thisQualifier);
|
|
||||||
context.aliaser().setAliasForThis(descriptor, aliasForThis.name());
|
|
||||||
return aliasForThis;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static JsExpression applyIntrinsicToBinaryExpression(@NotNull TranslationContext context,
|
public static JsExpression applyIntrinsicToBinaryExpression(@NotNull TranslationContext context,
|
||||||
@NotNull Intrinsic intrinsic,
|
@NotNull Intrinsic intrinsic,
|
||||||
|
|||||||
Reference in New Issue
Block a user