KT-2298 js inter-module communication

This commit is contained in:
develar
2012-06-21 14:24:22 +04:00
parent 622235b172
commit 63e41b771f
32 changed files with 347 additions and 233 deletions
@@ -22,6 +22,7 @@ import com.google.common.base.Predicates;
import com.google.common.collect.Iterables;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.psi.PsiFile;
import jet.Function0;
import org.jetbrains.annotations.NotNull;
@@ -40,6 +41,7 @@ import org.jetbrains.k2js.config.*;
import org.jetbrains.k2js.facade.K2JSTranslator;
import org.jetbrains.k2js.facade.MainCallParameters;
import java.io.File;
import java.util.List;
import static org.jetbrains.jet.cli.common.messages.CompilerMessageLocation.NO_LOCATION;
@@ -101,7 +103,6 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments, K2JSCompile
return ExitCode.INTERNAL_ERROR;
}
MainCallParameters mainCallParameters = arguments.createMainCallParameters();
return translateAndGenerateOutputFile(mainCallParameters, messageCollector, environmentForJS, config, outputFile);
}
@@ -151,10 +152,11 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments, K2JSCompile
@NotNull
private static Config getConfig(@NotNull K2JSCompilerArguments arguments, @NotNull Project project) {
EcmaVersion ecmaVersion = EcmaVersion.fromString(arguments.target);
String moduleId = FileUtil.getNameWithoutExtension(new File(arguments.outputFile));
if (arguments.libraryFiles == null) {
// lets discover the JS library definitions on the classpath
return new ClassPathLibraryDefintionsConfig(project, ecmaVersion);
return new ClassPathLibraryDefintionsConfig(project, moduleId, ecmaVersion);
}
return new LibrarySourcesConfig(project, arguments.libraryFiles, ecmaVersion);
return new LibrarySourcesConfig(project, moduleId, arguments.libraryFiles, ecmaVersion);
}
}
@@ -174,10 +174,13 @@ public final class K2JSCompiler implements TranslatingCompiler {
THashSet<Module> modules = new THashSet<Module>();
collectModuleDependencies(module, modules);
if (!modules.isEmpty()) {
VirtualFile[] files = CompilerManager.getInstance(module.getProject()).createModulesCompileScope(
modules.toArray(new Module[modules.size()]), false).getFiles(JetFileType.INSTANCE, true);
for (VirtualFile file : files) {
sb.append(file.getPath()).append(',');
for (Module dependency : modules) {
sb.append('@').append(dependency.getName()).append(',');
VirtualFile[] files = CompilerManager.getInstance(module.getProject()).createModuleCompileScope(dependency, false)
.getFiles(JetFileType.INSTANCE, true);
for (VirtualFile file : files) {
sb.append(file.getPath()).append(',');
}
}
}
@@ -28,6 +28,6 @@ import static org.jetbrains.jet.plugin.project.JsModuleDetector.getLibLocationAn
*/
public final class IDEAConfig extends LibrarySourcesConfig {
public IDEAConfig(@NotNull Project project) {
super(project, getLibLocationAndTargetForProject(project).first, EcmaVersion.defaultVersion());
super(project, "default", getLibLocationAndTargetForProject(project).first, EcmaVersion.defaultVersion());
}
}
@@ -42,7 +42,7 @@ public abstract class SingleFileTranslationTest extends BasicTest {
runFunctionOutputTest(EcmaVersion.all(), kotlinFilename, namespaceName, functionName, expectedResult);
}
protected void runFunctionOutputTest(@NotNull EnumSet<EcmaVersion> ecmaVersions, @NotNull String kotlinFilename,
protected void runFunctionOutputTest(@NotNull Iterable<EcmaVersion> ecmaVersions, @NotNull String kotlinFilename,
@NotNull String namespaceName,
@NotNull String functionName,
@NotNull Object expectedResult) throws Exception {
@@ -50,7 +50,7 @@ public abstract class SingleFileTranslationTest extends BasicTest {
runRhinoTests(kotlinFilename, ecmaVersions, new RhinoFunctionResultChecker(namespaceName, functionName, expectedResult));
}
public void checkFooBoxIsTrue(@NotNull String filename, @NotNull EnumSet<EcmaVersion> ecmaVersions) throws Exception {
public void checkFooBoxIsTrue(@NotNull String filename, @NotNull Iterable<EcmaVersion> ecmaVersions) throws Exception {
runFunctionOutputTest(ecmaVersions, filename, "foo", "box", true);
}
@@ -58,7 +58,7 @@ public abstract class SingleFileTranslationTest extends BasicTest {
checkFooBoxIsTrue(getTestName(true) + ".kt", EcmaVersion.all());
}
protected void fooBoxTest(@NotNull EnumSet<EcmaVersion> ecmaVersions) throws Exception {
protected void fooBoxTest(@NotNull Iterable<EcmaVersion> ecmaVersions) throws Exception {
checkFooBoxIsTrue(getTestName(true) + ".kt", ecmaVersions);
}
@@ -84,7 +84,7 @@ public abstract class SingleFileTranslationTest extends BasicTest {
runRhinoTests(kotlinFilename, ecmaVersions, new RhinoSystemOutputChecker(expectedResult));
}
protected void performTestWithMain(@NotNull EnumSet<EcmaVersion> ecmaVersions,
protected void performTestWithMain(@NotNull Iterable<EcmaVersion> ecmaVersions,
@NotNull String testName,
@NotNull String testId,
@NotNull String... args) throws Exception {
@@ -41,7 +41,7 @@ public final class TestConfig extends Config {
private /*var*/ List<JetFile> jsLibFiles = null;
public TestConfig(@NotNull Project project, @NotNull EcmaVersion version) {
super(project, version);
super(project, "main", version);
}
@NotNull
@@ -39,11 +39,6 @@ class RhinoFunctionManager {
this.functionName = functionName;
}
@NotNull
public String getFunctionName() {
return functionName;
}
private Script compileScript(int optimizationLevel) {
long startNano = System.nanoTime();
Context context = Context.enter();
@@ -17,6 +17,7 @@
package org.jetbrains.k2js.test.rhino;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.k2js.translate.context.Namer;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.Scriptable;
@@ -59,10 +60,14 @@ public class RhinoFunctionResultChecker implements RhinoResultChecker {
}
private String functionCallString() {
String result = functionName + "()";
StringBuilder sb = new StringBuilder();
if (namespaceName != null) {
result = "Kotlin.defs." + namespaceName + "." + result;
sb.append("Kotlin.modules.main");
if (namespaceName != Namer.getRootNamespaceName()) {
sb.append('.').append(namespaceName);
}
sb.append('.');
}
return result;
return sb.append(functionName).append("()").toString();
}
}
@@ -26,7 +26,6 @@ import org.jetbrains.k2js.test.BasicTest;
import org.mozilla.javascript.*;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.List;
import java.util.Map;
@@ -49,12 +48,7 @@ public final class RhinoUtils {
new Supplier<String>() {
@Override
public String get() {
try {
return FileUtil.loadFile(new File(BasicTest.JSLINT_LIB));
}
catch (IOException e) {
throw new RuntimeException(e);
}
return fileToString(BasicTest.JSLINT_LIB);
}
},
"JSLINT"
@@ -64,15 +58,19 @@ public final class RhinoUtils {
}
private static String fileToString(String file) {
try {
return FileUtil.loadFile(new File(file));
}
catch (IOException e) {
throw new RuntimeException(e);
}
}
private static void runFileWithRhino(@NotNull String inputFile,
@NotNull Context context,
@NotNull Scriptable scope) throws Exception {
FileReader reader = new FileReader(inputFile);
try {
context.evaluateReader(scope, reader, inputFile, 1, null);
} finally {
reader.close();
}
context.evaluateString(scope, fileToString(inputFile), inputFile, 1, null);
}
public static void runRhinoTest(@NotNull List<String> fileNames,
@@ -18,7 +18,6 @@ package org.jetbrains.k2js.analyze;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Sets;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
@@ -39,10 +38,10 @@ import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
import org.jetbrains.k2js.config.Config;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
/**
* @author Pavel Talanov
@@ -125,7 +124,7 @@ public final class AnalyzerFacadeForJS {
@NotNull
public static Collection<JetFile> withJsLibAdded(@NotNull Collection<JetFile> files, @NotNull Config config) {
Set<JetFile> allFiles = Sets.newHashSet();
Collection<JetFile> allFiles = new ArrayList<JetFile>();
allFiles.addAll(files);
allFiles.addAll(config.getLibFiles());
return allFiles;
@@ -28,8 +28,8 @@ import java.util.*;
public class ClassPathLibraryDefintionsConfig extends Config {
public static final String META_INF_SERVICES_FILE = "META-INF/services/org.jetbrains.kotlin.js.libraryDefinitions";
public ClassPathLibraryDefintionsConfig(@NotNull Project project, @NotNull EcmaVersion version) {
super(project, version);
public ClassPathLibraryDefintionsConfig(@NotNull Project project, @NotNull String moduleId, @NotNull EcmaVersion version) {
super(project, moduleId, version);
}
@NotNull
@@ -34,7 +34,7 @@ public abstract class Config {
@NotNull
public static Config getEmptyConfig(@NotNull Project project, @NotNull EcmaVersion ecmaVersion) {
return new Config(project, ecmaVersion) {
return new Config(project, "main", ecmaVersion) {
@NotNull
@Override
protected List<JetFile> generateLibFiles() {
@@ -117,9 +117,13 @@ public abstract class Config {
@NotNull
private final EcmaVersion target;
public Config(@NotNull Project project, @NotNull EcmaVersion ecmaVersion) {
@NotNull
private final String moduleId;
public Config(@NotNull Project project, @NotNull String moduleId, @NotNull EcmaVersion ecmaVersion) {
this.project = project;
this.target = ecmaVersion;
this.moduleId = moduleId;
}
@NotNull
@@ -132,6 +136,11 @@ public abstract class Config {
return target;
}
@NotNull
public String getModuleId() {
return moduleId;
}
@NotNull
protected abstract List<JetFile> generateLibFiles();
@@ -39,13 +39,17 @@ import java.util.zip.ZipFile;
* @author Pavel Talanov
*/
public class LibrarySourcesConfig extends Config {
public static final Key<Boolean> EXTERNAL_LIB = new Key<Boolean>("externalLib");
public static final Key<String> EXTERNAL_MODULE_NAME = new Key<String>("externalModule");
public static final String UNKNOWN_EXTERNAL_MODULE_NAME = "<unknown>";
@Nullable
private final String[] files;
public LibrarySourcesConfig(@NotNull Project project, @Nullable String[] files, @NotNull EcmaVersion ecmaVersion) {
super(project, ecmaVersion);
public LibrarySourcesConfig(@NotNull Project project,
@NotNull String moduleId,
@Nullable String[] files,
@NotNull EcmaVersion ecmaVersion) {
super(project, moduleId, ecmaVersion);
this.files = files;
}
@@ -57,16 +61,22 @@ public class LibrarySourcesConfig extends Config {
}
List<JetFile> jetFiles = new ArrayList<JetFile>();
String moduleName = UNKNOWN_EXTERNAL_MODULE_NAME;
for (String path : files) {
File file = new File(path);
try {
String name = file.getName();
if (path.charAt(0) == '@') {
moduleName = path.substring(1);
continue;
}
if (name.endsWith(".jar") || name.endsWith(".zip")) {
jetFiles.addAll(readZip(file));
}
else {
JetFile psiFile = JetFileUtils.createPsiFile(path, FileUtil.loadFile(file), getProject());
psiFile.putUserData(EXTERNAL_LIB, true);
psiFile.putUserData(EXTERNAL_MODULE_NAME, moduleName);
jetFiles.add(psiFile);
}
}
@@ -98,7 +108,7 @@ public class LibrarySourcesConfig extends Config {
InputStream stream = file.getInputStream(entry);
String text = FileUtil.loadTextAndClose(stream);
JetFile jetFile = JetFileUtils.createPsiFile(entry.getName(), text, getProject());
jetFile.putUserData(EXTERNAL_LIB, true);
jetFile.putUserData(EXTERNAL_MODULE_NAME, UNKNOWN_EXTERNAL_MODULE_NAME);
result.add(jetFile);
}
}
@@ -32,7 +32,6 @@ import org.jetbrains.k2js.utils.JetFileUtils;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import static org.jetbrains.k2js.facade.FacadeUtils.parseString;
@@ -96,7 +95,7 @@ public final class K2JSTranslator {
throws TranslationException {
JetStandardLibrary.initialize(config.getProject());
BindingContext bindingContext = AnalyzerFacadeForJS.analyzeFilesAndCheckErrors(filesToTranslate, config);
return Translation.generateAst(bindingContext, filesToTranslate, mainCallParameters, config.getTarget(), rawStatements);
return Translation.generateAst(bindingContext, filesToTranslate, mainCallParameters, config, rawStatements);
}
@NotNull
@@ -32,14 +32,13 @@ public final class Namer {
private static final String INITIALIZE_METHOD_NAME = "initialize";
private static final String CLASS_OBJECT_NAME = "createClass";
private static final String TRAIT_OBJECT_NAME = "createTrait";
private static final String NAMESPACE_OBJECT_NAME = "createNamespace";
private static final String OBJECT_OBJECT_NAME = "createObject";
private static final String SETTER_PREFIX = "set_";
private static final String GETTER_PREFIX = "get_";
private static final String BACKING_FIELD_PREFIX = "$";
private static final String SUPER_METHOD_NAME = "super_init";
private static final String KOTLIN_OBJECT_NAME = "Kotlin";
private static final String ROOT_NAMESPACE = "Root";
private static final String ROOT_NAMESPACE = "_";
private static final String RECEIVER_PARAMETER_NAME = "receiver";
private static final String CLASSES_OBJECT_NAME = "classes";
private static final String THROW_NPE_FUN_NAME = "throwNPE";
@@ -112,7 +111,7 @@ public final class Namer {
@NotNull
private final JsName traitName;
@NotNull
private final JsName namespaceName;
private final JsExpression definePackage;
@NotNull
private final JsName objectName;
@@ -129,7 +128,9 @@ public final class Namer {
kotlinName = rootScope.declareName(KOTLIN_OBJECT_NAME);
kotlinScope = new JsScope(rootScope, "Kotlin standard object");
traitName = kotlinScope.declareName(TRAIT_OBJECT_NAME);
namespaceName = kotlinScope.declareName(NAMESPACE_OBJECT_NAME);
definePackage = kotlin("definePackage");
className = kotlinScope.declareName(CLASS_OBJECT_NAME);
objectName = kotlinScope.declareName(OBJECT_OBJECT_NAME);
@@ -151,8 +152,8 @@ public final class Namer {
}
@NotNull
public JsExpression namespaceCreationMethodReference() {
return kotlin(namespaceName);
public JsExpression packageDefinitionMethodReference() {
return definePackage;
}
@NotNull
@@ -169,14 +170,17 @@ public final class Namer {
@NotNull
private JsExpression kotlin(@NotNull JsName name) {
JsNameRef reference = name.makeRef();
reference.setQualifier(kotlinName.makeRef());
return reference;
return kotlin(name.makeRef());
}
@NotNull
public JsExpression kotlin(@NotNull String name) {
return kotlin(kotlinScope.declareName(name));
}
@NotNull
private JsExpression kotlin(@NotNull JsExpression reference) {
setQualifier(reference, kotlinName.makeRef());
setQualifier(reference, kotlinObject());
return reference;
}
@@ -18,13 +18,17 @@ package org.jetbrains.k2js.translate.context;
import com.google.common.collect.Maps;
import com.google.dart.compiler.backend.js.ast.*;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
import org.jetbrains.k2js.config.EcmaVersion;
import org.jetbrains.k2js.config.LibrarySourcesConfig;
import org.jetbrains.k2js.translate.context.generator.Generator;
import org.jetbrains.k2js.translate.context.generator.Rule;
import org.jetbrains.k2js.translate.intrinsic.Intrinsics;
@@ -105,6 +109,11 @@ public final class StaticContext {
return ecmaVersion == EcmaVersion.v5;
}
@NotNull
public EcmaVersion getEcmaVersion() {
return ecmaVersion;
}
@NotNull
public JsProgram getProgram() {
return program;
@@ -179,8 +188,16 @@ public final class StaticContext {
if (!(descriptor instanceof NamespaceDescriptor)) {
return null;
}
String nameForNamespace = getNameForNamespace((NamespaceDescriptor) descriptor);
return getRootScope().declareUnobfuscatableName(nameForNamespace);
String name;
if (DescriptorUtils.isRootNamespace((NamespaceDescriptor) descriptor)) {
name = Namer.getRootNamespaceName();
}
else {
name = descriptor.getName().getName();
}
return getRootScope().declareUnobfuscatableName(name);
}
};
Rule<JsName> memberDeclarationsInsideParentsScope = new Rule<JsName>() {
@@ -385,14 +402,50 @@ public final class StaticContext {
Rule<JsNameRef> namespaceLevelDeclarationsHaveEnclosingNamespacesNamesAsQualifier = new Rule<JsNameRef>() {
@Override
public JsNameRef apply(@NotNull DeclarationDescriptor descriptor) {
DeclarationDescriptor containingDeclaration = getContainingDeclaration(descriptor);
if (!(containingDeclaration instanceof NamespaceDescriptor)) {
DeclarationDescriptor containingDescriptor = getContainingDeclaration(descriptor);
if (!(containingDescriptor instanceof NamespaceDescriptor)) {
return null;
}
JsName containingDeclarationName = getNameForDescriptor(containingDeclaration);
JsNameRef qualifier = containingDeclarationName.makeRef();
qualifier.setQualifier(getQualifierForDescriptor(containingDeclaration));
return qualifier;
final JsNameRef result = new JsNameRef(getNameForDescriptor(containingDescriptor));
if (DescriptorUtils.isRootNamespace((NamespaceDescriptor) containingDescriptor)) {
return result;
}
JsNameRef qualifier = result;
while ((containingDescriptor = getContainingDeclaration(containingDescriptor)) instanceof NamespaceDescriptor &&
!DescriptorUtils.isRootNamespace((NamespaceDescriptor) containingDescriptor)) {
JsNameRef ref = getNameForDescriptor(containingDescriptor).makeRef();
qualifier.setQualifier(ref);
qualifier = ref;
}
PsiElement element = BindingContextUtils.descriptorToDeclaration(bindingContext, descriptor);
if (element == null && descriptor instanceof PropertyAccessorDescriptor) {
element = BindingContextUtils.descriptorToDeclaration(bindingContext, ((PropertyAccessorDescriptor) descriptor)
.getCorrespondingProperty());
}
if (element != null) {
PsiFile file = element.getContainingFile();
String moduleName = file.getUserData(LibrarySourcesConfig.EXTERNAL_MODULE_NAME);
if (LibrarySourcesConfig.UNKNOWN_EXTERNAL_MODULE_NAME.equals(moduleName)) {
return null;
}
else if (moduleName != null) {
qualifier.setQualifier(new JsArrayAccess(namer.kotlin("modules"), program.getStringLiteral(moduleName)));
}
else if (result == qualifier && result.getIdent().equals("kotlin")) {
// todo WebDemoExamples2Test#testBuilder, package "kotlin" from kotlin/js/js.libraries/src/stdlib/JUMaps.kt must be inlined
return qualifier;
}
}
if (qualifier.getQualifier() == null) {
qualifier.setQualifier(new JsNameRef(Namer.getRootNamespaceName()));
}
return result;
}
};
Rule<JsNameRef> constructorHaveTheSameQualifierAsTheClass = new Rule<JsNameRef>() {
@@ -448,10 +501,7 @@ public final class StaticContext {
Rule<Boolean> topLevelNamespaceHaveNoQualifier = new Rule<Boolean>() {
@Override
public Boolean apply(@NotNull DeclarationDescriptor descriptor) {
if (!(descriptor instanceof NamespaceDescriptor)) {
return null;
}
if (DescriptorUtils.isTopLevelNamespace((NamespaceDescriptor) descriptor)) {
if (descriptor instanceof NamespaceDescriptor && DescriptorUtils.isRootNamespace((NamespaceDescriptor) descriptor)) {
return true;
}
return null;
@@ -24,6 +24,7 @@ import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.k2js.config.EcmaVersion;
import org.jetbrains.k2js.translate.intrinsic.Intrinsics;
import java.util.Map;
@@ -58,6 +59,10 @@ public final class TranslationContext {
return staticContext.isEcma5();
}
public boolean isNotEcma3() {
return staticContext.getEcmaVersion() != EcmaVersion.v3;
}
private TranslationContext(@NotNull StaticContext staticContext,
@NotNull DynamicContext dynamicContext,
@NotNull AliasingContext context) {
@@ -18,13 +18,11 @@ package org.jetbrains.k2js.translate.declaration;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.Lists;
import com.google.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.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.psi.JetClass;
import org.jetbrains.k2js.translate.context.Namer;
import org.jetbrains.k2js.translate.context.TranslationContext;
@@ -32,12 +30,12 @@ import org.jetbrains.k2js.translate.general.AbstractTranslator;
import org.jetbrains.k2js.translate.general.Translation;
import org.jetbrains.k2js.translate.utils.BindingUtils;
import org.jetbrains.k2js.translate.utils.ClassSortingUtils;
import org.jetbrains.k2js.translate.utils.JsAstUtils;
import java.util.ArrayList;
import java.util.List;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.*;
import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.getAllClassesDefinedInNamespace;
/**
* @author Pavel Talanov
@@ -142,18 +140,17 @@ public final class ClassDeclarationTranslator extends AbstractTranslator {
}
@NotNull
public List<JsPropertyInitializer> classDeclarationsForNamespace(@NotNull NamespaceDescriptor namespaceDescriptor) {
List<JsPropertyInitializer> result = Lists.newArrayList();
for (ClassDescriptor classDescriptor : getAllClassesDefinedInNamespace(namespaceDescriptor, bindingContext())) {
result.add(getClassNameToClassObject(classDescriptor));
}
return result;
}
@NotNull
private JsPropertyInitializer getClassNameToClassObject(@NotNull ClassDescriptor classDescriptor) {
public JsPropertyInitializer getClassNameToClassObject(@NotNull ClassDescriptor classDescriptor) {
JsName className = context().getNameForDescriptor(classDescriptor);
JsNameRef alreadyDefinedClassReference = qualified(className, getDeclarationsObjectName().makeRef());
return new JsPropertyInitializer(className.makeRef(), alreadyDefinedClassReference);
JsExpression value;
if (context().isEcma5()) {
value = JsAstUtils.createDataDescriptor(alreadyDefinedClassReference, false, context());
}
else {
value = alreadyDefinedClassReference;
}
return new JsPropertyInitializer(className.makeRef(), value);
}
}
@@ -19,6 +19,8 @@ package org.jetbrains.k2js.translate.declaration;
import com.google.dart.compiler.backend.js.ast.JsExpression;
import com.google.dart.compiler.backend.js.ast.JsPropertyInitializer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
@@ -39,6 +41,17 @@ import static org.jetbrains.k2js.translate.utils.BindingUtils.*;
* @author Pavel Talanov
*/
public final class DeclarationBodyVisitor extends TranslatorVisitor<List<JsPropertyInitializer>> {
@Nullable
private final ClassDeclarationTranslator classDeclarationTranslator;
public DeclarationBodyVisitor() {
classDeclarationTranslator = null;
}
public DeclarationBodyVisitor(ClassDeclarationTranslator classDeclarationTranslator) {
this.classDeclarationTranslator = classDeclarationTranslator;
}
@NotNull
public List<JsPropertyInitializer> traverseClass(@NotNull JetClassOrObject jetClass,
@NotNull TranslationContext context) {
@@ -51,7 +64,7 @@ public final class DeclarationBodyVisitor extends TranslatorVisitor<List<JsPrope
@NotNull
public List<JsPropertyInitializer> traverseNamespace(@NotNull NamespaceDescriptor namespace,
@NotNull TranslationContext context) {
@NotNull TranslationContext context) {
List<JsPropertyInitializer> properties = new ArrayList<JsPropertyInitializer>();
for (JetDeclaration declaration : getDeclarationsForNamespace(context.bindingContext(), namespace)) {
properties.addAll(declaration.accept(this, context));
@@ -62,7 +75,12 @@ public final class DeclarationBodyVisitor extends TranslatorVisitor<List<JsPrope
@Override
@NotNull
public List<JsPropertyInitializer> visitClass(@NotNull JetClass expression, @NotNull TranslationContext context) {
return Collections.emptyList();
if (classDeclarationTranslator == null) {
return Collections.emptyList();
}
ClassDescriptor classDescriptor = getClassDescriptor(context.bindingContext(), expression);
return Collections.singletonList(classDeclarationTranslator.getClassNameToClassObject(classDescriptor));
}
@Override
@@ -24,12 +24,10 @@ import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.k2js.translate.context.Namer;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.general.AbstractTranslator;
import org.jetbrains.k2js.translate.utils.JsAstUtils;
import org.jetbrains.k2js.translate.utils.JsDescriptorUtils;
import org.jetbrains.k2js.translate.utils.TranslationUtils;
import java.util.ArrayList;
import java.util.List;
@@ -37,7 +35,6 @@ import java.util.Set;
import static org.jetbrains.k2js.translate.utils.BindingUtils.getAllNonNativeNamespaceDescriptors;
import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.getAllClassesDefinedInNamespace;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.setQualifier;
/**
* @author Pavel Talanov
@@ -85,8 +82,8 @@ public final class NamespaceDeclarationTranslator extends AbstractTranslator {
private void namespacesDeclarations(List<JsStatement> statements) {
List<NamespaceTranslator> namespaceTranslators = getTranslatorsForNonEmptyNamespaces();
statements.addAll(declarationStatements(namespaceTranslators, context()));
statements.addAll(initializeStatements());
declarationStatements(namespaceTranslators, statements);
initializeStatements(namespaceTranslators, statements);
}
@NotNull
@@ -98,34 +95,31 @@ public final class NamespaceDeclarationTranslator extends AbstractTranslator {
return namespaceTranslators;
}
@NotNull
private static List<JsStatement> declarationStatements(@NotNull List<NamespaceTranslator> namespaceTranslators, TranslationContext context) {
List<JsStatement> result = Lists.newArrayList();
JsNameRef defs = JsAstUtils.qualified(context.jsScope().declareName("defs"), context.namer().kotlinObject());
for (NamespaceTranslator translator : namespaceTranslators) {
JsVars vars = translator.getDeclarationAsVar();
JsVars.JsVar var = vars.iterator().next();
JsNameRef ref = new JsNameRef(var.getName());
ref.setQualifier(defs);
result.add(vars);
result.add(JsAstUtils.assignment(ref, new JsNameRef(var.getName())).makeStmt());
private void declarationStatements(@NotNull List<NamespaceTranslator> namespaceTranslators,
@NotNull List<JsStatement> statements) {
JsObjectLiteral objectLiteral = new JsObjectLiteral();
JsNameRef packageMapNameRef = context().jsScope().declareName("_").makeRef();
JsExpression packageMapValue;
if (context().isNotEcma3()) {
packageMapValue = AstUtil.newInvocation(JsAstUtils.CREATE_OBJECT, context().program().getNullLiteral(), objectLiteral);
}
else {
packageMapValue = objectLiteral;
}
statements.add(JsAstUtils.newVar(packageMapNameRef.getName(), packageMapValue));
for (NamespaceTranslator translator : namespaceTranslators) {
translator.addNamespaceDeclaration(objectLiteral.getPropertyInitializers());
}
return result;
}
@NotNull
private List<JsStatement> initializeStatements() {
List<JsStatement> result = Lists.newArrayList();
for (NamespaceDescriptor descriptor : filterNonEmptyNamespaces(namespaceDescriptors)) {
JsNameRef initializeMethodReference = Namer.initializeMethodReference();
JsNameRef fqNamespaceNameRef = TranslationUtils.getQualifiedReference(context(), descriptor);
setQualifier(initializeMethodReference, fqNamespaceNameRef);
result.add(AstUtil.newInvocation(initializeMethodReference).makeStmt());
private static void initializeStatements(@NotNull List<NamespaceTranslator> namespaceTranslators,
@NotNull List<JsStatement> statements) {
for (NamespaceTranslator translator : namespaceTranslators) {
for (JsExpression expression : translator.getInitializers()) {
statements.add(expression.makeStmt());
}
}
return result;
}
@NotNull
@@ -25,15 +25,14 @@ import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.general.AbstractTranslator;
import org.jetbrains.k2js.translate.general.Translation;
import org.jetbrains.k2js.translate.initializer.InitializerUtils;
import org.jetbrains.k2js.translate.utils.JsAstUtils;
import org.jetbrains.k2js.translate.utils.JsDescriptorUtils;
import org.jetbrains.k2js.translate.utils.TranslationUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.newObjectLiteral;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.newVar;
/**
* @author Pavel.Talanov
@@ -49,6 +48,9 @@ public final class NamespaceTranslator extends AbstractTranslator {
@NotNull
private final ClassDeclarationTranslator classDeclarationTranslator;
@NotNull
private final List<JsExpression> initializers = new ArrayList<JsExpression>();
/*package*/ NamespaceTranslator(@NotNull NamespaceDescriptor descriptor,
@NotNull ClassDeclarationTranslator classDeclarationTranslator,
@NotNull TranslationContext context) {
@@ -58,80 +60,81 @@ public final class NamespaceTranslator extends AbstractTranslator {
this.classDeclarationTranslator = classDeclarationTranslator;
}
@NotNull
public JsVars getDeclarationAsVar() {
return newVar(namespaceName, getNamespaceDeclaration());
public List<JsExpression> getInitializers() {
return initializers;
}
@NotNull
public JsPropertyInitializer getDeclarationAsInitializer() {
addNamespaceInitializer();
return new JsPropertyInitializer(namespaceName.makeRef(), getNamespaceDeclaration());
}
public void addNamespaceDeclaration(List<JsPropertyInitializer> list) {
addNamespaceInitializer();
if (DescriptorUtils.isRootNamespace(descriptor)) {
list.addAll(getFunctionsAndClasses());
return;
}
JsExpression value = getNamespaceDeclaration();
if (context().isNotEcma3()) {
value = JsAstUtils.createDataDescriptor(value, false, context());
}
list.add(new JsPropertyInitializer(namespaceName.makeRef(), value));
}
@NotNull
private JsInvocation getNamespaceDeclaration() {
JsInvocation namespaceDeclaration = namespaceCreateMethodInvocation();
addNamespaceInitializersAndProperties(namespaceDeclaration);
namespaceDeclaration.getArguments().add(getClassesAndNestedNamespaces());
addIfNeed(getFunctionsAndClasses(), namespaceDeclaration.getArguments());
addIfNeed(getNestedNamespaceDeclarations(), namespaceDeclaration.getArguments());
return namespaceDeclaration;
}
private void addNamespaceInitializersAndProperties(@NotNull JsInvocation namespaceDeclaration) {
private void addNamespaceInitializer() {
JsFunction initializer = Translation.generateNamespaceInitializerMethod(descriptor, context());
List<JsPropertyInitializer> properties = new DeclarationBodyVisitor().traverseNamespace(descriptor, context());
if (context().isEcma5()) {
addEcma5InitializersAndProperties(namespaceDeclaration.getArguments(), initializer, properties);
}
else {
addEcma3InitializersAndProperties(namespaceDeclaration, initializer, properties);
if (!initializer.getBody().getStatements().isEmpty()) {
JsNameRef call = new JsNameRef("call");
call.setQualifier(initializer);
JsInvocation invocation = new JsInvocation();
invocation.setQualifier(call);
invocation.getArguments().add(TranslationUtils.getQualifiedReference(context(), descriptor));
initializers.add(invocation);
}
}
private static void addEcma3InitializersAndProperties(@NotNull JsInvocation namespaceDeclaration,
@NotNull JsFunction initializer,
@NotNull List<JsPropertyInitializer> properties) {
List<JsPropertyInitializer> propertyList = new ArrayList<JsPropertyInitializer>();
propertyList.add(InitializerUtils.generateInitializeMethod(initializer));
propertyList.addAll(properties);
namespaceDeclaration.getArguments().add(newObjectLiteral(propertyList));
}
private void addEcma5InitializersAndProperties(@NotNull List<JsExpression> expressions,
@NotNull JsFunction initializer,
@NotNull List<JsPropertyInitializer> properties) {
expressions.add(initializer.getBody().getStatements().isEmpty() ? context().program().getNullLiteral() : initializer);
expressions.add(properties.isEmpty() ? context().program().getNullLiteral() : newObjectLiteral(properties));
private List<JsPropertyInitializer> getFunctionsAndClasses() {
return new DeclarationBodyVisitor(classDeclarationTranslator).traverseNamespace(descriptor, context());
}
@NotNull
private JsInvocation namespaceCreateMethodInvocation() {
return AstUtil.newInvocation(context().namer().namespaceCreationMethodReference());
return AstUtil.newInvocation(context().namer().packageDefinitionMethodReference());
}
@NotNull
private JsObjectLiteral getClassesAndNestedNamespaces() {
JsObjectLiteral classesAndNestedNamespaces = new JsObjectLiteral();
classesAndNestedNamespaces.getPropertyInitializers().addAll(getClassesDefined());
classesAndNestedNamespaces.getPropertyInitializers().addAll(getNestedNamespaceDeclarations());
return classesAndNestedNamespaces;
}
@NotNull
private List<JsPropertyInitializer> getClassesDefined() {
return classDeclarationTranslator.classDeclarationsForNamespace(descriptor);
private void addIfNeed(@NotNull List<JsPropertyInitializer> declarations, @NotNull List<JsExpression> expressions) {
// ecma5 expects strict number of arguments, but ecma3 doesn't
if (!declarations.isEmpty()) {
expressions.add(newObjectLiteral(declarations));
}
else if (context().isNotEcma3()) {
expressions.add(context().program().getNullLiteral());
}
}
@NotNull
private List<JsPropertyInitializer> getNestedNamespaceDeclarations() {
if (DescriptorUtils.isRootNamespace(descriptor)) {
return Collections.emptyList();
}
List<JsPropertyInitializer> result = Lists.newArrayList();
List<NamespaceDescriptor> nestedNamespaces = JsDescriptorUtils.getNestedNamespaces(descriptor, context().bindingContext());
for (NamespaceDescriptor nestedNamespace : nestedNamespaces) {
NamespaceTranslator nestedNamespaceTranslator = new NamespaceTranslator(nestedNamespace, classDeclarationTranslator, context());
result.add(nestedNamespaceTranslator.getDeclarationAsInitializer());
initializers.addAll(nestedNamespaceTranslator.getInitializers());
}
return result;
}
@@ -19,6 +19,7 @@ package org.jetbrains.k2js.translate.general;
import com.google.dart.compiler.backend.js.JsNamer;
import com.google.dart.compiler.backend.js.JsPrettyNamer;
import com.google.dart.compiler.backend.js.ast.*;
import com.google.dart.compiler.util.AstUtil;
import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
@@ -28,7 +29,7 @@ import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
import org.jetbrains.k2js.config.EcmaVersion;
import org.jetbrains.k2js.config.Config;
import org.jetbrains.k2js.facade.MainCallParameters;
import org.jetbrains.k2js.facade.exceptions.MainFunctionNotFoundException;
import org.jetbrains.k2js.facade.exceptions.TranslationException;
@@ -148,10 +149,10 @@ public final class Translation {
@NotNull
public static JsProgram generateAst(@NotNull BindingContext bindingContext,
@NotNull List<JetFile> files, @NotNull MainCallParameters mainCallParameters,
@NotNull EcmaVersion ecmaVersion, List<String> rawStatements)
@NotNull Config config, List<String> rawStatements)
throws TranslationException {
try {
return doGenerateAst(bindingContext, files, mainCallParameters, ecmaVersion, rawStatements);
return doGenerateAst(bindingContext, files, mainCallParameters, config, rawStatements);
}
catch (UnsupportedOperationException e) {
throw new UnsupportedFeatureException("Unsupported feature used.", e);
@@ -164,10 +165,10 @@ public final class Translation {
@NotNull
private static JsProgram doGenerateAst(@NotNull BindingContext bindingContext, @NotNull List<JetFile> files,
@NotNull MainCallParameters mainCallParameters,
@NotNull EcmaVersion ecmaVersion, List<String> rawStatements) throws MainFunctionNotFoundException {
@NotNull Config config, List<String> rawStatements) throws MainFunctionNotFoundException {
//TODO: move some of the code somewhere
JetStandardLibrary standardLibrary = JetStandardLibrary.getInstance();
StaticContext staticContext = StaticContext.generateStaticContext(standardLibrary, bindingContext, ecmaVersion);
StaticContext staticContext = StaticContext.generateStaticContext(standardLibrary, bindingContext, config.getTarget());
JsProgram program = staticContext.getProgram();
JsBlock block = program.getGlobalBlock();
@@ -177,6 +178,8 @@ public final class Translation {
TranslationContext context = TranslationContext.rootContext(staticContext);
statements.addAll(translateFiles(files, context));
defineModule(statements, context, config);
if (mainCallParameters.shouldBeGenerated()) {
statements.add(generateCallToMain(context, files, mainCallParameters.arguments()));
}
@@ -186,6 +189,14 @@ public final class Translation {
return context.program();
}
private static void defineModule(@NotNull List<JsStatement> statements,
@NotNull TranslationContext context,
@NotNull Config config) {
statements.add(AstUtil.newInvocation(context.namer().kotlin("defineModule"),
context.program().getStringLiteral(config.getModuleId()),
context.jsScope().declareName("_").makeRef()).makeStmt());
}
@NotNull
private static JsStatement generateCallToMain(@NotNull TranslationContext context, @NotNull List<JetFile> files,
@NotNull List<String> arguments) throws MainFunctionNotFoundException {
@@ -214,12 +225,12 @@ public final class Translation {
JsAstUtils.setArguments(translatedCall, Collections.<JsExpression>singletonList(arrayLiteral));
}
@NotNull
private static void generateTestCalls(@NotNull TranslationContext context,
@NotNull List<JetFile> files,
@NotNull JsBlock block,
List<String> rawStatements) {
ClassDescriptor lastClassDescriptor = null;
boolean declaredVar = false;
List<JetNamedFunction> functions = JetTestFunctionDetector.findTestFunctions(context.bindingContext(), files);
for (JetNamedFunction function : functions) {
FunctionDescriptor functionDescriptor = getFunctionDescriptor(context.bindingContext(), function);
@@ -228,9 +239,16 @@ public final class Translation {
if (containingDeclaration instanceof ClassDescriptor) {
ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration;
String className = getQualifiedName(classDescriptor);
if (lastClassDescriptor != classDescriptor) {
lastClassDescriptor = classDescriptor;
String prefix = "";
if (!declaredVar) {
prefix = "var ";
declaredVar = true;
}
rawStatements.add(prefix + "_testCase = new Kotlin.main." + className + "();");
}
rawStatements.add("QUnit.test( \"" + className + "." + funName + "()\" , function() {");
String prefix = " var ";
rawStatements.add(prefix + "_testCase = new Kotlin.defs." + className + "();");
//rawStatements.add(" expect(0);");
rawStatements.add(" _testCase." + funName + "();");
} else {
@@ -213,7 +213,7 @@ public final class CallTranslator extends AbstractTranslator {
@NotNull
private JsInvocation generateCallMethodInvocation() {
JsNameRef callMethodNameRef = AstUtil.newQualifiedNameRef("call");
JsNameRef callMethodNameRef = new JsNameRef("call");
JsInvocation callMethodInvocation = new JsInvocation();
callMethodInvocation.setQualifier(callMethodNameRef);
setQualifier(callMethodInvocation, callParameters.getFunctionReference());
@@ -16,8 +16,8 @@
package org.jetbrains.k2js.translate.utils;
import com.google.common.collect.Sets;
import com.intellij.psi.PsiElement;
import com.intellij.util.containers.OrderedSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
@@ -321,7 +321,7 @@ public final class BindingUtils {
@NotNull
public static Set<NamespaceDescriptor> getAllNonNativeNamespaceDescriptors(@NotNull BindingContext context,
@NotNull List<JetFile> files) {
Set<NamespaceDescriptor> descriptorSet = Sets.newHashSet();
Set<NamespaceDescriptor> descriptorSet = new OrderedSet<NamespaceDescriptor>();
for (JetFile file : files) {
//TODO: can't be
NamespaceDescriptor namespaceDescriptor = getNamespaceDescriptor(context, file);
@@ -33,11 +33,13 @@ import java.util.*;
*/
public final class JsAstUtils {
private static final JsNameRef DEFINE_PROPERTY = new JsNameRef("defineProperty");
public static final JsNameRef CREATE_OBJECT = new JsNameRef("create");
private static final JsNameRef EMPTY_REF = new JsNameRef("");
static {
JsNameRef globalObjectReference = new JsNameRef("Object");
DEFINE_PROPERTY.setQualifier(globalObjectReference);
CREATE_OBJECT.setQualifier(globalObjectReference);
}
private JsAstUtils() {
@@ -301,21 +303,26 @@ public final class JsAstUtils {
return createPropertyDataDescriptor(descriptor.getModality().isOverridable(), descriptor, value, context);
}
@NotNull
public static JsObjectLiteral createDataDescriptor(@NotNull JsExpression value, boolean writable, @NotNull TranslationContext context) {
JsObjectLiteral dataDescriptor = new JsObjectLiteral();
dataDescriptor.getPropertyInitializers().add(new JsPropertyInitializer(context.program().getStringLiteral("value"), value));
if (writable) {
dataDescriptor.getPropertyInitializers().add(context.namer().writablePropertyDescriptorField());
}
return dataDescriptor;
}
@NotNull
private static JsObjectLiteral createPropertyDataDescriptor(boolean writable,
@NotNull DeclarationDescriptor descriptor,
@NotNull JsExpression value,
@NotNull TranslationContext context) {
JsObjectLiteral jsPropertyDescriptor = new JsObjectLiteral();
List<JsPropertyInitializer> meta = jsPropertyDescriptor.getPropertyInitializers();
meta.add(new JsPropertyInitializer(context.program().getStringLiteral("value"), value));
if (writable) {
meta.add(context.namer().writablePropertyDescriptorField());
}
JsObjectLiteral dataDescriptor = createDataDescriptor(value, writable, context);
if (AnnotationsUtils.isEnumerable(descriptor)) {
meta.add(context.namer().enumerablePropertyDescriptorField());
dataDescriptor.getPropertyInitializers().add(context.namer().enumerablePropertyDescriptorField());
}
return jsPropertyDescriptor;
return dataDescriptor;
}
@NotNull
@@ -30,7 +30,6 @@ import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.expressions.OperatorConventions;
import org.jetbrains.k2js.config.LibrarySourcesConfig;
import org.jetbrains.k2js.translate.context.Namer;
import java.util.ArrayList;
import java.util.Collection;
@@ -145,16 +144,6 @@ public final class JsDescriptorUtils {
return (functionDescriptor.getReceiverParameter().exists());
}
@NotNull
public static String getNameForNamespace(@NotNull NamespaceDescriptor descriptor) {
if (descriptor.getContainingDeclaration() instanceof ModuleDescriptor) {
return Namer.getRootNamespaceName();
}
else {
return descriptor.getName().getName();
}
}
//TODO: why callable descriptor
@Nullable
public static DeclarationDescriptor getExpectedThisDescriptor(@NotNull CallableDescriptor callableDescriptor) {
@@ -239,13 +228,18 @@ public final class JsDescriptorUtils {
List<DeclarationDescriptor> result = Lists.newArrayList();
for (DeclarationDescriptor descriptor : namespace.getMemberScope().getAllDescriptors()) {
if (!AnnotationsUtils.isPredefinedObject(descriptor)) {
PsiElement psiElement = BindingContextUtils.descriptorToDeclaration(context, descriptor);
if (psiElement != null) {
PsiFile file = psiElement.getContainingFile();
if (file.getUserData(LibrarySourcesConfig.EXTERNAL_LIB) == null) {
result.add(descriptor);
// namespace may be defined in multiple files
if (!(descriptor instanceof NamespaceDescriptor)) {
PsiElement psiElement = BindingContextUtils.descriptorToDeclaration(context, descriptor);
if (psiElement != null) {
PsiFile file = psiElement.getContainingFile();
if (file.getUserData(LibrarySourcesConfig.EXTERNAL_MODULE_NAME) != null) {
continue;
}
}
}
result.add(descriptor);
}
}
return result;
@@ -23,7 +23,6 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lexer.JetToken;
import org.jetbrains.jet.lexer.JetTokens;
import org.jetbrains.k2js.translate.context.Namer;
import java.util.Collections;
import java.util.List;
@@ -143,17 +142,6 @@ public final class PsiUtils {
return nameAsDeclaration;
}
@NotNull
public static String getNamespaceName(@NotNull JetFile psiFile) {
JetNamespaceHeader namespaceHeader = psiFile.getNamespaceHeader();
String name = namespaceHeader.getName();
assert name != null : "NamespaceHeader must have a name";
if (name.isEmpty()) {
return Namer.getRootNamespaceName();
}
return name;
}
@NotNull
public static JetExpression getLoopRange(@NotNull JetForExpression expression) {
JetExpression rangeExpression = expression.getLoopRange();
@@ -43,7 +43,7 @@ import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.getExpectedRe
*/
public final class TranslationUtils {
private static JsNameRef UNDEFINED_LITERAL = AstUtil.newQualifiedNameRef("undefined");
private static final JsNameRef UNDEFINED_LITERAL = AstUtil.newQualifiedNameRef("undefined");
private TranslationUtils() {
}
@@ -64,11 +64,7 @@ public final class TranslationUtils {
@NotNull
private static JsPropertyInitializer translateExtensionFunctionAsEcma5PropertyDescriptor(@NotNull JsFunction function,
@NotNull FunctionDescriptor descriptor, @NotNull TranslationContext context) {
JsObjectLiteral meta = new JsObjectLiteral();
meta.getPropertyInitializers().add(new JsPropertyInitializer(context.program().getStringLiteral("value"), function));
if (descriptor.getModality().isOverridable()) {
meta.getPropertyInitializers().add(context.namer().writablePropertyDescriptorField());
}
JsObjectLiteral meta = JsAstUtils.createDataDescriptor(function, descriptor.getModality().isOverridable(), context);
return new JsPropertyInitializer(context.getNameForDescriptor(descriptor).makeRef(), meta);
}
@@ -14,9 +14,7 @@
* limitations under the License.
*/
foo = Kotlin.createNamespace({initialize:function(){
}
, box:function(){
foo = Kotlin.definePackage({box:function(){
return !false;
}
});
@@ -46,9 +46,7 @@
return {A:A, B:B, C:C};
}
();
foo = Kotlin.createNamespace(classes, {initialize:function(){
}
, box:function(){
foo = Kotlin.definePackage(classes, {box:function(){
return (new foo.C).get_order() === 'ABC' && (new foo.B).get_order() === 'AB' && (new foo.A).get_order() === 'A';
}
});
+2 -2
View File
@@ -31,7 +31,7 @@ var kotlin = {set:function (receiver, key, value) {
return (obj1 === obj2);
};
Kotlin.defs = {};
Kotlin.modules = {};
Kotlin.Exceptions = {};
Kotlin.Exception = Kotlin.$createClass();
Kotlin.RuntimeException = Kotlin.$createClass(Kotlin.Exception);
@@ -44,7 +44,7 @@ var kotlin = {set:function (receiver, key, value) {
Kotlin.Exceptions.UnsupportedOperationException = Kotlin.$createClass(Kotlin.Exception);
Kotlin.Exceptions.IOException = Kotlin.$createClass(Kotlin.Exception);
Kotlin.throwNPE = function() {
Kotlin.throwNPE = function () {
throw Kotlin.$new(Kotlin.Exceptions.NullPointerException)();
};
@@ -141,9 +141,7 @@ var Kotlin = {};
}
})();
Kotlin.createNamespace = function () {
return Kotlin.createTrait.apply(null, arguments);
};
Kotlin.definePackage = Kotlin.createTrait;
Kotlin.createClass = (function () {
var METHODS = {addMethods: addMethods};
@@ -243,4 +241,12 @@ var Kotlin = {};
var singletonClass = Kotlin.createClass.apply(null, arguments);
return new singletonClass();
};
Kotlin.defineModule = function (id, module) {
if (id in Kotlin.modules) {
throw Kotlin.$new(Kotlin.Exceptions.IllegalArgumentException)();
}
Kotlin.modules[id] = module;
};
})();
+28 -10
View File
@@ -110,18 +110,27 @@ var Kotlin = {};
return o;
};
function emptyFunction() {
}
Kotlin.createNamespace = function (initializer, properties, classesAndNestedNamespaces) {
var o = Object.create(null, properties || undefined);
Object.defineProperty(o, "initialize", {value: initializer || emptyFunction});
var keys = Object.keys(classesAndNestedNamespaces);
for (var i = 0, n = keys.length; i < n; i++) {
var name = keys[i];
Object.defineProperty(o, name, {value: classesAndNestedNamespaces[name]});
Kotlin.definePackage = function (functionsAndClasses, nestedNamespaces) {
//var p = parent[localName];
//if (!p) {
// p = Object.create(null, functionsAndClasses || undefined);
// Object.defineProperty(parent, localName, {value: p});
//}
//else if (functionsAndClasses) {
// Object.defineProperties(p, functionsAndClasses);
//}
var p = Object.create(null, functionsAndClasses || undefined);
if (nestedNamespaces) {
var keys = Object.keys(nestedNamespaces);
for (var i = 0, n = keys.length; i < n; i++) {
var name = keys[i];
Object.defineProperty(p, name, {value:nestedNamespaces[name]});
}
}
return o;
return p;
};
Kotlin.$new = function (f) {
@@ -170,4 +179,13 @@ var Kotlin = {};
return Kotlin.createClass(parent || null, initializer, descriptors);
};
Kotlin.defineModule = function (id, module) {
if (id in Kotlin.modules) {
throw Kotlin.$new(Kotlin.Exceptions.IllegalArgumentException)();
}
Object.freeze(module);
Object.defineProperty(Kotlin.modules, id, {value: module});
};
})();