Reorganise context structure, refactor
This commit is contained in:
Generated
+442
-353
File diff suppressed because it is too large
Load Diff
+6
-7
@@ -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);
|
||||
+12
-13
@@ -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);
|
||||
}
|
||||
|
||||
+14
-14
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -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
|
||||
|
||||
+5
-5
@@ -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();
|
||||
|
||||
+17
-9
@@ -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
|
||||
|
||||
+5
-4
@@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user