pull https://github.com/develar/kotlin ecma5-iter3 Make most of the tests work.
Thanks to develar.
This commit is contained in:
-3
@@ -410,9 +410,6 @@
|
||||
<inspection_tool class="UtilityClassWithPublicConstructor" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="UtilityClassWithoutPrivateConstructor" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="ignoreClassesWithOnlyMain" value="false" />
|
||||
<option name="ignorableAnnotations">
|
||||
<value />
|
||||
</option>
|
||||
</inspection_tool>
|
||||
<inspection_tool class="VolatileLongOrDoubleField" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="WaitNotInLoop" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
|
||||
Generated
+2
-2
@@ -2,15 +2,15 @@
|
||||
<library name="js-libs">
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/js/js.translator/lib/json.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/js/js.translator/lib/rhino-1.7R3.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/js/js.translator/lib/dart-r3300.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/js/js.translator/lib/closure-compiler.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/js/js.translator/lib/rhino-1.7R4.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$PROJECT_DIR$/js/js.translator/lib/rhino-1.7R3-src.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/js/js.translator/lib/dart-r3300-src.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/js/js.translator/lib/closure-compiler.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/js/js.translator/lib/rhino-1.7R4-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
@@ -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;
|
||||
@@ -63,21 +65,15 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments, K2JSCompile
|
||||
@NotNull
|
||||
@Override
|
||||
protected ExitCode doExecute(K2JSCompilerArguments arguments, PrintingMessageCollector messageCollector, Disposable rootDisposable) {
|
||||
|
||||
if (arguments.srcdir == null && arguments.sourceFiles == null) {
|
||||
messageCollector.report(CompilerMessageSeverity.ERROR, "Specify sources location via -srcdir", NO_LOCATION);
|
||||
if (arguments.sourceFiles == null) {
|
||||
messageCollector.report(CompilerMessageSeverity.ERROR, "Specify sources location via -sourceFiles", NO_LOCATION);
|
||||
return ExitCode.INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
JetCoreEnvironment environmentForJS = JetCoreEnvironment.getCoreEnvironmentForJS(rootDisposable);
|
||||
|
||||
if (arguments.srcdir != null) {
|
||||
environmentForJS.addSources(arguments.srcdir);
|
||||
}
|
||||
if (arguments.sourceFiles != null) {
|
||||
for (String sourceFile : arguments.sourceFiles) {
|
||||
environmentForJS.addSources(sourceFile);
|
||||
}
|
||||
for (String sourceFile : arguments.sourceFiles) {
|
||||
environmentForJS.addSources(sourceFile);
|
||||
}
|
||||
|
||||
Project project = environmentForJS.getProject();
|
||||
@@ -101,7 +97,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 +146,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);
|
||||
if (arguments.libzip == null) {
|
||||
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 ZippedLibrarySourcesConfig(project, arguments.libzip, ecmaVersion);
|
||||
return new LibrarySourcesConfig(project, moduleId, arguments.libraryFiles, ecmaVersion);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,30 +17,28 @@
|
||||
package org.jetbrains.jet.cli.js;
|
||||
|
||||
import com.sampullara.cli.Argument;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.cli.common.CompilerArguments;
|
||||
import org.jetbrains.k2js.facade.MainCallParameters;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
|
||||
/**
|
||||
* NOTE: for now K2JSCompiler supports only minimal amount of parameters required to launch it from the plugin.
|
||||
* You can specify only one source folder, path to the file where generated file will be stored, path to zipped library sources.
|
||||
* You can specify path to the file where generated file will be stored, path to zipped library sources.
|
||||
*/
|
||||
public class K2JSCompilerArguments extends CompilerArguments {
|
||||
@Argument(value = "output", description = "Output file path")
|
||||
public String outputFile;
|
||||
|
||||
//NOTE: may well be a subject to change soon
|
||||
@Argument(value = "libzip", description = "Path to zipped lib sources")
|
||||
public String libzip;
|
||||
@Argument(value = "libraryFiles", description = "Path to zipped lib sources or kotlin files")
|
||||
public String[] libraryFiles;
|
||||
|
||||
@Argument(value = "srcdir", description = "Sources directory")
|
||||
public String srcdir;
|
||||
@Argument(value = "sourceFiles", description = "Source files (dir or file)")
|
||||
public String[] sourceFiles;
|
||||
|
||||
@Argument(value = "target", description = "Generate js files for specific ECMA version (3 or 5, default ECMA 3)")
|
||||
public String target;
|
||||
@@ -54,14 +52,13 @@ public class K2JSCompilerArguments extends CompilerArguments {
|
||||
@Argument(value = "version", description = "Display compiler version")
|
||||
public boolean version;
|
||||
|
||||
@Argument(value = "mainCall", description = "Whether a main function should be invoked; either 'main' or 'mainWithArgs'")
|
||||
public String mainCall;
|
||||
@Nullable
|
||||
@Argument(value = "main", description = "Whether a main function should be called; either 'call' or 'noCall', default 'call' (main function will be auto detected)")
|
||||
public String main;
|
||||
|
||||
@Argument(value = "help", alias = "h", description = "Show help")
|
||||
public boolean help;
|
||||
|
||||
public List<String> sourceFiles;
|
||||
|
||||
@Override
|
||||
public boolean isHelp() {
|
||||
return help;
|
||||
@@ -84,22 +81,16 @@ public class K2JSCompilerArguments extends CompilerArguments {
|
||||
|
||||
@Override
|
||||
public String getSrc() {
|
||||
if (sourceFiles != null) {
|
||||
return sourceFiles.toString();
|
||||
}
|
||||
return srcdir;
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
public MainCallParameters createMainCallParameters() {
|
||||
if (mainCall != null) {
|
||||
if (mainCall.equals("main")) {
|
||||
return MainCallParameters.mainWithoutArguments();
|
||||
}
|
||||
if (mainCall.equals("mainWithArgs")) {
|
||||
// TODO should we pass the arguments to the compiler?
|
||||
return MainCallParameters.mainWithArguments(new ArrayList<String>());
|
||||
}
|
||||
if ("noCall".equals(main)) {
|
||||
return MainCallParameters.noCall();
|
||||
}
|
||||
else {
|
||||
// TODO should we pass the arguments to the compiler?
|
||||
return MainCallParameters.mainWithoutArguments();
|
||||
}
|
||||
return MainCallParameters.noCall();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,27 +17,29 @@
|
||||
package org.jetbrains.jet.plugin.compiler;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.intellij.openapi.application.AccessToken;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.compiler.CompileContext;
|
||||
import com.intellij.openapi.compiler.CompileScope;
|
||||
import com.intellij.openapi.compiler.CompilerMessageCategory;
|
||||
import com.intellij.openapi.compiler.TranslatingCompiler;
|
||||
import com.intellij.openapi.application.ReadAction;
|
||||
import com.intellij.openapi.compiler.*;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ModuleOrderEntry;
|
||||
import com.intellij.openapi.roots.ModuleRootManager;
|
||||
import com.intellij.openapi.roots.OrderEntry;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.Chunk;
|
||||
import com.intellij.util.StringBuilderSpinAllocator;
|
||||
import gnu.trove.THashSet;
|
||||
import jet.Function1;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.plugin.JetFileType;
|
||||
import org.jetbrains.jet.plugin.k2jsrun.K2JSRunnerUtils;
|
||||
import org.jetbrains.jet.plugin.project.JsModuleDetector;
|
||||
|
||||
import java.io.PrintStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.jetbrains.jet.plugin.compiler.CompilerUtils.invokeExecMethod;
|
||||
import static org.jetbrains.jet.plugin.compiler.CompilerUtils.outputCompilerMessagesAndHandleExitCode;
|
||||
@@ -46,7 +48,6 @@ import static org.jetbrains.jet.plugin.compiler.CompilerUtils.outputCompilerMess
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public final class K2JSCompiler implements TranslatingCompiler {
|
||||
|
||||
@Override
|
||||
public boolean isCompilableFile(VirtualFile file, CompileContext context) {
|
||||
if (!(file.getFileType() instanceof JetFileType)) {
|
||||
@@ -115,16 +116,9 @@ public final class K2JSCompiler implements TranslatingCompiler {
|
||||
@NotNull
|
||||
private static Integer doExec(@NotNull CompileContext context, @NotNull CompilerEnvironment environment, @NotNull PrintStream out,
|
||||
@NotNull Module module) throws Exception {
|
||||
VirtualFile[] roots = ModuleRootManager.getInstance(module).getSourceRoots();
|
||||
if (roots.length != 1) {
|
||||
context.addMessage(CompilerMessageCategory.ERROR, "K2JSCompiler does not support multiple module source roots.", null, -1, -1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
VirtualFile outDir = context.getModuleOutputDirectory(module);
|
||||
String outFile = outDir == null ? null : K2JSRunnerUtils.constructPathToGeneratedFile(context.getProject(), outDir.getPath());
|
||||
|
||||
String[] commandLineArgs = constructArguments(context.getProject(), outFile, roots[0]);
|
||||
String outFile = outDir == null ? null : outDir.getPath() + "/" + module.getName() + ".js";
|
||||
String[] commandLineArgs = constructArguments(module, outFile);
|
||||
Object rc = invokeExecMethod(environment, out, context, commandLineArgs, "org.jetbrains.jet.cli.js.K2JSCompiler");
|
||||
|
||||
if (outDir != null && !ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
@@ -134,30 +128,96 @@ public final class K2JSCompiler implements TranslatingCompiler {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String[] constructArguments(@NotNull Project project, @Nullable String outFile, @NotNull VirtualFile srcDir) {
|
||||
private static String[] constructArguments(@NotNull Module module, @Nullable String outFile) {
|
||||
VirtualFile[] sourceFiles = getSourceFiles(module);
|
||||
|
||||
ArrayList<String> args = Lists.newArrayList("-tags", "-verbose", "-version");
|
||||
addPathToSourcesDir(args, srcDir);
|
||||
addPathToSourcesDir(sourceFiles, args);
|
||||
addOutputPath(outFile, args);
|
||||
addLibLocationAndTarget(project, args);
|
||||
addLibLocationAndTarget(module, args);
|
||||
return ArrayUtil.toStringArray(args);
|
||||
}
|
||||
|
||||
private static void addLibLocationAndTarget(@NotNull Project project, @NotNull ArrayList<String> args) {
|
||||
Pair<String, String> libLocationAndTarget = JsModuleDetector.getLibLocationAndTargetForProject(project);
|
||||
if (libLocationAndTarget.first != null) {
|
||||
args.add("-libzip");
|
||||
args.add(libLocationAndTarget.first);
|
||||
// we cannot use OrderEnumerator because it has critical bug — try https://gist.github.com/2953261, processor will never be called for module dependency
|
||||
// we don't use context.getCompileScope().getAffectedModules() because we want to know about linkage type (well, we ignore scope right now, but in future...)
|
||||
private static void collectModuleDependencies(Module dependentModule, Set<Module> modules) {
|
||||
for (OrderEntry entry : ModuleRootManager.getInstance(dependentModule).getOrderEntries()) {
|
||||
if (entry instanceof ModuleOrderEntry) {
|
||||
ModuleOrderEntry moduleEntry = (ModuleOrderEntry) entry;
|
||||
if (!moduleEntry.getScope().isForProductionCompile()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Module module = moduleEntry.getModule();
|
||||
if (module == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (modules.add(module) && moduleEntry.isExported()) {
|
||||
collectModuleDependencies(module, modules);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static VirtualFile[] getSourceFiles(@NotNull Module module) {
|
||||
return CompilerManager.getInstance(module.getProject()).createModuleCompileScope(module, false)
|
||||
.getFiles(JetFileType.INSTANCE, true);
|
||||
}
|
||||
|
||||
private static void addLibLocationAndTarget(@NotNull Module module, @NotNull ArrayList<String> args) {
|
||||
Pair<String[], String> libLocationAndTarget = JsModuleDetector.getLibLocationAndTargetForProject(module);
|
||||
|
||||
StringBuilder sb = StringBuilderSpinAllocator.alloc();
|
||||
AccessToken token = ReadAction.start();
|
||||
try {
|
||||
THashSet<Module> modules = new THashSet<Module>();
|
||||
collectModuleDependencies(module, modules);
|
||||
if (!modules.isEmpty()) {
|
||||
for (Module dependency : modules) {
|
||||
sb.append('@').append(dependency.getName()).append(',');
|
||||
|
||||
for (VirtualFile file : getSourceFiles(dependency)) {
|
||||
sb.append(file.getPath()).append(',');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (libLocationAndTarget.first != null) {
|
||||
for (String file : libLocationAndTarget.first) {
|
||||
sb.append(file).append(',');
|
||||
}
|
||||
}
|
||||
|
||||
if (sb.length() > 0) {
|
||||
args.add("-libraryFiles");
|
||||
args.add(sb.substring(0, sb.length() - 1));
|
||||
}
|
||||
}
|
||||
finally {
|
||||
token.finish();
|
||||
StringBuilderSpinAllocator.dispose(sb);
|
||||
}
|
||||
|
||||
if (libLocationAndTarget.second != null) {
|
||||
args.add("-target");
|
||||
args.add(libLocationAndTarget.second);
|
||||
}
|
||||
}
|
||||
|
||||
private static void addPathToSourcesDir(@NotNull ArrayList<String> args, @NotNull VirtualFile srcDir) {
|
||||
String srcPath = srcDir.getPath();
|
||||
args.add("-srcdir");
|
||||
args.add(srcPath);
|
||||
private static void addPathToSourcesDir(@NotNull VirtualFile[] sourceFiles, @NotNull ArrayList<String> args) {
|
||||
args.add("-sourceFiles");
|
||||
|
||||
StringBuilder sb = StringBuilderSpinAllocator.alloc();
|
||||
try {
|
||||
for (VirtualFile file : sourceFiles) {
|
||||
sb.append(file.getPath()).append(',');
|
||||
}
|
||||
args.add(sb.substring(0, sb.length() - 1));
|
||||
}
|
||||
finally {
|
||||
StringBuilderSpinAllocator.dispose(sb);
|
||||
}
|
||||
}
|
||||
|
||||
private static void addOutputPath(@Nullable String outFile, @NotNull ArrayList<String> args) {
|
||||
|
||||
@@ -19,15 +19,15 @@ package org.jetbrains.jet.plugin.project;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.k2js.config.EcmaVersion;
|
||||
import org.jetbrains.k2js.config.ZippedLibrarySourcesConfig;
|
||||
import org.jetbrains.k2js.config.LibrarySourcesConfig;
|
||||
|
||||
import static org.jetbrains.jet.plugin.project.JsModuleDetector.getLibLocationAndTargetForProject;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public final class IDEAConfig extends ZippedLibrarySourcesConfig {
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,10 +36,6 @@ public final class JsModuleDetector {
|
||||
private JsModuleDetector() {
|
||||
}
|
||||
|
||||
public static boolean isJsProject(@NotNull Project project) {
|
||||
return getJSModule(project) != null;
|
||||
}
|
||||
|
||||
public static boolean isJsModule(@NotNull Module module) {
|
||||
return K2JSModuleComponent.getInstance(module).isJavaScriptModule();
|
||||
}
|
||||
@@ -57,15 +53,22 @@ public final class JsModuleDetector {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Pair<String, String> getLibLocationAndTargetForProject(@NotNull Project project) {
|
||||
public static Pair<String[], String> getLibLocationAndTargetForProject(@NotNull Project project) {
|
||||
Module module = getJSModule(project);
|
||||
if (module == null) {
|
||||
return Pair.empty();
|
||||
}
|
||||
else {
|
||||
return getLibLocationAndTargetForProject(module);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Pair<String[], String> getLibLocationAndTargetForProject(@NotNull Module module) {
|
||||
K2JSModuleComponent jsModuleComponent = K2JSModuleComponent.getInstance(module);
|
||||
String pathToJavaScriptLibrary = jsModuleComponent.getPathToJavaScriptLibrary();
|
||||
String basePath = ModuleRootManager.getInstance(module).getContentRoots()[0].getPath();
|
||||
return Pair.create(basePath + pathToJavaScriptLibrary, jsModuleComponent.getEcmaVersion().toString());
|
||||
return Pair.create(new String[] {basePath + pathToJavaScriptLibrary}, jsModuleComponent.getEcmaVersion().toString());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -3,4 +3,6 @@ package js;
|
||||
native
|
||||
public annotation class native(name : String = "") {}
|
||||
native
|
||||
public annotation class library(name : String = "") {}
|
||||
public annotation class library(name : String = "") {}
|
||||
native
|
||||
public annotation class enumerable() {}
|
||||
@@ -1,11 +1,15 @@
|
||||
package js.debug
|
||||
|
||||
import js.*
|
||||
import js.noImpl
|
||||
|
||||
// https://developer.mozilla.org/en/DOM/console
|
||||
native trait Console {
|
||||
native fun dir(o: Any): Unit = noImpl
|
||||
native fun error(vararg o: Any?): Unit = noImpl
|
||||
native fun info(vararg o: Any?): Unit = noImpl
|
||||
native fun log(vararg o: Any?): Unit = noImpl
|
||||
native fun warn(vararg o: Any?): Unit = noImpl
|
||||
}
|
||||
|
||||
native
|
||||
val console : consoleClass = js.noImpl
|
||||
|
||||
native
|
||||
class consoleClass() {
|
||||
fun log(message : Any?) : Unit = js.noImpl
|
||||
}
|
||||
val console:Console = noImpl
|
||||
@@ -12,12 +12,11 @@ public trait Comparator<T> {
|
||||
|
||||
library
|
||||
public trait Iterator<T> {
|
||||
open fun next() : T = js.noImpl
|
||||
open fun hasNext() : Boolean = js.noImpl
|
||||
open fun remove() : Unit = js.noImpl
|
||||
open public fun next() : T = js.noImpl
|
||||
open public fun hasNext() : Boolean = js.noImpl
|
||||
open public fun remove() : Unit = js.noImpl
|
||||
}
|
||||
|
||||
|
||||
val Collections = object {
|
||||
library("collectionsMax")
|
||||
public fun max<T>(col : Collection<T>, comp : Comparator<T>) : T = js.noImpl
|
||||
@@ -55,120 +54,74 @@ val Collections = object {
|
||||
}
|
||||
|
||||
library
|
||||
public open class ArrayList<E>() : java.util.List<E> {
|
||||
public override fun size() : Int = js.noImpl
|
||||
public override fun isEmpty() : Boolean = js.noImpl
|
||||
public override fun contains(o : Any?) : Boolean = js.noImpl
|
||||
public override fun iterator() : Iterator<E> = js.noImpl
|
||||
// public override fun indexOf(o : Any?) : Int = js.noImpl
|
||||
// public override fun lastIndexOf(o : Any?) : Int = js.noImpl
|
||||
// public override fun toArray() : Array<Any?> = js.noImpl
|
||||
// public override fun toArray<T>(a : Array<out T>) : Array<T> = js.noImpl
|
||||
public override fun get(index : Int) : E = js.noImpl
|
||||
public override fun set(index : Int, element : E) : E = js.noImpl
|
||||
public override fun add(e : E) : Boolean = js.noImpl
|
||||
public override fun add(index : Int, element : E) : Unit = js.noImpl
|
||||
library("removeByIndex")
|
||||
public override fun remove(index : Int) : E = js.noImpl
|
||||
public override fun remove(o : Any?) : Boolean = js.noImpl
|
||||
public override fun clear() : Unit = js.noImpl
|
||||
public override fun addAll(c : java.util.Collection<out E>) : Boolean = js.noImpl
|
||||
// public override fun addAll(index : Int, c : java.util.Collection<out E>) : Boolean = js.noImpl
|
||||
}
|
||||
|
||||
library
|
||||
public trait Collection<E> : java.lang.Iterable<E> {
|
||||
open public fun size() : Int
|
||||
open public fun isEmpty() : Boolean
|
||||
open public fun contains(o : Any?) : Boolean
|
||||
override public fun iterator() : java.util.Iterator<E>
|
||||
// open public fun toArray() : Array<Any?>
|
||||
// open public fun toArray<T>(a : Array<out T>) : Array<T>
|
||||
open public fun add(e : E) : Boolean
|
||||
open public fun remove(o : Any?) : Boolean
|
||||
public trait Collection<E>: Iterable<E> {
|
||||
open public fun size(): Int
|
||||
open public fun isEmpty(): Boolean
|
||||
open public fun contains(o: Any?): Boolean
|
||||
override public fun iterator(): Iterator<E>
|
||||
public fun toArray(): Array<E>
|
||||
// open public fun toArray<T>(a : Array<out T>) : Array<T>
|
||||
open public fun add(e: E): Boolean
|
||||
open public fun remove(o: Any?): Boolean
|
||||
//open public fun containsAll(c : java.util.Collection<*>) : Boolean
|
||||
open public fun addAll(c : java.util.Collection<out E>) : Boolean
|
||||
open public fun addAll(c: Collection<out E>): Boolean
|
||||
//open public fun removeAll(c : java.util.Collection<*>) : Boolean
|
||||
//open public fun retainAll(c : java.util.Collection<*>) : Boolean
|
||||
open public fun clear() : Unit
|
||||
open public fun clear(): Unit
|
||||
}
|
||||
|
||||
library
|
||||
public abstract open class AbstractCollection<E>() : Collection<E> {
|
||||
public abstract class AbstractCollection<E>() : Collection<E> {
|
||||
override public fun toArray(): Array<E> = js.noImpl
|
||||
|
||||
override public fun isEmpty(): Boolean = js.noImpl
|
||||
override public fun contains(o: Any?): Boolean = js.noImpl
|
||||
override public fun iterator(): Iterator<E> = js.noImpl
|
||||
|
||||
override public fun add(e: E): Boolean = js.noImpl
|
||||
override public fun remove(o: Any?): Boolean = js.noImpl
|
||||
|
||||
override public fun addAll(c: Collection<out E>): Boolean = js.noImpl
|
||||
|
||||
override public fun clear(): Unit = js.noImpl
|
||||
override public fun size(): Int = js.noImpl
|
||||
}
|
||||
|
||||
library
|
||||
public abstract open class AbstractList<E>() : AbstractCollection<E>(), List<E> {
|
||||
public override fun isEmpty() : Boolean = js.noImpl
|
||||
public override fun contains(o : Any?) : Boolean = js.noImpl
|
||||
public override fun iterator() : Iterator<E> = js.noImpl
|
||||
// public override fun indexOf(o : Any?) : Int = js.noImpl
|
||||
// public override fun lastIndexOf(o : Any?) : Int = js.noImpl
|
||||
// public override fun toArray() : Array<Any?> = js.noImpl
|
||||
// public override fun toArray<T>(a : Array<out T>) : Array<T> = js.noImpl
|
||||
public override fun set(index : Int, element : E) : E = js.noImpl
|
||||
public override fun add(e : E) : Boolean = js.noImpl
|
||||
public override fun add(index : Int, element : E) : Unit = js.noImpl
|
||||
library("removeByIndex")
|
||||
public override fun remove(index : Int) : E = js.noImpl
|
||||
public override fun remove(o : Any?) : Boolean = js.noImpl
|
||||
public override fun clear() : Unit = js.noImpl
|
||||
public override fun addAll(c : java.util.Collection<out E>) : Boolean = js.noImpl
|
||||
// public override fun addAll(index : Int, c : java.util.Collection<out E>) : Boolean = js.noImpl
|
||||
public trait List<E>: Collection<E> {
|
||||
public fun get(index: Int): E
|
||||
public fun set(index: Int, element: E): E
|
||||
|
||||
public fun add(index: Int, element: E): Unit
|
||||
public fun remove(index: Int): E
|
||||
|
||||
public fun indexOf(o: E?): Int
|
||||
}
|
||||
|
||||
library
|
||||
public trait List<E> : Collection<E> {
|
||||
override public fun size() : Int
|
||||
override public fun isEmpty() : Boolean
|
||||
override public fun contains(o : Any?) : Boolean
|
||||
override public fun iterator() : java.util.Iterator<E>
|
||||
// override public fun toArray() : Array<Any?>
|
||||
// Simulate Java's array covariance
|
||||
// override public fun toArray<T>(a : Array<out T>) : Array<T>
|
||||
override public fun add(e : E) : Boolean
|
||||
override public fun remove(o : Any?) : Boolean
|
||||
// override public fun containsAll(c : java.util.Collection<*>) : Boolean
|
||||
override public fun addAll(c : java.util.Collection<out E>) : Boolean
|
||||
// open public fun addAll(index : Int, c : java.util.Collection<out E>) : Boolean
|
||||
// override public fun removeAll(c : java.util.Collection<*>) : Boolean
|
||||
// override public fun retainAll(c : java.util.Collection<*>) : Boolean
|
||||
override public fun clear() : Unit
|
||||
open public fun get(index : Int) : E
|
||||
open public fun set(index : Int, element : E) : E
|
||||
open public fun add(index : Int, element : E) : Unit
|
||||
open public fun remove(index : Int) : E
|
||||
// open public fun indexOf(o : Any?) : Int
|
||||
// open public fun lastIndexOf(o : Any?) : Int
|
||||
public abstract class AbstractList<E>(): AbstractCollection<E>(), List<E> {
|
||||
override public fun get(index: Int): E = js.noImpl
|
||||
override public fun set(index: Int, element: E): E = js.noImpl
|
||||
|
||||
library("addAt")
|
||||
override public public fun add(index: Int, element: E): Unit = js.noImpl
|
||||
|
||||
library("removeAt")
|
||||
override public fun remove(index: Int): E = js.noImpl
|
||||
|
||||
override public fun indexOf(o: E?): Int = js.noImpl
|
||||
}
|
||||
|
||||
library
|
||||
public open class ArrayList<E>() : AbstractList<E>() {
|
||||
}
|
||||
|
||||
library
|
||||
public trait Set<E> : Collection<E> {
|
||||
override public fun size() : Int
|
||||
override public fun isEmpty() : Boolean
|
||||
override public fun contains(o : Any?) : Boolean
|
||||
override public fun iterator() : java.util.Iterator<E>
|
||||
// override public fun toArray() : Array<Any?>
|
||||
// override public fun toArray<T>(a : Array<out T>) : Array<T>
|
||||
override public fun add(e : E) : Boolean
|
||||
override public fun remove(o : Any?) : Boolean
|
||||
//override public fun containsAll(c : java.util.Collection<*>) : Boolean
|
||||
override public fun addAll(c : java.util.Collection<out E>) : Boolean
|
||||
//override public fun retainAll(c : java.util.Collection<*>) : Boolean
|
||||
//override public fun removeAll(c : java.util.Collection<*>) : Boolean
|
||||
override public fun clear() : Unit
|
||||
}
|
||||
|
||||
library
|
||||
public open class HashSet<E>() : java.util.Set<E> {
|
||||
public override fun iterator() : java.util.Iterator<E> = js.noImpl
|
||||
public override fun size() : Int = js.noImpl
|
||||
public override fun isEmpty() : Boolean = js.noImpl
|
||||
public override fun contains(o : Any?) : Boolean = js.noImpl
|
||||
public override fun add(e : E) : Boolean = js.noImpl
|
||||
public override fun remove(o : Any?) : Boolean = js.noImpl
|
||||
public override fun clear() : Unit = js.noImpl
|
||||
override fun addAll(c : java.util.Collection<out E>) : Boolean = js.noImpl
|
||||
public open class HashSet<E>(): AbstractCollection<E>(), java.util.Set<E> {
|
||||
}
|
||||
|
||||
library
|
||||
@@ -186,23 +139,23 @@ public trait Map<K, V> {
|
||||
open public fun values() : java.util.Collection<V>
|
||||
|
||||
open public fun entrySet() : java.util.Set<Entry<K, V>>
|
||||
// open public fun equals(o : Any?) : Boolean
|
||||
// open public fun hashCode() : Int
|
||||
// open public fun equals(o : Any?) : Boolean
|
||||
// open public fun hashCode() : Int
|
||||
|
||||
trait Entry<K, V> {
|
||||
open public fun getKey() : K
|
||||
open public fun getValue() : V
|
||||
open public fun setValue(value : V) : V
|
||||
// open public fun equals(o : Any?) : Boolean
|
||||
// open public fun hashCode() : Int
|
||||
// open public fun equals(o : Any?) : Boolean
|
||||
// open public fun hashCode() : Int
|
||||
}
|
||||
}
|
||||
|
||||
library
|
||||
public open class HashMap<K, V>() : java.util.Map<K, V> {
|
||||
public open class HashMap<K, V>() : Map<K, V> {
|
||||
public override fun size() : Int = js.noImpl
|
||||
public override fun isEmpty() : Boolean = js.noImpl
|
||||
public override fun get(key : Any?) : V = js.noImpl
|
||||
public override fun get(key : Any?) : V? = js.noImpl
|
||||
public override fun containsKey(key : Any?) : Boolean = js.noImpl
|
||||
public override fun put(key : K, value : V) : V = js.noImpl
|
||||
public override fun putAll(m : java.util.Map<out K, out V>) : Unit = js.noImpl
|
||||
@@ -215,37 +168,23 @@ public open class HashMap<K, V>() : java.util.Map<K, V> {
|
||||
}
|
||||
|
||||
library
|
||||
public open class LinkedList<E>() : List<E> {
|
||||
public override fun iterator() : java.util.Iterator<E> = js.noImpl
|
||||
public override fun isEmpty() : Boolean = js.noImpl
|
||||
public override fun contains(o : Any?) : Boolean = js.noImpl
|
||||
public override fun size() : Int = js.noImpl
|
||||
public override fun add(e : E) : Boolean = js.noImpl
|
||||
public override fun remove(o : Any?) : Boolean = js.noImpl
|
||||
public override fun addAll(c : java.util.Collection<out E>) : Boolean = js.noImpl
|
||||
public override fun clear() : Unit = js.noImpl
|
||||
public override fun get(index : Int) : E = js.noImpl
|
||||
public override fun set(index : Int, element : E) : E = js.noImpl
|
||||
public override fun add(index : Int, element : E) : Unit = js.noImpl
|
||||
public override fun remove(index : Int) : E = js.noImpl
|
||||
public fun poll() : E? = js.noImpl
|
||||
public fun peek() : E? = js.noImpl
|
||||
public fun offer(e : E) : Boolean = js.noImpl
|
||||
public open class LinkedList<E>(): AbstractList<E>() {
|
||||
public override fun get(index: Int): E = js.noImpl
|
||||
public override fun set(index: Int, element: E): E = js.noImpl
|
||||
public override fun add(index: Int, element: E): Unit = js.noImpl
|
||||
public fun poll(): E? = js.noImpl
|
||||
public fun peek(): E? = js.noImpl
|
||||
public fun offer(e: E): Boolean = js.noImpl
|
||||
}
|
||||
|
||||
library
|
||||
public class StringBuilder() : Appendable {
|
||||
override fun append(c: Char): Appendable? = js.noImpl
|
||||
override fun append(csq: CharSequence?): Appendable? = js.noImpl
|
||||
override fun append(csq: CharSequence?, start: Int, end: Int): Appendable? = js.noImpl
|
||||
override public fun append(c: Char): Appendable? = js.noImpl
|
||||
override public fun append(csq: CharSequence?): Appendable? = js.noImpl
|
||||
override public fun append(csq: CharSequence?, start: Int, end: Int): Appendable? = js.noImpl
|
||||
public fun append(obj : Any?) : StringBuilder = js.noImpl
|
||||
public fun toString() : String = js.noImpl
|
||||
}
|
||||
|
||||
library
|
||||
public class NoSuchElementException() : Exception() {}
|
||||
|
||||
public trait Enumeration<E> {
|
||||
open fun hasMoreElements(): Boolean
|
||||
open fun nextElement(): E?
|
||||
}
|
||||
public class NoSuchElementException() : Exception() {}
|
||||
@@ -21,4 +21,13 @@ library("jsonFromTuples")
|
||||
public fun json2(pairs : Array<Tuple2<String, Any?>>) : Json = js.noImpl
|
||||
|
||||
library("jsonAddProperties")
|
||||
public fun Json.add(other : Json) : Json = js.noImpl
|
||||
public fun Json.add(other : Json) : Json = js.noImpl
|
||||
|
||||
native
|
||||
public trait JsonClass {
|
||||
public fun stringify(o: Any): String = noImpl
|
||||
public fun parse<T>(text: String): T = noImpl
|
||||
}
|
||||
|
||||
native
|
||||
public val JSON:JsonClass = noImpl
|
||||
@@ -43,6 +43,8 @@ public abstract class BasicTest extends TestWithEnvironment {
|
||||
private static final String CASES = "cases/";
|
||||
private static final String OUT = "out/";
|
||||
private static final String EXPECTED = "expected/";
|
||||
|
||||
public static final String JSLINT_LIB = pathToTestFilesRoot() + "jslint.js";
|
||||
|
||||
@NotNull
|
||||
private String mainDirectory = "";
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -28,8 +28,11 @@ import java.util.List;
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public class TestConfig extends Config {
|
||||
public final class TestConfig extends Config {
|
||||
|
||||
//NOTE: hard-coded in kotlin-lib files
|
||||
@NotNull
|
||||
public static final String TEST_MODULE_NAME = "JS_TESTS";
|
||||
@NotNull
|
||||
private final List<JetFile> jsLibFiles;
|
||||
@NotNull
|
||||
@@ -37,7 +40,7 @@ public class TestConfig extends Config {
|
||||
|
||||
public TestConfig(@NotNull Project project, @NotNull EcmaVersion version,
|
||||
@NotNull List<JetFile> files, @NotNull BindingContext context) {
|
||||
super(project, version);
|
||||
super(project, TEST_MODULE_NAME, version);
|
||||
jsLibFiles = files;
|
||||
libraryContext = context;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2010-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.k2js.test.rhino;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.mozilla.javascript.Function;
|
||||
import org.mozilla.javascript.Scriptable;
|
||||
|
||||
/**
|
||||
* @author Sergey Simonchik
|
||||
*/
|
||||
class FunctionWithScope {
|
||||
private final Function fun;
|
||||
private final Scriptable scope;
|
||||
|
||||
FunctionWithScope(@NotNull Function function, @NotNull Scriptable scope) {
|
||||
this.fun = function;
|
||||
this.scope = scope;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Function getFunction() {
|
||||
return fun;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Scriptable getScope() {
|
||||
return scope;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright 2010-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.k2js.test.rhino;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.mozilla.javascript.Context;
|
||||
import org.mozilla.javascript.Function;
|
||||
import org.mozilla.javascript.Script;
|
||||
import org.mozilla.javascript.Scriptable;
|
||||
|
||||
/**
|
||||
* @author Sergey Simonchik
|
||||
*/
|
||||
class RhinoFunctionManager {
|
||||
private static final Logger LOG = Logger.getInstance(RhinoFunctionManager.class);
|
||||
|
||||
private final ThreadLocal<FunctionWithScope> threadLocalFunction = new ThreadLocal<FunctionWithScope>() {
|
||||
@Override
|
||||
protected FunctionWithScope initialValue() {
|
||||
if (script == null) {
|
||||
synchronized (threadLocalFunction) {
|
||||
if (script == null) {
|
||||
script = compileScript(9);
|
||||
}
|
||||
}
|
||||
}
|
||||
return extractFunctionWithScope(script);
|
||||
}
|
||||
};
|
||||
|
||||
private volatile Script script;
|
||||
|
||||
private final Supplier<String> scriptSourceProvider;
|
||||
private final String functionName;
|
||||
|
||||
public RhinoFunctionManager(@NotNull Supplier<String> scriptSourceProvider,
|
||||
@NotNull String functionName) {
|
||||
this.scriptSourceProvider = scriptSourceProvider;
|
||||
this.functionName = functionName;
|
||||
}
|
||||
|
||||
private Script compileScript(int optimizationLevel) {
|
||||
long startNano = System.nanoTime();
|
||||
Context context = Context.enter();
|
||||
try {
|
||||
context.setOptimizationLevel(optimizationLevel);
|
||||
String scriptSource = scriptSourceProvider.get();
|
||||
return context.compileString(scriptSource, "<" + functionName + " script>", 1, null);
|
||||
}
|
||||
finally {
|
||||
Context.exit();
|
||||
LOG.info(formatMessage(startNano, functionName + " script rhino compilation"));
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private FunctionWithScope extractFunctionWithScope(@NotNull Script script) {
|
||||
long startNano = System.nanoTime();
|
||||
Context context = Context.enter();
|
||||
try {
|
||||
Scriptable scope = context.initStandardObjects();
|
||||
script.exec(context, scope);
|
||||
Object jsLintObj = scope.get(functionName, scope);
|
||||
if (jsLintObj instanceof Function) {
|
||||
Function jsLint = (Function) jsLintObj;
|
||||
return new FunctionWithScope(jsLint, scope);
|
||||
}
|
||||
else {
|
||||
throw new RuntimeException(functionName + " is undefined or not a function.");
|
||||
}
|
||||
}
|
||||
finally {
|
||||
Context.exit();
|
||||
LOG.info(formatMessage(startNano, functionName + " function extraction"));
|
||||
}
|
||||
}
|
||||
|
||||
private static String formatMessage(long startTimeNano, @NotNull String actionName) {
|
||||
long nanoDuration = System.nanoTime() - startTimeNano;
|
||||
return String.format("[%s] %s took %.2f ms",
|
||||
Thread.currentThread().getName(),
|
||||
actionName,
|
||||
nanoDuration / 1000000.0);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public FunctionWithScope getFunctionWithScope() {
|
||||
return threadLocalFunction.get();
|
||||
}
|
||||
}
|
||||
+4
-3
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.k2js.test.rhino;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.mozilla.javascript.Context;
|
||||
import org.mozilla.javascript.NativeJavaObject;
|
||||
|
||||
/**
|
||||
@@ -33,13 +34,13 @@ public class RhinoFunctionNativeObjectResultChecker extends RhinoFunctionResultC
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void assertResultValid(Object result) {
|
||||
protected void assertResultValid(Object result, Context context) {
|
||||
if (result instanceof NativeJavaObject) {
|
||||
NativeJavaObject nativeJavaObject = (NativeJavaObject) result;
|
||||
Object unwrap = nativeJavaObject.unwrap();
|
||||
super.assertResultValid(unwrap);
|
||||
super.assertResultValid(unwrap, context);
|
||||
} else {
|
||||
super.assertResultValid(result);
|
||||
super.assertResultValid(result, context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
package org.jetbrains.k2js.test.rhino;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.k2js.test.config.TestConfig;
|
||||
import org.jetbrains.k2js.translate.context.Namer;
|
||||
import org.mozilla.javascript.Context;
|
||||
import org.mozilla.javascript.Scriptable;
|
||||
|
||||
@@ -46,11 +48,12 @@ public class RhinoFunctionResultChecker implements RhinoResultChecker {
|
||||
public void runChecks(Context context, Scriptable scope) throws Exception {
|
||||
Object result = evaluateFunction(context, scope);
|
||||
flushSystemOut(context, scope);
|
||||
assertResultValid(result);
|
||||
assertResultValid(result, context);
|
||||
}
|
||||
|
||||
protected void assertResultValid(Object result) {
|
||||
assertEquals("Result of " + namespaceName + "." + functionName + "() is not what expected!", expectedResult, result);
|
||||
protected void assertResultValid(Object result, Context context) {
|
||||
String ecmaVersion = context.getLanguageVersion() == Context.VERSION_1_8 ? "ecma5" : "ecma3";
|
||||
assertEquals("Result of " + namespaceName + "." + functionName + "() is not what expected (" + ecmaVersion + ")!", expectedResult, result);
|
||||
String report = namespaceName + "." + functionName + "() = " + Context.toString(result);
|
||||
System.out.println(report);
|
||||
}
|
||||
@@ -60,10 +63,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." + TestConfig.TEST_MODULE_NAME);
|
||||
if (namespaceName != Namer.getRootNamespaceName()) {
|
||||
sb.append('.').append(namespaceName);
|
||||
}
|
||||
sb.append('.');
|
||||
}
|
||||
return result;
|
||||
return sb.append(functionName).append("()").toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,15 +17,19 @@
|
||||
package org.jetbrains.k2js.test.rhino;
|
||||
|
||||
import closurecompiler.internal.com.google.common.collect.Maps;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.k2js.config.EcmaVersion;
|
||||
import org.jetbrains.k2js.facade.K2JSTranslator;
|
||||
import org.mozilla.javascript.Context;
|
||||
import org.mozilla.javascript.Scriptable;
|
||||
import org.mozilla.javascript.ScriptableObject;
|
||||
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;
|
||||
import java.util.Set;
|
||||
@@ -37,6 +41,28 @@ import static org.jetbrains.k2js.test.BasicTest.pathToTestFilesRoot;
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public final class RhinoUtils {
|
||||
@NotNull
|
||||
private static final Set<String> IGNORED_JSLINT_WARNINGS = Sets.newHashSet();
|
||||
|
||||
static {
|
||||
// todo dart ast bug
|
||||
IGNORED_JSLINT_WARNINGS.add("Unexpected space between '}' and '('.");
|
||||
// don't read JS, use kotlin and idea debugger ;)
|
||||
IGNORED_JSLINT_WARNINGS
|
||||
.add("Wrap an immediate function invocation in parentheses to assist the reader in understanding that the expression is the result of a function, and not the function itself.");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static final RhinoFunctionManager functionManager = new RhinoFunctionManager(
|
||||
new Supplier<String>() {
|
||||
@Override
|
||||
public String get() {
|
||||
return fileToString(BasicTest.JSLINT_LIB);
|
||||
}
|
||||
},
|
||||
"JSLINT"
|
||||
);
|
||||
|
||||
|
||||
public static final String KOTLIN_JS_LIB_COMMON = pathToTestFilesRoot() + "kotlin_lib.js";
|
||||
private static final String KOTLIN_JS_LIB_ECMA_3 = pathToTestFilesRoot() + "kotlin_lib_ecma3.js";
|
||||
@@ -46,6 +72,15 @@ 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 {
|
||||
@@ -75,6 +110,8 @@ public final class RhinoUtils {
|
||||
runFileWithRhino(filename, context, scope);
|
||||
}
|
||||
checker.runChecks(context, scope);
|
||||
|
||||
lintIt(context, fileNames.get(fileNames.size() - 1));
|
||||
}
|
||||
finally {
|
||||
Context.exit();
|
||||
@@ -147,4 +184,61 @@ public final class RhinoUtils {
|
||||
static void flushSystemOut(@NotNull Context context, @NotNull Scriptable scope) {
|
||||
context.evaluateString(scope, K2JSTranslator.FLUSH_SYSTEM_OUT, "test", 0, null);
|
||||
}
|
||||
|
||||
private static void lintIt(Context context, String fileName) throws IOException {
|
||||
if (Boolean.valueOf(System.getProperty("test.lint.skip"))) {
|
||||
return;
|
||||
}
|
||||
|
||||
NativeObject options = new NativeObject();
|
||||
// todo fix dart ast?
|
||||
options.defineProperty("white", true, ScriptableObject.READONLY);
|
||||
// vars, http://uxebu.com/blog/2010/04/02/one-var-statement-for-one-variable/
|
||||
options.defineProperty("vars", true, ScriptableObject.READONLY);
|
||||
NativeArray globals = new NativeArray(new Object[] {"Kotlin"});
|
||||
options.defineProperty("predef", globals, ScriptableObject.READONLY);
|
||||
|
||||
Object[] args = {FileUtil.loadFile(new File(fileName)), options};
|
||||
FunctionWithScope functionWithScope = functionManager.getFunctionWithScope();
|
||||
Function function = functionWithScope.getFunction();
|
||||
Scriptable scope = functionWithScope.getScope();
|
||||
Object status = function.call(context, scope, scope, args);
|
||||
Boolean noErrors = (Boolean) Context.jsToJava(status, Boolean.class);
|
||||
if (!noErrors) {
|
||||
Object errors = function.get("errors", scope);
|
||||
if (errors == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
System.out.println(fileName);
|
||||
for (Object errorObj : ((NativeArray) errors)) {
|
||||
if (!(errorObj instanceof NativeObject)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
NativeObject e = (NativeObject) errorObj;
|
||||
int line = toInt(e.get("line"));
|
||||
int character = toInt(e.get("character"));
|
||||
if (line < 0 || character < 0) {
|
||||
continue;
|
||||
}
|
||||
Object reasonObj = e.get("reason");
|
||||
if (reasonObj instanceof String) {
|
||||
String reason = (String) reasonObj;
|
||||
if (IGNORED_JSLINT_WARNINGS.contains(reason)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
System.out.println(line + ":" + character + " " + reason);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static int toInt(Object obj) {
|
||||
if (obj instanceof Number) {
|
||||
return ((Number) obj).intValue();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,6 +51,10 @@ public final class ArrayListTest extends JavaClassesTest {
|
||||
fooBoxTest();
|
||||
}
|
||||
|
||||
public void testToArray() throws Exception {
|
||||
fooBoxTest();
|
||||
}
|
||||
|
||||
public void testIndexOOB() throws Exception {
|
||||
try {
|
||||
fooBoxTest();
|
||||
|
||||
@@ -74,4 +74,8 @@ public final class ExtensionFunctionTest extends SingleFileTranslationTest {
|
||||
public void testExtensionPropertyOnClassWithExplicitAndImplicitReceiver() throws Exception {
|
||||
fooBoxTest();
|
||||
}
|
||||
|
||||
public void testExtensionFunctionCalledFromFor() throws Exception {
|
||||
fooBoxTest();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,4 +34,8 @@ public final class MultiFileTest extends MultipleFilesTranslationTest {
|
||||
public void testClassesInheritedFromOtherFile() throws Exception {
|
||||
checkFooBoxIsTrue("classesInheritedFromOtherFile");
|
||||
}
|
||||
|
||||
public void testClassOfTheSameNameInAnotherPackage() throws Exception {
|
||||
checkFooBoxIsTrue("classOfTheSameNameInAnotherPackage");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,8 +16,11 @@
|
||||
|
||||
package org.jetbrains.k2js.test.semantics;
|
||||
|
||||
import org.jetbrains.k2js.config.EcmaVersion;
|
||||
import org.jetbrains.k2js.test.SingleFileTranslationTest;
|
||||
|
||||
import java.util.EnumSet;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
@@ -41,9 +44,13 @@ public final class ObjectTest extends SingleFileTranslationTest {
|
||||
fooBoxTest();
|
||||
}
|
||||
|
||||
public void testObjectInObject() throws Exception {
|
||||
fooBoxTest(EnumSet.noneOf(EcmaVersion.class));
|
||||
}
|
||||
|
||||
|
||||
public void testObjectInheritingFromATrait() throws Exception {
|
||||
fooBoxTest();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,10 +16,14 @@
|
||||
|
||||
package org.jetbrains.k2js.test.semantics;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.k2js.config.EcmaVersion;
|
||||
import org.jetbrains.k2js.test.SingleFileTranslationTest;
|
||||
import org.jetbrains.k2js.test.utils.JsTestUtils;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
@@ -79,4 +83,23 @@ public final class PropertyAccessTest extends SingleFileTranslationTest {
|
||||
public void testInitInstanceProperties() throws Exception {
|
||||
fooBoxTest(EnumSet.of(EcmaVersion.v5));
|
||||
}
|
||||
|
||||
public void testEnumerable() throws Exception {
|
||||
fooBoxTest(JsTestUtils.successOnEcmaV5());
|
||||
}
|
||||
|
||||
public void testOverloadedOverriddenFunctionPropertyName() throws Exception {
|
||||
//fooBoxTest(JsTestUtils.successOnEcmaV5());
|
||||
//fooBoxTest();
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
protected List<String> additionalJSFiles(@NotNull EcmaVersion ecmaVersion) {
|
||||
List<String> result = Lists.newArrayList(super.additionalJSFiles(ecmaVersion));
|
||||
if (getName().equals("testEnumerable")) {
|
||||
result.add(pathToTestFiles() + "enumerate.js");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ abstract class StdLibTestSupport extends SingleFileTranslationTest {
|
||||
K2JSCompiler compiler = new K2JSCompiler();
|
||||
K2JSCompilerArguments arguments = new K2JSCompilerArguments();
|
||||
arguments.outputFile = getOutputFilePath(getTestName(false) + ".compiler.kt", version);
|
||||
arguments.sourceFiles = files;
|
||||
arguments.sourceFiles = files.toArray(new String[files.size()]);
|
||||
arguments.verbose = true;
|
||||
System.out.println("Compiling with version: " + version + " to: " + arguments.outputFile);
|
||||
ExitCode answer = compiler.exec(System.out, arguments);
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -34,6 +35,11 @@ public final class JsTestUtils {
|
||||
private JsTestUtils() {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static EnumSet<EcmaVersion> successOnEcmaV5() {
|
||||
return EnumSet.of(EcmaVersion.v5);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String convertFileNameToDotJsFile(@NotNull String filename, @NotNull EcmaVersion ecmaVersion) {
|
||||
String postFix = "_" + ecmaVersion.toString() + ".js";
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -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;
|
||||
@@ -41,10 +40,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;
|
||||
|
||||
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isRootNamespace;
|
||||
|
||||
@@ -136,7 +135,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;
|
||||
|
||||
+4
-4
@@ -16,11 +16,11 @@
|
||||
|
||||
package org.jetbrains.k2js.config;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A Config implementation which is configured with a directory to find the standard library names from
|
||||
@@ -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
|
||||
|
||||
@@ -36,7 +36,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() {
|
||||
@@ -133,9 +133,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
|
||||
@@ -148,6 +152,11 @@ public abstract class Config {
|
||||
return target;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getModuleId() {
|
||||
return moduleId;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected abstract List<JetFile> generateLibFiles();
|
||||
|
||||
|
||||
+48
-15
@@ -18,6 +18,7 @@ package org.jetbrains.k2js.config;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -27,6 +28,7 @@ import org.jetbrains.k2js.utils.JetFileUtils;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
@@ -36,33 +38,63 @@ import java.util.zip.ZipFile;
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public class ZippedLibrarySourcesConfig extends Config {
|
||||
@Nullable
|
||||
protected final String pathToLibZip;
|
||||
public class LibrarySourcesConfig extends Config {
|
||||
public static final Key<String> EXTERNAL_MODULE_NAME = new Key<String>("externalModule");
|
||||
public static final String UNKNOWN_EXTERNAL_MODULE_NAME = "<unknown>";
|
||||
|
||||
public ZippedLibrarySourcesConfig(@NotNull Project project, @Nullable String pathToZip, @NotNull EcmaVersion ecmaVersion) {
|
||||
super(project, ecmaVersion);
|
||||
pathToLibZip = pathToZip;
|
||||
@Nullable
|
||||
private final String[] files;
|
||||
|
||||
public LibrarySourcesConfig(@NotNull Project project,
|
||||
@NotNull String moduleId,
|
||||
@Nullable String[] files,
|
||||
@NotNull EcmaVersion ecmaVersion) {
|
||||
super(project, moduleId, ecmaVersion);
|
||||
this.files = files;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<JetFile> generateLibFiles() {
|
||||
if (pathToLibZip == null) {
|
||||
if (files == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
try {
|
||||
File file = new File(pathToLibZip);
|
||||
ZipFile zipFile = new ZipFile(file);
|
||||
|
||||
List<JetFile> jetFiles = new ArrayList<JetFile>();
|
||||
String moduleName = UNKNOWN_EXTERNAL_MODULE_NAME;
|
||||
for (String path : files) {
|
||||
File file = new File(path);
|
||||
try {
|
||||
return traverseArchive(zipFile);
|
||||
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_MODULE_NAME, moduleName);
|
||||
jetFiles.add(psiFile);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
zipFile.close();
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
return Collections.emptyList();
|
||||
|
||||
return jetFiles;
|
||||
}
|
||||
|
||||
private List<JetFile> readZip(File file) throws IOException {
|
||||
ZipFile zipFile = new ZipFile(file);
|
||||
try {
|
||||
return traverseArchive(zipFile);
|
||||
}
|
||||
finally {
|
||||
zipFile.close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,6 +108,7 @@ public class ZippedLibrarySourcesConfig extends Config {
|
||||
InputStream stream = file.getInputStream(entry);
|
||||
String text = FileUtil.loadTextAndClose(stream);
|
||||
JetFile jetFile = JetFileUtils.createPsiFile(entry.getName(), text, getProject());
|
||||
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;
|
||||
@@ -97,9 +96,7 @@ public final class K2JSTranslator {
|
||||
throws TranslationException {
|
||||
JetStandardLibrary.initialize(config.getProject());
|
||||
BindingContext bindingContext = AnalyzerFacadeForJS.analyzeFilesAndCheckErrors(filesToTranslate, config);
|
||||
Collection<JetFile> files = AnalyzerFacadeForJS.withJsLibAdded(filesToTranslate, config);
|
||||
|
||||
return Translation.generateAst(bindingContext, Lists.newArrayList(files), mainCallParameters, config.getTarget(), rawStatements);
|
||||
return Translation.generateAst(bindingContext, filesToTranslate, mainCallParameters, config, rawStatements);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -25,7 +25,6 @@ import java.util.List;
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public abstract class MainCallParameters {
|
||||
|
||||
@NotNull
|
||||
public static MainCallParameters noCall() {
|
||||
return new MainCallParameters() {
|
||||
|
||||
@@ -53,8 +53,13 @@ public final class DynamicContext {
|
||||
|
||||
@NotNull
|
||||
public TemporaryVariable declareTemporary(@NotNull JsExpression initExpression) {
|
||||
return declareTemporary(initExpression, false);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public TemporaryVariable declareTemporary(@NotNull JsExpression initExpression, boolean initialize) {
|
||||
JsName temporaryName = currentScope.declareTemporary();
|
||||
JsVars temporaryDeclaration = newVar(temporaryName, /*no init expression in var statement*/ null);
|
||||
JsVars temporaryDeclaration = newVar(temporaryName, initialize ? initExpression : null);
|
||||
addVarDeclaration(jsBlock(), temporaryDeclaration);
|
||||
return new TemporaryVariable(temporaryName, initExpression);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -122,17 +121,24 @@ public final class Namer {
|
||||
@NotNull
|
||||
private final JsPropertyInitializer writablePropertyDescriptorField;
|
||||
|
||||
@NotNull
|
||||
private final JsPropertyInitializer enumerablePropertyDescriptorField;
|
||||
|
||||
private Namer(@NotNull JsScope rootScope) {
|
||||
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);
|
||||
|
||||
isTypeName = kotlinScope.declareName("isType");
|
||||
|
||||
writablePropertyDescriptorField = new JsPropertyInitializer(new JsNameRef("writable"), rootScope.getProgram().getTrueLiteral());
|
||||
JsProgram program = rootScope.getProgram();
|
||||
writablePropertyDescriptorField = new JsPropertyInitializer(program.getStringLiteral("writable"), program.getTrueLiteral());
|
||||
enumerablePropertyDescriptorField = new JsPropertyInitializer(program.getStringLiteral("enumerable"), program.getTrueLiteral());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -146,8 +152,8 @@ public final class Namer {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JsExpression namespaceCreationMethodReference() {
|
||||
return kotlin(namespaceName);
|
||||
public JsExpression packageDefinitionMethodReference() {
|
||||
return definePackage;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -164,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;
|
||||
}
|
||||
|
||||
@@ -190,6 +199,11 @@ public final class Namer {
|
||||
return writablePropertyDescriptorField;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JsPropertyInitializer enumerablePropertyDescriptorField() {
|
||||
return enumerablePropertyDescriptorField;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
/*package*/ JsScope getKotlinScope() {
|
||||
return kotlinScope;
|
||||
|
||||
@@ -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;
|
||||
@@ -153,6 +162,14 @@ public final class StaticContext {
|
||||
}
|
||||
|
||||
private final class NameGenerator extends Generator<JsName> {
|
||||
private JsName declareName(DeclarationDescriptor descriptor, String name) {
|
||||
NamingScope scope = getEnclosingScope(descriptor);
|
||||
// ecma 5 property name never declares as obfuscatable:
|
||||
// 1) property cannot be overloaded, so, name collision is not possible
|
||||
// 2) main reason: if property doesn't have any custom accessor, value holder will have the same name as accessor, so, the same name will be declared more than once
|
||||
return isEcma5() ? scope.declareUnobfuscatableName(name) : scope.declareObfuscatableName(name);
|
||||
}
|
||||
|
||||
public NameGenerator() {
|
||||
Rule<JsName> namesForStandardClasses = new Rule<JsName>() {
|
||||
@Override
|
||||
@@ -171,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>() {
|
||||
@@ -180,6 +205,9 @@ public final class StaticContext {
|
||||
@Nullable
|
||||
public JsName apply(@NotNull DeclarationDescriptor descriptor) {
|
||||
NamingScope namingScope = getEnclosingScope(descriptor);
|
||||
if (descriptor instanceof ClassDescriptor) {
|
||||
return namingScope.declareUnobfuscatableName(descriptor.getName().getName());
|
||||
}
|
||||
return namingScope.declareObfuscatableName(descriptor.getName().getName());
|
||||
}
|
||||
};
|
||||
@@ -203,11 +231,9 @@ public final class StaticContext {
|
||||
boolean isGetter = descriptor instanceof PropertyGetterDescriptor;
|
||||
PropertyAccessorDescriptor accessorDescriptor = (PropertyAccessorDescriptor) descriptor;
|
||||
String propertyName = accessorDescriptor.getCorrespondingProperty().getName().getName();
|
||||
String accessorName = Namer.getNameForAccessor(propertyName, isGetter, !accessorDescriptor.getReceiverParameter().exists() && isEcma5());
|
||||
NamingScope enclosingScope = getEnclosingScope(descriptor);
|
||||
return isEcma5()
|
||||
? enclosingScope.declareUnobfuscatableName(accessorName)
|
||||
: enclosingScope.declareObfuscatableName(accessorName);
|
||||
String accessorName = Namer.getNameForAccessor(propertyName, isGetter,
|
||||
!accessorDescriptor.getReceiverParameter().exists() && isEcma5());
|
||||
return declareName(descriptor, accessorName);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -232,19 +258,12 @@ public final class StaticContext {
|
||||
return null;
|
||||
}
|
||||
|
||||
//TODO: move somewhere
|
||||
NamingScope enclosingScope = getEnclosingScope(descriptor);
|
||||
if (isEcma5()) {
|
||||
String name = descriptor.getName().getName();
|
||||
if (JsDescriptorUtils.isAsPrivate((PropertyDescriptor) descriptor)) {
|
||||
name = '_' + name;
|
||||
}
|
||||
String name = descriptor.getName().getName();
|
||||
if (!isEcma5() || JsDescriptorUtils.isAsPrivate((PropertyDescriptor) descriptor)) {
|
||||
name = Namer.getKotlinBackingFieldName(name);
|
||||
}
|
||||
|
||||
return enclosingScope.declareUnobfuscatableName(name);
|
||||
}
|
||||
else {
|
||||
return enclosingScope.declareObfuscatableName(Namer.getKotlinBackingFieldName(descriptor.getName().getName()));
|
||||
}
|
||||
return declareName(descriptor, name);
|
||||
}
|
||||
};
|
||||
//TODO: hack!
|
||||
@@ -386,14 +405,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>() {
|
||||
@@ -449,10 +504,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) {
|
||||
@@ -152,6 +157,11 @@ public final class TranslationContext {
|
||||
return dynamicContext.declareTemporary(initExpression);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public TemporaryVariable declareTemporary(@NotNull JsExpression initExpression, boolean initialize) {
|
||||
return dynamicContext.declareTemporary(initExpression, initialize);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Namer namer() {
|
||||
return staticContext.getNamer();
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package org.jetbrains.k2js.translate.declaration;
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.JsNameRef;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.psi.JetClass;
|
||||
|
||||
public interface ClassAliasingMap {
|
||||
@Nullable
|
||||
JsNameRef get(JetClass declaration, JetClass referencedDeclaration);
|
||||
}
|
||||
+153
-97
@@ -16,28 +16,29 @@
|
||||
|
||||
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 gnu.trove.THashMap;
|
||||
import gnu.trove.TLinkable;
|
||||
import gnu.trove.TLinkableAdaptor;
|
||||
import gnu.trove.TLinkedList;
|
||||
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.descriptors.Modality;
|
||||
import org.jetbrains.jet.lang.psi.JetClass;
|
||||
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.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;
|
||||
import static com.google.dart.compiler.backend.js.ast.JsVars.JsVar;
|
||||
import static org.jetbrains.k2js.translate.general.Translation.translateClassDeclaration;
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getClassDescriptor;
|
||||
import static org.jetbrains.k2js.translate.utils.JsAstUtils.newBlock;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
@@ -45,115 +46,170 @@ import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.getAllClasses
|
||||
* Generates a big block where are all the classes(objects representing them) are created.
|
||||
*/
|
||||
public final class ClassDeclarationTranslator extends AbstractTranslator {
|
||||
private int localNameCounter;
|
||||
|
||||
@NotNull
|
||||
private final List<ClassDescriptor> descriptors;
|
||||
@NotNull
|
||||
private final BiMap<JsName, JsName> localToGlobalClassName;
|
||||
private final THashMap<JetClass, ListItem> openClassToItem = new THashMap<JetClass, ListItem>();
|
||||
|
||||
private final TLinkedList<ListItem> openList = new TLinkedList<ListItem>();
|
||||
private final List<ListItem> finalList = new ArrayList<ListItem>();
|
||||
|
||||
@NotNull
|
||||
private final JsFunction dummyFunction;
|
||||
@Nullable
|
||||
private JsName declarationsObject = null;
|
||||
@Nullable
|
||||
private JsStatement declarationsStatement = null;
|
||||
|
||||
public ClassDeclarationTranslator(@NotNull List<ClassDescriptor> descriptors,
|
||||
@NotNull TranslationContext context) {
|
||||
private final JsName declarationsObject;
|
||||
private final JsVar classesVar;
|
||||
|
||||
public ClassDeclarationTranslator(@NotNull TranslationContext context) {
|
||||
super(context);
|
||||
this.descriptors = descriptors;
|
||||
this.localToGlobalClassName = HashBiMap.create();
|
||||
this.dummyFunction = new JsFunction(context.jsScope());
|
||||
|
||||
dummyFunction = new JsFunction(context.jsScope());
|
||||
declarationsObject = context().jsScope().declareName(Namer.nameForClassesVariable());
|
||||
classesVar = new JsVars.JsVar(declarationsObject);
|
||||
}
|
||||
|
||||
private final class OpenClassRefProvider implements ClassAliasingMap {
|
||||
@Override
|
||||
@Nullable
|
||||
public JsNameRef get(JetClass declaration, JetClass referencedDeclaration) {
|
||||
ListItem item = openClassToItem.get(declaration);
|
||||
// class declared in library
|
||||
if (item == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
addAfter(item, openClassToItem.get(referencedDeclaration));
|
||||
return item.label;
|
||||
}
|
||||
|
||||
private void addAfter(@NotNull ListItem item, @NotNull ListItem referencedItem) {
|
||||
for (TLinkable link = item.getNext(); link != null; link = link.getNext()) {
|
||||
if (link == referencedItem) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
openList.remove(referencedItem);
|
||||
openList.addBefore((ListItem) item.getNext(), referencedItem);
|
||||
}
|
||||
}
|
||||
|
||||
private final class FinalClassRefProvider implements ClassAliasingMap {
|
||||
@Override
|
||||
public JsNameRef get(JetClass declaration, JetClass referencedDeclaration) {
|
||||
ListItem item = openClassToItem.get(declaration);
|
||||
return item == null ? null : item.label;
|
||||
}
|
||||
}
|
||||
|
||||
private static class ListItem extends TLinkableAdaptor {
|
||||
private final JetClass declaration;
|
||||
private final JsNameRef label;
|
||||
|
||||
private JsExpression translatedDeclaration;
|
||||
|
||||
private ListItem(JetClass declaration, JsNameRef label) {
|
||||
this.declaration = declaration;
|
||||
this.label = label;
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JsVars getDeclarationsStatement() {
|
||||
JsVars vars = new JsVars();
|
||||
vars.add(classesVar);
|
||||
return vars;
|
||||
}
|
||||
|
||||
public void generateDeclarations() {
|
||||
declarationsObject = context().jsScope().declareName(Namer.nameForClassesVariable());
|
||||
assert declarationsObject != null;
|
||||
declarationsStatement =
|
||||
newVar(declarationsObject, generateDummyFunctionInvocation());
|
||||
}
|
||||
JsObjectLiteral valueLiteral = new JsObjectLiteral();
|
||||
JsVars vars = new JsVars();
|
||||
List<JsPropertyInitializer> propertyInitializers = valueLiteral.getPropertyInitializers();
|
||||
|
||||
@NotNull
|
||||
public JsName getDeclarationsObjectName() {
|
||||
assert declarationsObject != null : "Should run generateDeclarations first";
|
||||
return declarationsObject;
|
||||
}
|
||||
generateOpenClassDeclarations(vars, propertyInitializers);
|
||||
generateFinalClassDeclarations(vars, propertyInitializers);
|
||||
|
||||
@NotNull
|
||||
public JsStatement getDeclarationsStatement() {
|
||||
assert declarationsStatement != null : "Should run generateDeclarations first";
|
||||
return declarationsStatement;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsInvocation generateDummyFunctionInvocation() {
|
||||
List<JsStatement> classDeclarations = generateClassDeclarationStatements();
|
||||
classDeclarations.add(new JsReturn(generateReturnedObjectLiteral()));
|
||||
dummyFunction.setBody(newBlock(classDeclarations));
|
||||
return AstUtil.newInvocation(dummyFunction);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsObjectLiteral generateReturnedObjectLiteral() {
|
||||
JsObjectLiteral returnedValueLiteral = new JsObjectLiteral();
|
||||
for (JsName localName : localToGlobalClassName.keySet()) {
|
||||
returnedValueLiteral.getPropertyInitializers().add(classEntry(localName));
|
||||
if (vars.isEmpty()) {
|
||||
classesVar.setInitExpr(valueLiteral);
|
||||
return;
|
||||
}
|
||||
return returnedValueLiteral;
|
||||
|
||||
List<JsStatement> result = new ArrayList<JsStatement>();
|
||||
result.add(vars);
|
||||
result.add(new JsReturn(valueLiteral));
|
||||
dummyFunction.setBody(newBlock(result));
|
||||
classesVar.setInitExpr(AstUtil.newInvocation(dummyFunction));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsPropertyInitializer classEntry(@NotNull JsName localName) {
|
||||
return new JsPropertyInitializer(localToGlobalClassName.get(localName).makeRef(), localName.makeRef());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<JsStatement> generateClassDeclarationStatements() {
|
||||
List<JsStatement> classDeclarations = new ArrayList<JsStatement>();
|
||||
for (JetClass jetClass : getClassDeclarations()) {
|
||||
classDeclarations.add(generateDeclaration(jetClass));
|
||||
private void generateOpenClassDeclarations(@NotNull JsVars vars, @NotNull List<JsPropertyInitializer> propertyInitializers) {
|
||||
ClassAliasingMap classAliasingMap = new OpenClassRefProvider();
|
||||
// first pass: set up list order
|
||||
for (ListItem item : openList) {
|
||||
item.translatedDeclaration = translateClassDeclaration(item.declaration, classAliasingMap, context());
|
||||
}
|
||||
return classDeclarations;
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
private List<JetClass> getClassDeclarations() {
|
||||
List<JetClass> classes = new ArrayList<JetClass>();
|
||||
for (ClassDescriptor classDescriptor : descriptors) {
|
||||
classes.add(BindingUtils.getClassForDescriptor(bindingContext(), classDescriptor));
|
||||
// second pass: generate
|
||||
for (ListItem item : openList) {
|
||||
generate(item, propertyInitializers, item.translatedDeclaration, vars);
|
||||
}
|
||||
return ClassSortingUtils.sortUsingInheritanceOrder(classes, bindingContext());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsStatement generateDeclaration(@NotNull JetClass declaration) {
|
||||
JsName localClassName = generateLocalAlias(declaration);
|
||||
JsExpression classDeclarationExpression =
|
||||
Translation.translateClassDeclaration(declaration, localToGlobalClassName.inverse(), context());
|
||||
return newVar(localClassName, classDeclarationExpression);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsName generateLocalAlias(@NotNull JetClass declaration) {
|
||||
JsName globalClassName = context().getNameForElement(declaration);
|
||||
JsName localAlias = dummyFunction.getScope().declareTemporary();
|
||||
localToGlobalClassName.put(localAlias, globalClassName);
|
||||
return localAlias;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<JsPropertyInitializer> classDeclarationsForNamespace(@NotNull NamespaceDescriptor namespaceDescriptor) {
|
||||
List<JsPropertyInitializer> result = Lists.newArrayList();
|
||||
for (ClassDescriptor classDescriptor : getAllClassesDefinedInNamespace(namespaceDescriptor)) {
|
||||
result.add(getClassNameToClassObject(classDescriptor));
|
||||
private void generateFinalClassDeclarations(@NotNull JsVars vars, @NotNull List<JsPropertyInitializer> propertyInitializers) {
|
||||
ClassAliasingMap classAliasingMap = new FinalClassRefProvider();
|
||||
for (ListItem item : finalList) {
|
||||
generate(item, propertyInitializers, translateClassDeclaration(item.declaration, classAliasingMap, context()), vars);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void generate(@NotNull ListItem item,
|
||||
@NotNull List<JsPropertyInitializer> propertyInitializers,
|
||||
@NotNull JsExpression definition,
|
||||
@NotNull JsVars vars) {
|
||||
JsExpression value;
|
||||
if (item.label.getName() == null) {
|
||||
value = definition;
|
||||
}
|
||||
else {
|
||||
assert item.label.getName() != null;
|
||||
vars.add(new JsVar(item.label.getName(), definition));
|
||||
value = item.label;
|
||||
}
|
||||
|
||||
propertyInitializers.add(new JsPropertyInitializer(item.label, value));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsPropertyInitializer getClassNameToClassObject(@NotNull ClassDescriptor classDescriptor) {
|
||||
JsName className = context().getNameForDescriptor(classDescriptor);
|
||||
JsNameRef alreadyDefinedClassReference = qualified(className, getDeclarationsObjectName().makeRef());
|
||||
return new JsPropertyInitializer(className.makeRef(), alreadyDefinedClassReference);
|
||||
public JsPropertyInitializer translateAndGetClassNameToClassObject(@NotNull JetClass declaration) {
|
||||
ClassDescriptor descriptor = getClassDescriptor(context().bindingContext(), declaration);
|
||||
|
||||
JsNameRef labelRef;
|
||||
String label = 'c' + Integer.toString(localNameCounter++, 36);
|
||||
boolean isFinal = descriptor.getModality() == Modality.FINAL;
|
||||
if (isFinal) {
|
||||
labelRef = new JsNameRef(label);
|
||||
}
|
||||
else {
|
||||
labelRef = dummyFunction.getScope().declareName(label).makeRef();
|
||||
}
|
||||
|
||||
ListItem item = new ListItem(declaration, labelRef);
|
||||
if (isFinal) {
|
||||
finalList.add(item);
|
||||
}
|
||||
else {
|
||||
openList.add(item);
|
||||
openClassToItem.put(declaration, item);
|
||||
}
|
||||
|
||||
JsNameRef qualifiedLabelRef = new JsNameRef(labelRef.getIdent());
|
||||
qualifiedLabelRef.setQualifier(declarationsObject.makeRef());
|
||||
JsExpression value;
|
||||
if (context().isEcma5()) {
|
||||
value = JsAstUtils.createDataDescriptor(qualifiedLabelRef, false, context());
|
||||
}
|
||||
else {
|
||||
value = qualifiedLabelRef;
|
||||
}
|
||||
|
||||
return new JsPropertyInitializer(context().program().getStringLiteral(descriptor.getName().getName()), value);
|
||||
}
|
||||
}
|
||||
|
||||
+21
-18
@@ -23,6 +23,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassKind;
|
||||
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetClass;
|
||||
import org.jetbrains.jet.lang.psi.JetClassOrObject;
|
||||
import org.jetbrains.jet.lang.psi.JetObjectLiteralExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetParameter;
|
||||
@@ -31,12 +32,11 @@ 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.BindingUtils;
|
||||
import org.jetbrains.k2js.translate.utils.JsAstUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.google.dart.compiler.util.AstUtil.newSequence;
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getClassDescriptor;
|
||||
@@ -64,8 +64,8 @@ public final class ClassTranslator extends AbstractTranslator {
|
||||
|
||||
@NotNull
|
||||
public static JsExpression generateClassCreationExpression(@NotNull JetClassOrObject classDeclaration,
|
||||
@NotNull Map<JsName, JsName> aliasingMap,
|
||||
@NotNull TranslationContext context) {
|
||||
@NotNull ClassAliasingMap aliasingMap,
|
||||
@NotNull TranslationContext context) {
|
||||
return (new ClassTranslator(classDeclaration, aliasingMap, context)).translateClassOrObjectCreation();
|
||||
}
|
||||
|
||||
@@ -73,13 +73,13 @@ public final class ClassTranslator extends AbstractTranslator {
|
||||
public static JsExpression generateClassCreationExpression(@NotNull JetClassOrObject classDeclaration,
|
||||
|
||||
@NotNull TranslationContext context) {
|
||||
return (new ClassTranslator(classDeclaration, Collections.<JsName, JsName>emptyMap(), context)).translateClassOrObjectCreation();
|
||||
return (new ClassTranslator(classDeclaration, null, context)).translateClassOrObjectCreation();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsExpression generateObjectLiteralExpression(@NotNull JetObjectLiteralExpression objectLiteralExpression,
|
||||
@NotNull TranslationContext context) {
|
||||
return (new ClassTranslator(objectLiteralExpression.getObjectDeclaration(), Collections.<JsName, JsName>emptyMap(), context))
|
||||
return (new ClassTranslator(objectLiteralExpression.getObjectDeclaration(), null, context))
|
||||
.translateObjectLiteralExpression();
|
||||
}
|
||||
|
||||
@@ -95,12 +95,12 @@ public final class ClassTranslator extends AbstractTranslator {
|
||||
@NotNull
|
||||
private final ClassDescriptor descriptor;
|
||||
|
||||
@NotNull
|
||||
private final Map<JsName, JsName> aliasingMap;
|
||||
@Nullable
|
||||
private final ClassAliasingMap aliasingMap;
|
||||
|
||||
private ClassTranslator(@NotNull JetClassOrObject classDeclaration,
|
||||
@NotNull Map<JsName, JsName> aliasingMap,
|
||||
@NotNull TranslationContext context) {
|
||||
@Nullable ClassAliasingMap aliasingMap,
|
||||
@NotNull TranslationContext context) {
|
||||
super(context.newDeclaration(classDeclaration));
|
||||
this.aliasingMap = aliasingMap;
|
||||
this.descriptor = getClassDescriptor(context.bindingContext(), classDeclaration);
|
||||
@@ -160,7 +160,7 @@ public final class ClassTranslator extends AbstractTranslator {
|
||||
if (!isTrait()) {
|
||||
JsFunction initializer = Translation.generateClassInitializerMethod(classDeclaration, classDeclarationContext);
|
||||
if (context().isEcma5()) {
|
||||
jsClassDeclaration.getArguments().add(isObject() ? initializer : JsAstUtils.encloseFunction(initializer));
|
||||
jsClassDeclaration.getArguments().add(initializer.getName() == null ? initializer : JsAstUtils.encloseFunction(initializer));
|
||||
}
|
||||
else {
|
||||
propertyList.add(InitializerUtils.generateInitializeMethod(initializer));
|
||||
@@ -209,8 +209,7 @@ public final class ClassTranslator extends AbstractTranslator {
|
||||
|
||||
private void addTraits(@NotNull List<JsExpression> superclassReferences,
|
||||
@NotNull List<ClassDescriptor> superclassDescriptors) {
|
||||
for (ClassDescriptor superClassDescriptor :
|
||||
superclassDescriptors) {
|
||||
for (ClassDescriptor superClassDescriptor : superclassDescriptors) {
|
||||
assert (superClassDescriptor.getKind() == ClassKind.TRAIT) : "Only traits are expected here";
|
||||
superclassReferences.add(getClassReference(superClassDescriptor));
|
||||
}
|
||||
@@ -227,12 +226,16 @@ public final class ClassTranslator extends AbstractTranslator {
|
||||
|
||||
@NotNull
|
||||
private JsExpression getClassReference(@NotNull ClassDescriptor superClassDescriptor) {
|
||||
//NOTE: aliasing here is needed for the declaration generation step
|
||||
JsName name = context().getNameForDescriptor(superClassDescriptor);
|
||||
JsName alias = aliasingMap.get(name);
|
||||
if (alias != null) {
|
||||
return alias.makeRef();
|
||||
// aliasing here is needed for the declaration generation step
|
||||
if (aliasingMap != null) {
|
||||
JsNameRef name = aliasingMap.get(BindingUtils.getClassForDescriptor(bindingContext(), superClassDescriptor),
|
||||
(JetClass) classDeclaration);
|
||||
if (name != null) {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
// from library
|
||||
return getQualifiedReference(context(), superClassDescriptor);
|
||||
}
|
||||
|
||||
|
||||
+20
-5
@@ -19,6 +19,7 @@ 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.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
||||
@@ -39,6 +40,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 +63,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 +74,11 @@ 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();
|
||||
}
|
||||
|
||||
return Collections.singletonList(classDeclarationTranslator.translateAndGetClassNameToClassObject(expression));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -71,10 +87,9 @@ public final class DeclarationBodyVisitor extends TranslatorVisitor<List<JsPrope
|
||||
@NotNull TranslationContext context) {
|
||||
JsPropertyInitializer methodAsPropertyInitializer = Translation.functionTranslator(expression, context).translateAsMethod();
|
||||
if (context.isEcma5()) {
|
||||
final FunctionDescriptor descriptor = getFunctionDescriptor(context.bindingContext(), expression);
|
||||
boolean overridable = descriptor.getModality().isOverridable();
|
||||
FunctionDescriptor descriptor = getFunctionDescriptor(context.bindingContext(), expression);
|
||||
JsExpression methodBodyExpression = methodAsPropertyInitializer.getValueExpr();
|
||||
methodAsPropertyInitializer.setValueExpr(JsAstUtils.createPropertyDataDescriptor(overridable, methodBodyExpression, context));
|
||||
methodAsPropertyInitializer.setValueExpr(JsAstUtils.createPropertyDataDescriptor(descriptor, methodBodyExpression, context));
|
||||
}
|
||||
return Collections.singletonList(methodAsPropertyInitializer);
|
||||
}
|
||||
|
||||
+35
-57
@@ -17,26 +17,25 @@
|
||||
package org.jetbrains.k2js.translate.declaration;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.dart.compiler.backend.js.ast.*;
|
||||
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||
import com.google.dart.compiler.backend.js.ast.JsNameRef;
|
||||
import com.google.dart.compiler.backend.js.ast.JsObjectLiteral;
|
||||
import com.google.dart.compiler.backend.js.ast.JsStatement;
|
||||
import com.google.dart.compiler.util.AstUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.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;
|
||||
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
|
||||
@@ -57,40 +56,22 @@ public final class NamespaceDeclarationTranslator extends AbstractTranslator {
|
||||
@NotNull TranslationContext context) {
|
||||
super(context);
|
||||
this.namespaceDescriptors = namespaceDescriptors;
|
||||
this.classDeclarationTranslator = new ClassDeclarationTranslator(getAllClasses(), context);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<ClassDescriptor> getAllClasses() {
|
||||
List<ClassDescriptor> result = Lists.newArrayList();
|
||||
for (NamespaceDescriptor namespaceDescriptor : namespaceDescriptors) {
|
||||
result.addAll(getAllClassesDefinedInNamespace(namespaceDescriptor));
|
||||
}
|
||||
return result;
|
||||
classDeclarationTranslator = new ClassDeclarationTranslator(context);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<JsStatement> translate() {
|
||||
List<JsStatement> result = classesDeclarations();
|
||||
result.addAll(namespacesDeclarations());
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<JsStatement> classesDeclarations() {
|
||||
List<JsStatement> result = Lists.newArrayList();
|
||||
classDeclarationTranslator.generateDeclarations();
|
||||
List<JsStatement> result = new ArrayList<JsStatement>();
|
||||
result.add(classDeclarationTranslator.getDeclarationsStatement());
|
||||
namespacesDeclarations(result);
|
||||
classDeclarationTranslator.generateDeclarations();
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<JsStatement> namespacesDeclarations() {
|
||||
List<JsStatement> result = Lists.newArrayList();
|
||||
private void namespacesDeclarations(List<JsStatement> statements) {
|
||||
List<NamespaceTranslator> namespaceTranslators = getTranslatorsForNonEmptyNamespaces();
|
||||
result.addAll(declarationStatements(namespaceTranslators, context()));
|
||||
result.addAll(initializeStatements(namespaceTranslators));
|
||||
return result;
|
||||
declarationStatements(namespaceTranslators, statements);
|
||||
initializeStatements(namespaceTranslators, statements);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -102,34 +83,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(@NotNull List<NamespaceTranslator> namespaceTranslators) {
|
||||
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
|
||||
@@ -144,10 +122,10 @@ public final class NamespaceDeclarationTranslator extends AbstractTranslator {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<NamespaceDescriptor> filterNonEmptyNamespaces(@NotNull List<NamespaceDescriptor> namespaceDescriptors) {
|
||||
private List<NamespaceDescriptor> filterNonEmptyNamespaces(@NotNull List<NamespaceDescriptor> namespaceDescriptors) {
|
||||
List<NamespaceDescriptor> result = Lists.newArrayList();
|
||||
for (NamespaceDescriptor descriptor : namespaceDescriptors) {
|
||||
if (!JsDescriptorUtils.isNamespaceEmpty(descriptor)) {
|
||||
if (!JsDescriptorUtils.isNamespaceEmpty(descriptor, context().bindingContext())) {
|
||||
result.add(descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
+48
-46
@@ -25,14 +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.List;
|
||||
|
||||
import static org.jetbrains.k2js.translate.utils.JsAstUtils.newObjectLiteral;
|
||||
import static org.jetbrains.k2js.translate.utils.JsAstUtils.newVar;
|
||||
|
||||
/**
|
||||
* @author Pavel.Talanov
|
||||
@@ -48,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) {
|
||||
@@ -57,82 +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();
|
||||
addNamespaceInitalizersAndProperties(namespaceDeclaration);
|
||||
namespaceDeclaration.getArguments().add(getClassesAndNestedNamespaces());
|
||||
addIfNeed(getFunctionsAndClasses(), namespaceDeclaration.getArguments());
|
||||
addIfNeed(getNestedNamespaceDeclarations(), namespaceDeclaration.getArguments());
|
||||
return namespaceDeclaration;
|
||||
}
|
||||
|
||||
private void addNamespaceInitalizersAndProperties(@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, 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 static void addEcma5InitializersAndProperties(@NotNull JsInvocation namespaceDeclaration,
|
||||
@NotNull JsFunction initializer,
|
||||
@NotNull List<JsPropertyInitializer> properties) {
|
||||
namespaceDeclaration.getArguments().add(initializer);
|
||||
namespaceDeclaration.getArguments().add(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 Lists.newArrayList();
|
||||
}
|
||||
List<JsPropertyInitializer> result = Lists.newArrayList();
|
||||
List<NamespaceDescriptor> nestedNamespaces = JsDescriptorUtils.getNestedNamespaces(descriptor);
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -116,12 +116,11 @@ public final class WhenTranslator extends AbstractTranslator {
|
||||
return statementToExecute;
|
||||
}
|
||||
JsExpression condition = translateConditions(entry);
|
||||
return new JsIf(condition, addDummyBreak(statementToExecute), null);
|
||||
return new JsIf(condition, addDummyBreakIfNeed(statementToExecute), null);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
JsStatement withReturnValueCaptured(@NotNull JsNode node) {
|
||||
|
||||
return convertToStatement(LastExpressionMutator.mutateLastExpression(node,
|
||||
new AssignToExpressionMutator(result.reference())));
|
||||
}
|
||||
@@ -172,8 +171,8 @@ public final class WhenTranslator extends AbstractTranslator {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static JsBlock addDummyBreak(@NotNull JsStatement statement) {
|
||||
return AstUtil.newBlock(statement, new JsBreak());
|
||||
private static JsStatement addDummyBreakIfNeed(@NotNull JsStatement statement) {
|
||||
return statement instanceof JsReturn ? statement : AstUtil.newBlock(statement, new JsBreak());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+2
-4
@@ -31,9 +31,7 @@ import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.general.Translation;
|
||||
import org.jetbrains.k2js.translate.reference.CallBuilder;
|
||||
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getHasNextCallable;
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getIteratorFunction;
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getNextFunction;
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.*;
|
||||
import static org.jetbrains.k2js.translate.utils.JsAstUtils.convertToBlock;
|
||||
import static org.jetbrains.k2js.translate.utils.JsAstUtils.newVar;
|
||||
import static org.jetbrains.k2js.translate.utils.PsiUtils.getLoopBody;
|
||||
@@ -104,7 +102,7 @@ public final class IteratorForTranslator extends ForTranslator {
|
||||
|
||||
// kotlin iterator define hasNext as property, but java util as function, our js side expects as property
|
||||
private static boolean isJavaUtilIterator(CallableDescriptor descriptor) {
|
||||
final DeclarationDescriptor declaration = descriptor.getContainingDeclaration();
|
||||
DeclarationDescriptor declaration = descriptor.getContainingDeclaration();
|
||||
return declaration != null && declaration.getName().getName().equals("Iterator");
|
||||
}
|
||||
|
||||
|
||||
@@ -19,8 +19,10 @@ 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.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
@@ -28,7 +30,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;
|
||||
@@ -36,6 +38,7 @@ import org.jetbrains.k2js.facade.exceptions.TranslationInternalException;
|
||||
import org.jetbrains.k2js.facade.exceptions.UnsupportedFeatureException;
|
||||
import org.jetbrains.k2js.translate.context.StaticContext;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.declaration.ClassAliasingMap;
|
||||
import org.jetbrains.k2js.translate.declaration.ClassTranslator;
|
||||
import org.jetbrains.k2js.translate.declaration.NamespaceDeclarationTranslator;
|
||||
import org.jetbrains.k2js.translate.expression.ExpressionVisitor;
|
||||
@@ -52,7 +55,6 @@ import org.jetbrains.k2js.translate.utils.dangerous.DangerousTranslator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.jetbrains.jet.plugin.JetMainDetector.getMainFunction;
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptor;
|
||||
@@ -83,9 +85,9 @@ public final class Translation {
|
||||
|
||||
@NotNull
|
||||
public static JsExpression translateClassDeclaration(@NotNull JetClass classDeclaration,
|
||||
@NotNull Map<JsName, JsName> aliasingMap,
|
||||
@NotNull ClassAliasingMap classAliasingMap,
|
||||
@NotNull TranslationContext context) {
|
||||
return ClassTranslator.generateClassCreationExpression(classDeclaration, aliasingMap, context);
|
||||
return ClassTranslator.generateClassCreationExpression(classDeclaration, classAliasingMap, context);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -148,10 +150,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 +166,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,8 +179,13 @@ 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()));
|
||||
JsStatement statement = generateCallToMain(context, files, mainCallParameters.arguments());
|
||||
if (statement != null) {
|
||||
statements.add(statement);
|
||||
}
|
||||
}
|
||||
generateTestCalls(context, files, block, rawStatements);
|
||||
JsNamer namer = new JsPrettyNamer();
|
||||
@@ -186,12 +193,20 @@ public final class Translation {
|
||||
return context.program();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
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());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static JsStatement generateCallToMain(@NotNull TranslationContext context, @NotNull List<JetFile> files,
|
||||
@NotNull List<String> arguments) throws MainFunctionNotFoundException {
|
||||
JetNamedFunction mainFunction = getMainFunction(files);
|
||||
if (mainFunction == null) {
|
||||
throw new MainFunctionNotFoundException("Main function was not found. Please check compiler arguments");
|
||||
return null;
|
||||
}
|
||||
JsInvocation translatedCall = generateInvocation(context, mainFunction);
|
||||
setArguments(context, arguments, translatedCall);
|
||||
@@ -214,12 +229,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 +243,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 {
|
||||
|
||||
+4
-3
@@ -19,6 +19,7 @@ package org.jetbrains.k2js.translate.operation;
|
||||
import com.google.dart.compiler.backend.js.ast.JsBinaryOperation;
|
||||
import com.google.dart.compiler.backend.js.ast.JsConditional;
|
||||
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||
import com.google.dart.compiler.backend.js.ast.JsNameRef;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.psi.JetUnaryExpression;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
@@ -62,9 +63,9 @@ public final class UnaryOperationTranslator {
|
||||
|
||||
@NotNull
|
||||
private static JsExpression translateExclExclOperator(@NotNull JetUnaryExpression expression, @NotNull TranslationContext context) {
|
||||
JsExpression translatedExpression = translateAsExpression(getBaseExpression(expression), context);
|
||||
JsBinaryOperation notNullCheck = notNullCheck(context, translatedExpression);
|
||||
return new JsConditional(notNullCheck, translatedExpression, context.namer().throwNPEFunctionCall());
|
||||
JsNameRef cachedValue = context.declareTemporary(translateAsExpression(getBaseExpression(expression), context), true).reference();
|
||||
JsBinaryOperation notNullCheck = notNullCheck(context, cachedValue);
|
||||
return new JsConditional(notNullCheck, cachedValue, context.namer().throwNPEFunctionCall());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -107,8 +107,10 @@ public final class CallBuilder {
|
||||
private CallTranslator finish() {
|
||||
if (resolvedCall == null) {
|
||||
assert descriptor != null;
|
||||
resolvedCall = ResolvedCallImpl.create(ResolutionCandidate.create(descriptor, false),
|
||||
TemporaryBindingTrace.create(new BindingTraceContext())); //todo
|
||||
resolvedCall = ResolvedCallImpl.create(ResolutionCandidate.create(descriptor, descriptor.getExpectedThisObject(),
|
||||
descriptor.getReceiverParameter(),
|
||||
ExplicitReceiverKind.THIS_OBJECT, false),
|
||||
TemporaryBindingTrace.create(new BindingTraceContext()));
|
||||
}
|
||||
if (descriptor == null) {
|
||||
descriptor = resolvedCall.getCandidateDescriptor().getOriginal();
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.jetbrains.k2js.translate.utils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassKind;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||
@@ -31,6 +32,8 @@ import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.getContaining
|
||||
*/
|
||||
public final class AnnotationsUtils {
|
||||
|
||||
private static final String ENUMERABLE = "js.enumerable";
|
||||
|
||||
private AnnotationsUtils() {
|
||||
}
|
||||
|
||||
@@ -69,10 +72,14 @@ public final class AnnotationsUtils {
|
||||
|
||||
@Nullable
|
||||
private static AnnotationDescriptor getAnnotationByName(@NotNull DeclarationDescriptor descriptor,
|
||||
@NotNull PredefinedAnnotation annotation) {
|
||||
@NotNull PredefinedAnnotation annotation) {
|
||||
return getAnnotationByName(descriptor, annotation.getFQName());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static AnnotationDescriptor getAnnotationByName(@NotNull DeclarationDescriptor descriptor, @NotNull String fqn) {
|
||||
for (AnnotationDescriptor annotationDescriptor : descriptor.getAnnotations()) {
|
||||
String annotationClassFQName = getAnnotationClassFQName(annotationDescriptor);
|
||||
if (annotationClassFQName.equals(annotation.getFQName())) {
|
||||
if (getAnnotationClassFQName(annotationDescriptor).equals(fqn)) {
|
||||
return annotationDescriptor;
|
||||
}
|
||||
}
|
||||
@@ -91,6 +98,16 @@ public final class AnnotationsUtils {
|
||||
return hasAnnotationOrInsideAnnotatedClass(descriptor, PredefinedAnnotation.NATIVE);
|
||||
}
|
||||
|
||||
public static boolean isEnumerable(@NotNull DeclarationDescriptor descriptor) {
|
||||
if (getAnnotationByName(descriptor, ENUMERABLE) != null) {
|
||||
return true;
|
||||
}
|
||||
ClassDescriptor containingClass = getContainingClass(descriptor);
|
||||
return containingClass != null &&
|
||||
(getAnnotationByName(containingClass, ENUMERABLE) != null ||
|
||||
(containingClass.getKind().equals(ClassKind.OBJECT) && containingClass.getName().isSpecial()));
|
||||
}
|
||||
|
||||
public static boolean isLibraryObject(@NotNull DeclarationDescriptor descriptor) {
|
||||
return hasAnnotationOrInsideAnnotatedClass(descriptor, PredefinedAnnotation.LIBRARY);
|
||||
}
|
||||
@@ -105,14 +122,15 @@ public final class AnnotationsUtils {
|
||||
}
|
||||
|
||||
public static boolean hasAnnotationOrInsideAnnotatedClass(@NotNull DeclarationDescriptor descriptor,
|
||||
@NotNull PredefinedAnnotation annotation) {
|
||||
if (getAnnotationByName(descriptor, annotation) != null) {
|
||||
@NotNull PredefinedAnnotation annotation) {
|
||||
return hasAnnotationOrInsideAnnotatedClass(descriptor, annotation.getFQName());
|
||||
}
|
||||
|
||||
private static boolean hasAnnotationOrInsideAnnotatedClass(@NotNull DeclarationDescriptor descriptor, @NotNull String fqn) {
|
||||
if (getAnnotationByName(descriptor, fqn) != null) {
|
||||
return true;
|
||||
}
|
||||
ClassDescriptor containingClass = getContainingClass(descriptor);
|
||||
if (containingClass == null) {
|
||||
return false;
|
||||
}
|
||||
return (getAnnotationByName(containingClass, annotation) != null);
|
||||
return containingClass != null && getAnnotationByName(containingClass, fqn) != null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.*;
|
||||
@@ -110,7 +110,7 @@ public final class BindingUtils {
|
||||
public static List<JetDeclaration> getDeclarationsForNamespace(@NotNull BindingContext bindingContext,
|
||||
@NotNull NamespaceDescriptor namespace) {
|
||||
List<JetDeclaration> declarations = new ArrayList<JetDeclaration>();
|
||||
for (DeclarationDescriptor descriptor : getContainedDescriptorsWhichAreNotPredefined(namespace)) {
|
||||
for (DeclarationDescriptor descriptor : getContainedDescriptorsWhichAreNotPredefined(namespace, bindingContext)) {
|
||||
if (descriptor instanceof NamespaceDescriptor) {
|
||||
continue;
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.k2js.translate.utils;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetClass;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.getSuperclassDescriptors;
|
||||
|
||||
|
||||
//TODO: can optimise using less dumb implementation
|
||||
//TODO: pass list of descriptors here, not the list of jet classes
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public final class ClassSortingUtils {
|
||||
|
||||
private ClassSortingUtils() {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static List<JetClass> sortUsingInheritanceOrder(@NotNull List<JetClass> elements,
|
||||
@NotNull BindingContext bindingContext) {
|
||||
List<ClassDescriptor> descriptors = descriptorsFromClasses(elements, bindingContext);
|
||||
PartiallyOrderedSet<ClassDescriptor> partiallyOrderedSet
|
||||
= new PartiallyOrderedSet<ClassDescriptor>(descriptors, inheritanceOrder());
|
||||
List<JetClass> sortedClasses = descriptorsToClasses(partiallyOrderedSet.partiallySortedElements(), bindingContext);
|
||||
assert elements.size() == sortedClasses.size();
|
||||
return sortedClasses;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static PartiallyOrderedSet.Order<ClassDescriptor> inheritanceOrder() {
|
||||
return new PartiallyOrderedSet.Order<ClassDescriptor>() {
|
||||
@Override
|
||||
public boolean firstDependsOnSecond(@NotNull ClassDescriptor first, @NotNull ClassDescriptor second) {
|
||||
return isDerivedClass(first, second);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static boolean isDerivedClass(@NotNull ClassDescriptor ancestor, @NotNull ClassDescriptor derived) {
|
||||
return (getSuperclassDescriptors(derived).contains(ancestor));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<JetClass> descriptorsToClasses(@NotNull List<ClassDescriptor> descriptors,
|
||||
@NotNull BindingContext bindingContext) {
|
||||
List<JetClass> sortedClasses = Lists.newArrayList();
|
||||
for (ClassDescriptor descriptor : descriptors) {
|
||||
sortedClasses.add(BindingUtils.getClassForDescriptor(bindingContext, descriptor));
|
||||
}
|
||||
return sortedClasses;
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
private static List<ClassDescriptor> descriptorsFromClasses(@NotNull List<JetClass> classesToSort,
|
||||
@NotNull BindingContext bindingContext) {
|
||||
List<ClassDescriptor> descriptorList = new ArrayList<ClassDescriptor>();
|
||||
for (JetClass jetClass : classesToSort) {
|
||||
descriptorList.add(BindingUtils.getClassDescriptor(bindingContext, jetClass));
|
||||
}
|
||||
return descriptorList;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -21,6 +21,8 @@ import com.google.dart.compiler.backend.js.ast.*;
|
||||
import com.google.dart.compiler.util.AstUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
|
||||
@@ -31,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() {
|
||||
@@ -289,20 +293,36 @@ public final class JsAstUtils {
|
||||
@NotNull TranslationContext context) {
|
||||
return AstUtil.newInvocation(DEFINE_PROPERTY, new JsThisRef(),
|
||||
context.program().getStringLiteral(context.getNameForDescriptor(descriptor).getIdent()),
|
||||
createPropertyDataDescriptor(descriptor.isVar(), value, context));
|
||||
createPropertyDataDescriptor(descriptor.isVar(), descriptor, value, context));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsObjectLiteral createPropertyDataDescriptor(boolean writable,
|
||||
public static JsObjectLiteral createPropertyDataDescriptor(@NotNull FunctionDescriptor 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));
|
||||
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) {
|
||||
meta.add(context.namer().writablePropertyDescriptorField());
|
||||
dataDescriptor.getPropertyInitializers().add(context.namer().writablePropertyDescriptorField());
|
||||
}
|
||||
return jsPropertyDescriptor;
|
||||
return dataDescriptor;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static JsObjectLiteral createPropertyDataDescriptor(boolean writable,
|
||||
@NotNull DeclarationDescriptor descriptor,
|
||||
@NotNull JsExpression value,
|
||||
@NotNull TranslationContext context) {
|
||||
JsObjectLiteral dataDescriptor = createDataDescriptor(value, writable, context);
|
||||
if (AnnotationsUtils.isEnumerable(descriptor)) {
|
||||
dataDescriptor.getPropertyInitializers().add(context.namer().enumerablePropertyDescriptorField());
|
||||
}
|
||||
return dataDescriptor;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -17,15 +17,19 @@
|
||||
package org.jetbrains.k2js.translate.utils;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
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.name.Name;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
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.translate.context.Namer;
|
||||
import org.jetbrains.k2js.config.LibrarySourcesConfig;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
@@ -140,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) {
|
||||
@@ -193,22 +187,12 @@ public final class JsDescriptorUtils {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static List<ClassDescriptor> getAllClassesDefinedInNamespace(@NotNull NamespaceDescriptor namespaceDescriptor) {
|
||||
List<ClassDescriptor> classDescriptors = Lists.newArrayList();
|
||||
for (DeclarationDescriptor descriptor : getContainedDescriptorsWhichAreNotPredefined(namespaceDescriptor)) {
|
||||
if (descriptor instanceof ClassDescriptor) {
|
||||
classDescriptors.add((ClassDescriptor)descriptor);
|
||||
}
|
||||
}
|
||||
return classDescriptors;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static List<NamespaceDescriptor> getNestedNamespaces(@NotNull NamespaceDescriptor namespaceDescriptor) {
|
||||
public static List<NamespaceDescriptor> getNestedNamespaces(@NotNull NamespaceDescriptor namespaceDescriptor,
|
||||
@NotNull BindingContext context) {
|
||||
List<NamespaceDescriptor> result = Lists.newArrayList();
|
||||
for (DeclarationDescriptor descriptor : getContainedDescriptorsWhichAreNotPredefined(namespaceDescriptor)) {
|
||||
for (DeclarationDescriptor descriptor : getContainedDescriptorsWhichAreNotPredefined(namespaceDescriptor, context)) {
|
||||
if (descriptor instanceof NamespaceDescriptor) {
|
||||
result.add((NamespaceDescriptor)descriptor);
|
||||
result.add((NamespaceDescriptor) descriptor);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@@ -227,10 +211,22 @@ public final class JsDescriptorUtils {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static List<DeclarationDescriptor> getContainedDescriptorsWhichAreNotPredefined(@NotNull NamespaceDescriptor namespace) {
|
||||
public static List<DeclarationDescriptor> getContainedDescriptorsWhichAreNotPredefined(@NotNull NamespaceDescriptor namespace,
|
||||
@NotNull BindingContext context) {
|
||||
List<DeclarationDescriptor> result = Lists.newArrayList();
|
||||
for (DeclarationDescriptor descriptor : namespace.getMemberScope().getAllDescriptors()) {
|
||||
if (!AnnotationsUtils.isPredefinedObject(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);
|
||||
}
|
||||
}
|
||||
@@ -238,11 +234,11 @@ public final class JsDescriptorUtils {
|
||||
}
|
||||
|
||||
//TODO: at the moment this check is very ineffective
|
||||
public static boolean isNamespaceEmpty(@NotNull NamespaceDescriptor namespace) {
|
||||
List<DeclarationDescriptor> containedDescriptors = getContainedDescriptorsWhichAreNotPredefined(namespace);
|
||||
public static boolean isNamespaceEmpty(@NotNull NamespaceDescriptor namespace, @NotNull BindingContext context) {
|
||||
List<DeclarationDescriptor> containedDescriptors = getContainedDescriptorsWhichAreNotPredefined(namespace, context);
|
||||
for (DeclarationDescriptor descriptor : containedDescriptors) {
|
||||
if (descriptor instanceof NamespaceDescriptor) {
|
||||
if (!isNamespaceEmpty((NamespaceDescriptor)descriptor)) {
|
||||
if (!isNamespaceEmpty((NamespaceDescriptor) descriptor, context)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,121 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.k2js.translate.utils;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
* <p/>
|
||||
* This is very inefficient but simple implementation of partially orderered set.
|
||||
* Feel free to replace with library implementation.
|
||||
*/
|
||||
public final class PartiallyOrderedSet<Element> {
|
||||
|
||||
private class Arc {
|
||||
@NotNull
|
||||
public final Element from;
|
||||
@NotNull
|
||||
public final Element to;
|
||||
|
||||
private Arc(@NotNull Element from, @NotNull Element to) {
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}
|
||||
}
|
||||
|
||||
public interface Order<Element> {
|
||||
boolean firstDependsOnSecond(@NotNull Element first, @NotNull Element second);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private final List<Arc> arcs = Lists.newArrayList();
|
||||
@NotNull
|
||||
private final Map<Element, Integer> incomingArcs = Maps.newHashMap();
|
||||
@NotNull
|
||||
private final List<Element> elementsWithZeroIncoming = Lists.newArrayList();
|
||||
|
||||
public PartiallyOrderedSet(@NotNull Collection<Element> elements, @NotNull Order<Element> order) {
|
||||
elementsWithZeroIncoming.addAll(elements);
|
||||
for (@NotNull Element first : elements) {
|
||||
for (@NotNull Element second : elements) {
|
||||
if (order.firstDependsOnSecond(first, second)) {
|
||||
arcs.add(new Arc(first, second));
|
||||
increaseIncomingCount(second);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void increaseIncomingCount(@NotNull Element element) {
|
||||
if (!incomingArcs.containsKey(element)) {
|
||||
incomingArcs.put(element, 1);
|
||||
elementsWithZeroIncoming.remove(element);
|
||||
}
|
||||
else {
|
||||
Integer count = incomingArcs.get(element);
|
||||
incomingArcs.put(element, count + 1);
|
||||
}
|
||||
}
|
||||
|
||||
private void decreaseIncomingCount(@NotNull Element element) {
|
||||
assert incomingArcs.containsKey(element);
|
||||
Integer count = incomingArcs.get(element);
|
||||
if (count == 1) {
|
||||
incomingArcs.remove(element);
|
||||
elementsWithZeroIncoming.add(element);
|
||||
}
|
||||
else {
|
||||
incomingArcs.put(element, count - 1);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<Element> partiallySortedElements() {
|
||||
List<Element> result = Lists.newArrayList();
|
||||
while (!elementsWithZeroIncoming.isEmpty()) {
|
||||
result.add(getNextElement());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Element getNextElement() {
|
||||
Element elementWithZeroIncoming = getElementWithZeroIncoming();
|
||||
for (Arc arc : arcs) {
|
||||
if (arc.from == elementWithZeroIncoming) {
|
||||
decreaseIncomingCount(arc.to);
|
||||
}
|
||||
}
|
||||
return elementWithZeroIncoming;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Element getElementWithZeroIncoming() {
|
||||
int indexOfLast = elementsWithZeroIncoming.size() - 1;
|
||||
Element element = elementsWithZeroIncoming.get(indexOfLast);
|
||||
elementsWithZeroIncoming.remove(indexOfLast);
|
||||
return element;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -22,8 +22,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public enum PredefinedAnnotation {
|
||||
|
||||
|
||||
LIBRARY("js.library"),
|
||||
NATIVE("js.native");
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package foo
|
||||
|
||||
class SimpleEnumerator {
|
||||
private var counter = 0
|
||||
|
||||
fun getNext(): String {
|
||||
counter++;
|
||||
return counter.toString()
|
||||
}
|
||||
|
||||
fun hasMoreElements(): Boolean = counter < 1
|
||||
}
|
||||
|
||||
class SimpleEnumeratorWrapper(private val enumerator: SimpleEnumerator) {
|
||||
val hasNext: Boolean
|
||||
get() = enumerator.hasMoreElements()
|
||||
|
||||
fun next() = enumerator.getNext()
|
||||
}
|
||||
|
||||
fun SimpleEnumerator.iterator(): SimpleEnumeratorWrapper {
|
||||
return SimpleEnumeratorWrapper(this)
|
||||
}
|
||||
|
||||
fun box(): Boolean {
|
||||
var o = ""
|
||||
val enumerator = SimpleEnumerator()
|
||||
for (s in enumerator) {
|
||||
o += s;
|
||||
}
|
||||
|
||||
return o == "1"
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package foo
|
||||
|
||||
import java.util.ArrayList
|
||||
|
||||
fun box() : Boolean {
|
||||
var i = 0
|
||||
val list = ArrayList<Int>()
|
||||
while (i++ < 3) {
|
||||
list.add(i)
|
||||
}
|
||||
val array = list.toArray()
|
||||
return array[0] == 1 && array[1] == 2 && array[2] == 3
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -14,11 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
var foo = Kotlin.createNamespace({initialize:function(){
|
||||
}
|
||||
, box:function(){
|
||||
var foo = Kotlin.definePackage({box:function(){
|
||||
return !false;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -46,9 +46,7 @@
|
||||
return {A:A, B:B, C:C};
|
||||
}
|
||||
();
|
||||
var foo = Kotlin.createNamespace(classes, {initialize:function(){
|
||||
}
|
||||
, box:function(){
|
||||
var 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';
|
||||
}
|
||||
});
|
||||
|
||||
@@ -14,6 +14,11 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// todo org.jetbrains.k2js.test.semantics.WebDemoExamples2Test#testBuilder
|
||||
var kotlin = {set:function (receiver, key, value) {
|
||||
return receiver.put(key, value);
|
||||
}};
|
||||
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
@@ -23,10 +28,10 @@
|
||||
return obj1.equals(obj2);
|
||||
}
|
||||
}
|
||||
return (obj1 === obj2);
|
||||
return obj1 === obj2;
|
||||
};
|
||||
|
||||
Kotlin.defs = {};
|
||||
Kotlin.modules = {};
|
||||
Kotlin.Exceptions = {};
|
||||
Kotlin.Exception = Kotlin.$createClass();
|
||||
Kotlin.RuntimeException = Kotlin.$createClass(Kotlin.Exception);
|
||||
@@ -39,121 +44,126 @@
|
||||
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)();
|
||||
};
|
||||
|
||||
Kotlin.AbstractList = Kotlin.$createClass({
|
||||
set:function (index, value) {
|
||||
throw Kotlin.$new(Kotlin.Exceptions.UnsupportedOperationException)();
|
||||
},
|
||||
iterator:function () {
|
||||
return Kotlin.$new(Kotlin.ArrayIterator)(this);
|
||||
},
|
||||
isEmpty:function () {
|
||||
return (this.size() === 0);
|
||||
},
|
||||
add:function (element) {
|
||||
throw Kotlin.$new(Kotlin.Exceptions.UnsupportedOperationException)();
|
||||
},
|
||||
addAll:function (collection) {
|
||||
var it = collection.iterator();
|
||||
while (it.get_hasNext()) {
|
||||
this.add(it.next());
|
||||
}
|
||||
},
|
||||
remove:function(value) {
|
||||
for (var i = 0; i < this.$size; ++i) {
|
||||
if (this.array[i] == value) {
|
||||
this.removeByIndex(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
removeByIndex:function (index) {
|
||||
throw Kotlin.$new(Kotlin.Exceptions.UnsupportedOperationException)();
|
||||
},
|
||||
clear:function () {
|
||||
throw Kotlin.$new(Kotlin.Exceptions.UnsupportedOperationException)();
|
||||
},
|
||||
contains:function (obj) {
|
||||
for (var i = 0; i < this.$size; ++i) {
|
||||
if (Kotlin.equals(this.array[i], obj)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
function throwAbstractFunctionInvocationError() {
|
||||
throw new TypeError("Function is abstract");
|
||||
}
|
||||
|
||||
Kotlin.ArrayList = Kotlin.$createClass({
|
||||
initialize:function () {
|
||||
this.array = [];
|
||||
this.$size = 0;
|
||||
Kotlin.Iterator = Kotlin.$createClass({
|
||||
initialize: function () {
|
||||
},
|
||||
get:function (index) {
|
||||
if ((index < 0) || (index >= this.$size)) {
|
||||
throw Kotlin.Exceptions.IndexOutOfBounds;
|
||||
}
|
||||
return (this.array)[index];
|
||||
next: throwAbstractFunctionInvocationError,
|
||||
get_hasNext: throwAbstractFunctionInvocationError
|
||||
});
|
||||
|
||||
var ArrayIterator = Kotlin.$createClass(Kotlin.Iterator, {
|
||||
initialize: function (array) {
|
||||
this.array = array;
|
||||
this.size = array.length;
|
||||
this.index = 0;
|
||||
},
|
||||
set:function (index, value) {
|
||||
if ((index < 0) || (index >= this.$size)) {
|
||||
throw Kotlin.Exceptions.IndexOutOfBounds;
|
||||
}
|
||||
(this.array)[index] = value;
|
||||
next: function () {
|
||||
return this.array[this.index++];
|
||||
},
|
||||
size:function () {
|
||||
return this.$size;
|
||||
get_hasNext: function () {
|
||||
return this.index < this.size;
|
||||
}
|
||||
});
|
||||
|
||||
var ListIterator = Kotlin.$createClass(ArrayIterator, {
|
||||
initialize: function (list) {
|
||||
this.list = list;
|
||||
this.size = list.size();
|
||||
this.index = 0;
|
||||
},
|
||||
iterator:function () {
|
||||
return Kotlin.$new(Kotlin.ArrayIterator)(this);
|
||||
next: function () {
|
||||
return this.list.get(this.index++);
|
||||
},
|
||||
isEmpty:function () {
|
||||
return (this.$size === 0);
|
||||
get_hasNext: function () {
|
||||
return this.index < this.size;
|
||||
}
|
||||
});
|
||||
|
||||
Kotlin.AbstractList = Kotlin.$createClass({
|
||||
iterator: function () {
|
||||
return Kotlin.$new(ListIterator)(this);
|
||||
},
|
||||
add:function (element) {
|
||||
this.array[this.$size++] = element;
|
||||
isEmpty: function () {
|
||||
return this.size() == 0;
|
||||
},
|
||||
addAll:function (collection) {
|
||||
addAll: function (collection) {
|
||||
var it = collection.iterator();
|
||||
while (it.get_hasNext()) {
|
||||
this.add(it.next());
|
||||
}
|
||||
},
|
||||
remove:function(value) {
|
||||
for (var i = 0; i < this.$size; ++i) {
|
||||
if (this.array[i] == value) {
|
||||
this.removeByIndex(i);
|
||||
return;
|
||||
}
|
||||
remove: function (o) {
|
||||
var index = this.indexOf(o);
|
||||
if (index != -1) {
|
||||
this.removeAt(index);
|
||||
}
|
||||
},
|
||||
removeByIndex:function (index) {
|
||||
for (var i = index; i < this.$size - 1; ++i) {
|
||||
this.array[i] = this.array[i + 1];
|
||||
}
|
||||
this.$size--;
|
||||
},
|
||||
clear:function () {
|
||||
this.array = [];
|
||||
this.$size = 0;
|
||||
},
|
||||
contains:function (obj) {
|
||||
for (var i = 0; i < this.$size; ++i) {
|
||||
if (Kotlin.equals(this.array[i], obj)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
contains: function (o) {
|
||||
return this.indexOf(o) != -1;
|
||||
}
|
||||
});
|
||||
|
||||
Kotlin.ArrayList = Kotlin.$createClass(Kotlin.AbstractList, {
|
||||
initialize: function () {
|
||||
this.array = [];
|
||||
this.$size = 0;
|
||||
},
|
||||
get: function (index) {
|
||||
if (index < 0 || index >= this.$size) {
|
||||
throw Kotlin.Exceptions.IndexOutOfBounds;
|
||||
}
|
||||
return this.array[index];
|
||||
},
|
||||
set: function (index, value) {
|
||||
if (index < 0 || index >= this.$size) {
|
||||
throw Kotlin.Exceptions.IndexOutOfBounds;
|
||||
}
|
||||
this.array[index] = value;
|
||||
},
|
||||
toArray: function () {
|
||||
return this.array.slice(0, this.$size);
|
||||
},
|
||||
size: function () {
|
||||
return this.$size;
|
||||
},
|
||||
iterator: function () {
|
||||
return Kotlin.arrayIterator(this.array);
|
||||
},
|
||||
add: function (element) {
|
||||
this.array[this.$size++] = element;
|
||||
},
|
||||
addAt: function (index, element) {
|
||||
this.array.splice(index, 0, element);
|
||||
},
|
||||
removeAt: function (index) {
|
||||
this.array.splice(index, 1);
|
||||
this.$size--;
|
||||
},
|
||||
clear: function () {
|
||||
this.array.length = 0;
|
||||
this.$size = 0;
|
||||
},
|
||||
indexOf: function (o) {
|
||||
for (var i = 0, n = this.$size; i < n; ++i) {
|
||||
if (Kotlin.equals(this.array[i], o)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
});
|
||||
|
||||
Kotlin.parseInt = function (str) {
|
||||
return parseInt(str, 10);
|
||||
}
|
||||
;
|
||||
};
|
||||
|
||||
Kotlin.safeParseInt = function(str) {
|
||||
var r = parseInt(str, 10);
|
||||
@@ -207,57 +217,32 @@
|
||||
Kotlin.System.out().print(s);
|
||||
};
|
||||
|
||||
Kotlin.AbstractFunctionInvocationError = Kotlin.$createClass();
|
||||
|
||||
Kotlin.Iterator = Kotlin.$createClass({
|
||||
initialize:function () {
|
||||
},
|
||||
next:function () {
|
||||
throw Kotlin.$new(Kotlin.AbstractFunctionInvocationError)();
|
||||
},
|
||||
get_hasNext:function () {
|
||||
throw Kotlin.$new(Kotlin.AbstractFunctionInvocationError)();
|
||||
}
|
||||
});
|
||||
|
||||
Kotlin.Runnable = Kotlin.$createClass({
|
||||
run:function () {
|
||||
throw Kotlin.$new(Kotlin.AbstractFunctionInvocationError)();
|
||||
}
|
||||
});
|
||||
|
||||
Kotlin.ArrayIterator = Kotlin.$createClass(Kotlin.Iterator, {
|
||||
initialize: function (array) {
|
||||
this.array = array;
|
||||
this.index = 0;
|
||||
},
|
||||
next: function () {
|
||||
return this.array.get(this.index++);
|
||||
},
|
||||
get_hasNext: function () {
|
||||
return this.array.size() > this.index;
|
||||
}
|
||||
});
|
||||
|
||||
Kotlin.RangeIterator = Kotlin.$createClass(Kotlin.Iterator, {
|
||||
initialize:function (start, count, reversed) {
|
||||
initialize: function (start, count, reversed) {
|
||||
this.$start = start;
|
||||
this.$count = count;
|
||||
this.$reversed = reversed;
|
||||
this.$i = this.get_start();
|
||||
}, get_start:function () {
|
||||
},
|
||||
get_start: function () {
|
||||
return this.$start;
|
||||
}, get_count:function () {
|
||||
},
|
||||
get_count: function () {
|
||||
return this.$count;
|
||||
}, set_count:function (tmp$0) {
|
||||
},
|
||||
set_count: function (tmp$0) {
|
||||
this.$count = tmp$0;
|
||||
}, get_reversed:function () {
|
||||
},
|
||||
get_reversed: function () {
|
||||
return this.$reversed;
|
||||
}, get_i:function () {
|
||||
},
|
||||
get_i: function () {
|
||||
return this.$i;
|
||||
}, set_i:function (tmp$0) {
|
||||
},
|
||||
set_i: function (tmp$0) {
|
||||
this.$i = tmp$0;
|
||||
}, next:function () {
|
||||
},
|
||||
next: function () {
|
||||
this.set_count(this.get_count() - 1);
|
||||
if (this.get_reversed()) {
|
||||
this.set_i(this.get_i() - 1);
|
||||
@@ -273,44 +258,51 @@
|
||||
}
|
||||
});
|
||||
|
||||
Kotlin.NumberRange = Kotlin.$createClass({initialize:function (start, size, reversed) {
|
||||
this.$start = start;
|
||||
this.$size = size;
|
||||
this.$reversed = reversed;
|
||||
}, get_start:function () {
|
||||
return this.$start;
|
||||
}, get_size:function () {
|
||||
return this.$size;
|
||||
}, get_reversed:function () {
|
||||
return this.$reversed;
|
||||
}, get_end:function () {
|
||||
return this.get_reversed() ? this.get_start() - this.get_size() + 1 : this.get_start() + this.get_size() - 1;
|
||||
}, contains:function (number) {
|
||||
if (this.get_reversed()) {
|
||||
return number <= this.get_start() && number > this.get_start() - this.get_size();
|
||||
Kotlin.NumberRange = Kotlin.$createClass({
|
||||
initialize: function (start, size, reversed) {
|
||||
this.$start = start;
|
||||
this.$size = size;
|
||||
this.$reversed = reversed;
|
||||
},
|
||||
get_start: function () {
|
||||
return this.$start;
|
||||
},
|
||||
get_size: function () {
|
||||
return this.$size;
|
||||
},
|
||||
get_reversed: function () {
|
||||
return this.$reversed;
|
||||
},
|
||||
get_end: function () {
|
||||
return this.get_reversed() ? this.get_start() - this.get_size() + 1 : this.get_start() + this.get_size() - 1;
|
||||
},
|
||||
contains: function (number) {
|
||||
if (this.get_reversed()) {
|
||||
return number <= this.get_start() && number > this.get_start() - this.get_size();
|
||||
}
|
||||
else {
|
||||
return number >= this.get_start() && number < this.get_start() + this.get_size();
|
||||
}
|
||||
},
|
||||
iterator: function () {
|
||||
return Kotlin.$new(Kotlin.RangeIterator)(this.get_start(), this.get_size(), this.get_reversed());
|
||||
}
|
||||
else {
|
||||
return number >= this.get_start() && number < this.get_start() + this.get_size();
|
||||
}
|
||||
}, iterator:function () {
|
||||
return Kotlin.$new(Kotlin.RangeIterator)(this.get_start(), this.get_size(), this.get_reversed());
|
||||
}
|
||||
});
|
||||
|
||||
Kotlin.Comparator = Kotlin.$createClass(
|
||||
{
|
||||
initialize: function () {
|
||||
},
|
||||
compare: function (el1, el2) {
|
||||
throw Kotlin.$new(Kotlin.AbstractFunctionInvocationError)();
|
||||
}
|
||||
Kotlin.Comparator = Kotlin.$createClass({
|
||||
initialize: function () {
|
||||
},
|
||||
compare: throwAbstractFunctionInvocationError
|
||||
});
|
||||
|
||||
var ComparatorImpl = Kotlin.$createClass(Kotlin.Comparator, {
|
||||
initialize: function (comparator) {
|
||||
this.compare = comparator;
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
Kotlin.comparator = function (f) {
|
||||
var result = Kotlin.$new(Kotlin.Comparator)();
|
||||
result.compare = f;
|
||||
return result;
|
||||
return Kotlin.$new(ComparatorImpl)(f);
|
||||
};
|
||||
|
||||
Kotlin.collectionsMax = function (col, comp) {
|
||||
@@ -369,25 +361,8 @@
|
||||
return Kotlin.$new(Kotlin.NumberRange)(0, arr.length);
|
||||
};
|
||||
|
||||
var intrinsicArrayIterator = Kotlin.$createClass(
|
||||
Kotlin.Iterator,
|
||||
{
|
||||
initialize: function (arr) {
|
||||
this.arr = arr;
|
||||
this.len = arr.length;
|
||||
this.i = 0;
|
||||
},
|
||||
next: function () {
|
||||
return this.arr[this.i++];
|
||||
},
|
||||
get_hasNext: function () {
|
||||
return this.i < this.len;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
Kotlin.arrayIterator = function (arr) {
|
||||
return Kotlin.$new(intrinsicArrayIterator)(arr);
|
||||
Kotlin.arrayIterator = function (array) {
|
||||
return Kotlin.$new(ArrayIterator)(array);
|
||||
};
|
||||
|
||||
Kotlin.toString = function (obj) {
|
||||
@@ -796,14 +771,11 @@
|
||||
Kotlin.HashTable = Hashtable;
|
||||
})();
|
||||
|
||||
Kotlin.HashMap = Kotlin.$createClass(
|
||||
{
|
||||
initialize:function () {
|
||||
Kotlin.HashTable.call(this);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
Kotlin.HashMap = Kotlin.$createClass({
|
||||
initialize: function () {
|
||||
Kotlin.HashTable.call(this);
|
||||
}
|
||||
});
|
||||
|
||||
(function () {
|
||||
function HashSet(hashingFunction, equalityFunction) {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
/* Prototype JavaScript framework, version 1.6.1
|
||||
* (c) 2005-2009 Sam Stephenson
|
||||
*
|
||||
* Prototype is freely distributable under the terms of an MIT-style license.
|
||||
* For details, see the Prototype web site: http://www.prototypejs.org/
|
||||
*
|
||||
*--------------------------------------------------------------------------*/
|
||||
/* Prototype JavaScript framework, version 1.6.1
|
||||
* (c) 2005-2009 Sam Stephenson
|
||||
*
|
||||
* Prototype is freely distributable under the terms of an MIT-style license.
|
||||
* For details, see the Prototype web site: http://www.prototypejs.org/
|
||||
*
|
||||
*--------------------------------------------------------------------------*/
|
||||
var Kotlin = {};
|
||||
|
||||
(function () {
|
||||
@@ -12,13 +12,14 @@ var Kotlin = {};
|
||||
var emptyFunction = function () {
|
||||
};
|
||||
|
||||
function $A(iterable) {
|
||||
if (!iterable) return [];
|
||||
if ('toArray' in Object(iterable)) return iterable.toArray();
|
||||
var length = iterable.length || 0, results = new Array(length);
|
||||
while (length--) results[length] = iterable[length];
|
||||
return results;
|
||||
}
|
||||
Kotlin.argumentsToArrayLike = function (args) {
|
||||
var n = args.length;
|
||||
var result = new Array(n);
|
||||
while (n--) {
|
||||
result[n] = args[n];
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
(function () {
|
||||
function extend(destination, source) {
|
||||
@@ -62,11 +63,6 @@ var Kotlin = {};
|
||||
return array;
|
||||
}
|
||||
|
||||
function merge(array, args) {
|
||||
array = slice.call(array, 0);
|
||||
return update(array, args);
|
||||
}
|
||||
|
||||
function argumentNames() {
|
||||
var names = this.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1]
|
||||
.replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g, '')
|
||||
@@ -74,15 +70,6 @@ var Kotlin = {};
|
||||
return names.length == 1 && !names[0] ? [] : names;
|
||||
}
|
||||
|
||||
function bind(context) {
|
||||
if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this;
|
||||
var __method = this, args = slice.call(arguments, 1);
|
||||
return function () {
|
||||
var a = merge(args, arguments);
|
||||
return __method.apply(context, a);
|
||||
};
|
||||
}
|
||||
|
||||
function bindAsEventListener(context) {
|
||||
var __method = this, args = slice.call(arguments, 1);
|
||||
return function (event) {
|
||||
@@ -101,7 +88,6 @@ var Kotlin = {};
|
||||
|
||||
return {
|
||||
argumentNames: argumentNames,
|
||||
bind: bind,
|
||||
bindAsEventListener: bindAsEventListener,
|
||||
wrap: wrap
|
||||
};
|
||||
@@ -129,21 +115,18 @@ var Kotlin = {};
|
||||
var property = properties[i];
|
||||
object[property] = source[property];
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
return function () {
|
||||
var result = {};
|
||||
for (var i = 0, length = arguments.length; i < length; i++) {
|
||||
var result = arguments[0];
|
||||
for (var i = 1, n = arguments.length; i < n; i++) {
|
||||
add(result, arguments[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
})();
|
||||
|
||||
Kotlin.createNamespace = function () {
|
||||
return Kotlin.createTrait.apply(null, arguments);
|
||||
};
|
||||
Kotlin.definePackage = Kotlin.createTrait;
|
||||
|
||||
Kotlin.createClass = (function () {
|
||||
var METHODS = {addMethods: addMethods};
|
||||
@@ -152,7 +135,7 @@ var Kotlin = {};
|
||||
}
|
||||
|
||||
function create() {
|
||||
var parent = null, properties = $A(arguments);
|
||||
var parent = null, properties = Kotlin.argumentsToArrayLike(arguments);
|
||||
if (typeof (properties[0]) == "function") {
|
||||
parent = properties.shift();
|
||||
}
|
||||
@@ -243,4 +226,12 @@ var Kotlin = {};
|
||||
var singletonClass = Kotlin.createClass.apply(null, arguments);
|
||||
return new singletonClass();
|
||||
};
|
||||
})();
|
||||
|
||||
Kotlin.defineModule = function (id, module) {
|
||||
if ((id in Kotlin.modules) && (id !== "JS_TESTS")) {
|
||||
throw Kotlin.$new(Kotlin.Exceptions.IllegalArgumentException)();
|
||||
}
|
||||
|
||||
Kotlin.modules[id] = module;
|
||||
};
|
||||
})();
|
||||
@@ -20,89 +20,75 @@ var Kotlin = {};
|
||||
return false;
|
||||
};
|
||||
|
||||
// todo compatibility for opera https://raw.github.com/gist/1000718/es5compat-gs.js
|
||||
// as separated function to reduce scope
|
||||
function createConstructor(proto, initializer) {
|
||||
return function () {
|
||||
var o = Object.create(proto);
|
||||
if (initializer != null) {
|
||||
initializer.apply(o, arguments);
|
||||
}
|
||||
|
||||
Object.seal(o);
|
||||
return o;
|
||||
};
|
||||
}
|
||||
|
||||
function computeProto(bases, properties) {
|
||||
var proto = null;
|
||||
for (var i = 0, n = bases.length; i < n; i++) {
|
||||
var base = bases[i];
|
||||
var baseProto = base.proto;
|
||||
if (baseProto == null || base.properties == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!proto) {
|
||||
proto = Object.create(baseProto, properties || undefined);
|
||||
continue;
|
||||
}
|
||||
Object.defineProperties(proto, base.properties);
|
||||
// todo test A -> B, C(->D) *properties from D is not yet added to proto*
|
||||
}
|
||||
|
||||
return proto;
|
||||
}
|
||||
|
||||
// proto must be created for class even if it is not needed (requires for is operator)
|
||||
Kotlin.createClass = (function () {
|
||||
function create(bases, initializer, properties) {
|
||||
var proto;
|
||||
var baseInitializer = null;
|
||||
var isTrait = initializer == null;
|
||||
if (!bases) {
|
||||
proto = !properties && isTrait ? null : Object.create(null, properties || undefined);
|
||||
Kotlin.createClass = function (bases, initializer, properties) {
|
||||
var proto;
|
||||
var baseInitializer = null;
|
||||
var isTrait = initializer == null;
|
||||
if (!bases) {
|
||||
proto = !properties && isTrait ? null : Object.create(null, properties || undefined);
|
||||
}
|
||||
else if (!Array.isArray(bases)) {
|
||||
baseInitializer = bases.initializer;
|
||||
proto = !properties && isTrait ? bases.proto : Object.create(bases.proto, properties || undefined);
|
||||
}
|
||||
else {
|
||||
proto = computeProto(bases, properties);
|
||||
// first is superclass, other are traits
|
||||
baseInitializer = bases[0].initializer;
|
||||
// all bases are traits without properties
|
||||
if (proto == null && !isTrait) {
|
||||
proto = Object.create(null, properties || undefined);
|
||||
}
|
||||
else if (!Array.isArray(bases)) {
|
||||
baseInitializer = bases.initializer;
|
||||
proto = !properties && isTrait ? bases.proto : Object.create(bases.proto, properties || undefined);
|
||||
}
|
||||
else {
|
||||
proto = computeProto(bases, properties);
|
||||
// first is superclass, other are traits
|
||||
baseInitializer = bases[0].initializer;
|
||||
// all bases are traits without properties
|
||||
if (proto == null && !isTrait) {
|
||||
proto = Object.create(null, properties || undefined);
|
||||
}
|
||||
}
|
||||
|
||||
var constructor = createConstructor(proto, initializer);
|
||||
Object.defineProperty(constructor, "proto", {value: proto});
|
||||
Object.defineProperty(constructor, "properties", {value: properties || null});
|
||||
// null for trait
|
||||
if (!isTrait) {
|
||||
Object.defineProperty(constructor, "initializer", {value: initializer});
|
||||
|
||||
Object.defineProperty(initializer, "baseInitializer", {value: baseInitializer});
|
||||
Object.seal(initializer);
|
||||
}
|
||||
|
||||
Object.seal(constructor);
|
||||
return constructor;
|
||||
}
|
||||
|
||||
// as separate function to reduce scope
|
||||
function createConstructor(proto, initializer) {
|
||||
return function () {
|
||||
var o = Object.create(proto);
|
||||
if (initializer != null) {
|
||||
initializer.apply(o, arguments);
|
||||
}
|
||||
if (initializer == null || !initializer.hasOwnProperty("skipSeal")) {
|
||||
Object.seal(o);
|
||||
}
|
||||
return o;
|
||||
};
|
||||
var constructor = createConstructor(proto, initializer);
|
||||
Object.defineProperty(constructor, "proto", {value: proto});
|
||||
Object.defineProperty(constructor, "properties", {value: properties || null});
|
||||
// null for trait
|
||||
if (!isTrait) {
|
||||
Object.defineProperty(constructor, "initializer", {value: initializer});
|
||||
|
||||
Object.defineProperty(initializer, "baseInitializer", {value: baseInitializer});
|
||||
Object.freeze(initializer);
|
||||
}
|
||||
|
||||
function computeProto(bases, properties) {
|
||||
var proto = null;
|
||||
for (var i = 0, n = bases.length; i < n; i++) {
|
||||
var base = bases[i];
|
||||
var baseProto = base.proto;
|
||||
if (baseProto == null || base.properties == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!proto) {
|
||||
proto = Object.create(baseProto, properties || undefined);
|
||||
continue;
|
||||
}
|
||||
|
||||
// chrome bug related to getOwnPropertyDescriptor (sometimes returns undefined), so, we keep properties
|
||||
//var names = Object.getOwnPropertyNames(baseProto);
|
||||
//for (var j = 0, k = names.length; j < k; j++) {
|
||||
// var descriptor = Object.getOwnPropertyDescriptor(baseProto, names[i]);
|
||||
// Object.defineProperty(proto, names[i], descriptor);
|
||||
//}
|
||||
Object.defineProperties(proto, base.properties);
|
||||
|
||||
// todo test A -> B, C(->D) *properties from D is not yet added to proto*
|
||||
}
|
||||
|
||||
return proto;
|
||||
}
|
||||
|
||||
return create;
|
||||
})();
|
||||
Object.freeze(constructor);
|
||||
return constructor;
|
||||
};
|
||||
|
||||
Kotlin.createObject = function (initializer, properties) {
|
||||
var o = Object.create(null, properties || undefined);
|
||||
@@ -110,15 +96,18 @@ var Kotlin = {};
|
||||
return o;
|
||||
};
|
||||
|
||||
Kotlin.createNamespace = function (initializer, properties, classesAndNestedNamespaces) {
|
||||
var o = Object.create(null, properties || undefined);
|
||||
Object.defineProperty(o, "initialize", {value: initializer});
|
||||
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 = 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) {
|
||||
@@ -126,7 +115,7 @@ var Kotlin = {};
|
||||
};
|
||||
|
||||
Kotlin.$createClass = function (parent, properties) {
|
||||
if (typeof (parent) != "function") {
|
||||
if (parent !== null && typeof (parent) != "function") {
|
||||
properties = parent;
|
||||
parent = null;
|
||||
}
|
||||
@@ -161,10 +150,16 @@ var Kotlin = {};
|
||||
}
|
||||
}
|
||||
|
||||
if (initializer) {
|
||||
Object.defineProperty(initializer, "skipSeal", {value: true});
|
||||
}
|
||||
|
||||
return Kotlin.createClass(parent || null, initializer, descriptors);
|
||||
};
|
||||
|
||||
Kotlin.defineModule = function (id, module) {
|
||||
var isTestMode = id === "JS_TESTS";
|
||||
if ((id in Kotlin.modules) && (!isTestMode)) {
|
||||
throw Kotlin.$new(Kotlin.Exceptions.IllegalArgumentException)();
|
||||
}
|
||||
|
||||
Object.freeze(module);
|
||||
Object.defineProperty(Kotlin.modules, id, {value: module, writable: isTestMode});
|
||||
};
|
||||
})();
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package foo
|
||||
|
||||
open class A() {
|
||||
fun f() = 3
|
||||
}
|
||||
|
||||
fun box() = (A().f() + bar.A().f()) == 9
|
||||
@@ -0,0 +1,5 @@
|
||||
package bar
|
||||
|
||||
open class A() {
|
||||
fun f() = 6
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package foo
|
||||
|
||||
object A {
|
||||
val query = object {val status = "complete"}
|
||||
}
|
||||
|
||||
object B {
|
||||
private val ov = "d"
|
||||
val query = object {val status = "complete" + ov}
|
||||
}
|
||||
|
||||
class C {
|
||||
val query = object {val status = "complete"}
|
||||
}
|
||||
|
||||
fun box() = A.query.status == "complete" && B.query.status == "completed" && C().query.status == "completed"
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package foo
|
||||
|
||||
import js.enumerable
|
||||
import js.native
|
||||
|
||||
native
|
||||
fun <T> _enumerate(o:T):T = noImpl
|
||||
|
||||
native
|
||||
fun _findFirst<T>(o:Any):T = noImpl
|
||||
|
||||
enumerable
|
||||
class Test() {
|
||||
val a:Int = 100
|
||||
val b:String = "s"
|
||||
}
|
||||
|
||||
class P() {
|
||||
enumerable
|
||||
val a:Int = 100
|
||||
val b:String = "s"
|
||||
}
|
||||
|
||||
fun box():Boolean {
|
||||
val test = _enumerate(Test())
|
||||
val p = _enumerate(P())
|
||||
return (100 == test.a && "s" == test.b) && p.a == 100 && _findFirst<Int>(object {val test = 100}) == 100;
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package foo
|
||||
|
||||
trait I {
|
||||
fun test():String
|
||||
}
|
||||
|
||||
class P : I {
|
||||
override fun test():String {return "a" + test("b")}
|
||||
private fun test(p:String):String {return p}
|
||||
}
|
||||
|
||||
fun box():Boolean {
|
||||
return P().test() == "ab"
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
function _enumerate(o) {
|
||||
var r = {};
|
||||
for (var p in o) {
|
||||
r[p] = o[p];
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
function _findFirst(o) {
|
||||
for (var p in o) {
|
||||
return o[p];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user