Reorganise context structure, refactor

This commit is contained in:
Pavel Talanov
2011-12-05 16:51:28 +04:00
parent a175566eec
commit d3eaff5d76
24 changed files with 927 additions and 654 deletions
+442 -353
View File
File diff suppressed because it is too large Load Diff
@@ -1,8 +1,7 @@
package org.jetbrains.k2js.declarations;
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 com.google.dart.compiler.backend.js.ast.JsScope;
import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -10,23 +9,23 @@ import org.jetbrains.annotations.Nullable;
public final class DeclarationContext {
@NotNull
public static DeclarationContext rootContext(@NotNull JsScope scope, @Nullable JsNameRef qualifier) {
public static DeclarationContext rootContext(@NotNull NamingScope scope, @Nullable JsNameRef qualifier) {
return new DeclarationContext(scope, qualifier);
}
@NotNull
private final JsScope scope;
private final NamingScope scope;
@Nullable
private final JsNameRef qualifier;
private DeclarationContext(@NotNull JsScope scope, @Nullable JsNameRef qualifier) {
private DeclarationContext(@NotNull NamingScope scope, @Nullable JsNameRef qualifier) {
this.scope = scope;
this.qualifier = qualifier;
}
@NotNull
public JsScope getScope() {
public NamingScope getScope() {
return scope;
}
@@ -36,7 +35,7 @@ public final class DeclarationContext {
}
@NotNull
public DeclarationContext innerDeclaration(@NotNull JsScope declarationScope, @NotNull JsName declarationName) {
public DeclarationContext innerDeclaration(@NotNull NamingScope declarationScope, @NotNull JsName declarationName) {
JsNameRef reference = declarationName.makeRef();
if (qualifier != null) {
AstUtil.setQualifier(reference, qualifier);
@@ -1,11 +1,11 @@
package org.jetbrains.k2js.declarations;
package org.jetbrains.k2js.translate.context;
import com.google.dart.compiler.backend.js.ast.JsName;
import com.google.dart.compiler.backend.js.ast.JsScope;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.k2js.translate.context.Namer;
import static org.jetbrains.k2js.translate.utils.DescriptorUtils.getOwnDeclarations;
/**
* @author Talanov Pavel
@@ -22,22 +22,22 @@ public final class DeclarationVisitor extends DeclarationDescriptorVisitor<Void,
@NotNull
private DeclarationContext declareClass(@NotNull ClassDescriptor descriptor,
@NotNull DeclarationContext context) {
JsScope classScope = declareScope(descriptor, context, "class " + descriptor.getName());
NamingScope classScope = declareScope(descriptor, context, "class " + descriptor.getName());
JsName className = declareName(descriptor, context);
return context.innerDeclaration(classScope, className);
}
private JsScope declareScope(@NotNull DeclarationDescriptor descriptor, @NotNull DeclarationContext context,
@NotNull String scopeName) {
JsScope classScope = new JsScope(context.getScope(), scopeName);
declarations.putScope(descriptor, classScope);
return classScope;
private NamingScope declareScope(@NotNull DeclarationDescriptor descriptor, @NotNull DeclarationContext context,
@NotNull String scopeName) {
NamingScope innerScope = context.getScope().innerScope(scopeName);
declarations.putScope(descriptor, innerScope);
return innerScope;
}
@NotNull
private JsName declareName(@NotNull DeclarationDescriptor descriptor, @NotNull DeclarationContext context,
@NotNull String name) {
JsName jsName = context.getScope().declareName(name);
JsName jsName = context.getScope().declareVariable(descriptor, name);
declarations.putName(descriptor, jsName);
declarations.putQualifier(descriptor, context.getQualifier());
return jsName;
@@ -59,8 +59,7 @@ public final class DeclarationVisitor extends DeclarationDescriptorVisitor<Void,
}
private void declareClassMembers(@NotNull ClassDescriptor descriptor, @NotNull DeclarationContext context) {
for (DeclarationDescriptor memberDescriptor :
descriptor.getDefaultType().getMemberScope().getAllDescriptors()) {
for (DeclarationDescriptor memberDescriptor : getOwnDeclarations(descriptor)) {
memberDescriptor.accept(this, context);
}
}
@@ -120,7 +119,7 @@ public final class DeclarationVisitor extends DeclarationDescriptorVisitor<Void,
private DeclarationContext extractNamespaceDeclaration(@NotNull NamespaceDescriptor descriptor,
@NotNull DeclarationContext context) {
JsName namespaceName = declareName(descriptor, context, nameForNamespace(descriptor));
JsScope namespaceScope = declareScope(descriptor, context, "namespace " + namespaceName.getIdent());
NamingScope namespaceScope = declareScope(descriptor, context, "namespace " + namespaceName.getIdent());
return context.innerDeclaration(namespaceScope, namespaceName);
}
@@ -1,8 +1,7 @@
package org.jetbrains.k2js.declarations;
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 com.google.dart.compiler.backend.js.ast.JsScope;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
@@ -15,30 +14,31 @@ import java.util.Map;
* @author Talanov Pavel
*/
public final class Declarations {
@NotNull
private final Map<DeclarationDescriptor, JsScope> descriptorToScopeMap = new HashMap<DeclarationDescriptor, JsScope>();
public static Declarations newInstance(@NotNull NamingScope rootScope) {
return new Declarations(rootScope);
}
@NotNull
private final Map<DeclarationDescriptor, NamingScope> descriptorToScopeMap = new HashMap<DeclarationDescriptor, NamingScope>();
@NotNull
private final Map<DeclarationDescriptor, JsName> descriptorToNameMap = new HashMap<DeclarationDescriptor, JsName>();
@NotNull
private final Map<DeclarationDescriptor, JsNameRef> descriptorToQualifierMap = new HashMap<DeclarationDescriptor, JsNameRef>();
@NotNull
private final JsScope rootScope;
private final NamingScope rootScope;
private Declarations(@NotNull JsScope scope) {
private Declarations(@NotNull NamingScope scope) {
this.rootScope = scope;
}
@NotNull
static public Declarations newInstance(@NotNull JsScope rootScope) {
return new Declarations(rootScope);
}
public void extractDeclarations(@NotNull DeclarationDescriptor descriptor) {
DeclarationVisitor visitor = new DeclarationVisitor(this);
descriptor.accept(visitor, DeclarationContext.rootContext(rootScope, null));
}
//TODO: provide a mechanism to do intrinsics
public void extractStandardLibrary(@NotNull JetStandardLibrary standardLibrary,
@NotNull JsNameRef standardLibraryObjectName) {
DeclarationVisitor visitor = new DeclarationVisitor(this);
@@ -50,8 +50,8 @@ public final class Declarations {
}
@NotNull
public JsScope getScope(@NotNull DeclarationDescriptor descriptor) {
JsScope scope = descriptorToScopeMap.get(descriptor.getOriginal());
public NamingScope getScope(@NotNull DeclarationDescriptor descriptor) {
NamingScope scope = descriptorToScopeMap.get(descriptor.getOriginal());
assert scope != null : "Unknown declaration";
return scope;
}
@@ -78,7 +78,7 @@ public final class Declarations {
return qualifier;
}
/*package*/ void putScope(@NotNull DeclarationDescriptor descriptor, @NotNull JsScope scope) {
/*package*/ void putScope(@NotNull DeclarationDescriptor descriptor, @NotNull NamingScope scope) {
// assert !descriptorToScopeMap.containsKey(descriptor) : "Already contains that key!";
descriptorToScopeMap.put(descriptor, scope);
}
@@ -0,0 +1,78 @@
package org.jetbrains.k2js.translate.context;
import com.google.dart.compiler.backend.js.ast.JsBlock;
import com.google.dart.compiler.backend.js.ast.JsExpression;
import com.google.dart.compiler.backend.js.ast.JsName;
import com.google.dart.compiler.backend.js.ast.JsScope;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
public class DynamicContext {
@NotNull
public static DynamicContext rootContext(@NotNull NamingScope rootScope, @NotNull JsBlock globalBlock) {
return new DynamicContext(rootScope, globalBlock);
}
@NotNull
public static DynamicContext contextWithScope(@NotNull NamingScope scope) {
return new DynamicContext(scope, new JsBlock());
}
@NotNull
private NamingScope namingScope;
@NotNull
private JsBlock currentBlock;
private DynamicContext(@NotNull NamingScope scope, @NotNull JsBlock block) {
this.namingScope = scope;
this.currentBlock = block;
}
@NotNull
public DynamicContext innerScope(@NotNull JsScope scope) {
return new DynamicContext(namingScope.innerScope(scope), currentBlock);
}
@NotNull
public DynamicContext innerBlock(@NotNull JsBlock block) {
return new DynamicContext(namingScope, block);
}
@NotNull
public JsName getLocalName(@NotNull DeclarationDescriptor descriptor) {
JsName name = namingScope.getName(descriptor);
assert name != null : descriptor.getName() + " is not declared. Use isDeclared to check.";
return name;
}
public boolean isDeclared(@NotNull DeclarationDescriptor descriptor) {
return namingScope.isDeclared(descriptor);
}
@NotNull
public TemporaryVariable declareTemporary(@NotNull JsExpression initExpression) {
return new TemporaryVariable(namingScope.declareTemporary(), initExpression);
}
@NotNull
public TemporaryVariable declareTemporaryWithName(@NotNull String preferredName,
@NotNull JsExpression initExpression) {
return new TemporaryVariable(namingScope.declareTemporaryWithName(preferredName), initExpression);
}
@NotNull
public JsName declareLocalVariable(@NotNull DeclarationDescriptor descriptor) {
return namingScope.declareVariable(descriptor, descriptor.getName());
}
@NotNull
public JsScope jsScope() {
return namingScope.jsScope();
}
@NotNull
public JsBlock jsBlock() {
return currentBlock;
}
}
@@ -0,0 +1,89 @@
package org.jetbrains.k2js.translate.context;
import com.google.dart.compiler.backend.js.ast.JsName;
import com.google.dart.compiler.backend.js.ast.JsScope;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import java.util.HashMap;
import java.util.Map;
/**
* @author Talanov Pavel
*/
public final class NamingScope {
@NotNull
public static NamingScope rootScope(@NotNull JsScope rootScope) {
return new NamingScope(rootScope, null);
}
@NotNull
private final JsScope scope;
@Nullable
private final NamingScope parent;
@NotNull
private final Map<DeclarationDescriptor, JsName> descriptorToNameMap =
new HashMap<DeclarationDescriptor, JsName>();
private NamingScope(@NotNull JsScope correspondingScope, @Nullable NamingScope parent) {
this.scope = correspondingScope;
this.parent = parent;
}
@NotNull
public NamingScope innerScope(@NotNull String scopeName) {
JsScope innerJsScope = new JsScope(jsScope(), scopeName);
return new NamingScope(innerJsScope, this);
}
@NotNull
public NamingScope innerScope(@NotNull JsScope correspondingScope) {
return new NamingScope(correspondingScope, this);
}
@Nullable
public JsName getName(@NotNull DeclarationDescriptor descriptor) {
JsName name = descriptorToNameMap.get(descriptor);
if (name != null) return name;
if (parent != null) return parent.getName(descriptor);
return null;
}
@NotNull
public JsName declareVariable(@NotNull DeclarationDescriptor descriptor,
@NotNull String name) {
JsName declaredName = scope.declareName(name);
descriptorToNameMap.put(descriptor, declaredName);
return declaredName;
}
@NotNull
public JsName declareVariable(@NotNull DeclarationDescriptor descriptor) {
return declareVariable(descriptor, descriptor.getName());
}
public boolean isDeclared(@NotNull DeclarationDescriptor descriptor) {
return (getName(descriptor.getOriginal()) != null);
}
//TODO protect global namespace
public JsName declareTemporary() {
return scope.declareTemporary();
}
public JsName declareTemporaryWithName(@NotNull String preferredName) {
return scope.declareName(preferredName);
}
@NotNull
public JsScope jsScope() {
return scope;
}
}
@@ -3,26 +3,26 @@ package org.jetbrains.k2js.translate.context;
import com.google.dart.compiler.backend.js.ast.JsName;
import com.google.dart.compiler.backend.js.ast.JsProgram;
import com.google.dart.compiler.backend.js.ast.JsRootScope;
import com.google.dart.compiler.backend.js.ast.JsScope;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.psi.JetElement;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.types.JetStandardLibrary;
import org.jetbrains.k2js.declarations.Declarations;
import org.jetbrains.k2js.translate.intrinsic.Intrinsics;
import org.jetbrains.k2js.translate.utils.BindingUtils;
public class StaticContext {
public static StaticContext generateStaticContext(@NotNull JetStandardLibrary library,
@NotNull BindingContext bindingContext) {
JsProgram program = new JsProgram("main");
JsRootScope rootScope = program.getRootScope();
Namer namer = Namer.newInstance(rootScope);
JsRootScope jsRootScope = program.getRootScope();
Namer namer = Namer.newInstance(jsRootScope);
Aliaser aliaser = Aliaser.aliasesForStandardClasses(library, namer);
Declarations declarations = Declarations.newInstance(rootScope);
NamingScope scope = NamingScope.rootScope(jsRootScope);
Declarations declarations = Declarations.newInstance(scope);
Intrinsics intrinsics = Intrinsics.standardLibraryIntrinsics(library);
return new StaticContext(program, bindingContext, declarations, aliaser, namer, intrinsics);
return new StaticContext(program, bindingContext, declarations, aliaser, namer, intrinsics, scope);
}
@NotNull
@@ -43,16 +43,21 @@ public class StaticContext {
@NotNull
private final Intrinsics intrinsics;
@NotNull
private final NamingScope rootScope;
private StaticContext(@NotNull JsProgram program, @NotNull BindingContext bindingContext,
@NotNull Declarations declarations, @NotNull Aliaser aliaser,
@NotNull Namer namer, @NotNull Intrinsics intrinsics) {
@NotNull Namer namer, @NotNull Intrinsics intrinsics,
@NotNull NamingScope rootScope) {
this.program = program;
this.bindingContext = bindingContext;
this.declarations = declarations;
this.aliaser = aliaser;
this.namer = namer;
this.intrinsics = intrinsics;
this.rootScope = rootScope;
}
@NotNull
@@ -86,34 +91,26 @@ public class StaticContext {
}
@NotNull
public JsScope getScopeForDescriptor(@NotNull DeclarationDescriptor descriptor) {
public NamingScope getRootScope() {
return rootScope;
}
@NotNull
public NamingScope getScopeForDescriptor(@NotNull DeclarationDescriptor descriptor) {
return declarations.getScope(descriptor);
}
@NotNull
public JsScope getScopeForElement(@NotNull JetElement element) {
DeclarationDescriptor descriptor = getDescriptorForElement(element);
public NamingScope getScopeForElement(@NotNull JetElement element) {
DeclarationDescriptor descriptor = BindingUtils.getDescriptorForElement(bindingContext, element);
return getScopeForDescriptor(descriptor);
}
@NotNull
public JsName getNameForDescriptor(@NotNull DeclarationDescriptor descriptor) {
public JsName getGlobalName(@NotNull DeclarationDescriptor descriptor) {
return declarations.getName(descriptor);
}
@NotNull
public JsName getNameForElement(@NotNull JetElement element) {
DeclarationDescriptor descriptor = getDescriptorForElement(element);
return getNameForDescriptor(descriptor);
}
@NotNull
DeclarationDescriptor getDescriptorForElement(@NotNull JetElement element) {
DeclarationDescriptor descriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, element);
assert descriptor != null : "Element should have a descriptor";
return descriptor;
}
public boolean isDeclared(@NotNull DeclarationDescriptor descriptor) {
return declarations.hasDeclaredName(descriptor);
}
@@ -0,0 +1,38 @@
package org.jetbrains.k2js.translate.context;
import com.google.dart.compiler.backend.js.ast.JsExpression;
import com.google.dart.compiler.backend.js.ast.JsName;
import com.google.dart.compiler.backend.js.ast.JsNameRef;
import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull;
/**
* @author Talanov Pavel
*/
public final class TemporaryVariable {
@NotNull
private final JsExpression assignmentExpression;
@NotNull
private final JsName variableName;
/*package*/ TemporaryVariable(@NotNull JsName temporaryName, @NotNull JsExpression initExpression) {
this.variableName = temporaryName;
this.assignmentExpression = AstUtil.newAssignment(variableName.makeRef(), initExpression);
}
@NotNull
public JsNameRef nameReference() {
return variableName.makeRef();
}
@NotNull
/*package*/ JsName name() {
return variableName;
}
@NotNull
public JsExpression assignmentExpression() {
return assignmentExpression;
}
}
@@ -1,13 +1,11 @@
package org.jetbrains.k2js.translate.context;
import com.google.dart.compiler.backend.js.ast.JsName;
import com.google.dart.compiler.backend.js.ast.JsProgram;
import com.google.dart.compiler.backend.js.ast.JsScope;
import com.google.dart.compiler.backend.js.ast.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.PropertyAccessorDescriptor;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.k2js.declarations.Declarations;
import org.jetbrains.k2js.translate.intrinsic.Intrinsics;
import org.jetbrains.k2js.translate.utils.BindingUtils;
@@ -16,90 +14,64 @@ import org.jetbrains.k2js.translate.utils.BindingUtils;
*/
public final class TranslationContext {
private static class Scopes {
public Scopes(@NotNull JsScope enclosingScope, @NotNull JsScope functionScope, @NotNull JsScope namespaceScope) {
this.enclosingScope = enclosingScope;
this.classScope = functionScope;
this.namespaceScope = namespaceScope;
}
@NotNull
public final JsScope enclosingScope;
@NotNull
public final JsScope classScope;
@NotNull
public final JsScope namespaceScope;
}
@NotNull
public static TranslationContext rootContext(@NotNull StaticContext staticContext) {
JsScope rootScope = staticContext.getProgram().getRootScope();
Scopes scopes = new Scopes(rootScope, rootScope, rootScope);
return new TranslationContext(staticContext, scopes);
}
@NotNull
private final Scopes scopes;
private final DynamicContext dynamicContext;
@NotNull
private final StaticContext staticContext;
@NotNull
public static TranslationContext rootContext(@NotNull StaticContext staticContext) {
JsProgram program = staticContext.getProgram();
JsBlock globalBlock = program.getGlobalBlock();
return new TranslationContext(staticContext,
DynamicContext.rootContext(staticContext.getRootScope(), globalBlock));
}
private TranslationContext(@NotNull StaticContext staticContext, @NotNull Scopes scopes) {
this.scopes = scopes;
private TranslationContext(@NotNull StaticContext staticContext, @NotNull DynamicContext dynamicContext) {
this.dynamicContext = dynamicContext;
this.staticContext = staticContext;
}
@NotNull
public TranslationContext newNamespace(@NotNull JetNamespace declaration) {
return newNamespace(BindingUtils.getNamespaceDescriptor(staticContext.getBindingContext(), declaration));
}
@NotNull
public TranslationContext newNamespace(@NotNull NamespaceDescriptor descriptor) {
JsScope namespaceScope = staticContext.getDeclarations().getScope(descriptor);
Scopes newScopes = new Scopes(namespaceScope, namespaceScope, namespaceScope);
return new TranslationContext(staticContext, newScopes);
}
@NotNull
public TranslationContext newClass(@NotNull JetClass declaration) {
return newClass(BindingUtils.getClassDescriptor(staticContext.getBindingContext(), declaration));
}
@NotNull
public TranslationContext newClass(@NotNull ClassDescriptor descriptor) {
JsScope classScope = staticContext.getDeclarations().getScope(descriptor);
Scopes newScopes = new Scopes(classScope, classScope, scopes.namespaceScope);
return new TranslationContext(staticContext, newScopes);
}
@NotNull
public TranslationContext newPropertyAccess(@NotNull JetPropertyAccessor declaration) {
return newPropertyAccess(BindingUtils.getPropertyAccessorDescriptor(staticContext.getBindingContext(), declaration));
}
@NotNull
public TranslationContext newPropertyAccess(@NotNull PropertyAccessorDescriptor descriptor) {
return newFunctionDeclaration(descriptor);
}
@NotNull
public TranslationContext newFunctionDeclaration(@NotNull JetNamedFunction declaration) {
return newFunctionDeclaration(BindingUtils.getFunctionDescriptor(staticContext.getBindingContext(), declaration));
}
@NotNull
public TranslationContext newFunctionDeclaration(@NotNull FunctionDescriptor descriptor) {
JsScope functionScope = staticContext.getDeclarations().getScope(descriptor);
Scopes newScopes = new Scopes(functionScope, scopes.classScope, scopes.namespaceScope);
return new TranslationContext(staticContext, newScopes);
public TranslationContext contextWithScope(@NotNull NamingScope newScope) {
return new TranslationContext(staticContext, DynamicContext.contextWithScope(newScope));
}
// Note: Should be used if and only if scope has no corresponding descriptor
@NotNull
public TranslationContext newEnclosingScope(@NotNull JsScope enclosingScope) {
Scopes newScopes = new Scopes(enclosingScope, scopes.classScope, scopes.namespaceScope);
return new TranslationContext(staticContext, newScopes);
public TranslationContext innerJsScope(@NotNull JsScope enclosingScope) {
return new TranslationContext(staticContext, dynamicContext.innerScope(enclosingScope));
}
@NotNull
public TranslationContext newNamespace(@NotNull JetNamespace declaration) {
return newDeclaration(BindingUtils.getNamespaceDescriptor(staticContext.getBindingContext(), declaration));
}
@NotNull
public TranslationContext newDeclaration(@NotNull DeclarationDescriptor descriptor) {
NamingScope declarationScope = staticContext.getDeclarations().getScope(descriptor);
return contextWithScope(declarationScope);
}
@NotNull
public TranslationContext newClass(@NotNull JetClass declaration) {
return newDeclaration(BindingUtils.getClassDescriptor(staticContext.getBindingContext(), declaration));
}
@NotNull
public TranslationContext newPropertyAccess(@NotNull JetPropertyAccessor declaration) {
return newDeclaration(BindingUtils.getPropertyAccessorDescriptor(staticContext.getBindingContext(), declaration));
}
@NotNull
public TranslationContext newPropertyAccess(@NotNull PropertyAccessorDescriptor descriptor) {
return newDeclaration(descriptor);
}
@NotNull
public TranslationContext newFunctionDeclaration(@NotNull JetNamedFunction declaration) {
return newDeclaration(BindingUtils.getFunctionDescriptor(staticContext.getBindingContext(), declaration));
}
@NotNull
@@ -107,54 +79,65 @@ public final class TranslationContext {
return staticContext.getBindingContext();
}
@NotNull
public JsProgram program() {
return staticContext.getProgram();
}
@NotNull
public JsScope enclosingScope() {
return scopes.enclosingScope;
}
@NotNull
public JsScope namespaceScope() {
return scopes.namespaceScope;
}
@NotNull
public JsScope classScope() {
return scopes.classScope;
}
@NotNull
public JsScope getScopeForDescriptor(@NotNull DeclarationDescriptor descriptor) {
public NamingScope getScopeForDescriptor(@NotNull DeclarationDescriptor descriptor) {
return staticContext.getScopeForDescriptor(descriptor);
}
@NotNull
public JsScope getScopeForElement(@NotNull JetElement element) {
public NamingScope getScopeForElement(@NotNull JetElement element) {
return staticContext.getScopeForElement(element);
}
@NotNull
public JsName getNameForDescriptor(@NotNull DeclarationDescriptor descriptor) {
return staticContext.getNameForDescriptor(descriptor);
if (dynamicContext.isDeclared(descriptor)) {
return dynamicContext.getLocalName(descriptor);
}
return staticContext.getGlobalName(descriptor);
}
@NotNull
public JsName getNameForElement(@NotNull JetElement element) {
return staticContext.getNameForElement(element);
}
@NotNull
private DeclarationDescriptor getDescriptorForElement(@NotNull JetElement element) {
return staticContext.getDescriptorForElement(element);
DeclarationDescriptor descriptor = BindingUtils.getDescriptorForElement(bindingContext(), element);
return getNameForDescriptor(descriptor);
}
public boolean isDeclared(@NotNull DeclarationDescriptor descriptor) {
return staticContext.isDeclared(descriptor);
if (dynamicContext.isDeclared(descriptor)) {
return true;
} else {
return staticContext.isDeclared(descriptor);
}
}
@NotNull
public TemporaryVariable declareTemporary(@NotNull JsExpression initExpression) {
return dynamicContext.declareTemporary(initExpression);
}
@NotNull
public JsName declareLocalVariable(@NotNull DeclarationDescriptor descriptor) {
return dynamicContext.declareLocalVariable(descriptor);
}
@NotNull
public JsName declareLocalVariable(@NotNull JetElement element) {
DeclarationDescriptor declarationDescriptor =
BindingUtils.getDescriptorForElement(bindingContext(), element);
return dynamicContext.declareLocalVariable(declarationDescriptor);
}
@NotNull
public TemporaryVariable newAliasForThis() {
TemporaryVariable aliasForThis = dynamicContext.declareTemporaryWithName("that", new JsThisRef());
aliaser().setAliasForThis(aliasForThis.name());
return aliasForThis;
}
public void removeAliasForThis() {
aliaser().removeAliasForThis();
}
@NotNull
@@ -176,4 +159,14 @@ public final class TranslationContext {
public Intrinsics intrinsics() {
return staticContext.getIntrinsics();
}
@NotNull
public JsProgram program() {
return staticContext.getProgram();
}
@NotNull
public JsScope jsScope() {
return dynamicContext.jsScope();
}
}
@@ -40,11 +40,11 @@ public final class ClassDeclarationTranslator extends AbstractTranslator {
super(context);
this.namespace = namespace;
this.localToGlobalClassName = new HashMap<JsName, JsName>();
this.dummyFunctionScope = new JsScope(context().enclosingScope(), "class declaration function");
this.dummyFunctionScope = new JsScope(context().jsScope(), "class declaration function");
}
public void generateDeclarations() {
declarationsObject = context().enclosingScope().declareName(Namer.nameForClassesVariable());
declarationsObject = context().jsScope().declareName(Namer.nameForClassesVariable());
assert declarationsObject != null;
declarationsStatement =
AstUtil.newAssignmentStatement(declarationsObject.makeRef(), generateDummyFunctionInvocation());
@@ -20,6 +20,8 @@ import org.jetbrains.k2js.translate.utils.BindingUtils;
import java.util.ArrayList;
import java.util.List;
import static org.jetbrains.k2js.translate.utils.BindingUtils.getPropertyDescriptorForConstructorParameter;
/**
* @author Talanov Pavel
*/
@@ -127,7 +129,7 @@ public final class ClassTranslator extends AbstractTranslator {
List<JsPropertyInitializer> result = new ArrayList<JsPropertyInitializer>();
for (JetParameter parameter : classDeclaration.getPrimaryConstructorParameters()) {
PropertyDescriptor descriptor =
BindingUtils.getPropertyDescriptorForConstructorParameter(context().bindingContext(), parameter);
getPropertyDescriptorForConstructorParameter(context().bindingContext(), parameter);
if (descriptor != null) {
result.addAll(PropertyTranslator.translateAccessors(descriptor, context()));
}
@@ -18,8 +18,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.assignmentToBackingFieldFromParameter;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.backingFieldReference;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.*;
/**
* @author Talanov Pavel
@@ -105,8 +104,7 @@ public final class PropertyTranslator extends AbstractTranslator {
@NotNull
private JsFunction generateDefaultGetterFunction(@NotNull PropertyGetterDescriptor descriptor) {
JsReturn returnExpression = new JsReturn(backingFieldReference(context(), property));
JsFunction getterFunction =
JsFunction.getAnonymousFunctionWithScope(context().getScopeForDescriptor(descriptor));
JsFunction getterFunction = functionWithScope(context().getScopeForDescriptor(descriptor));
getterFunction.setBody(AstUtil.convertToBlock(returnExpression));
return getterFunction;
}
@@ -121,10 +119,9 @@ public final class PropertyTranslator extends AbstractTranslator {
@NotNull
private JsFunction generateDefaultSetterFunction(@NotNull PropertySetterDescriptor propertySetterDescriptor) {
JsFunction result = JsFunction.getAnonymousFunctionWithScope(
context().getScopeForDescriptor(propertySetterDescriptor));
JsFunction result = functionWithScope(context().getScopeForDescriptor(propertySetterDescriptor));
JsParameter defaultParameter =
new JsParameter(propertyAccessContext(propertySetterDescriptor).enclosingScope().declareTemporary());
new JsParameter(propertyAccessContext(propertySetterDescriptor).jsScope().declareTemporary());
JsStatement assignment = assignmentToBackingFieldFromParameter(context(), property, defaultParameter);
result.setParameters(Arrays.asList(defaultParameter));
result.setBody(AstUtil.convertToBlock(assignment));
@@ -22,7 +22,8 @@ import org.jetbrains.k2js.translate.utils.BindingUtils;
import java.util.List;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.*;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.notNullCheck;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateInitializerForProperty;
/**
* @author Talanov Pavel
@@ -103,7 +104,7 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
@NotNull
// assume it is a local variable declaration
public JsNode visitProperty(@NotNull JetProperty expression, @NotNull TranslationContext context) {
JsName jsPropertyName = context.enclosingScope().declareName(getPropertyName(expression));
JsName jsPropertyName = context.declareLocalVariable(expression);
JsExpression jsInitExpression = translateInitializerForProperty(expression, context);
return AstUtil.newVar(jsPropertyName, jsInitExpression);
}
@@ -3,7 +3,9 @@ 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.DeclarationDescriptor;
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.general.AbstractTranslator;
import org.jetbrains.k2js.translate.general.Translation;
@@ -11,6 +13,10 @@ import org.jetbrains.k2js.translate.general.Translation;
import java.util.ArrayList;
import java.util.List;
import static org.jetbrains.k2js.translate.utils.BindingUtils.getDescriptorForElement;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.functionWithScope;
/**
* @author Talanov Pavel
*/
@@ -42,33 +48,30 @@ public final class FunctionTranslator extends AbstractTranslator {
return new JsPropertyInitializer(functionName.makeRef(), function);
}
//TODO: consider refactoring
@NotNull
public JsExpression translateAsLiteral() {
//TODO: provide a way not to pollute global namespace
JsName aliasForThis = context().enclosingScope().declareName("that");
context().aliaser().setAliasForThis(aliasForThis);
TemporaryVariable aliasForThis = context().newAliasForThis();
JsFunction function = generateFunctionObject();
context().aliaser().removeAliasForThis();
JsExpression assignThatToThis = AstUtil.newAssignment(aliasForThis.makeRef(), new JsThisRef());
return AstUtil.newSequence(assignThatToThis, function);
context().removeAliasForThis();
return AstUtil.newSequence(aliasForThis.assignmentExpression(), function);
}
@NotNull
private JsFunction generateFunctionObject() {
functionObject.setParameters(translateParameters(functionDeclaration.getValueParameters(),
functionObject.getScope()));
functionObject.setBody(translateBody());
TranslationContext innerContext = functionBodyContext();
functionObject.setParameters(translateParameters(functionDeclaration.getValueParameters(), innerContext));
functionObject.setBody(translateBody(innerContext));
return functionObject;
}
private JsFunction createFunctionObject() {
if (isDeclaration()) {
return JsFunction.getAnonymousFunctionWithScope
return functionWithScope
(context().getScopeForElement((JetDeclaration) functionDeclaration));
}
if (isLiteral()) {
return new JsFunction(context().enclosingScope());
//TODO: look into
return new JsFunction(context().jsScope());
}
throw new AssertionError("Unsupported type of functionDeclaration.");
}
@@ -83,11 +86,11 @@ public final class FunctionTranslator extends AbstractTranslator {
}
@NotNull
private JsBlock translateBody() {
private JsBlock translateBody(@NotNull TranslationContext functionBodyContext) {
JetExpression jetBodyExpression = functionDeclaration.getBodyExpression();
//TODO decide if there are cases where this assert is illegal
assert jetBodyExpression != null : "Function without body not supported";
JsNode body = Translation.translateExpression(jetBodyExpression, functionBodyContext());
JsNode body = Translation.translateExpression(jetBodyExpression, functionBodyContext);
return wrapWithReturnIfNeeded(body, !functionDeclaration.hasBlockBody());
}
@@ -124,19 +127,27 @@ public final class FunctionTranslator extends AbstractTranslator {
return context().newPropertyAccess((JetPropertyAccessor) functionDeclaration);
}
if (isLiteral()) {
return context().newEnclosingScope(functionObject.getScope());
return context().innerJsScope(functionObject.getScope());
}
throw new AssertionError("Unsupported type of functionDeclaration.");
}
@NotNull
private List<JsParameter> translateParameters(@NotNull List<JetParameter> jetParameters,
@NotNull JsScope functionScope) {
@NotNull TranslationContext functionBodyContext) {
List<JsParameter> jsParameters = new ArrayList<JsParameter>();
for (JetParameter jetParameter : jetParameters) {
JsName parameterName = functionScope.declareName(jetParameter.getName());
JsName parameterName = declareParameter(jetParameter, functionBodyContext);
jsParameters.add(new JsParameter(parameterName));
}
return jsParameters;
}
@NotNull
private JsName declareParameter(@NotNull JetParameter jetParameter,
@NotNull TranslationContext functionBodyContext) {
DeclarationDescriptor parameterDescriptor =
getDescriptorForElement(context().bindingContext(), jetParameter);
return context().declareLocalVariable(parameterDescriptor);
}
}
@@ -15,6 +15,7 @@ import java.util.List;
/**
* @author Talanov Pavel
*/
//TODO: look into using temporary variable for counter
public class WhenTranslator extends AbstractTranslator {
@NotNull
@@ -35,7 +36,7 @@ public class WhenTranslator extends AbstractTranslator {
super(context);
this.whenExpression = expression;
this.expressionToMatch = translateExpressionToMatch(whenExpression);
this.dummyCounterName = context.enclosingScope().declareTemporary();
this.dummyCounterName = context.jsScope().declareTemporary();
}
@NotNull
@@ -2,11 +2,11 @@ package org.jetbrains.k2js.translate.initializer;
import com.google.dart.compiler.backend.js.ast.JsFunction;
import com.google.dart.compiler.backend.js.ast.JsPropertyInitializer;
import com.google.dart.compiler.backend.js.ast.JsScope;
import com.google.dart.compiler.backend.js.ast.JsStatement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.JetDeclaration;
import org.jetbrains.k2js.translate.context.Namer;
import org.jetbrains.k2js.translate.context.NamingScope;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.general.AbstractTranslator;
@@ -21,12 +21,12 @@ public abstract class AbstractInitializerTranslator extends AbstractTranslator {
@NotNull
protected final InitializerVisitor visitor;
@NotNull
protected final JsScope initializerMethodScope;
protected final NamingScope initializerMethodScope;
protected AbstractInitializerTranslator(@NotNull JsScope initializerMethodScope, @NotNull TranslationContext context) {
super(context.newEnclosingScope(initializerMethodScope));
protected AbstractInitializerTranslator(@NotNull NamingScope scope, @NotNull TranslationContext context) {
super(context.contextWithScope(scope));
this.visitor = new InitializerVisitor();
this.initializerMethodScope = initializerMethodScope;
this.initializerMethodScope = scope;
}
abstract protected JsFunction generateInitializerFunction();
@@ -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.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
import org.jetbrains.jet.lang.psi.JetClass;
import org.jetbrains.jet.lang.psi.JetDelegationSpecifier;
@@ -11,12 +12,14 @@ import org.jetbrains.jet.lang.psi.JetDelegatorToSuperCall;
import org.jetbrains.jet.lang.psi.JetParameter;
import org.jetbrains.k2js.translate.context.Namer;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.utils.BindingUtils;
import org.jetbrains.k2js.translate.utils.TranslationUtils;
import java.util.ArrayList;
import java.util.List;
import static org.jetbrains.k2js.translate.utils.BindingUtils.*;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.functionWithScope;
/**
* @author Talanov Pavel
*/
@@ -28,15 +31,15 @@ public final class ClassInitializerTranslator extends AbstractInitializerTransla
private final List<JsStatement> initializerStatements = new ArrayList<JsStatement>();
public ClassInitializerTranslator(@NotNull JetClass classDeclaration, @NotNull TranslationContext context) {
super(new JsScope(context.getScopeForElement(classDeclaration),
"initializer " + classDeclaration.getName()), context);
super(context.getScopeForElement(classDeclaration).innerScope
("initializer " + classDeclaration.getName()), context);
this.classDeclaration = classDeclaration;
}
@Override
@NotNull
protected JsFunction generateInitializerFunction() {
JsFunction result = JsFunction.getAnonymousFunctionWithScope(initializerMethodScope);
JsFunction result = functionWithScope(initializerMethodScope);
//NOTE: that while we translate constructor parameters we also add property initializer statements
// for properties declared as constructor parameters
result.setParameters(translatePrimaryConstructorParameters());
@@ -52,7 +55,7 @@ public final class ClassInitializerTranslator extends AbstractInitializerTransla
}
private void mayBeAddCallToSuperMethod() {
if (BindingUtils.hasAncestorClass(context().bindingContext(), classDeclaration)) {
if (hasAncestorClass(context().bindingContext(), classDeclaration)) {
JetDelegatorToSuperCall superCall = getSuperCall();
if (superCall == null) return;
addCallToSuperMethod(superCall);
@@ -60,7 +63,8 @@ public final class ClassInitializerTranslator extends AbstractInitializerTransla
}
private void addCallToSuperMethod(@NotNull JetDelegatorToSuperCall superCall) {
JsName superMethodName = initializerMethodScope.declareName(Namer.superMethodName());
//TODO: look into
JsName superMethodName = initializerMethodScope.jsScope().declareName(Namer.superMethodName());
List<JsExpression> arguments = translateArguments(superCall);
initializerStatements.add(AstUtil.convertToStatement
(AstUtil.newInvocation(AstUtil.thisQualifiedReference(superMethodName), arguments)));
@@ -83,10 +87,12 @@ public final class ClassInitializerTranslator extends AbstractInitializerTransla
return result;
}
//TODO: util method
@NotNull
List<JsParameter> translatePrimaryConstructorParameters() {
List<JetParameter> parameterList = classDeclaration.getPrimaryConstructorParameters();
List<JsParameter> result = new ArrayList<JsParameter>();
for (JetParameter jetParameter : classDeclaration.getPrimaryConstructorParameters()) {
for (JetParameter jetParameter : parameterList) {
result.add(translateParameter(jetParameter));
}
return result;
@@ -94,7 +100,9 @@ public final class ClassInitializerTranslator extends AbstractInitializerTransla
@NotNull
private JsParameter translateParameter(@NotNull JetParameter jetParameter) {
JsName parameterName = initializerMethodScope.declareName(jetParameter.getName());
DeclarationDescriptor parameterDescriptor =
getDescriptorForElement(context().bindingContext(), jetParameter);
JsName parameterName = initializerMethodScope.declareVariable(parameterDescriptor);
JsParameter jsParameter = new JsParameter(parameterName);
mayBeAddInitializerStatementForProperty(jsParameter, jetParameter);
return jsParameter;
@@ -103,7 +111,7 @@ public final class ClassInitializerTranslator extends AbstractInitializerTransla
private void mayBeAddInitializerStatementForProperty(@NotNull JsParameter jsParameter,
@NotNull JetParameter jetParameter) {
PropertyDescriptor propertyDescriptor =
BindingUtils.getPropertyDescriptorForConstructorParameter(context().bindingContext(), jetParameter);
getPropertyDescriptorForConstructorParameter(context().bindingContext(), jetParameter);
if (propertyDescriptor != null) {
initializerStatements.add
(TranslationUtils.assignmentToBackingFieldFromParameter
@@ -1,12 +1,13 @@
package org.jetbrains.k2js.translate.initializer;
import com.google.dart.compiler.backend.js.ast.JsFunction;
import com.google.dart.compiler.backend.js.ast.JsScope;
import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.JetNamespace;
import org.jetbrains.k2js.translate.context.TranslationContext;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.functionWithScope;
/**
* @author Talanov Pavel
*/
@@ -16,15 +17,15 @@ public final class NamespaceInitializerTranslator extends AbstractInitializerTra
private final JetNamespace namespace;
public NamespaceInitializerTranslator(@NotNull JetNamespace namespace, @NotNull TranslationContext context) {
super(new JsScope(context.getScopeForElement(namespace),
"initializer " + namespace.getName()), context);
super(context.getScopeForElement(namespace).innerScope
("initializer " + namespace.getName()), context);
this.namespace = namespace;
}
@Override
@NotNull
protected JsFunction generateInitializerFunction() {
JsFunction result = JsFunction.getAnonymousFunctionWithScope(initializerMethodScope);
JsFunction result = functionWithScope(initializerMethodScope);
result.setBody(AstUtil.newBlock(translatePropertyAndAnonymousInitializers(namespace)));
return result;
}
@@ -1,13 +1,12 @@
package org.jetbrains.k2js.translate.operation;
import com.google.dart.compiler.backend.js.ast.JsExpression;
import com.google.dart.compiler.backend.js.ast.JsName;
import com.google.dart.compiler.backend.js.ast.JsNameRef;
import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.psi.JetUnaryExpression;
import org.jetbrains.jet.lang.types.expressions.OperatorConventions;
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.reference.AccessTranslator;
@@ -84,8 +83,8 @@ public abstract class IncrementTranslator extends AbstractTranslator {
private JsExpression asPostfixWithReassignment() {
// code fragment: expr(a++)
// generate: expr( (t1 = a, t2 = t1, a = t1.inc(), t2) )
TemporaryVariable t1 = declareTemporary(accessTranslator.translateAsGet());
TemporaryVariable t2 = declareTemporary(t1.nameReference());
TemporaryVariable t1 = context().declareTemporary(accessTranslator.translateAsGet());
TemporaryVariable t2 = context().declareTemporary(t1.nameReference());
JsExpression variableReassignment = variableReassignment(t1.nameReference());
return AstUtil.newSequence(t1.assignmentExpression(), t2.assignmentExpression(),
variableReassignment, t2.nameReference());
@@ -95,8 +94,8 @@ public abstract class IncrementTranslator extends AbstractTranslator {
private JsExpression asPostfixWithNoReassignment() {
// code fragment: expr(a++)
// generate: expr( (t1 = a, t2 = t1, t2.inc(), t1) )
TemporaryVariable t1 = declareTemporary(accessTranslator.translateAsGet());
TemporaryVariable t2 = declareTemporary(t1.nameReference());
TemporaryVariable t1 = context().declareTemporary(accessTranslator.translateAsGet());
TemporaryVariable t2 = context().declareTemporary(t1.nameReference());
JsExpression methodCall = operationExpression(t2.nameReference());
JsExpression returnedValue = t1.nameReference();
return AstUtil.newSequence(t1.assignmentExpression(), t2.assignmentExpression(), methodCall, returnedValue);
@@ -110,35 +109,4 @@ public abstract class IncrementTranslator extends AbstractTranslator {
@NotNull
abstract JsExpression operationExpression(@NotNull JsExpression receiver);
//TODO: consider moving into context
protected final class TemporaryVariable {
@NotNull
private final JsExpression assignmentExpression;
@NotNull
private final JsName variableName;
private TemporaryVariable(@NotNull JsExpression initExpression) {
this.variableName = context().enclosingScope().declareTemporary();
this.assignmentExpression = AstUtil.newAssignment(variableName.makeRef(), initExpression);
}
@NotNull
public JsNameRef nameReference() {
return variableName.makeRef();
}
@NotNull
public JsExpression assignmentExpression() {
return assignmentExpression;
}
}
@NotNull
public TemporaryVariable declareTemporary(@NotNull JsExpression initExpression) {
return new TemporaryVariable(initExpression);
}
}
@@ -19,17 +19,11 @@ import java.util.List;
*/
public final class ArrayAccessTranslator extends AccessTranslator {
public static ArrayAccessTranslator newInstance(@NotNull JetArrayAccessExpression expression,
@NotNull TranslationContext context) {
return new ArrayAccessTranslator(expression, context);
}
// public static JsExpression translateAsArrayGet(@NotNull JetArrayAccessExpression expression,
// @NotNull TranslationContext context) {
// return (new ArrayAccessTranslator(expression, context)).translateAsGet();
// }
@NotNull
private final JetArrayAccessExpression expression;
@NotNull
@@ -38,10 +38,9 @@ public class ReferenceTranslator extends AbstractTranslator {
@NotNull
//TODO: make this process simpler and clearer
public JsExpression translateSimpleName() {
tryResolveAsAliasReference();
tryResolveAsAlias();
tryResolveAsPropertyAccess();
tryResolveAsImplicitlyQualifiedExpression();
tryResolveAsLocalReference();
tryResolveAsReference();
if (result != null) {
return result;
}
@@ -49,7 +48,7 @@ public class ReferenceTranslator extends AbstractTranslator {
}
//TODO: refactor
private void tryResolveAsImplicitlyQualifiedExpression() {
private void tryResolveAsReference() {
if (alreadyResolved()) return;
DeclarationDescriptor referencedDescriptor =
@@ -61,9 +60,11 @@ public class ReferenceTranslator extends AbstractTranslator {
JsName referencedName = context().getNameForDescriptor(referencedDescriptor);
JsExpression implicitReceiver = getImplicitReceiver(referencedDescriptor, context());
if (implicitReceiver == null) return;
result = AstUtil.qualified(referencedName, implicitReceiver);
if (implicitReceiver != null) {
result = AstUtil.qualified(referencedName, implicitReceiver);
} else {
result = context().getNameForDescriptor(referencedDescriptor).makeRef();
}
}
@Nullable
@@ -79,7 +80,7 @@ public class ReferenceTranslator extends AbstractTranslator {
return context.declarations().getQualifier(referencedDescriptor);
}
private void tryResolveAsAliasReference() {
private void tryResolveAsAlias() {
//TODO: decide if this code is meaningful
if (alreadyResolved()) return;
@@ -103,23 +104,4 @@ public class ReferenceTranslator extends AbstractTranslator {
result = PropertyAccessTranslator.translateAsPropertyGetterCall(simpleName, context());
}
private void tryResolveAsLocalReference() {
if (alreadyResolved()) return;
String name = getReferencedName();
JsName localReferencedName = TranslationUtils.getLocalReferencedName(context(), name);
if (localReferencedName == null) return;
result = localReferencedName.makeRef();
}
@NotNull
private String getReferencedName() {
String name = simpleName.getReferencedName();
assert name != null : "SimpleNameExpression should reference a name";
return name;
}
}
@@ -272,4 +272,12 @@ public final class BindingUtils {
return (FunctionDescriptor) descriptorForReferenceExpression;
}
@NotNull
public static DeclarationDescriptor getDescriptorForElement(@NotNull BindingContext context,
@NotNull JetElement element) {
DeclarationDescriptor descriptor = context.get(BindingContext.DECLARATION_TO_DESCRIPTOR, element);
assert descriptor != null : element + " doesn't have a descriptor.";
return descriptor;
}
}
@@ -1,10 +1,16 @@
package org.jetbrains.k2js.translate.utils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.types.expressions.OperatorConventions;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* @author Talanov Pavel
*/
@@ -32,4 +38,24 @@ public final class DescriptorUtils {
public static boolean isConstructorDescriptor(@NotNull FunctionDescriptor descriptor) {
return (descriptor instanceof ConstructorDescriptor);
}
@NotNull
public static List<DeclarationDescriptor> getOwnDeclarations(@NotNull ClassDescriptor classDescriptor) {
Collection<DeclarationDescriptor> allDescriptors =
classDescriptor.getDefaultType().getMemberScope().getAllDescriptors();
return filterByOwner(classDescriptor, allDescriptors);
}
@NotNull
private static List<DeclarationDescriptor> filterByOwner(@NotNull DeclarationDescriptor ownerDescriptor,
@NotNull Collection<DeclarationDescriptor> allDescriptors) {
List<DeclarationDescriptor> resultingList = new ArrayList<DeclarationDescriptor>();
for (DeclarationDescriptor memberDescriptor : allDescriptors) {
if (memberDescriptor.getContainingDeclaration() == ownerDescriptor) {
resultingList.add(memberDescriptor);
}
}
return resultingList;
}
}
@@ -8,7 +8,7 @@ import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.k2js.translate.context.Namer;
import org.jetbrains.k2js.translate.context.NamingScope;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.general.Translation;
@@ -16,6 +16,7 @@ import java.util.ArrayList;
import java.util.List;
import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptorForOperationExpression;
import static org.jetbrains.k2js.translate.utils.BindingUtils.getPropertyDescriptor;
/**
* @author Talanov Pavel
@@ -36,13 +37,6 @@ public final class TranslationUtils {
return AstUtil.equals(expressionToCheck, nullLiteral);
}
@Nullable
public static JsName getLocalReferencedName(@NotNull TranslationContext context,
@NotNull String name) {
return context.enclosingScope().findExistingName(name);
}
@NotNull
public static List<JsExpression> translateArgumentList(@NotNull TranslationContext context,
@NotNull List<? extends ValueArgument> jetArguments) {
@@ -65,19 +59,19 @@ public final class TranslationUtils {
@NotNull
public static JsNameRef backingFieldReference(@NotNull TranslationContext context,
@NotNull JetProperty expression) {
JsName backingFieldName = getBackingFieldName(getPropertyName(expression), context);
return getThisQualifiedNameReference(context, backingFieldName);
PropertyDescriptor propertyDescriptor = getPropertyDescriptor(context.bindingContext(), expression);
return backingFieldReference(context, propertyDescriptor);
}
@NotNull
public static JsNameRef backingFieldReference(@NotNull TranslationContext context,
@NotNull PropertyDescriptor descriptor) {
JsName backingFieldName = getBackingFieldName(descriptor.getName(), context);
JsName backingFieldName = context.getNameForDescriptor(descriptor);
if (BindingUtils.isOwnedByClass(descriptor)) {
return getThisQualifiedNameReference(context, backingFieldName);
}
assert BindingUtils.isOwnedByNamespace(descriptor)
: "Only classes and namespaces may own descriptors";
: "Only classes and namespaces may own backing fields.";
JsNameRef qualifier = context.declarations().getQualifier(descriptor);
return AstUtil.qualified(backingFieldName, qualifier);
}
@@ -91,13 +85,6 @@ public final class TranslationUtils {
return propertyName;
}
@NotNull
static private JsName getBackingFieldName(@NotNull String propertyName,
@NotNull TranslationContext context) {
String backingFieldName = Namer.getKotlinBackingFieldName(propertyName);
return context.enclosingScope().findExistingName(backingFieldName);
}
@Nullable
public static JsExpression translateInitializerForProperty(@NotNull JetProperty declaration,
@NotNull TranslationContext context) {
@@ -220,4 +207,9 @@ public final class TranslationUtils {
return overloadedOperationReference;
}
@NotNull
public static JsFunction functionWithScope(@NotNull NamingScope scope) {
return JsFunction.getAnonymousFunctionWithScope(scope.jsScope());
}
}