Skip to content

Commit

Permalink
Javac front-end wired in with minimal tree conversion.
Browse files Browse the repository at this point in the history
	Change on 2016/09/07 by tball <tball@google.com>

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=132488331
  • Loading branch information
tomball committed Sep 9, 2016
1 parent ea27ebf commit 66f357a
Show file tree
Hide file tree
Showing 11 changed files with 721 additions and 91 deletions.
5 changes: 4 additions & 1 deletion translator/Makefile
Expand Up @@ -35,7 +35,7 @@ SOURCEPATH = $(CWD):$(JAVA_SOURCE_DIR)
BASE_PACKAGE = com/google/devtools/j2objc BASE_PACKAGE = com/google/devtools/j2objc


DIST_DEPS = $(JSR305_JAR) j2objc_annotations.jar DIST_DEPS = $(JSR305_JAR) j2objc_annotations.jar
INTERNAL_DEPS = $(ECLIPSE_JARS) $(GUAVA_JAR) $(ASM_JAR) $(JSR305_JAR) INTERNAL_DEPS = $(ECLIPSE_JARS) $(GUAVA_JAR) $(ASM_JAR) $(JSR305_JAR) $(JAVAC_JAR)
JAR_DEPS_DIST = $(DIST_DEPS:%=$(DIST_JAR_DIR)/%) $(INTERNAL_DEPS:%=$(JAVA_DEPS_JAR_DIR)/%) JAR_DEPS_DIST = $(DIST_DEPS:%=$(DIST_JAR_DIR)/%) $(INTERNAL_DEPS:%=$(JAVA_DEPS_JAR_DIR)/%)
JAR_DEPS_PATH = $(subst $(eval) ,:,$(strip $(JAR_DEPS_DIST))) JAR_DEPS_PATH = $(subst $(eval) ,:,$(strip $(JAR_DEPS_DIST)))
JUNIT_JAR_DIST = $(DIST_JAR_DIR)/$(JUNIT_JAR) JUNIT_JAR_DIST = $(DIST_JAR_DIR)/$(JUNIT_JAR)
Expand Down Expand Up @@ -183,6 +183,9 @@ JAVA_SOURCES = \
gen/TypeGenerator.java \ gen/TypeGenerator.java \
gen/TypeImplementationGenerator.java \ gen/TypeImplementationGenerator.java \
gen/TypePrivateDeclarationGenerator.java \ gen/TypePrivateDeclarationGenerator.java \
javac/JavacEnvironment.java \
javac/JavacParser.java \
javac/TreeConverter.java \
jdt/BindingConverter.java \ jdt/BindingConverter.java \
jdt/JdtAnnotationBinding.java \ jdt/JdtAnnotationBinding.java \
jdt/JdtAnnotationMirror.java \ jdt/JdtAnnotationMirror.java \
Expand Down
1 change: 1 addition & 0 deletions translator/jarjar.rules
@@ -1,3 +1,4 @@
rule com.google.common.** j2objc.@0 rule com.google.common.** j2objc.@0
rule com.sun.** j2objc.@0
rule org.eclipse.** j2objc.@0 rule org.eclipse.** j2objc.@0
rule org.osgi.** j2objc.@0 rule org.osgi.** j2objc.@0
Expand Up @@ -1031,6 +1031,6 @@ public static Parser newParser() {
if (instance.javaFrontEnd == FrontEnd.JDT) { if (instance.javaFrontEnd == FrontEnd.JDT) {
return new com.google.devtools.j2objc.jdt.JdtParser(); return new com.google.devtools.j2objc.jdt.JdtParser();
} }
throw new AssertionError("javac front-end not implemented"); return new com.google.devtools.j2objc.javac.JavacParser();
} }
} }
Expand Up @@ -20,9 +20,8 @@
import com.google.devtools.j2objc.types.Types; import com.google.devtools.j2objc.types.Types;
import com.google.devtools.j2objc.util.NameTable; import com.google.devtools.j2objc.util.NameTable;
import com.google.devtools.j2objc.util.ParserEnvironment; import com.google.devtools.j2objc.util.ParserEnvironment;
import org.eclipse.jdt.core.dom.ASTNode;

import java.util.List; import java.util.List;
import org.eclipse.jdt.core.dom.ASTNode;


/** /**
* Tree node for a Java compilation unit. * Tree node for a Java compilation unit.
Expand Down Expand Up @@ -76,6 +75,16 @@ public CompilationUnit(
} }
} }


public CompilationUnit(ParserEnvironment env, String sourceFilePath, String mainTypeName,
String source) {
super();
this.env = env;
this.sourceFilePath = Preconditions.checkNotNull(sourceFilePath);
this.mainTypeName = Preconditions.checkNotNull(mainTypeName);
this.source = Preconditions.checkNotNull(source);
newlines = findNewlines(source);
}

public CompilationUnit(CompilationUnit other) { public CompilationUnit(CompilationUnit other) {
super(other); super(other);
this.env = other.env; this.env = other.env;
Expand Down Expand Up @@ -217,6 +226,11 @@ public CompilationUnit addNativeBlock(NativeDeclaration decl) {
return this; return this;
} }


public CompilationUnit addType(AbstractTypeDeclaration type) {
types.add(type);
return this;
}

public CompilationUnit addType(int index, AbstractTypeDeclaration type) { public CompilationUnit addType(int index, AbstractTypeDeclaration type) {
types.add(index, type); types.add(index, type);
return this; return this;
Expand Down
Expand Up @@ -14,7 +14,6 @@


package com.google.devtools.j2objc.javac; package com.google.devtools.j2objc.javac;


import com.google.devtools.j2objc.ast.TreeNode;
import com.google.devtools.j2objc.util.NameTable.Factory; import com.google.devtools.j2objc.util.NameTable.Factory;
import com.google.devtools.j2objc.util.ParserEnvironment; import com.google.devtools.j2objc.util.ParserEnvironment;
import com.sun.tools.javac.code.Symbol.ClassSymbol; import com.sun.tools.javac.code.Symbol.ClassSymbol;
Expand All @@ -32,6 +31,7 @@
import javax.lang.model.util.Types; import javax.lang.model.util.Types;


class JavacEnvironment extends ParserEnvironment { class JavacEnvironment extends ParserEnvironment {
private final Context context;
private final ClassReader classReader; private final ClassReader classReader;
private final Names javacNames; private final Names javacNames;
private final Symtab symbolTable; private final Symtab symbolTable;
Expand All @@ -40,6 +40,7 @@ class JavacEnvironment extends ParserEnvironment {


protected JavacEnvironment(Factory nameTableFactory, Context context) { protected JavacEnvironment(Factory nameTableFactory, Context context) {
super(nameTableFactory); super(nameTableFactory);
this.context = context;
classReader = ClassReader.instance(context); classReader = ClassReader.instance(context);
javacNames = Names.instance(context); javacNames = Names.instance(context);
symbolTable = Symtab.instance(context); symbolTable = Symtab.instance(context);
Expand Down Expand Up @@ -86,6 +87,10 @@ private ClassSymbol enterClassJavac9(Name className) {
} }
} }


public Context getContext() {
return context;
}

@Override @Override
public Elements elementUtilities() { public Elements elementUtilities() {
return javacElements; return javacElements;
Expand All @@ -95,10 +100,4 @@ public Elements elementUtilities() {
public Types typeUtilities() { public Types typeUtilities() {
return javacTypes; return javacTypes;
} }

@Override
public TreeNode convert(Object tree) {
// TODO(tball): replace with call to javac tree converter.
return null;
}
} }
@@ -0,0 +1,166 @@
/*
* 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 com.google.devtools.j2objc.javac;

import com.google.common.base.Joiner;
import com.google.devtools.j2objc.Options;
import com.google.devtools.j2objc.ast.CompilationUnit;
import com.google.devtools.j2objc.file.InputFile;
import com.google.devtools.j2objc.util.ErrorUtil;
import com.google.devtools.j2objc.util.Parser;
import com.google.devtools.j2objc.util.SourceVersion;
import com.sun.source.tree.CompilationUnitTree;
import com.sun.tools.javac.api.JavacTaskImpl;
import com.sun.tools.javac.tree.JCTree;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.tools.Diagnostic;
import javax.tools.Diagnostic.Kind;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;

/**
* Parser front-end that uses javac.
*
* @author Tom Ball
*/
public class JavacParser extends Parser {

@Override
public void setEnableDocComments(boolean enable) {
// Ignore, since JavacTaskImpl always enables them.

// TODO(tball): Disable doc comments with a ParserFactory subclass whose newParser()
// method uses this flag instead of its keepDocComments argument (this argument actually
// causes all comments to be saved, not just doc comments).
}

@Override
public CompilationUnit parse(InputFile file) {
return null;
}

@Override
public CompilationUnit parse(String mainType, String path, String source) {
return null;
}

private List<String> getJavacOptions() {
List<String> options = new ArrayList<>();

options.addAll(maybeBuildPathOption("-classpath", Options.getClassPathEntries()));
options.addAll(maybeBuildPathOption("-sourcepath", Options.getSourcePathEntries()));
options.addAll(maybeBuildPathOption("-processorpath", Options.getProcessorPathEntries()));
options.add("-Xbootclasspath:" + makePathString(Options.getBootClasspath()));

options.add("-d");
options.add(Options.getOutputDirectory().getPath());
if (encoding != null) {
options.add("-encoding");
options.add(encoding);
}
SourceVersion javaLevel = Options.getSourceVersion();
if (javaLevel != null) {
options.add("-source");
options.add(javaLevel.flag());
options.add("-target");
options.add(javaLevel.flag());
}
// TODO(tball): turn on any specified lint warnings.

return options;
}

private List<String> maybeBuildPathOption(String flag, List<String> pathEntries) {
ArrayList<String> flags = new ArrayList<>();
if (pathEntries != null && !pathEntries.isEmpty()) {
flags.add(flag);
flags.add(makePathString(pathEntries));
}
return flags;
}

private String makePathString(List<String> paths) {
return Joiner.on(":").join(paths);
}

@Override
public void parseFiles(Collection<String> paths, Handler handler, SourceVersion sourceVersion) {
List<File> files = new ArrayList<>();
for (String path : paths) {
files.add(new File(path));
}

JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>();
Charset charset = encoding != null ? Charset.forName(encoding) : Options.getCharset();
StandardJavaFileManager fileManager =
compiler.getStandardFileManager(diagnostics, null, charset);
List<String> javacOptions = getJavacOptions();

Iterable<? extends JavaFileObject> fileObjects = fileManager.getJavaFileObjectsFromFiles(files);
JavacTaskImpl task = (JavacTaskImpl) compiler.getTask(
null, fileManager, diagnostics, javacOptions, null, fileObjects);
JavacEnvironment env = new JavacEnvironment(nameTableFactory, task.getContext());

List<CompilationUnitTree> units = new ArrayList<>();
try {
for (CompilationUnitTree unit : task.parse()) {
units.add(unit);
}
task.analyze();
} catch (IOException e) {
// Error listener will report errors.
}

for (Diagnostic<? extends JavaFileObject> diagnostic : diagnostics.getDiagnostics()) {
Kind kind = diagnostic.getKind();
if (kind == Kind.ERROR) {
ErrorUtil.error(diagnostic.getMessage(null));
} else if (kind == Kind.MANDATORY_WARNING || kind == Kind.WARNING) {
ErrorUtil.warning(diagnostic.getMessage(null));
} else {
// Ignore other diagnostic types.
}
}

for (CompilationUnitTree ast : units) {
com.google.devtools.j2objc.ast.CompilationUnit unit =
TreeConverter.convertCompilationUnit(env, (JCTree.JCCompilationUnit) ast);
handler.handleParsedUnit(unit.getSourceFilePath(), unit);
}

try {
fileManager.close();
} catch (IOException e) {
ErrorUtil.fatalError(e, "failed closing javac file manager");
}
}

@Override
public org.eclipse.jdt.core.dom.CompilationUnit parseWithoutBindings(String unitName,
String source) {
// TODO(tball): implement after API updated to return j2objc's CompilationUnit.
throw new AssertionError("not implemented");
}

}

0 comments on commit 66f357a

Please sign in to comment.