Skip to content

Commit

Permalink
Added ParserEnvironment, moved NameTable and Types into it, and defin…
Browse files Browse the repository at this point in the history
…ed JDT implementation.

Roll-forward of 129653929, now that build paths are fixed.

	Change on 2016/08/22 by tball <tball@google.com>

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=130946247
  • Loading branch information
tomball committed Sep 7, 2016
1 parent 319b849 commit d792a9f
Show file tree
Hide file tree
Showing 8 changed files with 220 additions and 39 deletions.
1 change: 1 addition & 0 deletions translator/.classpath
Expand Up @@ -10,6 +10,7 @@
<classpathentry kind="lib" path="../java_deps/build_result/jsr305.jar"/>
<classpathentry kind="lib" path="../java_deps/build_result/asm.jar"/>
<classpathentry kind="lib" path="../java_deps/build_result/guava-19.0.jar"/>
<classpathentry kind="lib" path="../java_deps/build_result/javac.jar"/>
<classpathentry kind="lib" path="../java_deps/build_result/org.eclipse.core.contenttype_3.4.200.v20140207-1251.jar"/>
<classpathentry kind="lib" path="../java_deps/build_result/org.eclipse.core.jobs_3.6.1.v20141204-0235.jar"/>
<classpathentry kind="lib" path="../java_deps/build_result/org.eclipse.core.resources_3.9.1.v20140825-1431.jar"/>
Expand Down
Expand Up @@ -19,7 +19,7 @@
import com.google.devtools.j2objc.jdt.TreeConverter;
import com.google.devtools.j2objc.types.Types;
import com.google.devtools.j2objc.util.NameTable;

import com.google.devtools.j2objc.util.ParserEnvironment;
import org.eclipse.jdt.core.dom.ASTNode;

import java.util.List;
Expand All @@ -29,8 +29,7 @@
*/
public class CompilationUnit extends TreeNode {

private final Types typeEnv;
private final NameTable nameTable;
private final ParserEnvironment env;
private final String sourceFilePath;
private final String mainTypeName;
private final String source;
Expand All @@ -46,11 +45,10 @@ public class CompilationUnit extends TreeNode {
ChildList.create(AbstractTypeDeclaration.class, this);

public CompilationUnit(
org.eclipse.jdt.core.dom.CompilationUnit jdtNode, String sourceFilePath,
String mainTypeName, String source, NameTable.Factory nameTableFactory) {
ParserEnvironment env, org.eclipse.jdt.core.dom.CompilationUnit jdtNode,
String sourceFilePath, String mainTypeName, String source) {
super(jdtNode);
typeEnv = new Types(jdtNode.getAST());
nameTable = nameTableFactory == null ? null : nameTableFactory.newNameTable(typeEnv);
this.env = env;
this.sourceFilePath = Preconditions.checkNotNull(sourceFilePath);
this.mainTypeName = Preconditions.checkNotNull(mainTypeName);
this.source = Preconditions.checkNotNull(source);
Expand Down Expand Up @@ -80,8 +78,7 @@ public CompilationUnit(

public CompilationUnit(CompilationUnit other) {
super(other);
typeEnv = other.getTypeEnv();
nameTable = other.getNameTable();
this.env = other.env;
sourceFilePath = other.getSourceFilePath();
mainTypeName = other.getMainTypeName();
source = other.getSource();
Expand All @@ -99,11 +96,11 @@ public Kind getKind() {
}

public Types getTypeEnv() {
return typeEnv;
return env.types();
}

public NameTable getNameTable() {
return nameTable;
return env.nameTable();
}

public String getSourceFilePath() {
Expand Down
@@ -0,0 +1,97 @@
/*
* 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.devtools.j2objc.util.NameTable.Factory;
import com.google.devtools.j2objc.util.ParserEnvironment;
import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Symtab;
import com.sun.tools.javac.jvm.ClassReader;
import com.sun.tools.javac.model.JavacElements;
import com.sun.tools.javac.model.JavacTypes;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.Name;
import com.sun.tools.javac.util.Names;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javax.lang.model.element.Element;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;

class JavacEnvironment extends ParserEnvironment {
private final ClassReader classReader;
private final Names javacNames;
private final Symtab symbolTable;
private final JavacElements javacElements;
private final JavacTypes javacTypes;

protected JavacEnvironment(Factory nameTableFactory, Context context) {
super(nameTableFactory);
classReader = ClassReader.instance(context);
javacNames = Names.instance(context);
symbolTable = Symtab.instance(context);
javacElements = JavacElements.instance(context);
javacTypes = JavacTypes.instance(context);
}

@Override
public Element resolve(String name) {
Name className = javacNames.fromString(name);

// Check first if compiler already created or loaded the class.
ClassSymbol symbol = symbolTable.classes.get(className);
if (symbol == null) {
// Not available, read it from a class file.
// Note: the enterName(Name) method moved from ClassReader to
// Symtab in Java 9. Reflection is used to support both locations.
symbol = enterClassJavac(className);
if (symbol != null) {
symbolTable.classes.put(className, symbol);
} else {
symbol = enterClassJavac9(className);
// The symbolTable is already updated in Java 9.
}
}
return symbol;
}

private ClassSymbol enterClassJavac(Name className) {
try {
Method m = ClassReader.class.getDeclaredMethod("enterName", Name.class);
return (ClassSymbol) m.invoke(classReader, className);
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
return null;
}
}

private ClassSymbol enterClassJavac9(Name className) {
try {
Method m = Symtab.class.getDeclaredMethod("enterName", Name.class);
return (ClassSymbol) m.invoke(symbolTable, className);
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
return null;
}
}

@Override
public Elements elementUtilities() {
return javacElements;
}

@Override
public Types typeUtilities() {
return javacTypes;
}
}
Expand Up @@ -107,7 +107,7 @@
import com.google.devtools.j2objc.ast.VariableDeclarationFragment;
import com.google.devtools.j2objc.ast.VariableDeclarationStatement;
import com.google.devtools.j2objc.ast.WhileStatement;
import com.google.devtools.j2objc.util.NameTable;
import com.google.devtools.j2objc.util.ParserEnvironment;
import java.util.ArrayList;
import java.util.List;
import javax.lang.model.element.ExecutableElement;
Expand All @@ -120,9 +120,9 @@
public class TreeConverter {

public static CompilationUnit convertCompilationUnit(
org.eclipse.jdt.core.dom.CompilationUnit jdtUnit, String sourceFilePath, String mainTypeName,
String source, NameTable.Factory nameTableFactory) {
return new CompilationUnit(jdtUnit, sourceFilePath, mainTypeName, source, nameTableFactory);
ParserEnvironment env, org.eclipse.jdt.core.dom.CompilationUnit jdtUnit,
String sourceFilePath, String mainTypeName, String source) {
return new CompilationUnit(env, jdtUnit, sourceFilePath, mainTypeName, source);
}

public static Statement convertStatement(org.eclipse.jdt.core.dom.Statement jdtStatement) {
Expand Down
Expand Up @@ -21,15 +21,13 @@
import com.google.devtools.j2objc.jdt.JdtTypeBinding;
import com.google.devtools.j2objc.util.BindingUtil;
import com.google.devtools.j2objc.util.NameTable;

import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.Modifier;

import com.google.devtools.j2objc.util.ParserEnvironment;
import java.util.HashMap;
import java.util.Map;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.TypeMirror;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.Modifier;

/**
* Types is a singleton service class for type-related operations.
Expand All @@ -38,7 +36,7 @@
*/
public class Types {

private final AST ast;
private final ParserEnvironment environment;
private final Map<ITypeBinding, ITypeBinding> typeMap = Maps.newHashMap();
private final Map<ITypeBinding, ITypeBinding> primitiveToWrapperTypes =
new HashMap<ITypeBinding, ITypeBinding>();
Expand Down Expand Up @@ -86,8 +84,8 @@ public class Types {
private final IOSMethodBinding allocMethod;
private final IOSMethodBinding deallocMethod;

public Types(AST ast) {
this.ast = ast;
public Types(ParserEnvironment env) {
this.environment = env;

// Find core java types.
javaObjectType = resolveWellKnownType("java.lang.Object");
Expand Down Expand Up @@ -190,7 +188,7 @@ private void populatePrimitiveAndWrapperTypeMaps() {
}

private JdtTypeBinding resolveWellKnownType(String name) {
return BindingConverter.wrapBinding(ast.resolveWellKnownType(name));
return (JdtTypeBinding) BindingConverter.unwrapElement(environment.resolve(name));
}

private void loadPrimitiveAndWrapperTypes(String primitiveName, String wrapperName) {
Expand Down
Expand Up @@ -21,6 +21,7 @@
import com.google.devtools.j2objc.Options.LintOption;
import com.google.devtools.j2objc.file.InputFile;
import com.google.devtools.j2objc.file.RegularInputFile;
import com.google.devtools.j2objc.jdt.BindingConverter;
import com.google.devtools.j2objc.jdt.TreeConverter;
import java.io.File;
import java.io.IOException;
Expand All @@ -30,6 +31,7 @@
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import javax.lang.model.element.Element;
import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTParser;
Expand Down Expand Up @@ -167,8 +169,9 @@ public com.google.devtools.j2objc.ast.CompilationUnit parse(String mainTypeName,
RegularInputFile file = new RegularInputFile(path);
mainTypeName = FileUtil.getQualifiedMainTypeName(file, unit);
}
return TreeConverter.convertCompilationUnit(
unit, path, mainTypeName, source, NameTable.newFactory());
ParserEnvironment env =
new JdtParserEnvironment(unit.getAST(), nameTableFactory);
return TreeConverter.convertCompilationUnit(env, unit, path, mainTypeName, source);
}

private CompilationUnit parse(String unitName, String source, boolean resolveBindings) {
Expand All @@ -195,9 +198,11 @@ public void acceptAST(String sourceFilePath, CompilationUnit ast) {
RegularInputFile file = new RegularInputFile(sourceFilePath);
try {
String source = FileUtil.readFile(file);
ParserEnvironment env =
new JdtParserEnvironment(ast.getAST(), nameTableFactory);
com.google.devtools.j2objc.ast.CompilationUnit unit =
TreeConverter.convertCompilationUnit(
ast, sourceFilePath, FileUtil.getMainTypeName(file), source, nameTableFactory);
env, ast, sourceFilePath, FileUtil.getMainTypeName(file), source);
handler.handleParsedUnit(sourceFilePath, unit);
} catch (IOException e) {
ErrorUtil.error("Error reading file " + file.getPath() + ": " + e.getMessage());
Expand Down Expand Up @@ -264,4 +269,28 @@ private boolean checkCompilationErrors(String filename, CompilationUnit unit) {
}
return !hasErrors;
}

private static class JdtParserEnvironment extends ParserEnvironment {
private final AST ast;

JdtParserEnvironment(AST ast, NameTable.Factory nameTableFactory) {
super(nameTableFactory);
this.ast = ast;
}

@Override
public Element resolve(String name) {
return BindingConverter.getElement(ast.resolveWellKnownType(name));
}

@Override
public javax.lang.model.util.Elements elementUtilities() {
throw new AssertionError("not implemented");
}

@Override
public javax.lang.model.util.Types typeUtilities() {
throw new AssertionError("not implemented");
}
}
}
Expand Up @@ -29,13 +29,6 @@
import com.google.devtools.j2objc.types.PointerTypeBinding;
import com.google.devtools.j2objc.types.Types;
import com.google.j2objc.annotations.ObjectiveCName;

import org.eclipse.jdt.core.dom.IAnnotationBinding;
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.IVariableBinding;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
Expand All @@ -52,6 +45,11 @@
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import org.eclipse.jdt.core.dom.IAnnotationBinding;
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.IVariableBinding;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;

/**
* Singleton service for type/method/variable name support.
Expand Down Expand Up @@ -332,8 +330,8 @@ private Factory() {
}
}

public NameTable newNameTable(Types typeEnv) {
return new NameTable(typeEnv, prefixMap, methodMappings);
public NameTable newNameTable(ParserEnvironment env) {
return new NameTable(env, prefixMap, methodMappings);
}
}

Expand All @@ -342,8 +340,8 @@ public static Factory newFactory() {
}

private NameTable(
Types typeEnv, PackagePrefixes prefixMap, Map<String, String> methodMappings) {
this.typeEnv = typeEnv;
ParserEnvironment env, PackagePrefixes prefixMap, Map<String, String> methodMappings) {
this.typeEnv = env.types();
this.prefixMap = prefixMap;
this.methodMappings = methodMappings;
}
Expand Down Expand Up @@ -924,7 +922,8 @@ public String getFullName(TypeMirror t) {
* name is "JavaUtilArrayList_ListItr".
*/
public String getFullName(ITypeBinding binding) {
binding = typeEnv.mapType(binding.getErasure()); // Make sure type variables aren't included.
// Make sure type variables aren't included.
binding = typeEnv.mapType(binding.getErasure());

// Avoid package prefix renaming for package-info types, and use a valid ObjC name that doesn't
// have a dash character.
Expand Down

0 comments on commit d792a9f

Please sign in to comment.