Finished work on namespaces.
This commit is contained in:
@@ -290,6 +290,7 @@ public class AstUtil {
|
|||||||
return new JsBinaryOperation(JsBinaryOperator.OR, op1, op2);
|
return new JsBinaryOperation(JsBinaryOperator.OR, op1, op2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO
|
||||||
public static void setQualifier(JsExpression selector, JsExpression receiver) {
|
public static void setQualifier(JsExpression selector, JsExpression receiver) {
|
||||||
if (selector instanceof JsInvocation) {
|
if (selector instanceof JsInvocation) {
|
||||||
setQualifier(((JsInvocation) selector).getQualifier(), receiver);
|
setQualifier(((JsInvocation) selector).getQualifier(), receiver);
|
||||||
|
|||||||
@@ -149,6 +149,10 @@ public final class BindingUtils {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static public boolean belongsToNamespace(@NotNull BindingContext context, @NotNull JetProperty property) {
|
||||||
|
return getPropertyDescriptor(context, property).getContainingDeclaration() instanceof NamespaceDescriptor;
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
static public ResolvedCall<?> getResolvedCall(@NotNull BindingContext context,
|
static public ResolvedCall<?> getResolvedCall(@NotNull BindingContext context,
|
||||||
@NotNull JetExpression expression) {
|
@NotNull JetExpression expression) {
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ import org.jetbrains.jet.lang.psi.JetClass;
|
|||||||
import org.jetbrains.jet.lang.psi.JetNamedDeclaration;
|
import org.jetbrains.jet.lang.psi.JetNamedDeclaration;
|
||||||
import org.jetbrains.jet.lang.psi.JetNamespace;
|
import org.jetbrains.jet.lang.psi.JetNamespace;
|
||||||
|
|
||||||
|
|
||||||
|
//TODO: thing about redesigning this class
|
||||||
public class InitializerGenerator {
|
public class InitializerGenerator {
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
|||||||
@@ -79,5 +79,9 @@ public final class Namer {
|
|||||||
return AstUtil.newQualifiedNameRef("isType");
|
return AstUtil.newQualifiedNameRef("isType");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static JsNameRef initializeMethodReference() {
|
||||||
|
return AstUtil.newQualifiedNameRef("initialize");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,10 +2,15 @@ package org.jetbrains.k2js.translate;
|
|||||||
|
|
||||||
import com.google.dart.compiler.backend.js.ast.JsFunction;
|
import com.google.dart.compiler.backend.js.ast.JsFunction;
|
||||||
import com.google.dart.compiler.backend.js.ast.JsScope;
|
import com.google.dart.compiler.backend.js.ast.JsScope;
|
||||||
|
import com.google.dart.compiler.backend.js.ast.JsStatement;
|
||||||
import com.google.dart.compiler.util.AstUtil;
|
import com.google.dart.compiler.util.AstUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetDeclaration;
|
||||||
import org.jetbrains.jet.lang.psi.JetNamespace;
|
import org.jetbrains.jet.lang.psi.JetNamespace;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Talanov Pavel
|
* @author Talanov Pavel
|
||||||
*/
|
*/
|
||||||
@@ -28,4 +33,14 @@ public final class NamespaceInitializerVisitor extends AbstractInitializerVisito
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NotNull
|
||||||
|
public List<JsStatement> visitNamespace(@NotNull JetNamespace expression, @NotNull TranslationContext context) {
|
||||||
|
List<JsStatement> initializerStatements = new ArrayList<JsStatement>();
|
||||||
|
for (JetDeclaration declaration : expression.getDeclarations()) {
|
||||||
|
initializerStatements.addAll(declaration.accept(this, context));
|
||||||
|
}
|
||||||
|
return initializerStatements;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,48 +14,61 @@ import java.util.List;
|
|||||||
public final class NamespaceTranslator extends AbstractTranslator {
|
public final class NamespaceTranslator extends AbstractTranslator {
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static NamespaceTranslator newInstance(@NotNull TranslationContext context) {
|
private final JetNamespace namespace;
|
||||||
return new NamespaceTranslator(context);
|
@NotNull
|
||||||
|
private final JsName namespaceName;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static JsStatement translate(@NotNull TranslationContext context,
|
||||||
|
@NotNull JetNamespace namespace) {
|
||||||
|
return (new NamespaceTranslator(context, namespace)).translateNamespace();
|
||||||
}
|
}
|
||||||
|
|
||||||
private NamespaceTranslator(@NotNull TranslationContext context) {
|
private NamespaceTranslator(@NotNull TranslationContext context, @NotNull JetNamespace namespace) {
|
||||||
super(context);
|
super(context);
|
||||||
|
this.namespace = namespace;
|
||||||
|
this.namespaceName = context.getNameForElement(namespace);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public JsStatement translateNamespace(@NotNull JetNamespace namespace) {
|
public JsStatement translateNamespace() {
|
||||||
ClassDeclarationTranslator translator = new ClassDeclarationTranslator(translationContext(), namespace);
|
ClassDeclarationTranslator translator = new ClassDeclarationTranslator(translationContext(), namespace);
|
||||||
translator.generateDeclarations();
|
translator.generateDeclarations();
|
||||||
JsName declarationsObjectName = translator.getDeclarationsObjectName();
|
JsName declarationsObjectName = translator.getDeclarationsObjectName();
|
||||||
JsBlock result = new JsBlock();
|
JsBlock result = new JsBlock();
|
||||||
JsInvocation namespaceDeclaration = namespaceCreateMethodInvocation(namespace);
|
JsInvocation namespaceDeclaration = namespaceCreateMethodInvocation();
|
||||||
namespaceDeclaration.getArguments().add(declarationsObjectName.makeRef());
|
namespaceDeclaration.getArguments().add(declarationsObjectName.makeRef());
|
||||||
addMemberDeclarations(namespace, namespaceDeclaration);
|
addMemberDeclarations(namespaceDeclaration);
|
||||||
result.addStatement(translator.getDeclarationsStatement());
|
result.addStatement(translator.getDeclarationsStatement());
|
||||||
result.addStatement(namespaceDeclarationStatement(namespace, namespaceDeclaration));
|
result.addStatement(namespaceDeclarationStatement(namespaceDeclaration));
|
||||||
|
result.addStatement(namespaceInitializeStatement());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private JsStatement namespaceInitializeStatement() {
|
||||||
|
JsNameRef initializeMethodReference = Namer.initializeMethodReference();
|
||||||
|
AstUtil.setQualifier(initializeMethodReference, namespaceName.makeRef());
|
||||||
|
return AstUtil.newInvocation(initializeMethodReference).makeStmt();
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private JsInvocation namespaceCreateMethodInvocation(@NotNull JetNamespace namespace) {
|
private JsInvocation namespaceCreateMethodInvocation() {
|
||||||
return AstUtil.newInvocation(Namer.namespaceCreationMethodReference());
|
return AstUtil.newInvocation(Namer.namespaceCreationMethodReference());
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private JsStatement namespaceDeclarationStatement(@NotNull JetNamespace namespace,
|
private JsStatement namespaceDeclarationStatement(@NotNull JsInvocation namespaceDeclaration) {
|
||||||
@NotNull JsInvocation namespaceDeclaration) {
|
|
||||||
return AstUtil.newAssignmentStatement
|
return AstUtil.newAssignmentStatement
|
||||||
(translationContext().getNameForElement(namespace).makeRef(), namespaceDeclaration);
|
(translationContext().getNameForElement(namespace).makeRef(), namespaceDeclaration);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addMemberDeclarations(@NotNull JetNamespace namespace,
|
private void addMemberDeclarations(@NotNull JsInvocation jsNamespace) {
|
||||||
@NotNull JsInvocation jsNamespace) {
|
JsObjectLiteral jsClassDescription = translateNamespaceMemberDeclarations();
|
||||||
JsObjectLiteral jsClassDescription = translateNamespaceMemberDeclarations(namespace);
|
|
||||||
jsNamespace.getArguments().add(jsClassDescription);
|
jsNamespace.getArguments().add(jsClassDescription);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private JsObjectLiteral translateNamespaceMemberDeclarations(@NotNull JetNamespace namespace) {
|
private JsObjectLiteral translateNamespaceMemberDeclarations() {
|
||||||
List<JsPropertyInitializer> propertyList = new ArrayList<JsPropertyInitializer>();
|
List<JsPropertyInitializer> propertyList = new ArrayList<JsPropertyInitializer>();
|
||||||
propertyList.add(InitializerGenerator.generateInitializeMethod(namespace, translationContext()));
|
propertyList.add(InitializerGenerator.generateInitializeMethod(namespace, translationContext()));
|
||||||
propertyList.addAll(new DeclarationBodyVisitor().traverseNamespace(namespace,
|
propertyList.addAll(new DeclarationBodyVisitor().traverseNamespace(namespace,
|
||||||
|
|||||||
@@ -92,7 +92,8 @@ public final class PropertyAccessTranslator extends AbstractTranslator {
|
|||||||
if (setterName == null) {
|
if (setterName == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return AstUtil.newInvocation(AstUtil.thisQualifiedReference(setterName));
|
JsNameRef setterReference = Translation.generateCorrectReference(translationContext(), expression, setterName);
|
||||||
|
return AstUtil.newInvocation(setterReference);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
|||||||
@@ -32,10 +32,10 @@ public final class ReferenceProvider {
|
|||||||
//TODO
|
//TODO
|
||||||
@NotNull
|
@NotNull
|
||||||
public JsNameRef generateCorrectReference() {
|
public JsNameRef generateCorrectReference() {
|
||||||
if (requiresThisQualifier) {
|
if (requiresNamespaceQualifier) {
|
||||||
return AstUtil.thisQualifiedReference(referencedName);
|
|
||||||
} else if (requiresNamespaceQualifier) {
|
|
||||||
return context.getNamespaceQualifiedReference(referencedName);
|
return context.getNamespaceQualifiedReference(referencedName);
|
||||||
|
} else if (requiresThisQualifier) {
|
||||||
|
return AstUtil.thisQualifiedReference(referencedName);
|
||||||
}
|
}
|
||||||
return referencedName.makeRef();
|
return referencedName.makeRef();
|
||||||
}
|
}
|
||||||
@@ -46,9 +46,8 @@ public final class ReferenceProvider {
|
|||||||
|
|
||||||
private boolean requiresThisQualifier(@NotNull JetSimpleNameExpression expression) {
|
private boolean requiresThisQualifier(@NotNull JetSimpleNameExpression expression) {
|
||||||
JsName name = context.enclosingScope().findExistingName(referencedName.getIdent());
|
JsName name = context.enclosingScope().findExistingName(referencedName.getIdent());
|
||||||
boolean isNamespaceMember = requiresNamespaceQualifier;
|
|
||||||
boolean isClassMember = context.classScope().ownsName(name);
|
boolean isClassMember = context.classScope().ownsName(name);
|
||||||
boolean isBackingFieldAccess = expression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER;
|
boolean isBackingFieldAccess = expression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER;
|
||||||
return (isNamespaceMember && !isClassMember) || isClassMember || isBackingFieldAccess;
|
return isClassMember || isBackingFieldAccess;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import com.google.dart.compiler.util.AstUtil;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||||
import org.jetbrains.jet.lang.psi.JetNamespace;
|
import org.jetbrains.jet.lang.psi.JetNamespace;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
|
||||||
import org.jetbrains.jet.lang.psi.JetWhenExpression;
|
import org.jetbrains.jet.lang.psi.JetWhenExpression;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
import org.jetbrains.k2js.declarations.Declarations;
|
import org.jetbrains.k2js.declarations.Declarations;
|
||||||
@@ -32,8 +33,9 @@ public final class Translation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
static public NamespaceTranslator namespaceTranslator(@NotNull TranslationContext context) {
|
static public JsStatement translateNamespace(@NotNull JetNamespace namespace,
|
||||||
return NamespaceTranslator.newInstance(context);
|
@NotNull TranslationContext context) {
|
||||||
|
return NamespaceTranslator.translate(context, namespace);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -76,10 +78,19 @@ public final class Translation {
|
|||||||
return WhenTranslator.translateWhenExpression(expression, context);
|
return WhenTranslator.translateWhenExpression(expression, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
static public JsNameRef generateCorrectReference(@NotNull TranslationContext context,
|
||||||
|
@NotNull JetSimpleNameExpression expression,
|
||||||
|
@NotNull JsName referencedName) {
|
||||||
|
return (new ReferenceProvider(context, expression, referencedName)).generateCorrectReference();
|
||||||
|
}
|
||||||
|
|
||||||
public static void generateAst(@NotNull JsProgram result, @NotNull BindingContext bindingContext,
|
public static void generateAst(@NotNull JsProgram result, @NotNull BindingContext bindingContext,
|
||||||
@NotNull Declarations declarations, @NotNull JetNamespace namespace) {
|
@NotNull Declarations declarations, @NotNull JetNamespace namespace) {
|
||||||
JsBlock block = result.getFragmentBlock(0);
|
JsBlock block = result.getFragmentBlock(0);
|
||||||
TranslationContext context = TranslationContext.rootContext(result, bindingContext, declarations);
|
TranslationContext context = TranslationContext.rootContext(result, bindingContext, declarations);
|
||||||
block.addStatement(Translation.namespaceTranslator(context).translateNamespace(namespace));
|
block.addStatement(Translation.translateNamespace(namespace, context));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,11 @@ public class TranslatorVisitor<T> extends JetVisitor<T, TranslationContext> {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
protected JsNameRef backingFieldReference(@NotNull JetProperty expression, @NotNull TranslationContext context) {
|
protected JsNameRef backingFieldReference(@NotNull JetProperty expression, @NotNull TranslationContext context) {
|
||||||
return AstUtil.thisQualifiedReference(getBackingFieldName(getPropertyName(expression), context));
|
JsName backingFieldName = getBackingFieldName(getPropertyName(expression), context);
|
||||||
|
if (BindingUtils.belongsToNamespace(context.bindingContext(), expression)) {
|
||||||
|
return context.getNamespaceQualifiedReference(backingFieldName);
|
||||||
|
}
|
||||||
|
return AstUtil.thisQualifiedReference(backingFieldName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
|||||||
@@ -89,12 +89,6 @@ public class KotlinLibTest extends IncludeLibraryTest {
|
|||||||
new RhinoFunctionResultChecker("test", true));
|
new RhinoFunctionResultChecker("test", true));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void namespacePropertyAccess() throws Exception {
|
|
||||||
runRhinoTest(Arrays.asList(kotlinLibraryPath(), cases("namespace2.js")),
|
|
||||||
new RhinoFunctionResultChecker("test", true));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void isSameType() throws Exception {
|
public void isSameType() throws Exception {
|
||||||
runRhinoTest(Arrays.asList(kotlinLibraryPath(), cases("isSameType.js")),
|
runRhinoTest(Arrays.asList(kotlinLibraryPath(), cases("isSameType.js")),
|
||||||
|
|||||||
@@ -1,35 +0,0 @@
|
|||||||
{
|
|
||||||
classes = function(){
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
();
|
|
||||||
foo = Namespace.create(classes, {initialize:function(){
|
|
||||||
this.$b = 0
|
|
||||||
}
|
|
||||||
, set_b:function(tmp$0){
|
|
||||||
this.$b = tmp$0;
|
|
||||||
}
|
|
||||||
, get_b:function(){
|
|
||||||
return this.$b;
|
|
||||||
}
|
|
||||||
, loop:function(times){
|
|
||||||
while (times > 0) {
|
|
||||||
var u = function(){
|
|
||||||
return this.set_b(this.get_b() + 1);
|
|
||||||
}
|
|
||||||
;
|
|
||||||
u(times--);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
, box:function(){
|
|
||||||
this.loop(5);
|
|
||||||
return this.get_b() === 5;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function test() {
|
|
||||||
return foo.box()
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user