Skip to content
This repository has been archived by the owner on Aug 2, 2019. It is now read-only.

Commit

Permalink
Initial commit.
Browse files Browse the repository at this point in the history
  • Loading branch information
Aivean committed Jul 18, 2015
0 parents commit 03b289b
Show file tree
Hide file tree
Showing 5 changed files with 299 additions and 0 deletions.
157 changes: 157 additions & 0 deletions pom.xml
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>
38 changes: 38 additions & 0 deletions readme.md
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.
15 changes: 15 additions & 0 deletions src/main/scala/com/github/scalatojava/Main.scala
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+.*", ""))
}
79 changes: 79 additions & 0 deletions src/main/scala/com/github/scalatojava/ScalaToJava.scala
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 src/test/scala/com/github/scalatojava/ScalaToJavaSpec.scala
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 _")
}
}

0 comments on commit 03b289b

Please sign in to comment.