Finished work on namespaces.
This commit is contained in:
@@ -290,6 +290,7 @@ public class AstUtil {
|
||||
return new JsBinaryOperation(JsBinaryOperator.OR, op1, op2);
|
||||
}
|
||||
|
||||
//TODO
|
||||
public static void setQualifier(JsExpression selector, JsExpression receiver) {
|
||||
if (selector instanceof JsInvocation) {
|
||||
setQualifier(((JsInvocation) selector).getQualifier(), receiver);
|
||||
|
||||
@@ -149,6 +149,10 @@ public final class BindingUtils {
|
||||
return null;
|
||||
}
|
||||
|
||||
static public boolean belongsToNamespace(@NotNull BindingContext context, @NotNull JetProperty property) {
|
||||
return getPropertyDescriptor(context, property).getContainingDeclaration() instanceof NamespaceDescriptor;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static public ResolvedCall<?> getResolvedCall(@NotNull BindingContext context,
|
||||
@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.JetNamespace;
|
||||
|
||||
|
||||
//TODO: thing about redesigning this class
|
||||
public class InitializerGenerator {
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -79,5 +79,9 @@ public final class Namer {
|
||||
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.JsScope;
|
||||
import com.google.dart.compiler.backend.js.ast.JsStatement;
|
||||
import com.google.dart.compiler.util.AstUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.psi.JetDeclaration;
|
||||
import org.jetbrains.jet.lang.psi.JetNamespace;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Talanov Pavel
|
||||
*/
|
||||
@@ -28,4 +33,14 @@ public final class NamespaceInitializerVisitor extends AbstractInitializerVisito
|
||||
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 {
|
||||
|
||||
@NotNull
|
||||
public static NamespaceTranslator newInstance(@NotNull TranslationContext context) {
|
||||
return new NamespaceTranslator(context);
|
||||
private final JetNamespace namespace;
|
||||
@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);
|
||||
this.namespace = namespace;
|
||||
this.namespaceName = context.getNameForElement(namespace);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JsStatement translateNamespace(@NotNull JetNamespace namespace) {
|
||||
public JsStatement translateNamespace() {
|
||||
ClassDeclarationTranslator translator = new ClassDeclarationTranslator(translationContext(), namespace);
|
||||
translator.generateDeclarations();
|
||||
JsName declarationsObjectName = translator.getDeclarationsObjectName();
|
||||
JsBlock result = new JsBlock();
|
||||
JsInvocation namespaceDeclaration = namespaceCreateMethodInvocation(namespace);
|
||||
JsInvocation namespaceDeclaration = namespaceCreateMethodInvocation();
|
||||
namespaceDeclaration.getArguments().add(declarationsObjectName.makeRef());
|
||||
addMemberDeclarations(namespace, namespaceDeclaration);
|
||||
addMemberDeclarations(namespaceDeclaration);
|
||||
result.addStatement(translator.getDeclarationsStatement());
|
||||
result.addStatement(namespaceDeclarationStatement(namespace, namespaceDeclaration));
|
||||
result.addStatement(namespaceDeclarationStatement(namespaceDeclaration));
|
||||
result.addStatement(namespaceInitializeStatement());
|
||||
return result;
|
||||
}
|
||||
|
||||
private JsStatement namespaceInitializeStatement() {
|
||||
JsNameRef initializeMethodReference = Namer.initializeMethodReference();
|
||||
AstUtil.setQualifier(initializeMethodReference, namespaceName.makeRef());
|
||||
return AstUtil.newInvocation(initializeMethodReference).makeStmt();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsInvocation namespaceCreateMethodInvocation(@NotNull JetNamespace namespace) {
|
||||
private JsInvocation namespaceCreateMethodInvocation() {
|
||||
return AstUtil.newInvocation(Namer.namespaceCreationMethodReference());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsStatement namespaceDeclarationStatement(@NotNull JetNamespace namespace,
|
||||
@NotNull JsInvocation namespaceDeclaration) {
|
||||
private JsStatement namespaceDeclarationStatement(@NotNull JsInvocation namespaceDeclaration) {
|
||||
return AstUtil.newAssignmentStatement
|
||||
(translationContext().getNameForElement(namespace).makeRef(), namespaceDeclaration);
|
||||
}
|
||||
|
||||
private void addMemberDeclarations(@NotNull JetNamespace namespace,
|
||||
@NotNull JsInvocation jsNamespace) {
|
||||
JsObjectLiteral jsClassDescription = translateNamespaceMemberDeclarations(namespace);
|
||||
private void addMemberDeclarations(@NotNull JsInvocation jsNamespace) {
|
||||
JsObjectLiteral jsClassDescription = translateNamespaceMemberDeclarations();
|
||||
jsNamespace.getArguments().add(jsClassDescription);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsObjectLiteral translateNamespaceMemberDeclarations(@NotNull JetNamespace namespace) {
|
||||
private JsObjectLiteral translateNamespaceMemberDeclarations() {
|
||||
List<JsPropertyInitializer> propertyList = new ArrayList<JsPropertyInitializer>();
|
||||
propertyList.add(InitializerGenerator.generateInitializeMethod(namespace, translationContext()));
|
||||
propertyList.addAll(new DeclarationBodyVisitor().traverseNamespace(namespace,
|
||||
|
||||
@@ -92,7 +92,8 @@ public final class PropertyAccessTranslator extends AbstractTranslator {
|
||||
if (setterName == null) {
|
||||
return null;
|
||||
}
|
||||
return AstUtil.newInvocation(AstUtil.thisQualifiedReference(setterName));
|
||||
JsNameRef setterReference = Translation.generateCorrectReference(translationContext(), expression, setterName);
|
||||
return AstUtil.newInvocation(setterReference);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -32,10 +32,10 @@ public final class ReferenceProvider {
|
||||
//TODO
|
||||
@NotNull
|
||||
public JsNameRef generateCorrectReference() {
|
||||
if (requiresThisQualifier) {
|
||||
return AstUtil.thisQualifiedReference(referencedName);
|
||||
} else if (requiresNamespaceQualifier) {
|
||||
if (requiresNamespaceQualifier) {
|
||||
return context.getNamespaceQualifiedReference(referencedName);
|
||||
} else if (requiresThisQualifier) {
|
||||
return AstUtil.thisQualifiedReference(referencedName);
|
||||
}
|
||||
return referencedName.makeRef();
|
||||
}
|
||||
@@ -46,9 +46,8 @@ public final class ReferenceProvider {
|
||||
|
||||
private boolean requiresThisQualifier(@NotNull JetSimpleNameExpression expression) {
|
||||
JsName name = context.enclosingScope().findExistingName(referencedName.getIdent());
|
||||
boolean isNamespaceMember = requiresNamespaceQualifier;
|
||||
boolean isClassMember = context.classScope().ownsName(name);
|
||||
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.jet.lang.psi.JetExpression;
|
||||
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.resolve.BindingContext;
|
||||
import org.jetbrains.k2js.declarations.Declarations;
|
||||
@@ -32,8 +33,9 @@ public final class Translation {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
static public NamespaceTranslator namespaceTranslator(@NotNull TranslationContext context) {
|
||||
return NamespaceTranslator.newInstance(context);
|
||||
static public JsStatement translateNamespace(@NotNull JetNamespace namespace,
|
||||
@NotNull TranslationContext context) {
|
||||
return NamespaceTranslator.translate(context, namespace);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -76,10 +78,19 @@ public final class Translation {
|
||||
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,
|
||||
@NotNull Declarations declarations, @NotNull JetNamespace namespace) {
|
||||
JsBlock block = result.getFragmentBlock(0);
|
||||
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
|
||||
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
|
||||
|
||||
@@ -89,12 +89,6 @@ public class KotlinLibTest extends IncludeLibraryTest {
|
||||
new RhinoFunctionResultChecker("test", true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void namespacePropertyAccess() throws Exception {
|
||||
runRhinoTest(Arrays.asList(kotlinLibraryPath(), cases("namespace2.js")),
|
||||
new RhinoFunctionResultChecker("test", true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isSameType() throws Exception {
|
||||
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