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

Add support for input from a file or a whole directory of sources; classpath from repo #5

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
148 changes: 148 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
#################################### Java.gitignore

*.class

# Mobile Tools for Java (J2ME)
.mtj.tmp/

# Package Files #
*.jar
*.war
*.ear

# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*

#################################### Scala.gitignore

*.class
*.log

# sbt specific
.cache
.history
.lib/
dist/*
target/
lib_managed/
src_managed/
project/boot/
project/plugins/project/

# Scala-IDE specific
.scala_dependencies
.worksheet

#################################### Eclipse.gitignore

*.pydevproject
.metadata
.gradle
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.settings/
.loadpath

# Eclipse Core
.project

# External tool builders
.externalToolBuilders/

# Locally stored "Eclipse launch configurations"
*.launch

# CDT-specific
.cproject

# JDT-specific (Eclipse Java Development Tools)
.classpath

# Java annotation processor (APT)
.factorypath

# PDT-specific
.buildpath

# sbteclipse plugin
.target

# TeXlipse plugin
.texlipse

#################################### Linux.gitignore

*~

# KDE directory preferences
.directory

# Linux trash folder which might appear on any partition or disk
.Trash-*

#################################### JetBrains.gitignore

# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio

*.iml

## Directory-based project format:
.idea/
# if you remove the above rule, at least ignore the following:

# User-specific stuff:
# .idea/workspace.xml
# .idea/tasks.xml
# .idea/dictionaries

# Sensitive or high-churn files:
# .idea/dataSources.ids
# .idea/dataSources.xml
# .idea/sqlDataSources.xml
# .idea/dynamic.xml
# .idea/uiDesigner.xml

# Gradle:
# .idea/gradle.xml
# .idea/libraries

# Mongo Explorer plugin:
# .idea/mongoSettings.xml

## File-based project format:
*.ipr
*.iws
*.iml

## Plugin-specific files:

# IntelliJ
/out/

# mpeltonen/sbt-idea plugin
.idea_modules/

# JIRA plugin
atlassian-ide-plugin.xml

# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties

#################################### Mac

.DS_Store

#################################### Maven

log/
target/



14 changes: 13 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,18 @@
<version>2.2.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>

</dependencies>

<build>
Expand Down Expand Up @@ -131,7 +143,7 @@
<configuration>
<archive>
<manifest>
<mainClass>com.github.scalatojava.Main</mainClass>
<mainClass>com.github.scalatojava.MainExtended</mainClass>
</manifest>
</archive>
<descriptors>
Expand Down
14 changes: 14 additions & 0 deletions src/main/java/com/github/scalatojava/Constants.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.github.scalatojava;

/**
* @author eitanraviv@github
* @since 21 Sept 2015.
*/
public class Constants
{
public static final String LS = System.getProperty("line.separator");
public static final String FS = System.getProperty("file.separator");
public static final String PS = System.getProperty("path.separator");

public static final String S2J = "scala2java_";
}
41 changes: 41 additions & 0 deletions src/main/java/com/github/scalatojava/MainExtended.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.github.scalatojava;

import com.github.scalatojava.inputs.ScalaToJavaFromSourceTree;
import com.github.scalatojava.inputs.ScalaToJavaFromStandaloneFile;
import com.strobel.core.ArrayUtilities;
import com.strobel.core.StringUtilities;

import java.io.File;

/**
* @author eitanraviv@github
* @since 21 Sept 2015.
*/
public class MainExtended
{
public static void main(String[] args) throws Exception
{
String pathToTranslate = System.getProperty("path");
String repo = System.getProperty("repo");
boolean slim = ArrayUtilities.contains(args, "--slim");


if (StringUtilities.isNullOrEmpty(pathToTranslate))
{
new ScalaToJavaFromStandardInput().run(args);
return;
}

File file = new File(pathToTranslate);
if (file.isDirectory())
{
new ScalaToJavaFromSourceTree().run(pathToTranslate, repo, slim);
}
else if (file.isFile())
{
new ScalaToJavaFromStandaloneFile().run(pathToTranslate, repo, slim);
}

System.out.println("done");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package com.github.scalatojava.compilation;

import com.github.scalatojava.Constants;
import com.github.scalatojava.NoRetryMetadataSystem;
import com.github.scalatojava.files.FileExtension;
import com.github.scalatojava.files.filters.ClassFileFilter;
import com.strobel.assembler.InputTypeLoader;
import com.strobel.assembler.metadata.Buffer;
import com.strobel.assembler.metadata.TypeDefinition;
import com.strobel.decompiler.DecompilationOptions;
import com.strobel.decompiler.DecompilerSettings;
import com.strobel.decompiler.PlainTextOutput;
import com.strobel.decompiler.languages.Languages;
import com.strobel.decompiler.languages.java.JavaFormattingOptions;
import com.strobel.decompiler.languages.java.JavaLanguage;
import scala.collection.JavaConversions;
import scala.tools.nsc.Global;
import scala.tools.nsc.Settings;

import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.nio.file.Files;
import java.util.Arrays;

public class ScalaToJavaWithClasspath
{
protected String classpath;
protected boolean slim;

public ScalaToJavaWithClasspath(String classpath, boolean slim)
{
this.classpath = classpath;
this.slim = slim;
}

public String decompile(final File file) throws IOException
{
final InputTypeLoader typeLoader = new InputTypeLoader();
typeLoader.tryLoadType(file.getPath(), new Buffer(Files.readAllBytes(file.toPath())));
final JavaLanguage javaLanguage = Languages.java();
final NoRetryMetadataSystem metadataSystem = new NoRetryMetadataSystem(typeLoader);
final TypeDefinition resolvedType = metadataSystem.resolveType(FileExtension.remove(file.getName()), false);

final DecompilerSettings settings = new DecompilerSettings();
settings.setLanguage(javaLanguage);
settings.setTypeLoader(typeLoader);
settings.setFormattingOptions(JavaFormattingOptions.createDefault());
final DecompilationOptions options = new DecompilationOptions();
options.setSettings(settings);
options.setFullDecompilation(true);
final StringWriter writer = new StringWriter();
final PlainTextOutput output = new PlainTextOutput(writer);
javaLanguage.decompileType(resolvedType, output, options);
writer.flush();
String java = writer.toString();
if (slim)
java = java.replaceFirst("(?s)public final class _\\$\\s+.*", "");
return java;
}

public File[] compile(final File scalaSourceFile, final File containerDirForCompiledFiles)
{
final Global.Run runner = getCompilerRun(containerDirForCompiledFiles);
runner.compile(JavaConversions.asScalaBuffer(Arrays.asList(scalaSourceFile.getPath())).toList());
return containerDirForCompiledFiles.listFiles(new ClassFileFilter());
}

private Global.Run getCompilerRun(File dir)
{
final Settings settings = new Settings();
settings.processArgumentString(prepareCompileArgs(dir));
final Global compiler = new Global(settings);
return compiler.new Run();
}

private String prepareCompileArgs(File dir)
{
StringBuilder args = new StringBuilder();
args.append(" -target:jvm-1.8")
.append(" -explaintypes")
.append(" -Xscript _")
.append(" -usejavacp")
.append(" -d ").append(dir.getPath());
if (classpath != null && classpath.trim().length() > 0)
{
args.append(" -classpath \"").append(classpath).append("\"");
}
return args.toString();
}

public String apply(final String value) throws IOException
{
final File tempDir = Files.createTempDirectory("s2j").toFile();
final File scalaFile = new File(tempDir, "_.scala");
Files.write(scalaFile.toPath(), value.getBytes());
File[] compileds = compile(scalaFile, tempDir);
StringBuilder javaSource = new StringBuilder();
for (File compiled : compileds)
{
String s = decompile(compiled);
javaSource.append(s).append(Constants.LS);
}
return javaSource.toString();
}
}
54 changes: 54 additions & 0 deletions src/main/java/com/github/scalatojava/files/FileExtension.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.github.scalatojava.files;

import com.strobel.core.StringUtilities;

/**
* @author eitanraviv@github
* @since 21 Sept 2015.
*/
public class FileExtension
{
public static String replace(String filename, String extensionReplacement)
{
guardUndefined(filename);
if (filename.lastIndexOf(".") == -1) {
filename += ".";
}
if (StringUtilities.isNullOrEmpty(extensionReplacement)) {
return filename;
}
if (extensionReplacement.startsWith(".")) {
extensionReplacement = extensionReplacement.substring(1);
}

filename = filename.substring(0, filename.lastIndexOf(".") + 1) + extensionReplacement;
guardUndefined(filename);
return filename;
}

public static String get(String filename)
{
guardUndefined(filename);
if (filename.lastIndexOf(".") == -1) {
return "";
}
return filename.substring(filename.lastIndexOf(".") + 1, filename.length());
}

public static String remove(String filename)
{
guardUndefined(filename);
if (filename.lastIndexOf(".") == -1) {
return filename;
}
return filename.substring(0, filename.lastIndexOf("."));
}

private static void guardUndefined(String filename)
{
if (filename == null || filename.equals(".") || filename.equals(".."))
{
throw new IllegalArgumentException("the operation is undefined on this filename");
}
}
}
Loading