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