collect imports info via annotation processing API and feed it to dependency Mappings

This commit is contained in:
Eugene Zhuravlev
2012-02-11 18:12:28 +01:00
parent d585fdd30f
commit c13789d6c8
11 changed files with 833 additions and 126 deletions
@@ -47,8 +47,9 @@ message Message {
enum Type {
BUILD_MESSAGE = 1;
OUTPUT_OBJECT = 2;
BUILD_COMPLETED = 3;
REQUEST_ACK = 4;
CLASS_DATA = 3;
BUILD_COMPLETED = 4;
REQUEST_ACK = 5;
}
message CompileMessage {
@@ -87,10 +88,18 @@ message Message {
optional bytes content = 7;
}
message ClassData {
required string class_name = 1;
repeated string import_statement = 2;
repeated string static_import = 3;
repeated string identifier = 4;
}
required Type response_type = 1;
optional CompileMessage compile_message = 2;
optional OutputObject output_object = 3;
optional bool completion_status = 4;
optional ClassData class_data = 4;
optional bool completion_status = 5;
}
required UUID session_id = 1;
@@ -70,6 +70,8 @@ public class JavaBuilder extends ModuleLevelBuilder {
private static final Key<Callbacks.Backend> DELTA_MAPPINGS_CALLBACK_KEY = Key.create("_dependency_data_");
private final ExecutorService myTaskRunner;
private int myTasksInProgress = 0;
private final Object myCounterLock = new Object();
private final List<ClassPostProcessor> myClassProcessors = new ArrayList<ClassPostProcessor>();
public JavaBuilder(ExecutorService tasksExecutor) {
@@ -375,10 +377,45 @@ public class JavaBuilder extends ModuleLevelBuilder {
return rc;
}
finally {
classesConsumer.ensurePendingTasksCompleted();
ensurePendingTasksCompleted();
}
}
private void ensurePendingTasksCompleted() {
synchronized (myCounterLock) {
while (myTasksInProgress > 0) {
try {
myCounterLock.wait();
}
catch (InterruptedException ignored) {
}
}
}
}
private void submitAsyncTask(final Runnable taskRunnable) {
synchronized (myCounterLock) {
myTasksInProgress++;
}
myTaskRunner.submit(new Runnable() {
public void run() {
try {
taskRunnable.run();
}
finally {
synchronized (myCounterLock) {
myTasksInProgress = Math.max(0, myTasksInProgress - 1);
if (myTasksInProgress == 0) {
myCounterLock.notifyAll();
}
}
}
}
});
}
private static JavacServerClient ensureJavacServerLaunched(CompileContext context) throws Exception {
final ExternalJavacDescriptor descriptor = ExternalJavacDescriptor.KEY.get(context);
if (descriptor != null) {
@@ -736,7 +773,7 @@ public class JavaBuilder extends ModuleLevelBuilder {
return version >= Opcodes.V1_6 && version != Opcodes.V1_1 ? ClassWriter.COMPUTE_FRAMES : ClassWriter.COMPUTE_MAXS;
}
private static class DiagnosticSink implements DiagnosticOutputConsumer {
private class DiagnosticSink implements DiagnosticOutputConsumer {
private final CompileContext myContext;
private volatile int myErrorCount = 0;
private volatile int myWarningCount = 0;
@@ -745,6 +782,20 @@ public class JavaBuilder extends ModuleLevelBuilder {
myContext = context;
}
public void registerImports(final String className, final Collection<String> imports, final Collection<String> staticImports) {
submitAsyncTask(new Runnable() {
public void run() {
final Callbacks.Backend callback = DELTA_MAPPINGS_CALLBACK_KEY.get(myContext);
if (callback != null) {
final BuildDataManager dataManager = myContext.getDataManager();
synchronized (dataManager.getMappings()) {
callback.registerImports(className, imports, staticImports);
}
}
}
});
}
public void outputLineAvailable(String line) {
if (!StringUtil.isEmpty(line)) {
//if (line.startsWith("[") && line.endsWith("]")) {
@@ -1068,8 +1119,6 @@ public class JavaBuilder extends ModuleLevelBuilder {
private class ClassProcessingConsumer implements OutputFileConsumer {
private final CompileContext myCompileContext;
private final OutputFileConsumer myDelegateOutputFileSink;
private int myTasksInProgress = 0;
private final Object myCounterLock = new Object();
public ClassProcessingConsumer(CompileContext compileContext, OutputFileConsumer sink) {
myCompileContext = compileContext;
@@ -1081,8 +1130,7 @@ public class JavaBuilder extends ModuleLevelBuilder {
}
public void save(@NotNull final OutputFileObject fileObject) {
incTaskCount();
myTaskRunner.submit(new Runnable() {
submitAsyncTask(new Runnable() {
public void run() {
try {
for (ClassPostProcessor processor : myClassProcessors) {
@@ -1090,43 +1138,10 @@ public class JavaBuilder extends ModuleLevelBuilder {
}
}
finally {
try {
myDelegateOutputFileSink.save(fileObject);
}
finally {
decTaskCount();
}
myDelegateOutputFileSink.save(fileObject);
}
}
});
}
private void decTaskCount() {
synchronized (myCounterLock) {
myTasksInProgress = Math.max(0, myTasksInProgress - 1);
if (myTasksInProgress == 0) {
myCounterLock.notifyAll();
}
}
}
private void incTaskCount() {
synchronized (myCounterLock) {
myTasksInProgress++;
}
}
public void ensurePendingTasksCompleted() {
synchronized (myCounterLock) {
while (myTasksInProgress > 0) {
try {
myCounterLock.wait();
}
catch (InterruptedException ignored) {
}
}
}
}
}
}
@@ -1,7 +1,7 @@
package org.jetbrains.jps.javac;
import javax.tools.DiagnosticListener;
import javax.tools.JavaFileObject;
import javax.tools.*;
import java.util.Collection;
/**
* @author Eugene Zhuravlev
@@ -9,4 +9,5 @@ import javax.tools.JavaFileObject;
*/
public interface DiagnosticOutputConsumer extends DiagnosticListener<JavaFileObject> {
void outputLineAvailable(String line);
void registerImports(String className, Collection<String> imports, Collection<String> staticImports);
}
@@ -1,17 +1,16 @@
package org.jetbrains.jps.javac;
import com.sun.source.tree.*;
import com.sun.source.tree.ClassTree;
import com.sun.source.tree.ImportTree;
import com.sun.source.tree.Tree;
import com.sun.source.util.TreeScanner;
import com.sun.source.util.Trees;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.*;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.Name;
import javax.lang.model.element.TypeElement;
import java.util.HashSet;
import java.util.Set;
/**
@@ -19,13 +18,15 @@ import java.util.Set;
* Date: 2/1/12
*
*/
//@SupportedSourceVersion(SourceVersion.RELEASE_7)
@SupportedSourceVersion(SourceVersion.RELEASE_7)
@SupportedAnnotationTypes("*")
public class JavacASTAnalyser extends AbstractProcessor{
private Trees myTrees;
private final DiagnosticOutputConsumer myOutputConsumer;
private final boolean mySuppressOtherProcessors;
public JavacASTAnalyser(boolean suppressOtherProcessors) {
public JavacASTAnalyser(DiagnosticOutputConsumer outputConsumer, boolean suppressOtherProcessors) {
myOutputConsumer = outputConsumer;
mySuppressOtherProcessors = suppressOtherProcessors;
}
@@ -37,65 +38,158 @@ public class JavacASTAnalyser extends AbstractProcessor{
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
MyAnalyzer scaner = new MyAnalyzer();
for (Element element : roundEnv.getRootElements()) {
final Tree tree = myTrees.getTree(element);
scaner.scan(tree, myTrees);
}
final Set<? extends Element> elements = roundEnv.getRootElements();
for (Element element : elements) {
if (!(element instanceof TypeElement)) {
continue;
}
final TypeElement typeElement = (TypeElement)element;
final ImportsCollector importsCollector = new ImportsCollector();
importsCollector.scan(myTrees.getPath(typeElement).getParentPath().getLeaf(), myTrees);
final Set<String> imports = importsCollector.getImports();
final Set<String> staticImports = importsCollector.getStaticImports();
if (!imports.isEmpty() || !staticImports.isEmpty()) {
final String className = typeElement.getQualifiedName().toString();
myOutputConsumer.registerImports(className, imports, staticImports);
}
break;
}
return mySuppressOtherProcessors;
}
private static class ImportsCollector extends TreeScanner<Object, Trees> {
private Set<String> myImports = new HashSet<String>();
private Set<String> myStaticImports = new HashSet<String>();
public Set<String> getImports() {
return myImports;
}
public Set<String> getStaticImports() {
return myStaticImports;
}
private static class MyAnalyzer extends TreeScanner<Object, Trees> {
@Override
public Object visitImport(ImportTree node, Trees trees) {
return null/*super.visitImport(node, trees)*/;
final Tree identifier = node.getQualifiedIdentifier();
final Set<String> container = node.isStatic()? myStaticImports : myImports;
container.add(identifier.toString());
return null;
}
@Override
public Object visitClass(ClassTree node, Trees trees) {
return scan(node.getMembers(), trees);
}
@Override
public Object visitVariable(VariableTree node, Trees trees) {
final ModifiersTree modifiers = node.getModifiers();
final Set<Modifier> flags = modifiers.getFlags();
if (flags.contains(Modifier.STATIC) && flags.contains(Modifier.FINAL)) {
final Name variableName = node.getName();
// todo register constant
final ConstantRefsFinder finder = new ConstantRefsFinder();
finder.scan(node.getInitializer(), trees);
// todo: process found refs
}
return null;
}
@Override
public Object visitMethod(MethodTree node, Trees trees) {
final ConstantRefsFinder finder = new ConstantRefsFinder();
finder.scan(node.getBody(), trees);
// todo: process found refs
return null;
}
}
//public void registerOverriddenMethod(TypeElement classElement, ExecutableElement method) {
// final Elements utils = myProcessingEnvironment.getElementUtils();
// final String qName = utils.getBinaryName(classElement).toString();
// List<MethodDescriptor> descriptors = myOverriddenMethods.get(qName);
// if (descriptors == null) {
// descriptors = new ArrayList<MethodDescriptor>();
// myOverriddenMethods.put(qName, descriptors);
// }
// final StringBuilder buf = new StringBuilder();
// buf.append("(");
// for (VariableElement param : method.getParameters()) {
// buf.append(getSignature(param.asType()));
// }
// buf.append(")").append(getSignature(method.getReturnType()));
// descriptors.add(new MethodDescriptor(method.getSimpleName().toString(), buf.toString()));
//}
private static class ConstantRefsFinder extends TreeScanner<Object, Trees> {
@Override
public Object visitMethodInvocation(MethodInvocationTree node, Trees trees) {
return scan(node.getArguments(), trees);
}
@Override
public Object visitMemberSelect(MemberSelectTree node, Trees trees) {
return super.visitMemberSelect(node, trees);
}
@Override
public Object visitIdentifier(IdentifierTree node, Trees trees) {
return super.visitIdentifier(node, trees);
}
//private static String getSignature(TypeMirror type) {
// switch (type.getKind()) {
// case BOOLEAN: return "Z";
// case BYTE: return "B";
// case CHAR: return "C";
// case SHORT: return "S";
// case INT: return "I";
// case LONG: return "J";
// case FLOAT: return "F";
// case DOUBLE: return "D";
// case VOID: return "V";
// case ARRAY:
// final String signature = getSignature(((ArrayType)type).getComponentType());
// return signature != null? "[" + signature : null;
// case DECLARED:
// final TypeElement typeElement = (TypeElement)((DeclaredType)type).asElement();
// final String qName = typeElement.getQualifiedName().toString().replace(".", "/");
// return "L" + qName + ";";
// default:
// return null;
// }
//}
}
//private static class IdentifiersCollector extends TreeScanner<Object, Trees> {
// private Set<Name> myIdentifiers = new HashSet<Name>();
// private Set<String> myImports = new HashSet<String>();
// private Set<String> myStaticImports = new HashSet<String>();
//
// public Set<String> getIdentifiers() {
// final HashSet<String> result = new HashSet<String>();
// for (Name name : myIdentifiers) {
// result.add(name.toString());
// }
// return result;
// }
//
// @Override
// public Object visitImport(ImportTree node, Trees trees) {
// final Tree identifier = node.getQualifiedIdentifier();
// final Set<String> container = node.isStatic()? myStaticImports : myImports;
// container.add(identifier.toString());
// return null;
// }
//
// @Override
// public Object visitAnnotation(AnnotationTree node, Trees trees) {
// return scan(node.getArguments(), trees);
// }
//
// @Override
// public Object visitIdentifier(IdentifierTree node, Trees trees) {
// myIdentifiers.add(node.getName());
// return super.visitIdentifier(node, trees);
// }
//
// @Override
// public Object visitMemberSelect(MemberSelectTree node, Trees trees) {
// myIdentifiers.add(node.getIdentifier());
// return scan(node.getExpression(), trees);
// }
//
// @Override
// public Object visitClass(ClassTree node, Trees trees) {
// return scan(node.getMembers(), trees);
// }
//
// @Override
// public Object visitVariable(VariableTree node, Trees trees) {
// return scan(node.getInitializer(), trees);
// }
//
// @Override
// public Object visitMethod(MethodTree node, Trees trees) {
// return scan(node.getBody(), trees);
// }
//
// @Override
// public Object visitMethodInvocation(MethodInvocationTree node, Trees trees) {
// return scan(node.getArguments(), trees);
// }
//
// @Override
// public Object visitTypeCast(TypeCastTree node, Trees trees) {
// return scan(node.getExpression(), trees);
// }
//
// @Override
// public Object visitInstanceOf(InstanceOfTree node, Trees trees) {
// return scan(node.getExpression(), trees);
// }
//}
}
@@ -68,8 +68,8 @@ public class JavacMain {
final JavaCompiler.CompilationTask task = compiler.getTask(
out, fileManager, outConsumer, filterOptionList(options), null, fileManager.toJavaFileObjects(sources)
);
//final JavacASTAnalyser analyzer = new JavacASTAnalyser(shouldSuppressAnnotationProcessing(options));
//task.setProcessors(Collections.singleton(analyzer));
final JavacASTAnalyser analyzer = new JavacASTAnalyser(outConsumer, shouldSuppressAnnotationProcessing(options));
task.setProcessors(Collections.singleton(analyzer));
return task.call();
}
finally {
@@ -4,8 +4,7 @@ import com.google.protobuf.ByteString;
import com.intellij.openapi.util.io.FileUtil;
import org.jetbrains.annotations.Nullable;
import javax.tools.Diagnostic;
import javax.tools.JavaFileObject;
import javax.tools.*;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.PrintStream;
@@ -86,6 +85,20 @@ public class JavacProtoUtil {
return builder.build();
}
public static JavacRemoteProto.Message.Response createClassDataResponse(String className, Collection<String> imports, Collection<String> staticImports) {
final JavacRemoteProto.Message.Response.ClassData.Builder msgBuilder = JavacRemoteProto.Message.Response.ClassData.newBuilder();
msgBuilder.setClassName(className);
if (!imports.isEmpty()) {
msgBuilder.addAllImportStatement(imports);
}
if (!staticImports.isEmpty()) {
msgBuilder.addAllStaticImport(imports);
}
final JavacRemoteProto.Message.Response.Builder builder = JavacRemoteProto.Message.Response.newBuilder();
builder.setResponseType(JavacRemoteProto.Message.Response.Type.CLASS_DATA).setClassData(msgBuilder.build());
return builder.build();
}
public static JavacRemoteProto.Message.Response createStdOutputResponse(String text) {
final JavacRemoteProto.Message.Response.CompileMessage.Builder msgBuilder = JavacRemoteProto.Message.Response.CompileMessage.newBuilder();
msgBuilder.setKind(JavacRemoteProto.Message.Response.CompileMessage.Kind.STD_OUT);
@@ -1831,8 +1831,9 @@ public final class JavacRemoteProto {
implements com.google.protobuf.Internal.EnumLite {
BUILD_MESSAGE(0, 1),
OUTPUT_OBJECT(1, 2),
BUILD_COMPLETED(2, 3),
REQUEST_ACK(3, 4),
CLASS_DATA(2, 3),
BUILD_COMPLETED(3, 4),
REQUEST_ACK(4, 5),
;
@@ -1842,8 +1843,9 @@ public final class JavacRemoteProto {
switch (value) {
case 1: return BUILD_MESSAGE;
case 2: return OUTPUT_OBJECT;
case 3: return BUILD_COMPLETED;
case 4: return REQUEST_ACK;
case 3: return CLASS_DATA;
case 4: return BUILD_COMPLETED;
case 5: return REQUEST_ACK;
default: return null;
}
}
@@ -3014,6 +3016,496 @@ public final class JavacRemoteProto {
// @@protoc_insertion_point(class_scope:org.jetbrains.javac.Message.Response.OutputObject)
}
public static final class ClassData extends
com.google.protobuf.GeneratedMessageLite {
// Use ClassData.newBuilder() to construct.
private ClassData() {
initFields();
}
private ClassData(boolean noInit) {}
private static final ClassData defaultInstance;
public static ClassData getDefaultInstance() {
return defaultInstance;
}
public ClassData getDefaultInstanceForType() {
return defaultInstance;
}
// required string class_name = 1;
public static final int CLASS_NAME_FIELD_NUMBER = 1;
private boolean hasClassName;
private java.lang.String className_ = "";
public boolean hasClassName() { return hasClassName; }
public java.lang.String getClassName() { return className_; }
// repeated string import_statement = 2;
public static final int IMPORT_STATEMENT_FIELD_NUMBER = 2;
private java.util.List<java.lang.String> importStatement_ =
java.util.Collections.emptyList();
public java.util.List<java.lang.String> getImportStatementList() {
return importStatement_;
}
public int getImportStatementCount() { return importStatement_.size(); }
public java.lang.String getImportStatement(int index) {
return importStatement_.get(index);
}
// repeated string static_import = 3;
public static final int STATIC_IMPORT_FIELD_NUMBER = 3;
private java.util.List<java.lang.String> staticImport_ =
java.util.Collections.emptyList();
public java.util.List<java.lang.String> getStaticImportList() {
return staticImport_;
}
public int getStaticImportCount() { return staticImport_.size(); }
public java.lang.String getStaticImport(int index) {
return staticImport_.get(index);
}
// repeated string identifier = 4;
public static final int IDENTIFIER_FIELD_NUMBER = 4;
private java.util.List<java.lang.String> identifier_ =
java.util.Collections.emptyList();
public java.util.List<java.lang.String> getIdentifierList() {
return identifier_;
}
public int getIdentifierCount() { return identifier_.size(); }
public java.lang.String getIdentifier(int index) {
return identifier_.get(index);
}
private void initFields() {
}
public final boolean isInitialized() {
if (!hasClassName) return false;
return true;
}
public void writeTo(com.google.protobuf.CodedOutputStream output)
throws java.io.IOException {
getSerializedSize();
if (hasClassName()) {
output.writeString(1, getClassName());
}
for (java.lang.String element : getImportStatementList()) {
output.writeString(2, element);
}
for (java.lang.String element : getStaticImportList()) {
output.writeString(3, element);
}
for (java.lang.String element : getIdentifierList()) {
output.writeString(4, element);
}
}
private int memoizedSerializedSize = -1;
public int getSerializedSize() {
int size = memoizedSerializedSize;
if (size != -1) return size;
size = 0;
if (hasClassName()) {
size += com.google.protobuf.CodedOutputStream
.computeStringSize(1, getClassName());
}
{
int dataSize = 0;
for (java.lang.String element : getImportStatementList()) {
dataSize += com.google.protobuf.CodedOutputStream
.computeStringSizeNoTag(element);
}
size += dataSize;
size += 1 * getImportStatementList().size();
}
{
int dataSize = 0;
for (java.lang.String element : getStaticImportList()) {
dataSize += com.google.protobuf.CodedOutputStream
.computeStringSizeNoTag(element);
}
size += dataSize;
size += 1 * getStaticImportList().size();
}
{
int dataSize = 0;
for (java.lang.String element : getIdentifierList()) {
dataSize += com.google.protobuf.CodedOutputStream
.computeStringSizeNoTag(element);
}
size += dataSize;
size += 1 * getIdentifierList().size();
}
memoizedSerializedSize = size;
return size;
}
public static org.jetbrains.jps.javac.JavacRemoteProto.Message.Response.ClassData parseFrom(
com.google.protobuf.ByteString data)
throws com.google.protobuf.InvalidProtocolBufferException {
return newBuilder().mergeFrom(data).buildParsed();
}
public static org.jetbrains.jps.javac.JavacRemoteProto.Message.Response.ClassData parseFrom(
com.google.protobuf.ByteString data,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
return newBuilder().mergeFrom(data, extensionRegistry)
.buildParsed();
}
public static org.jetbrains.jps.javac.JavacRemoteProto.Message.Response.ClassData parseFrom(byte[] data)
throws com.google.protobuf.InvalidProtocolBufferException {
return newBuilder().mergeFrom(data).buildParsed();
}
public static org.jetbrains.jps.javac.JavacRemoteProto.Message.Response.ClassData parseFrom(
byte[] data,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
return newBuilder().mergeFrom(data, extensionRegistry)
.buildParsed();
}
public static org.jetbrains.jps.javac.JavacRemoteProto.Message.Response.ClassData parseFrom(java.io.InputStream input)
throws java.io.IOException {
return newBuilder().mergeFrom(input).buildParsed();
}
public static org.jetbrains.jps.javac.JavacRemoteProto.Message.Response.ClassData parseFrom(
java.io.InputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException {
return newBuilder().mergeFrom(input, extensionRegistry)
.buildParsed();
}
public static org.jetbrains.jps.javac.JavacRemoteProto.Message.Response.ClassData parseDelimitedFrom(java.io.InputStream input)
throws java.io.IOException {
Builder builder = newBuilder();
if (builder.mergeDelimitedFrom(input)) {
return builder.buildParsed();
} else {
return null;
}
}
public static org.jetbrains.jps.javac.JavacRemoteProto.Message.Response.ClassData parseDelimitedFrom(
java.io.InputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException {
Builder builder = newBuilder();
if (builder.mergeDelimitedFrom(input, extensionRegistry)) {
return builder.buildParsed();
} else {
return null;
}
}
public static org.jetbrains.jps.javac.JavacRemoteProto.Message.Response.ClassData parseFrom(
com.google.protobuf.CodedInputStream input)
throws java.io.IOException {
return newBuilder().mergeFrom(input).buildParsed();
}
public static org.jetbrains.jps.javac.JavacRemoteProto.Message.Response.ClassData parseFrom(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException {
return newBuilder().mergeFrom(input, extensionRegistry)
.buildParsed();
}
public static Builder newBuilder() { return Builder.create(); }
public Builder newBuilderForType() { return newBuilder(); }
public static Builder newBuilder(org.jetbrains.jps.javac.JavacRemoteProto.Message.Response.ClassData prototype) {
return newBuilder().mergeFrom(prototype);
}
public Builder toBuilder() { return newBuilder(this); }
public static final class Builder extends
com.google.protobuf.GeneratedMessageLite.Builder<
org.jetbrains.jps.javac.JavacRemoteProto.Message.Response.ClassData, Builder> {
private org.jetbrains.jps.javac.JavacRemoteProto.Message.Response.ClassData result;
// Construct using org.jetbrains.jps.javac.JavacRemoteProto.Message.Response.ClassData.newBuilder()
private Builder() {}
private static Builder create() {
Builder builder = new Builder();
builder.result = new org.jetbrains.jps.javac.JavacRemoteProto.Message.Response.ClassData();
return builder;
}
protected org.jetbrains.jps.javac.JavacRemoteProto.Message.Response.ClassData internalGetResult() {
return result;
}
public Builder clear() {
if (result == null) {
throw new IllegalStateException(
"Cannot call clear() after build().");
}
result = new org.jetbrains.jps.javac.JavacRemoteProto.Message.Response.ClassData();
return this;
}
public Builder clone() {
return create().mergeFrom(result);
}
public org.jetbrains.jps.javac.JavacRemoteProto.Message.Response.ClassData getDefaultInstanceForType() {
return org.jetbrains.jps.javac.JavacRemoteProto.Message.Response.ClassData.getDefaultInstance();
}
public boolean isInitialized() {
return result.isInitialized();
}
public org.jetbrains.jps.javac.JavacRemoteProto.Message.Response.ClassData build() {
if (result != null && !isInitialized()) {
throw newUninitializedMessageException(result);
}
return buildPartial();
}
private org.jetbrains.jps.javac.JavacRemoteProto.Message.Response.ClassData buildParsed()
throws com.google.protobuf.InvalidProtocolBufferException {
if (!isInitialized()) {
throw newUninitializedMessageException(
result).asInvalidProtocolBufferException();
}
return buildPartial();
}
public org.jetbrains.jps.javac.JavacRemoteProto.Message.Response.ClassData buildPartial() {
if (result == null) {
throw new IllegalStateException(
"build() has already been called on this Builder.");
}
if (result.importStatement_ != java.util.Collections.EMPTY_LIST) {
result.importStatement_ =
java.util.Collections.unmodifiableList(result.importStatement_);
}
if (result.staticImport_ != java.util.Collections.EMPTY_LIST) {
result.staticImport_ =
java.util.Collections.unmodifiableList(result.staticImport_);
}
if (result.identifier_ != java.util.Collections.EMPTY_LIST) {
result.identifier_ =
java.util.Collections.unmodifiableList(result.identifier_);
}
org.jetbrains.jps.javac.JavacRemoteProto.Message.Response.ClassData returnMe = result;
result = null;
return returnMe;
}
public Builder mergeFrom(org.jetbrains.jps.javac.JavacRemoteProto.Message.Response.ClassData other) {
if (other == org.jetbrains.jps.javac.JavacRemoteProto.Message.Response.ClassData.getDefaultInstance()) return this;
if (other.hasClassName()) {
setClassName(other.getClassName());
}
if (!other.importStatement_.isEmpty()) {
if (result.importStatement_.isEmpty()) {
result.importStatement_ = new java.util.ArrayList<java.lang.String>();
}
result.importStatement_.addAll(other.importStatement_);
}
if (!other.staticImport_.isEmpty()) {
if (result.staticImport_.isEmpty()) {
result.staticImport_ = new java.util.ArrayList<java.lang.String>();
}
result.staticImport_.addAll(other.staticImport_);
}
if (!other.identifier_.isEmpty()) {
if (result.identifier_.isEmpty()) {
result.identifier_ = new java.util.ArrayList<java.lang.String>();
}
result.identifier_.addAll(other.identifier_);
}
return this;
}
public Builder mergeFrom(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException {
while (true) {
int tag = input.readTag();
switch (tag) {
case 0:
return this;
default: {
if (!parseUnknownField(input, extensionRegistry, tag)) {
return this;
}
break;
}
case 10: {
setClassName(input.readString());
break;
}
case 18: {
addImportStatement(input.readString());
break;
}
case 26: {
addStaticImport(input.readString());
break;
}
case 34: {
addIdentifier(input.readString());
break;
}
}
}
}
// required string class_name = 1;
public boolean hasClassName() {
return result.hasClassName();
}
public java.lang.String getClassName() {
return result.getClassName();
}
public Builder setClassName(java.lang.String value) {
if (value == null) {
throw new NullPointerException();
}
result.hasClassName = true;
result.className_ = value;
return this;
}
public Builder clearClassName() {
result.hasClassName = false;
result.className_ = getDefaultInstance().getClassName();
return this;
}
// repeated string import_statement = 2;
public java.util.List<java.lang.String> getImportStatementList() {
return java.util.Collections.unmodifiableList(result.importStatement_);
}
public int getImportStatementCount() {
return result.getImportStatementCount();
}
public java.lang.String getImportStatement(int index) {
return result.getImportStatement(index);
}
public Builder setImportStatement(int index, java.lang.String value) {
if (value == null) {
throw new NullPointerException();
}
result.importStatement_.set(index, value);
return this;
}
public Builder addImportStatement(java.lang.String value) {
if (value == null) {
throw new NullPointerException();
}
if (result.importStatement_.isEmpty()) {
result.importStatement_ = new java.util.ArrayList<java.lang.String>();
}
result.importStatement_.add(value);
return this;
}
public Builder addAllImportStatement(
java.lang.Iterable<? extends java.lang.String> values) {
if (result.importStatement_.isEmpty()) {
result.importStatement_ = new java.util.ArrayList<java.lang.String>();
}
super.addAll(values, result.importStatement_);
return this;
}
public Builder clearImportStatement() {
result.importStatement_ = java.util.Collections.emptyList();
return this;
}
// repeated string static_import = 3;
public java.util.List<java.lang.String> getStaticImportList() {
return java.util.Collections.unmodifiableList(result.staticImport_);
}
public int getStaticImportCount() {
return result.getStaticImportCount();
}
public java.lang.String getStaticImport(int index) {
return result.getStaticImport(index);
}
public Builder setStaticImport(int index, java.lang.String value) {
if (value == null) {
throw new NullPointerException();
}
result.staticImport_.set(index, value);
return this;
}
public Builder addStaticImport(java.lang.String value) {
if (value == null) {
throw new NullPointerException();
}
if (result.staticImport_.isEmpty()) {
result.staticImport_ = new java.util.ArrayList<java.lang.String>();
}
result.staticImport_.add(value);
return this;
}
public Builder addAllStaticImport(
java.lang.Iterable<? extends java.lang.String> values) {
if (result.staticImport_.isEmpty()) {
result.staticImport_ = new java.util.ArrayList<java.lang.String>();
}
super.addAll(values, result.staticImport_);
return this;
}
public Builder clearStaticImport() {
result.staticImport_ = java.util.Collections.emptyList();
return this;
}
// repeated string identifier = 4;
public java.util.List<java.lang.String> getIdentifierList() {
return java.util.Collections.unmodifiableList(result.identifier_);
}
public int getIdentifierCount() {
return result.getIdentifierCount();
}
public java.lang.String getIdentifier(int index) {
return result.getIdentifier(index);
}
public Builder setIdentifier(int index, java.lang.String value) {
if (value == null) {
throw new NullPointerException();
}
result.identifier_.set(index, value);
return this;
}
public Builder addIdentifier(java.lang.String value) {
if (value == null) {
throw new NullPointerException();
}
if (result.identifier_.isEmpty()) {
result.identifier_ = new java.util.ArrayList<java.lang.String>();
}
result.identifier_.add(value);
return this;
}
public Builder addAllIdentifier(
java.lang.Iterable<? extends java.lang.String> values) {
if (result.identifier_.isEmpty()) {
result.identifier_ = new java.util.ArrayList<java.lang.String>();
}
super.addAll(values, result.identifier_);
return this;
}
public Builder clearIdentifier() {
result.identifier_ = java.util.Collections.emptyList();
return this;
}
// @@protoc_insertion_point(builder_scope:org.jetbrains.javac.Message.Response.ClassData)
}
static {
defaultInstance = new ClassData(true);
org.jetbrains.jps.javac.JavacRemoteProto.internalForceInit();
defaultInstance.initFields();
}
// @@protoc_insertion_point(class_scope:org.jetbrains.javac.Message.Response.ClassData)
}
// required .org.jetbrains.javac.Message.Response.Type response_type = 1;
public static final int RESPONSE_TYPE_FIELD_NUMBER = 1;
private boolean hasResponseType;
@@ -3035,8 +3527,15 @@ public final class JavacRemoteProto {
public boolean hasOutputObject() { return hasOutputObject; }
public org.jetbrains.jps.javac.JavacRemoteProto.Message.Response.OutputObject getOutputObject() { return outputObject_; }
// optional bool completion_status = 4;
public static final int COMPLETION_STATUS_FIELD_NUMBER = 4;
// optional .org.jetbrains.javac.Message.Response.ClassData class_data = 4;
public static final int CLASS_DATA_FIELD_NUMBER = 4;
private boolean hasClassData;
private org.jetbrains.jps.javac.JavacRemoteProto.Message.Response.ClassData classData_;
public boolean hasClassData() { return hasClassData; }
public org.jetbrains.jps.javac.JavacRemoteProto.Message.Response.ClassData getClassData() { return classData_; }
// optional bool completion_status = 5;
public static final int COMPLETION_STATUS_FIELD_NUMBER = 5;
private boolean hasCompletionStatus;
private boolean completionStatus_ = false;
public boolean hasCompletionStatus() { return hasCompletionStatus; }
@@ -3046,6 +3545,7 @@ public final class JavacRemoteProto {
responseType_ = org.jetbrains.jps.javac.JavacRemoteProto.Message.Response.Type.BUILD_MESSAGE;
compileMessage_ = org.jetbrains.jps.javac.JavacRemoteProto.Message.Response.CompileMessage.getDefaultInstance();
outputObject_ = org.jetbrains.jps.javac.JavacRemoteProto.Message.Response.OutputObject.getDefaultInstance();
classData_ = org.jetbrains.jps.javac.JavacRemoteProto.Message.Response.ClassData.getDefaultInstance();
}
public final boolean isInitialized() {
if (!hasResponseType) return false;
@@ -3055,6 +3555,9 @@ public final class JavacRemoteProto {
if (hasOutputObject()) {
if (!getOutputObject().isInitialized()) return false;
}
if (hasClassData()) {
if (!getClassData().isInitialized()) return false;
}
return true;
}
@@ -3070,8 +3573,11 @@ public final class JavacRemoteProto {
if (hasOutputObject()) {
output.writeMessage(3, getOutputObject());
}
if (hasClassData()) {
output.writeMessage(4, getClassData());
}
if (hasCompletionStatus()) {
output.writeBool(4, getCompletionStatus());
output.writeBool(5, getCompletionStatus());
}
}
@@ -3093,9 +3599,13 @@ public final class JavacRemoteProto {
size += com.google.protobuf.CodedOutputStream
.computeMessageSize(3, getOutputObject());
}
if (hasClassData()) {
size += com.google.protobuf.CodedOutputStream
.computeMessageSize(4, getClassData());
}
if (hasCompletionStatus()) {
size += com.google.protobuf.CodedOutputStream
.computeBoolSize(4, getCompletionStatus());
.computeBoolSize(5, getCompletionStatus());
}
memoizedSerializedSize = size;
return size;
@@ -3250,6 +3760,9 @@ public final class JavacRemoteProto {
if (other.hasOutputObject()) {
mergeOutputObject(other.getOutputObject());
}
if (other.hasClassData()) {
mergeClassData(other.getClassData());
}
if (other.hasCompletionStatus()) {
setCompletionStatus(other.getCompletionStatus());
}
@@ -3297,7 +3810,16 @@ public final class JavacRemoteProto {
setOutputObject(subBuilder.buildPartial());
break;
}
case 32: {
case 34: {
org.jetbrains.jps.javac.JavacRemoteProto.Message.Response.ClassData.Builder subBuilder = org.jetbrains.jps.javac.JavacRemoteProto.Message.Response.ClassData.newBuilder();
if (hasClassData()) {
subBuilder.mergeFrom(getClassData());
}
input.readMessage(subBuilder, extensionRegistry);
setClassData(subBuilder.buildPartial());
break;
}
case 40: {
setCompletionStatus(input.readBool());
break;
}
@@ -3401,7 +3923,44 @@ public final class JavacRemoteProto {
return this;
}
// optional bool completion_status = 4;
// optional .org.jetbrains.javac.Message.Response.ClassData class_data = 4;
public boolean hasClassData() {
return result.hasClassData();
}
public org.jetbrains.jps.javac.JavacRemoteProto.Message.Response.ClassData getClassData() {
return result.getClassData();
}
public Builder setClassData(org.jetbrains.jps.javac.JavacRemoteProto.Message.Response.ClassData value) {
if (value == null) {
throw new NullPointerException();
}
result.hasClassData = true;
result.classData_ = value;
return this;
}
public Builder setClassData(org.jetbrains.jps.javac.JavacRemoteProto.Message.Response.ClassData.Builder builderForValue) {
result.hasClassData = true;
result.classData_ = builderForValue.build();
return this;
}
public Builder mergeClassData(org.jetbrains.jps.javac.JavacRemoteProto.Message.Response.ClassData value) {
if (result.hasClassData() &&
result.classData_ != org.jetbrains.jps.javac.JavacRemoteProto.Message.Response.ClassData.getDefaultInstance()) {
result.classData_ =
org.jetbrains.jps.javac.JavacRemoteProto.Message.Response.ClassData.newBuilder(result.classData_).mergeFrom(value).buildPartial();
} else {
result.classData_ = value;
}
result.hasClassData = true;
return this;
}
public Builder clearClassData() {
result.hasClassData = false;
result.classData_ = org.jetbrains.jps.javac.JavacRemoteProto.Message.Response.ClassData.getDefaultInstance();
return this;
}
// optional bool completion_status = 5;
public boolean hasCompletionStatus() {
return result.hasCompletionStatus();
}
@@ -122,6 +122,12 @@ public class JavacServer {
final JavacRemoteProto.Message.Response response = JavacProtoUtil.createBuildMessageResponse(diagnostic);
Channels.write(ctx.getChannel(), JavacProtoUtil.toMessage(sessionId, response));
}
@Override
public void registerImports(String className, Collection<String> imports, Collection<String> staticImports) {
final JavacRemoteProto.Message.Response response = JavacProtoUtil.createClassDataResponse(className, imports, staticImports);
Channels.write(ctx.getChannel(), JavacProtoUtil.toMessage(sessionId, response));
}
};
final OutputFileConsumer outputSink = new OutputFileConsumer() {
@@ -4,10 +4,10 @@ import com.google.protobuf.ByteString;
import com.google.protobuf.MessageLite;
import org.jetbrains.jps.client.ProtobufResponseHandler;
import javax.tools.Diagnostic;
import javax.tools.JavaFileObject;
import javax.tools.*;
import java.io.File;
import java.net.URI;
import java.util.Collection;
import java.util.Locale;
/**
@@ -82,6 +82,15 @@ public class JavacServerResponseHandler implements ProtobufResponseHandler{
return false;
}
if (responseType == JavacRemoteProto.Message.Response.Type.CLASS_DATA) {
final JavacRemoteProto.Message.Response.ClassData data = response.getClassData();
final String className = data.getClassName();
final Collection<String> imports = data.getImportStatementList();
final Collection<String> staticImports = data.getStaticImportList();
myDiagnosticSink.registerImports(className, imports, staticImports);
return false;
}
if (responseType == JavacRemoteProto.Message.Response.Type.BUILD_COMPLETED) {
myTerminatedSuccessfully = response.getCompletionStatus();
return true;
@@ -1,6 +1,7 @@
package org.jetbrains.ether.dependencyView;
import org.objectweb.asm.ClassReader;
import java.util.Collection;
/**
@@ -26,8 +27,7 @@ public class Callbacks {
public interface Backend {
Collection<String> getClassFiles();
void associate(String classFileName, SourceFileNameLookup sourceLookup, ClassReader cr);
void markOverride(String className, String methodName, String methodSignature);
void registerConstantUsage(String className, String fieldName, String fieldOwner);
void registerImports(Collection<String> imports, String rootClass);
void registerImports(String className, Collection<String> imports, Collection<String> staticImports);
}
}
@@ -1732,23 +1732,24 @@ public class Mappings {
}
}
@Override
public void markOverride(final String className, final String methodName, final String methodSignature) {
//To change body of implemented methods use File | Settings | File Templates.
}
@Override
public void registerConstantUsage(final String className, final String fieldName, final String fieldOwner) {
//To change body of implemented methods use File | Settings | File Templates.
}
@Override
public void registerImports(final Collection<String> imports, final String rootClass) {
final DependencyContext.S rootClassName = myContext.get(rootClass);
public void registerImports(final String className, final Collection<String> imports, Collection<String> staticImports) {
// todo: proces static imports as well
final DependencyContext.S rootClassName = myContext.get(className.replace(".", "/"));
// todo: postpone processing until data collected is complete and myClassToSourceFile contains the mapping
final DependencyContext.S fileName = myClassToSourceFile.get(rootClassName);
for (final String i : imports) {
final DependencyContext.S iname = myContext.get(i);
if (i.endsWith("*")) {
continue; // filter out wildcard imports
}
final DependencyContext.S iname = myContext.get(i.replace(".", "/"));
myClassToClassDependency.put(rootClassName, iname);