From 4cff5f975947a299d2e3c559ace43bd68269c5d9 Mon Sep 17 00:00:00 2001 From: James Strachan Date: Wed, 30 May 2012 15:50:06 +0100 Subject: [PATCH] modified the JS compiler so that it can have definitions and library sources specified or discovered on the classpath; so for example we can then discover the kotlin standard library kotlin that needs to be compiled; plus the JS library definitions (which map to the kotlin-lib.js file) --- .../jetbrains/jet/cli/js/K2JSCompiler.java | 60 +++++++-------- .../k2js/test/semantics/StdLibToJSTest.java | 22 +----- .../ClassPathLibraryDefintionsConfig.java | 40 ++++++++++ .../config/ClassPathLibrarySourcesLoader.java | 40 ++++++++++ ...ourcesConfig.java => MetaInfServices.java} | 44 +++-------- .../config/ZippedLibrarySourcesConfig.java | 4 + .../k2js/translate/utils/BindingUtils.java | 1 - libraries/pom.xml | 5 +- libraries/tools/kotlin-maven-plugin/pom.xml | 77 ++++++++++++------- .../kotlin/maven/JSSourceJarMojo.java | 29 ++++++- 10 files changed, 206 insertions(+), 116 deletions(-) create mode 100644 js/js.translator/src/org/jetbrains/k2js/config/ClassPathLibraryDefintionsConfig.java create mode 100644 js/js.translator/src/org/jetbrains/k2js/config/ClassPathLibrarySourcesLoader.java rename js/js.translator/src/org/jetbrains/k2js/config/{ClassPathLibrarySourcesConfig.java => MetaInfServices.java} (70%) diff --git a/compiler/cli/src/org/jetbrains/jet/cli/js/K2JSCompiler.java b/compiler/cli/src/org/jetbrains/jet/cli/js/K2JSCompiler.java index 31e0df16f0a..1218a626cbe 100644 --- a/compiler/cli/src/org/jetbrains/jet/cli/js/K2JSCompiler.java +++ b/compiler/cli/src/org/jetbrains/jet/cli/js/K2JSCompiler.java @@ -36,10 +36,7 @@ import org.jetbrains.jet.cli.common.messages.PrintingMessageCollector; import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.k2js.analyze.AnalyzerFacadeForJS; -import org.jetbrains.k2js.config.ClassPathLibrarySourcesConfig; -import org.jetbrains.k2js.config.Config; -import org.jetbrains.k2js.config.EcmaVersion; -import org.jetbrains.k2js.config.ZippedLibrarySourcesConfig; +import org.jetbrains.k2js.config.*; import org.jetbrains.k2js.facade.K2JSTranslator; import org.jetbrains.k2js.facade.MainCallParameters; @@ -72,12 +69,35 @@ public class K2JSCompiler extends CLICompiler sourceFiles = sourceLoader.findSourceFiles(); + environmentForJS.getSourceFiles().addAll(sourceFiles); + + if (arguments.isVerbose()) { + Iterable fileNames = Iterables.transform(environmentForJS.getSourceFiles(), new Function() { + @Override + public String apply(@Nullable JetFile file) { + return file.getName(); + } + }); + System.out.println("Compiling source files: " + Joiner.on(", ").join(fileNames)); + } + String outputFile = arguments.outputFile; if (outputFile == null) { messageCollector.report(CompilerMessageSeverity.ERROR, "Specify output file via -output", CompilerMessageLocation.NO_LOCATION); @@ -89,29 +109,6 @@ public class K2JSCompiler extends CLICompiler fileNames = Iterables.transform(environmentForJS.getSourceFiles(), new Function() { - @Override - public String apply(@Nullable JetFile file) { - return file.getName(); - } - }); - System.out.println("Compiling source files: " + Joiner.on(", ").join(fileNames)); - } - return environmentForJS; - } - @NotNull private static ExitCode translateAndGenerateOutputFile(@NotNull MainCallParameters mainCall, @NotNull PrintingMessageCollector messageCollector, @@ -146,9 +143,8 @@ public class K2JSCompiler extends CLICompiler files = Lists.newArrayList(); - File stdlibDir = new File("libraries/stdlib/src"); assertTrue("Cannot find stdlib source: " + stdlibDir, stdlibDir.exists()); for (String file : stdLibFiles) { files.add(new File(stdlibDir, file).getPath()); } - generateJavaScriptFiles(files, getTestName(false) + ".kt", mainCallParameters, ecmaVersions); - - /* - runRhinoTests(getOutputFilePaths(kotlinFilename, ecmaVersions), - new RhinoFunctionNativeObjectResultChecker("test.browser", "foo", "Some Dynamically Created Content!!!")); - */ // lets add the standard JS library files for (String libFileName : Config.LIB_FILE_NAMES) { + System.out.println("Compiling " + libFileName); files.add(Config.LIBRARIES_LOCATION + libFileName); } + // now lets try invoke the compiler for (EcmaVersion version : ecmaVersions) { System.out.println("Compiling with version: " + version); diff --git a/js/js.translator/src/org/jetbrains/k2js/config/ClassPathLibraryDefintionsConfig.java b/js/js.translator/src/org/jetbrains/k2js/config/ClassPathLibraryDefintionsConfig.java new file mode 100644 index 00000000000..41133aebb07 --- /dev/null +++ b/js/js.translator/src/org/jetbrains/k2js/config/ClassPathLibraryDefintionsConfig.java @@ -0,0 +1,40 @@ +/* + * 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.config; + +import org.jetbrains.annotations.NotNull; +import com.intellij.openapi.project.Project; +import org.jetbrains.jet.lang.psi.JetFile; + +import java.util.*; + +/** + * A Config implementation which is configured with a directory to find the standard library names from + */ +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); + } + + @NotNull + @Override + public List generateLibFiles() { + return MetaInfServices.loadServicesFiles(META_INF_SERVICES_FILE, getProject()); + } +} diff --git a/js/js.translator/src/org/jetbrains/k2js/config/ClassPathLibrarySourcesLoader.java b/js/js.translator/src/org/jetbrains/k2js/config/ClassPathLibrarySourcesLoader.java new file mode 100644 index 00000000000..c73f6f18f26 --- /dev/null +++ b/js/js.translator/src/org/jetbrains/k2js/config/ClassPathLibrarySourcesLoader.java @@ -0,0 +1,40 @@ +/* + * 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.config; + +import com.intellij.openapi.project.Project; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.psi.JetFile; + +import java.util.*; + +/** + * A helper class to load the kotlin library sources to be compiled to JavaScript as part of a JavaScript build + */ +public class ClassPathLibrarySourcesLoader { + public static final String META_INF_SERVICES_FILE = "META-INF/services/org.jetbrains.kotlin.js.librarySource"; + @NotNull private final Project project; + + public ClassPathLibrarySourcesLoader(@NotNull Project project) { + this.project = project; + } + + @NotNull + public List findSourceFiles() { + return MetaInfServices.loadServicesFiles(META_INF_SERVICES_FILE, project); + } +} diff --git a/js/js.translator/src/org/jetbrains/k2js/config/ClassPathLibrarySourcesConfig.java b/js/js.translator/src/org/jetbrains/k2js/config/MetaInfServices.java similarity index 70% rename from js/js.translator/src/org/jetbrains/k2js/config/ClassPathLibrarySourcesConfig.java rename to js/js.translator/src/org/jetbrains/k2js/config/MetaInfServices.java index 516b0e19258..744808d985d 100644 --- a/js/js.translator/src/org/jetbrains/k2js/config/ClassPathLibrarySourcesConfig.java +++ b/js/js.translator/src/org/jetbrains/k2js/config/MetaInfServices.java @@ -16,13 +16,9 @@ package org.jetbrains.k2js.config; -import com.intellij.openapi.util.io.FileUtil; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.io.FileUtil; import org.jetbrains.jet.lang.psi.JetFile; -import org.jetbrains.k2js.config.Config; -import org.jetbrains.k2js.config.EcmaVersion; import org.jetbrains.k2js.utils.JetFileUtils; import java.io.BufferedReader; @@ -33,34 +29,24 @@ import java.net.URL; import java.util.*; /** - * A Config implementation which is configured with a directory to find the standard library names from + * A helper class to discover a META-INF/services file on the classpath and load the files referenced inside it */ -public class ClassPathLibrarySourcesConfig extends Config { - - public static final String LIBRARY_SOURCES_FILES = "META-INF/services/org.jetbrains.kotlin.js.librarySource"; - @Nullable - private /*var*/ List jsLibFiles = null; - - public ClassPathLibrarySourcesConfig(@NotNull Project project, @NotNull EcmaVersion version) { - super(project, version); - } - - @NotNull - private List initLibFiles(@NotNull Project project) { +public class MetaInfServices { + public static List loadServicesFiles(String metaInfServicesFile, Project project) { List libFiles = new ArrayList(); Set urlsLoaded = new HashSet(); try { - Enumeration resources = getClass().getClassLoader().getResources(LIBRARY_SOURCES_FILES); - loadLibFiles(resources, project, urlsLoaded, libFiles); - resources = Thread.currentThread().getContextClassLoader().getResources(LIBRARY_SOURCES_FILES); - loadLibFiles(resources, project, urlsLoaded, libFiles); + Enumeration resources = MetaInfServices.class.getClassLoader().getResources(metaInfServicesFile); + loadLibFiles(resources, urlsLoaded, libFiles, project); + resources = Thread.currentThread().getContextClassLoader().getResources(metaInfServicesFile); + loadLibFiles(resources, urlsLoaded, libFiles, project); } catch (IOException e) { throw new IllegalStateException(e); } return libFiles; } - private void loadLibFiles(Enumeration resources, @NotNull Project project, Set urlsLoaded, List libFiles) throws IOException { + protected static void loadLibFiles(Enumeration resources, Set urlsLoaded, List libFiles, Project project) throws IOException { while (resources != null && resources.hasMoreElements()) { URL url = resources.nextElement(); if (url != null) { @@ -84,6 +70,7 @@ public class ClassPathLibrarySourcesConfig extends Config { String text = FileUtil.loadTextAndClose(stream); JetFile file = JetFileUtils.createPsiFile(line, text, project); if (file != null) { + //System.out.println("Parsing file: " + text); libFiles.add(file); } } @@ -102,19 +89,10 @@ public class ClassPathLibrarySourcesConfig extends Config { * Tries to load the given resource name on the classpath */ public static InputStream loadClasspathResource(String resourceName) { - InputStream answer = ClassPathLibrarySourcesConfig.class.getClassLoader().getResourceAsStream(resourceName); + InputStream answer = ClassPathLibraryDefintionsConfig.class.getClassLoader().getResourceAsStream(resourceName); if (answer == null) { answer = Thread.currentThread().getContextClassLoader().getResourceAsStream(resourceName); } return answer; } - - @Override - @NotNull - public List generateLibFiles() { - if (jsLibFiles == null) { - jsLibFiles = initLibFiles(getProject()); - } - return jsLibFiles; - } } diff --git a/js/js.translator/src/org/jetbrains/k2js/config/ZippedLibrarySourcesConfig.java b/js/js.translator/src/org/jetbrains/k2js/config/ZippedLibrarySourcesConfig.java index 723e0171ba7..a251343eaf7 100644 --- a/js/js.translator/src/org/jetbrains/k2js/config/ZippedLibrarySourcesConfig.java +++ b/js/js.translator/src/org/jetbrains/k2js/config/ZippedLibrarySourcesConfig.java @@ -48,6 +48,7 @@ public class ZippedLibrarySourcesConfig extends Config { @NotNull @Override public List generateLibFiles() { + System.out.println("Parsing JS library source zip: " + pathToLibZip); if (pathToLibZip == null) { return Collections.emptyList(); } @@ -62,6 +63,8 @@ public class ZippedLibrarySourcesConfig extends Config { } } catch (IOException e) { + System.out.println("Failed to process " + pathToLibZip + ". Reason: " + e); + e.printStackTrace(); return Collections.emptyList(); } } @@ -76,6 +79,7 @@ public class ZippedLibrarySourcesConfig extends Config { InputStream stream = file.getInputStream(entry); String text = FileUtil.loadTextAndClose(stream); JetFile jetFile = JetFileUtils.createPsiFile(entry.getName(), text, getProject()); + System.out.println("Parsing file: " + entry.getName()); result.add(jetFile); } } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/utils/BindingUtils.java b/js/js.translator/src/org/jetbrains/k2js/translate/utils/BindingUtils.java index a8e8536aca1..b71abccce56 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/utils/BindingUtils.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/utils/BindingUtils.java @@ -189,7 +189,6 @@ public final class BindingUtils { public static DeclarationDescriptor getDescriptorForReferenceExpression(@NotNull BindingContext context, @NotNull JetReferenceExpression reference) { DeclarationDescriptor referencedDescriptor = getNullableDescriptorForReferenceExpression(context, reference); - assert referencedDescriptor != null : "Reference expression must reference a descriptor."; Preconditions.checkNotNull(referencedDescriptor, "Reference expression must reference a descriptor for reference %s at %s", reference.getText(), DiagnosticUtils.atLocation(reference)); return referencedDescriptor; diff --git a/libraries/pom.xml b/libraries/pom.xml index 3325f44c424..5690447ac4f 100644 --- a/libraries/pom.xml +++ b/libraries/pom.xml @@ -65,11 +65,8 @@ examples/kotlin-java-example - examples/js-example + examples/browser-example diff --git a/libraries/tools/kotlin-maven-plugin/pom.xml b/libraries/tools/kotlin-maven-plugin/pom.xml index b8b1951137d..04eabd45912 100644 --- a/libraries/tools/kotlin-maven-plugin/pom.xml +++ b/libraries/tools/kotlin-maven-plugin/pom.xml @@ -56,32 +56,57 @@ 2.9 - - maven-invoker-plugin - 1.5 - - src/it - ${project.build.directory}/it - - */pom.xml - - - - ${project.build.directory}/local-repo - verify.bsh - true - - - - integration-test - - - install - run - - - - + + + + + integrationTest + + true + + + + + maven-invoker-plugin + 1.5 + + src/it + ${project.build.directory}/it + + */pom.xml + + + + ${project.build.directory}/local-repo + verify.bsh + true + + + + integration-test + + + install + run + + + + + + + + + + + noTest + + false + + + diff --git a/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/JSSourceJarMojo.java b/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/JSSourceJarMojo.java index 647e8355ddb..78c375e7d55 100644 --- a/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/JSSourceJarMojo.java +++ b/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/JSSourceJarMojo.java @@ -5,6 +5,8 @@ import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.codehaus.plexus.util.FileUtils; +import org.jetbrains.k2js.config.ClassPathLibraryDefintionsConfig; +import org.jetbrains.k2js.config.ClassPathLibrarySourcesLoader; import java.io.File; import java.io.FileWriter; @@ -19,13 +21,21 @@ import java.io.PrintWriter; */ public class JSSourceJarMojo extends AbstractMojo { /** - * The Kotlin JavaScript library source code + * The Kotlin JavaScript library source code; the library code to be compiled to JavaScript * * @required * @parameter expression="${jsLibrarySourceDir}" */ private File librarySourceDir; + /** + * The Kotlin JavaScript definition source code; the kotlin code used to define APIs available in the kotlin-lib.js file + * + * @required + * @parameter expression="${jsDefinitionSourceDir}" + */ + private File definitionSourceDir; + /** * The directory for the copied code * @@ -41,7 +51,7 @@ public class JSSourceJarMojo extends AbstractMojo { getLog().warn("Source directory does not exist: " + librarySourceDir); } else { try { - File metaInfFile = new File(outputDir, "META-INF/services/org.jetbrains.kotlin.js.librarySource"); + File metaInfFile = new File(outputDir, ClassPathLibrarySourcesLoader.META_INF_SERVICES_FILE); metaInfFile.getParentFile().mkdirs(); FileUtils.copyDirectoryStructure(librarySourceDir, outputDir); @@ -54,6 +64,21 @@ public class JSSourceJarMojo extends AbstractMojo { throw new MojoFailureException(e.getMessage(), e); } } + if (definitionSourceDir.exists()) { + try { + File metaInfFile = new File(outputDir, ClassPathLibraryDefintionsConfig.META_INF_SERVICES_FILE); + metaInfFile.getParentFile().mkdirs(); + + FileUtils.copyDirectoryStructure(definitionSourceDir, outputDir); + + // now lets generate the META-INF/services/org.jetbrains.kotlin.js.libraryDefinitions file + PrintWriter writer = new PrintWriter(new FileWriter(metaInfFile)); + appendSourceFiles(writer, definitionSourceDir.getCanonicalPath(), definitionSourceDir); + writer.close(); + } catch (IOException e) { + throw new MojoFailureException(e.getMessage(), e); + } + } } private void appendSourceFiles(PrintWriter writer, String rootPath, File currentDir) throws IOException {