This repository has been archived by the owner on Aug 2, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 03b289b
Showing
5 changed files
with
299 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
<groupId>com.github.scalatojava</groupId> | ||
<artifactId>scala-to-java</artifactId> | ||
<version>1.0</version> | ||
|
||
<packaging>jar</packaging> | ||
<properties> | ||
<scala.version>2.11.4</scala.version> | ||
</properties> | ||
|
||
<repositories> | ||
<repository> | ||
<id>scala-tools.org</id> | ||
<name>Scala-Tools Maven2 Repository</name> | ||
<url>http://scala-tools.org/repo-releases</url> | ||
</repository> | ||
</repositories> | ||
|
||
<pluginRepositories> | ||
<pluginRepository> | ||
<id>scala-tools.org</id> | ||
<name>Scala-Tools Maven2 Repository</name> | ||
<url>http://scala-tools.org/repo-releases</url> | ||
</pluginRepository> | ||
</pluginRepositories> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>org.scala-lang</groupId> | ||
<artifactId>scala-library</artifactId> | ||
<version>${scala.version}</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.scala-lang</groupId> | ||
<artifactId>scala-compiler</artifactId> | ||
<version>${scala.version}</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.scala-lang</groupId> | ||
<artifactId>scala-reflect</artifactId> | ||
<version>${scala.version}</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.bitbucket.mstrobel</groupId> | ||
<artifactId>procyon-compilertools</artifactId> | ||
<version>0.5.29</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.scalatest</groupId> | ||
<artifactId>scalatest_2.11</artifactId> | ||
<version>2.2.5</version> | ||
<scope>test</scope> | ||
</dependency> | ||
</dependencies> | ||
|
||
<build> | ||
<plugins> | ||
<plugin> | ||
<groupId>org.apache.maven.plugins</groupId> | ||
<artifactId>maven-compiler-plugin</artifactId> | ||
<version>3.3</version> | ||
<configuration> | ||
<source>1.8</source> | ||
<target>1.8</target> | ||
</configuration> | ||
</plugin> | ||
<plugin> | ||
<groupId>org.scala-tools</groupId> | ||
<artifactId>maven-scala-plugin</artifactId> | ||
<version>2.15.2</version> | ||
<executions> | ||
<execution> | ||
<goals> | ||
<goal>compile</goal> | ||
<goal>testCompile</goal> | ||
</goals> | ||
</execution> | ||
</executions> | ||
<configuration> | ||
<scalaVersion>${scala.version}</scalaVersion> | ||
<args> | ||
<arg>-target:jvm-1.8</arg> | ||
</args> | ||
</configuration> | ||
</plugin> | ||
<!--disable surefire --> | ||
<plugin> | ||
<groupId>org.apache.maven.plugins</groupId> | ||
<artifactId>maven-surefire-plugin</artifactId> | ||
<version>2.7</version> | ||
<configuration> | ||
<skipTests>true</skipTests> | ||
</configuration> | ||
</plugin> | ||
<!--enable scalatest --> | ||
<plugin> | ||
<groupId>org.scalatest</groupId> | ||
<artifactId>scalatest-maven-plugin</artifactId> | ||
<version>1.0</version> | ||
<configuration> | ||
<reportsDirectory> | ||
${project.build.directory}/surefire-reports | ||
</reportsDirectory> | ||
<junitxml>.</junitxml> | ||
<filereports>WDF TestSuite.txt</filereports> | ||
</configuration> | ||
<executions> | ||
<execution> | ||
<id>test</id> | ||
<goals> | ||
<goal>test</goal> | ||
</goals> | ||
</execution> | ||
</executions> | ||
</plugin> | ||
<plugin> | ||
<executions> | ||
<execution> | ||
<id>make-assembly</id> | ||
<phase>package</phase> | ||
<goals> | ||
<goal>single</goal> | ||
</goals> | ||
</execution> | ||
</executions> | ||
<artifactId>maven-assembly-plugin</artifactId> | ||
<version>2.5.5</version> | ||
<configuration> | ||
<archive> | ||
<manifest> | ||
<mainClass>com.github.scalatojava.Main</mainClass> | ||
</manifest> | ||
</archive> | ||
<descriptorRefs> | ||
<descriptorRef>jar-with-dependencies</descriptorRef> | ||
</descriptorRefs> | ||
<finalName>scala-to-java</finalName> | ||
<appendAssemblyId>false</appendAssemblyId> | ||
</configuration> | ||
</plugin> | ||
</plugins> | ||
</build> | ||
<reporting> | ||
<plugins> | ||
<plugin> | ||
<groupId>org.scala-tools</groupId> | ||
<artifactId>maven-scala-plugin</artifactId> | ||
<configuration> | ||
<scalaVersion>${scala.version}</scalaVersion> | ||
</configuration> | ||
</plugin> | ||
</plugins> | ||
</reporting> | ||
</project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
Scala To Java | ||
--------- | ||
|
||
Simple tool written in Scala that reveals the mystery of scala compiler. | ||
Reads scala code from the StdIn and writes it's decompiled Java version | ||
to StdOut. | ||
|
||
|
||
Usage | ||
--- | ||
|
||
* Make sure you have Java 1.8 and Maven installed | ||
* Checkout the project | ||
* In project directory invoke `mvn clean package`. | ||
In target directory `scala-to-java.jar` will be created | ||
* Run application with `java -jar target/scala-to-java.jar` | ||
* Type any scala code, for example `println("hello, world")` | ||
and finish with `END` character (`Ctrl-D`) | ||
|
||
|
||
Source highlighting and more | ||
--- | ||
|
||
To improve usage experience, you may want to use external source code | ||
highlighter (like `pygmentize`) and `pv` as the indicator of transpiling | ||
process. | ||
|
||
My setup: | ||
```sh | ||
alias scala-to-java='java -jar ~/.scala-to-java.jar | pv -W | pygmentize -f | ||
256 -l java -O style=monokai' | ||
``` | ||
|
||
Credits | ||
--- | ||
|
||
Thanks to [Stanley Shyiko](https://github.com/shyiko), who | ||
actually implemented all the magic. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package com.github.scalatojava | ||
|
||
/** | ||
* @author <a href="mailto:[email protected]">Ivan Zaytsev</a> | ||
* 2015-07-12 | ||
*/ | ||
object Main extends App { | ||
val source = Iterator.continually(scala.io.StdIn.readLine()).takeWhile( | ||
_ != null).mkString("\n") | ||
|
||
println() | ||
private val java = ScalaToJava(source) | ||
|
||
println(java.replaceFirst("(?s)public final class _\\$\\s+.*", "")) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
package com.github.scalatojava | ||
|
||
import java.io.{File, StringWriter} | ||
import java.nio.file.{Paths, Files} | ||
|
||
import com.strobel.assembler.InputTypeLoader | ||
import com.strobel.assembler.metadata._ | ||
import com.strobel.decompiler.languages.Languages | ||
import com.strobel.decompiler.languages.java.JavaFormattingOptions | ||
import com.strobel.decompiler.{PlainTextOutput, DecompilerSettings, DecompilationOptions} | ||
import scala.collection.mutable | ||
import scala.tools.nsc._ | ||
import java.io._ | ||
import java.util.Arrays | ||
|
||
/** | ||
* Scala-to-Java translator | ||
* @author <a href="mailto:[email protected]">Stanley Shyiko</a> | ||
*/ | ||
object ScalaToJava { | ||
|
||
def decompile(file: File): String = { | ||
val settings = new DecompilerSettings | ||
settings.setLanguage(Languages.java) | ||
settings.setTypeLoader(new InputTypeLoader) | ||
settings.setFormattingOptions(JavaFormattingOptions.createDefault) | ||
|
||
val options = new DecompilationOptions | ||
options.setSettings(settings) | ||
options.setFullDecompilation(true) | ||
|
||
settings.getTypeLoader.tryLoadType(file.getPath, | ||
new Buffer(Files.readAllBytes(Paths.get(file.getPath)))) | ||
|
||
val metadataSystem = new NoRetryMetadataSystem(settings.getTypeLoader) | ||
val resolvedType = metadataSystem.resolveType(file.getName.substring(0, | ||
file.getName.length - ".class".length), mightBePrimitive = false) | ||
val writer = new StringWriter | ||
val output = new PlainTextOutput(writer) | ||
settings.getLanguage.decompileType(resolvedType, output, options) | ||
writer.flush() | ||
writer.toString | ||
} | ||
|
||
def compile(input: File, output: File): Array[File] = { | ||
val settings = new Settings | ||
settings processArgumentString "-Xscript _ -usejavacp -d " + output.getPath | ||
val compiler = new Global(settings) | ||
val runner = new compiler.Run | ||
runner.compile(List(input.getPath)) | ||
output.listFiles(new FilenameFilter { | ||
override def accept(dir: File, name: String): Boolean = name.endsWith(".class") | ||
}) | ||
} | ||
|
||
def apply(value: String): String = { | ||
val output = Files.createTempDirectory("s2j").toFile | ||
val input = new File(output, "_.scala") | ||
Files.write(input.toPath, Arrays.asList(value)) | ||
compile(input, output).map(decompile).mkString("\n\n") | ||
} | ||
|
||
class NoRetryMetadataSystem(typeLoader: ITypeLoader) extends MetadataSystem(typeLoader) { | ||
|
||
val failedTypes = mutable.Set[String]() | ||
|
||
override def resolveType(descriptor: String, mightBePrimitive: Boolean): TypeDefinition = { | ||
if (failedTypes.contains(descriptor)) { | ||
return null | ||
} | ||
val r = super.resolveType(descriptor, mightBePrimitive) | ||
if (r == null) { | ||
failedTypes.add(descriptor) | ||
} | ||
r | ||
} | ||
} | ||
} | ||
|
10 changes: 10 additions & 0 deletions
10
src/test/scala/com/github/scalatojava/ScalaToJavaSpec.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package com.github.scalatojava | ||
|
||
import org.scalatest._ | ||
|
||
class ScalaToJavaSpec extends FlatSpec with Matchers { | ||
|
||
it should "be able to convert scala to java" in { | ||
ScalaToJava("""println("hello world")""") should include("class _") | ||
} | ||
} |