Merge remote branch 'origin/master'

This commit is contained in:
irengrig
2012-02-12 20:02:20 +04:00
58 changed files with 1436 additions and 285 deletions
@@ -42,6 +42,11 @@ public class GeneralProjectSettingsElement extends ProjectStructureElement {
return "Project";
}
@Override
public String getTypeName() {
return "Project";
}
@Override
public void check(ProjectStructureProblemsHolder problemsHolder) {
final Graph<Chunk<ModifiableRootModel>> graph = ModuleCompilerUtil.toChunkGraph(
@@ -133,6 +133,11 @@ public class ArtifactProjectStructureElement extends ProjectStructureElement {
return "Artifact '" + getActualArtifactName() + "'";
}
@Override
public String getTypeName() {
return "Artifact";
}
@Override
public String getId() {
return "artifact:" + getActualArtifactName();
@@ -33,6 +33,8 @@ import com.intellij.openapi.roots.ui.configuration.libraryEditor.CreateNewLibrar
import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.*;
import com.intellij.openapi.ui.*;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.containers.MultiMap;
import com.intellij.util.ui.tree.TreeUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -250,42 +252,37 @@ public abstract class BaseLibrariesConfigurable extends BaseStructureConfigurabl
if (table != null) {
final Collection<ProjectStructureElementUsage> usages = myContext.getDaemonAnalyzer().getUsages(getSelectedElement());
if (usages.size() > 0) {
final List<String> modules = new ArrayList<String>();
final List<String> artifacts = new ArrayList<String>();
final MultiMap<String, ProjectStructureElementUsage> containerType2Usage = new MultiMap<String, ProjectStructureElementUsage>();
for (final ProjectStructureElementUsage usage : usages) {
if (usage instanceof UsageInModuleClasspath) {
modules.add(usage.getPresentableName());
} else if (usage instanceof UsageInArtifact) {
artifacts.add(usage.getPresentableName());
} else {
LOG.error("Unknown usage: " + usage.getClass().getName());
containerType2Usage.putValue(usage.getContainingElement().getTypeName(), usage);
}
List<String> types = new ArrayList<String>(containerType2Usage.keySet());
Collections.sort(types);
final StringBuilder sb = new StringBuilder("Library '");
sb.append(library.getName()).append("' is used in ");
for (int i = 0; i < types.size(); i++) {
if (i == types.size() - 1) {
sb.append(" and in ");
}
else if (i > 0) {
sb.append(", in ");
}
String type = types.get(i);
Collection<ProjectStructureElementUsage> usagesOfType = containerType2Usage.get(type);
if (usagesOfType.size() > 1) {
sb.append(usagesOfType.size()).append(" ").append(StringUtil.decapitalize(StringUtil.pluralize(type)));
}
else {
sb.append(StringUtil.decapitalize(usagesOfType.iterator().next().getContainingElement().getPresentableName()));
}
}
final StringBuilder sb = new StringBuilder("Library \"");
sb.append(library.getName()).append("\" is used in ");
if (modules.size() > 0) {
if (modules.size() == 1) {
sb.append("module ").append("\"").append(modules.get(0)).append("\"");
} else {
sb.append(modules.size()).append(" modules");
}
}
if (artifacts.size() > 0) {
sb.append(modules.size() > 0 ? " and in " : "");
if (artifacts.size() == 1) {
sb.append("artifact ").append("\"").append(artifacts.get(0)).append("\".");
} else {
sb.append(artifacts.size()).append(" artifacts.");
}
}
sb.append("\n\nAre you sure you want to delete this library?");
sb.append(".\n\nAre you sure you want to delete this library?");
if (DialogWrapper.OK_EXIT_CODE == Messages.showOkCancelDialog(myProject, sb.toString(),
"Confirm Library Deletion", Messages.getQuestionIcon())) {
"Delete Library", Messages.getQuestionIcon())) {
final ModuleStructureConfigurable rootConfigurable = ModuleStructureConfigurable.getInstance(myProject);
for (final ProjectStructureElementUsage usage : usages) {
@@ -48,6 +48,11 @@ public class FacetProjectStructureElement extends ProjectStructureElement {
return "Facet '" + myFacet.getName() + "' in module '" + myFacet.getModule().getName() + "'";
}
@Override
public String getTypeName() {
return "Facet";
}
@Override
public String getId() {
return "facet:" + FacetPointersManager.constructId(myFacet);
@@ -145,6 +145,11 @@ public class LibraryProjectStructureElement extends ProjectStructureElement {
return "Library '" + myLibrary.getName() + "'";
}
@Override
public String getTypeName() {
return "Library";
}
@Override
public String getId() {
return "library:" + myLibrary.getTable().getTableLevel() + ":" + myLibrary.getName();
@@ -140,6 +140,11 @@ public class ModuleProjectStructureElement extends ProjectStructureElement {
return "Module '" + myModule.getName() + "'";
}
@Override
public String getTypeName() {
return "Module";
}
@Override
public String getId() {
return "module:" + myModule.getName();
@@ -86,7 +86,7 @@ public class ProjectStructureDaemonAnalyzer implements Disposable {
if (LOG.isDebugEnabled()) {
LOG.debug("collecting usages in " + element);
}
result.setResult(element.getUsagesInElement());
result.setResult(getUsagesInElement(element));
}
}.execute().getResultObject();
@@ -102,6 +102,10 @@ public class ProjectStructureDaemonAnalyzer implements Disposable {
});
}
private static List<ProjectStructureElementUsage> getUsagesInElement(final ProjectStructureElement element) {
return ProjectStructureValidator.getUsagesInElement(element);
}
private void updateUsages(ProjectStructureElement element, List<ProjectStructureElementUsage> usages) {
removeUsagesInElement(element);
for (ProjectStructureElementUsage usage : usages) {
@@ -233,7 +237,7 @@ public class ProjectStructureDaemonAnalyzer implements Disposable {
public Collection<ProjectStructureElementUsage> getUsages(ProjectStructureElement selected) {
ProjectStructureElement[] elements = myElementWithNotCalculatedUsages.toArray(new ProjectStructureElement[myElementWithNotCalculatedUsages.size()]);
for (ProjectStructureElement element : elements) {
updateUsages(element, element.getUsagesInElement());
updateUsages(element, getUsagesInElement(element));
}
final Collection<ProjectStructureElementUsage> usages = mySourceElement2Usages.get(selected);
return usages != null ? usages : Collections.<ProjectStructureElementUsage>emptyList();
@@ -18,6 +18,8 @@ public abstract class ProjectStructureElement {
public abstract String getPresentableName();
public abstract String getTypeName();
public abstract String getId();
public abstract void check(ProjectStructureProblemsHolder problemsHolder);
@@ -16,6 +16,9 @@
package com.intellij.openapi.roots.ui.configuration.projectRoot.daemon;
import com.intellij.openapi.extensions.ExtensionPointName;
import org.jetbrains.annotations.Nullable;
import java.util.List;
/**
* User: ksafonov
@@ -25,6 +28,16 @@ public abstract class ProjectStructureValidator {
private static final ExtensionPointName<ProjectStructureValidator> EP_NAME =
ExtensionPointName.create("com.intellij.projectStructureValidator");
public static List<ProjectStructureElementUsage> getUsagesInElement(final ProjectStructureElement element) {
for (ProjectStructureValidator validator : EP_NAME.getExtensions()) {
List<ProjectStructureElementUsage> usages = validator.getUsagesIn(element);
if (usages != null) {
return usages;
}
}
return element.getUsagesInElement();
}
public static void check(ProjectStructureElement element, ProjectStructureProblemsHolder problemsHolder) {
for (ProjectStructureValidator validator : EP_NAME.getExtensions()) {
if (validator.checkElement(element, problemsHolder)) {
@@ -33,9 +46,19 @@ public abstract class ProjectStructureValidator {
}
element.check(problemsHolder);
}
/**
* @return <code>true</code> if it handled this element
*/
protected boolean checkElement(ProjectStructureElement element, ProjectStructureProblemsHolder problemsHolder) {
return false;
}
/**
* @return list of usages or <code>null</code> when it does not handle such element
*/
@Nullable
protected List<ProjectStructureElementUsage> getUsagesIn(final ProjectStructureElement element) {
return null;
}
}
@@ -48,6 +48,11 @@ public class SdkProjectStructureElement extends ProjectStructureElement {
return "SDK '" + mySdk.getName() + "'";
}
@Override
public String getTypeName() {
return "SDK";
}
@Override
public String getId() {
return "sdk:" + mySdk.getName();
@@ -4,3 +4,10 @@ End of files
Compiling files:
src/packageA/Base.java
End of files
Cleaning output files:
out/production/OverrideAnnotatedAnonymousNotRecompile/packageA/Derived$1.class
out/production/OverrideAnnotatedAnonymousNotRecompile/packageA/Derived.class
End of files
Compiling files:
src/packageA/Derived.java
End of files
@@ -5,8 +5,10 @@ Compiling files:
src/Base.java
End of files
Cleaning output files:
out/production/DeleteMethodImplementation4/BaseImpl.class
out/production/DeleteMethodImplementation4/BaseImplImpl.class
End of files
Compiling files:
src/BaseImpl.java
src/BaseImplImpl.java
End of files
@@ -4,3 +4,9 @@ End of files
Compiling files:
src/Base.java
End of files
Cleaning output files:
out/production/DeleteMethodImplementation5/BaseImpl.class
End of files
Compiling files:
src/BaseImpl.java
End of files
@@ -4,3 +4,9 @@ End of files
Compiling files:
src/BaseImpl.java
End of files
Cleaning output files:
out/production/DeleteMethodImplementation6/BaseImplImpl.class
End of files
Compiling files:
src/BaseImplImpl.java
End of files
@@ -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;
@@ -178,16 +178,13 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler
myFsState.beforeNextRoundStart();
}
public void afterCompileRound() {
myFsState.clearContextRoundData();
}
public void onChunkBuildStart(ModuleChunk chunk) {
myFsState.setContextChunk(chunk);
}
void onChunkBuildComplete(@NotNull ModuleChunk chunk) throws IOException {
myDataManager.flush(true);
myFsState.clearContextRoundData();
myFsState.clearContextChunk();
if (!myErrorsFound && !myCancelStatus.isCanceled()) {
@@ -52,10 +52,6 @@ public class FSState {
myContextModules.addAll(chunk.getModules());
}
public void clearContextChunk() {
myContextModules.clear();
}
public void beforeNextRoundStart() {
myLastRoundDelta = myCurrentRoundDelta;
myCurrentRoundDelta = new FilesDelta();
@@ -66,6 +62,10 @@ public class FSState {
myLastRoundDelta = null;
}
public void clearContextChunk() {
myContextModules.clear();
}
public void clearRecompile(RootDescriptor rd) {
getDelta(rd.module).clearRecompile(rd.root, rd.isTestRoot);
}
@@ -369,23 +369,23 @@ public class IncProjectBuilder {
private void runModuleLevelBuilders(final CompileContext context, ModuleChunk chunk) throws ProjectBuildException {
boolean rebuildFromScratchRequested = false;
float stageCount = myTotalModuleLevelBuilderCount;
final int modulesInChunk = chunk.getModules().size();
int buildersPassed = 0;
boolean nextPassRequired;
CHUNK_BUILD_START:
for (BuilderCategory category : BuilderCategory.values()) {
final List<ModuleLevelBuilder> builders = myBuilderRegistry.getBuilders(category);
if (builders.isEmpty()) {
continue;
do {
nextPassRequired = false;
context.beforeCompileRound(chunk);
if (!context.isProjectRebuild()) {
syncOutputFiles(context, chunk);
}
final int modulesInChunk = chunk.getModules().size();
int buildersPassed = 0;
boolean nextPassRequired;
do {
nextPassRequired = false;
context.beforeCompileRound(chunk);
if (!context.isProjectRebuild()) {
syncOutputFiles(context, chunk);
for (BuilderCategory category : BuilderCategory.values()) {
final List<ModuleLevelBuilder> builders = myBuilderRegistry.getBuilders(category);
if (builders.isEmpty()) {
continue;
}
for (ModuleLevelBuilder builder : builders) {
@@ -399,7 +399,7 @@ public class IncProjectBuilder {
if (!nextPassRequired) {
// recalculate basis
myModulesProcessed -= (buildersPassed * modulesInChunk) / stageCount;
stageCount += builders.size();
stageCount += myTotalModuleLevelBuilderCount;
myModulesProcessed += (buildersPassed * modulesInChunk) / stageCount;
}
nextPassRequired = true;
@@ -413,6 +413,8 @@ public class IncProjectBuilder {
context.markDirty(chunk);
// reverting to the beginning
myModulesProcessed -= (buildersPassed * modulesInChunk) / stageCount;
stageCount = myTotalModuleLevelBuilderCount;
buildersPassed = 0;
break CHUNK_BUILD_START;
}
catch (Exception e) {
@@ -429,10 +431,8 @@ public class IncProjectBuilder {
context.setDone(fraction);
}
}
while (nextPassRequired);
context.afterCompileRound();
}
while (nextPassRequired);
}
private void runProjectLevelBuilders(CompileContext context) throws ProjectBuildException {
@@ -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,6 +1,8 @@
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;
@@ -8,10 +10,10 @@ import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
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,16 +21,22 @@ import java.util.Set;
* Date: 2/1/12
*
*/
//@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;
}
@Override
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latest();
}
@Override
public void init(ProcessingEnvironment processingEnv) {
super.init(processingEnv);
@@ -37,65 +45,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);
// }
//}
}
@@ -18,7 +18,7 @@ public class JavacMain {
"-d", "-classpath", "-cp", "-bootclasspath"
));
private static final Set<String> FILTERED_SINGLE_OPTIONS = new HashSet<String>(Arrays.<String>asList(
"-verbose", "-proc:none"
"-verbose", "-proc:none", "-implicit:class", "-implicit:none"
));
public static boolean compile(Collection<String> options,
@@ -65,11 +65,12 @@ public class JavacMain {
};
try {
final Collection<String> _options = prepareOptions(options);
final JavaCompiler.CompilationTask task = compiler.getTask(
out, fileManager, outConsumer, filterOptionList(options), null, fileManager.toJavaFileObjects(sources)
out, fileManager, outConsumer, _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 {
@@ -86,11 +87,9 @@ public class JavacMain {
return false;
}
private static Collection<String> filterOptionList(final Collection<String> options) {
if (options.isEmpty()) {
return options;
}
private static Collection<String> prepareOptions(final Collection<String> options) {
final List<String> result = new ArrayList<String>();
result.add("-implicit:class");
boolean skip = false;
for (String option : options) {
if (FILTERED_OPTIONS.contains(option)) {
@@ -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;
@@ -72,7 +72,7 @@ public class GenericTest extends IncrementalTestCase {
public void testChangeToCovariantMethodInBase3() throws Exception {
doTest();
}
*/
public void testChangeVarargSignature() throws Exception {
doTest();
}
@@ -80,7 +80,6 @@ public class GenericTest extends IncrementalTestCase {
public void testChangeVarargSignature1() throws Exception {
doTest();
}
*/
public void testCovariance() throws Exception {
doTest();
@@ -114,7 +113,7 @@ public class GenericTest extends IncrementalTestCase {
doTest();
}
/* Not working yet
/* Not working yet */
public void testOverrideAnnotatedAnonymousNotRecompile() throws Exception {
doTest();
}
@@ -122,7 +121,6 @@ public class GenericTest extends IncrementalTestCase {
public void testOverrideAnnotatedInner() throws Exception {
doTest();
}
*/
public void testParamTypes() throws Exception {
doTest();
@@ -177,7 +177,7 @@ public abstract class IncrementalTestCase extends TestCase {
finally {
try {
closeAppender();
delete(new File(workDir));
//delete(new File(workDir));
}
finally {
Logger.setFactory(oldFactory);
@@ -116,11 +116,9 @@ public class MemberChangeTest extends IncrementalTestCase {
doTest();
}
/* Not working yet
public void testDeleteMethodImplementation4() throws Exception {
doTest();
}
*/
public void testDeleteMethodImplementation5() throws Exception {
doTest();
@@ -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);
}
}
@@ -1103,47 +1103,55 @@ public class Mappings {
}
if ((m.access & Opcodes.ACC_ABSTRACT) == 0) {
final Collection<Pair<MethodRepr, ClassRepr>> overriding = u.findOverridingMethods(m, it, false);
for (final Pair<MethodRepr, ClassRepr> p : overriding) {
final DependencyContext.S fName = myClassToSourceFile.get(p.second.name);
affectedFiles.add(new File(myContext.getValue(fName)));
}
for (DependencyContext.S p : propagated) {
final ClassRepr s = u.reprByName(p);
if (!p.equals(it.name)) {
final ClassRepr s = u.reprByName(p);
if (s != null) {
final Collection<Pair<MethodRepr, ClassRepr>> overridenInS = u.findOverridenMethods(m, s);
if (s != null) {
final Collection<Pair<MethodRepr, ClassRepr>> overridenInS = u.findOverridenMethods(m, s);
overridenInS.addAll(overridenMethods);
overridenInS.addAll(overridenMethods);
boolean allAbstract = true;
boolean visited = false;
boolean allAbstract = true;
boolean visited = false;
for (Pair<MethodRepr, ClassRepr> pp : overridenInS) {
final ClassRepr cc = pp.second;
for (Pair<MethodRepr, ClassRepr> pp : overridenInS) {
final ClassRepr cc = pp.second;
if (cc == myMockClass) {
visited = true;
continue;
}
if (cc.name.equals(it.name)) {
continue;
}
if (cc == myMockClass) {
visited = true;
continue;
allAbstract = ((pp.first.access & Opcodes.ACC_ABSTRACT) > 0) || ((cc.access & Opcodes.ACC_INTERFACE) > 0);
if (!allAbstract) {
break;
}
}
if (cc.name.equals(it.name)) {
continue;
}
if (allAbstract && visited) {
final DependencyContext.S source = myClassToSourceFile.get(p);
visited = true;
allAbstract = ((pp.first.access & Opcodes.ACC_ABSTRACT) > 0) || ((cc.access & Opcodes.ACC_INTERFACE) > 0);
if (!allAbstract) {
break;
}
}
if (allAbstract && visited) {
final DependencyContext.S source = myClassToSourceFile.get(p);
if (source != null) {
final String f = myContext.getValue(source);
debug(
"Removed method is not abstract & is overrides some abstract method which is not then over-overriden in subclass ",
p);
debug("Affecting subclass source file ", f);
affectedFiles.add(new File(f));
if (source != null) {
final String f = myContext.getValue(source);
debug("Removed method is not abstract & overrides some abstract method which is not then over-overriden in subclass ",
p);
debug("Affecting subclass source file ", f);
affectedFiles.add(new File(f));
}
}
}
}
@@ -1597,19 +1605,19 @@ public class Mappings {
for (DependencyContext.S f : delta.getChangedFiles()) {
mySourceFileToClasses.remove(f);
final Collection<ClassRepr> classes = delta.mySourceFileToClasses.get(f);
if (classes != null){
if (classes != null) {
mySourceFileToClasses.put(f, classes);
}
mySourceFileToUsages.remove(f);
final Collection<UsageRepr.Cluster> clusters = delta.mySourceFileToUsages.get(f);
if (clusters != null){
if (clusters != null) {
mySourceFileToUsages.put(f, clusters);
}
mySourceFileToAnnotationUsages.remove(f);
final Collection<UsageRepr.Usage> usages = delta.mySourceFileToAnnotationUsages.get(f);
if (usages != null){
if (usages != null) {
mySourceFileToAnnotationUsages.put(f, usages);
}
}
@@ -1637,7 +1645,7 @@ public class Mappings {
depClasses.retainAll(changedClasses);
if (! classChanged && depClasses.isEmpty()) {
if (!classChanged && depClasses.isEmpty()) {
continue;
}
}
@@ -1724,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);
@@ -154,7 +154,7 @@ public class NotificationsManagerImpl extends NotificationsManager implements No
case BALLOON:
default:
Balloon balloon = notifyByBalloon(notification, type, project);
if (!settings.isShouldLog()) {
if (!settings.isShouldLog() || type == NotificationDisplayType.STICKY_BALLOON) {
if (balloon == null) {
notification.expire();
} else {
@@ -719,7 +719,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
final ArrayList<FinalizableCommand> commandList,
boolean forced,
boolean autoFocusContents) {
if (/*!getFocusManagerImpl(myProject).isUnforcedRequestAllowed() && */!forced) return;
if (!FocusManagerImpl.getInstance().isUnforcedRequestAllowed() && !forced) return;
if (LOG.isDebugEnabled()) {
LOG.debug("enter: activateToolWindowImpl(" + id + ")");
@@ -246,7 +246,7 @@ message.nothing.to.show.in.structure.view=Nothing to show in the Structure View
error.license.collision=This license is being used elsewhere on the network by {0}.\nOnly one active computer at a time can use the license.\nWould you like to re-activate this computer?\nClick Yes to re-activate, or No to shutdown {1}.
title.license.collision.detected=License Collision Detected
message.licensed.to=Licensed to {0}
title.enter.license.data=Enter License Data
title.enter.license.data=Enter {0} License
message.purchase.or.upgrade=For information on how to upgrade your evaluation software please go to {0}
message.expiration.date=Expiration date: {0}
message.educational.license=1-Year Educational License. {0}
@@ -533,6 +533,12 @@
<group id="EditorContextBarMenu">
</group>
<group id="DirDiffMenu">
<action id="DirDiffMenu.SetCopyToRight" class="com.intellij.openapi.diff.impl.dir.actions.popup.SetCopyToRight" text="Set Copy to Right" icon="/vcs/arrow_right.png"/>
<action id="DirDiffMenu.SetCopyToLeft" class="com.intellij.openapi.diff.impl.dir.actions.popup.SetCopyToLeft" text="Set Copy to Left" icon="/vcs/arrow_left.png"/>
<action id="DirDiffMenu.SetDelete" class="com.intellij.openapi.diff.impl.dir.actions.popup.SetDelete" text="Set Delete" icon="/vcs/remove.png"/>
</group>
<action id="Rerun" class="com.intellij.execution.runners.FakeRerunAction" text="Rerun"/>
<action id="IncrementWindowWidth" class="com.intellij.ide.actions.WindowAction$IncrementWidth" use-shortcut-of="ResizeToolWindowRight"/>
@@ -192,6 +192,15 @@ public class DirDiffElement {
}
}
public void setOperation(@NotNull DirDiffOperation operation) {
if (myType == DType.EQUAL || myType == DType.SEPARATOR) return;
if (myType == DType.TARGET && operation == COPY_TO) return;
if (myType == DType.SOURCE && operation == COPY_FROM) return;
if (myType == DType.CHANGED && operation == DELETE) return;
myOperation = operation;
}
public Icon getIcon() {
return mySource != null ? mySource.getIcon() : myTarget.getIcon();
}
@@ -29,6 +29,7 @@ import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.ui.FilterComponent;
import com.intellij.ui.PopupHandler;
import com.intellij.ui.TableSpeedSearch;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.ui.components.JBLabel;
@@ -37,6 +38,7 @@ import com.intellij.ui.components.JBLoadingPanelListener;
import com.intellij.ui.table.JBTable;
import com.intellij.util.diff.FilesTooBigForDiffException;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NonNls;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
@@ -54,7 +56,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
* @author Konstantin Bulenkov
*/
@SuppressWarnings({"unchecked"})
public class DirDiffPanel implements Disposable {
public class DirDiffPanel implements Disposable, DataProvider {
public static final String DIVIDER_PROPERTY = "dir.diff.panel.divider.location";
private JPanel myDiffPanel;
private JBTable myTable;
@@ -77,6 +79,8 @@ public class DirDiffPanel implements Disposable {
private JComponent myViewComponent;
private DiffElement myCurrentElement;
private String oldFilter;
public static final DataKey<DirDiffTableModel> DIR_DIFF_MODEL = DataKey.create("DIR_DIFF_MODEL");
public static final DataKey<JTable> DIR_DIFF_TABLE = DataKey.create("DIR_DIFF_TABLE");
public DirDiffPanel(DirDiffTableModel model, DirDiffWindow wnd) {
myModel = model;
@@ -130,6 +134,7 @@ public class DirDiffPanel implements Disposable {
myTable.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON3) return;
if (myTable.getRowCount() > 0) {
final int row = myTable.rowAtPoint(e.getPoint());
final int col = myTable.columnAtPoint(e.getPoint());
@@ -192,12 +197,22 @@ public class DirDiffPanel implements Disposable {
}
}
final DirDiffToolbarActions actions = new DirDiffToolbarActions(myModel, myDiffPanel);
final ActionToolbar toolbar = ActionManager.getInstance().createActionToolbar("DirDiff", actions, true);
final ActionManager actionManager = ActionManager.getInstance();
final ActionToolbar toolbar = actionManager.createActionToolbar("DirDiff", actions, true);
registerCustomShortcuts(actions, myTable);
myToolBarPanel.add(toolbar.getComponent(), BorderLayout.CENTER);
final JBLabel label = new JBLabel("Use Space button or mouse click to change operation for the selected elements. Enter to perform.", SwingConstants.CENTER);
label.setForeground(UIUtil.getInactiveTextColor());
UIUtil.applyStyle(UIUtil.ComponentStyle.MINI, label);
DataManager.registerDataProvider(myFilesPanel, this);
myTable.addMouseListener(new PopupHandler() {
@Override
public void invokePopup(Component comp, int x, int y) {
final JPopupMenu popupMenu =
actionManager.createActionPopupMenu("DirDiffPanel", (ActionGroup)actionManager.getAction("DirDiffMenu")).getComponent();
popupMenu.show(comp, x, y);
}
});
myFilesPanel.add(label, BorderLayout.SOUTH);
final JBLoadingPanel loadingPanel = new JBLoadingPanel(new BorderLayout(), wnd.getDisposable());
loadingPanel.addListener(new JBLoadingPanelListener.Adapter() {
@@ -472,4 +487,18 @@ public class DirDiffPanel implements Disposable {
public void setupSplitter() {
mySplitPanel.setDividerLocation(Integer.valueOf(PropertiesComponent.getInstance().getValue(DIVIDER_PROPERTY, "200")));
}
@Override
public Object getData(@NonNls String dataId) {
if (PlatformDataKeys.PROJECT.is(dataId)) {
return myModel.getProject();
}
if (DIR_DIFF_MODEL.is(dataId)) {
return myModel;
}
if (DIR_DIFF_TABLE.is(dataId)) {
return myTable;
}
return null;
}
}
@@ -0,0 +1,30 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* 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.intellij.openapi.diff.impl.dir.actions.popup;
import com.intellij.openapi.diff.impl.dir.DirDiffOperation;
import org.jetbrains.annotations.NotNull;
/**
* @author Konstantin Bulenkov
*/
public class SetCopyToLeft extends SetOperationToBase {
@NotNull
@Override
protected DirDiffOperation getOperation() {
return DirDiffOperation.COPY_FROM;
}
}
@@ -0,0 +1,30 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* 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.intellij.openapi.diff.impl.dir.actions.popup;
import com.intellij.openapi.diff.impl.dir.DirDiffOperation;
import org.jetbrains.annotations.NotNull;
/**
* @author Konstantin Bulenkov
*/
public class SetCopyToRight extends SetOperationToBase {
@NotNull
@Override
protected DirDiffOperation getOperation() {
return DirDiffOperation.COPY_TO;
}
}
@@ -0,0 +1,30 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* 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.intellij.openapi.diff.impl.dir.actions.popup;
import com.intellij.openapi.diff.impl.dir.DirDiffOperation;
import org.jetbrains.annotations.NotNull;
/**
* @author Konstantin Bulenkov
*/
public class SetDelete extends SetOperationToBase {
@NotNull
@Override
protected DirDiffOperation getOperation() {
return DirDiffOperation.DELETE;
}
}
@@ -0,0 +1,66 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* 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.intellij.openapi.diff.impl.dir.actions.popup;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.diff.impl.dir.DirDiffElement;
import com.intellij.openapi.diff.impl.dir.DirDiffOperation;
import com.intellij.openapi.diff.impl.dir.DirDiffPanel;
import com.intellij.openapi.diff.impl.dir.DirDiffTableModel;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
/**
* @author Konstantin Bulenkov
*/
public abstract class SetOperationToBase extends AnAction {
@Override
public void actionPerformed(AnActionEvent e) {
DirDiffOperation operation = getOperation();
final DirDiffTableModel model = getModel(e);
final JTable table = getTable(e);
assert model != null && table != null;
for (DirDiffElement element : model.getSelectedElements()) {
element.setOperation(operation);
}
table.repaint();
}
@NotNull
protected abstract DirDiffOperation getOperation();
@Override
public void update(AnActionEvent e) {
final DirDiffTableModel model = getModel(e);
final JTable table = getTable(e);
e.getPresentation().setEnabled(table != null
&& model != null
&& !model.getSelectedElements().isEmpty());
}
@Nullable
private static JTable getTable(AnActionEvent e) {
return e.getData(DirDiffPanel.DIR_DIFF_TABLE);
}
@Nullable
public static DirDiffTableModel getModel(AnActionEvent e) {
return e.getData(DirDiffPanel.DIR_DIFF_MODEL);
}
}
@@ -17,6 +17,7 @@ package com.intellij.openapi.vcs.changes;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.ProjectComponent;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.DumbAwareRunnable;
import com.intellij.openapi.project.Project;
@@ -32,6 +33,7 @@ import com.intellij.util.Consumer;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import sun.reflect.Reflection;
import java.util.ArrayList;
import java.util.Collection;
@@ -40,6 +42,8 @@ import java.util.Collection;
* @author max
*/
public class VcsDirtyScopeManagerImpl extends VcsDirtyScopeManager implements ProjectComponent {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vcs.changes.VcsDirtyScopeManagerImpl");
private final Project myProject;
private final ChangeListManager myChangeListManager;
private final ProjectLevelVcsManager myVcsManager;
@@ -100,6 +104,10 @@ public class VcsDirtyScopeManagerImpl extends VcsDirtyScopeManager implements Pr
public void markEverythingDirty() {
if ((! myProject.isOpen()) || myProject.isDisposed() || myVcsManager.getAllActiveVcss().length == 0) return;
if (LOG.isDebugEnabled()) {
LOG.debug("everything dirty: " + Reflection.getCallerClass(1));
}
final LifeDrop lifeDrop = myLife.doIfAlive(new Runnable() {
public void run() {
myDirtBuilder.everythingDirty();
@@ -160,6 +168,10 @@ public class VcsDirtyScopeManagerImpl extends VcsDirtyScopeManager implements Pr
|| dirsConverted != null && ! dirsConverted.isEmpty();
if (! haveStuff) return;
if (LOG.isDebugEnabled()) {
LOG.debug("paths dirty: " + filesConverted + "; " + dirsConverted + "; " + Reflection.getCallerClass(2));
}
takeDirt(new Consumer<DirtBuilder>() {
public void consume(final DirtBuilder dirt) {
if (filesConverted != null) {
@@ -218,6 +230,10 @@ public class VcsDirtyScopeManagerImpl extends VcsDirtyScopeManager implements Pr
final boolean haveStuff = filesConverted != null && ! filesConverted.isEmpty() || dirsConverted != null && ! dirsConverted.isEmpty();
if (! haveStuff) return;
if (LOG.isDebugEnabled()) {
LOG.debug("files dirty: " + filesConverted + "; " + dirsConverted + "; " + Reflection.getCallerClass(2));
}
takeDirt(new Consumer<DirtBuilder>() {
public void consume(final DirtBuilder dirt) {
if (filesConverted != null) {
@@ -240,6 +256,9 @@ public class VcsDirtyScopeManagerImpl extends VcsDirtyScopeManager implements Pr
try {
final AbstractVcs vcs = myGuess.getVcsForDirty(file);
if (vcs == null) return;
if (LOG.isDebugEnabled()) {
LOG.debug("file dirty: " + file + "; " + Reflection.getCallerClass(2));
}
final VcsRoot root = new VcsRoot(vcs, file);
takeDirt(new Consumer<DirtBuilder>() {
public void consume(DirtBuilder dirtBuilder) {
@@ -254,6 +273,9 @@ public class VcsDirtyScopeManagerImpl extends VcsDirtyScopeManager implements Pr
try {
final AbstractVcs vcs = myGuess.getVcsForDirty(file);
if (vcs == null) return;
if (LOG.isDebugEnabled()) {
LOG.debug("file dirty: " + file + "; " + Reflection.getCallerClass(1));
}
final FilePathUnderVcs root = new FilePathUnderVcs(file, vcs);
takeDirt(new Consumer<DirtBuilder>() {
public void consume(DirtBuilder dirtBuilder) {
@@ -272,6 +294,9 @@ public class VcsDirtyScopeManagerImpl extends VcsDirtyScopeManager implements Pr
try {
final AbstractVcs vcs = myGuess.getVcsForDirty(dir);
if (vcs == null) return;
if (LOG.isDebugEnabled()) {
LOG.debug("dir dirty recursively: " + dir + "; " + Reflection.getCallerClass(2));
}
final VcsRoot root = new VcsRoot(vcs, dir);
takeDirt(new Consumer<DirtBuilder>() {
public void consume(DirtBuilder dirtBuilder) {
@@ -286,6 +311,9 @@ public class VcsDirtyScopeManagerImpl extends VcsDirtyScopeManager implements Pr
try {
final AbstractVcs vcs = myGuess.getVcsForDirty(path);
if (vcs == null) return;
if (LOG.isDebugEnabled()) {
LOG.debug("dir dirty recursively: " + path + "; " + Reflection.getCallerClass(2));
}
final FilePathUnderVcs root = new FilePathUnderVcs(path, vcs);
takeDirt(new Consumer<DirtBuilder>() {
public void consume(DirtBuilder dirtBuilder) {
@@ -25,6 +25,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.psi.*;
import com.intellij.psi.impl.PsiModificationTrackerImpl;
import com.intellij.ui.treeStructure.treetable.ListTreeTableModelOnColumns;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
@@ -34,7 +35,6 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.annotator.intentions.QuickfixUtil;
import org.jetbrains.plugins.groovy.annotator.intentions.dynamic.elements.*;
import org.jetbrains.plugins.groovy.annotator.intentions.dynamic.ui.DynamicElementSettings;
import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager;
import javax.swing.tree.DefaultMutableTreeNode;
import java.util.ArrayList;
@@ -384,8 +384,7 @@ public class DynamicManagerImpl extends DynamicManager {
final PsiFile file = PsiDocumentManager.getInstance(myProject).getPsiFile(textEditor.getDocument());
if (file == null) return;
GroovyPsiManager.getInstance(myProject).dropTypesCache();
PsiManager.getInstance(myProject).dropResolveCaches();
((PsiModificationTrackerImpl)PsiManager.getInstance(myProject).getModificationTracker()).incCounter();
DaemonCodeAnalyzer.getInstance(myProject).restart();
}
@@ -0,0 +1,104 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* 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 org.jetbrains.plugins.groovy.lang.psi.impl;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrApplicationStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCommandArgumentList;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
/**
* @author Max Medvedev
*/
public class ApplicationStatementUtil {
private static final Logger LOG = Logger.getInstance(ApplicationStatementUtil.class);
public static GrExpression convertToMethodCallExpression(GrExpression expr) {
final Project project = expr.getProject();
final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(project);
boolean copied = false;
if (expr instanceof GrApplicationStatement) {
expr = convertAppInternal(factory, (GrApplicationStatement)expr);
copied = true;
}
if (expr instanceof GrReferenceExpression &&
((GrReferenceExpression)expr).getDotToken() == null &&
((GrReferenceExpression)expr).getQualifier() != null) {
expr = convertRefInternal(factory, ((GrReferenceExpression)expr));
copied = true;
}
if (!shouldManage(expr)) return expr;
if (!copied) expr = (GrExpression)expr.copy();
for (PsiElement child = expr.getFirstChild(); child != null; child = child.getFirstChild()) {
if (child instanceof GrApplicationStatement) {
child = child.replace(convertAppInternal(factory, (GrApplicationStatement)child));
}
else if (child instanceof GrReferenceExpression &&
((GrReferenceExpression)child).getDotToken() == null &&
((GrReferenceExpression)child).getQualifier() != null) {
child = child.replace(convertRefInternal(factory, ((GrReferenceExpression)child)));
}
}
return expr;
}
private static boolean shouldManage(GrExpression expr) {
for (PsiElement child = expr.getFirstChild(); child != null; child = child.getFirstChild()) {
if (child instanceof GrApplicationStatement) {
return true;
}
else if (child instanceof GrReferenceExpression &&
((GrReferenceExpression)child).getDotToken() == null &&
((GrReferenceExpression)child).getQualifier() != null) {
return true;
}
}
return false;
}
private static GrReferenceExpression convertRefInternal(GroovyPsiElementFactory factory, GrReferenceExpression ref) {
ref.addAfter(factory.createDotToken("."), ref.getQualifier());
return ref;
}
private static GrMethodCallExpression convertAppInternal(GroovyPsiElementFactory factory, GrApplicationStatement app) {
final GrCommandArgumentList list = app.getArgumentList();
final GrMethodCallExpression prototype = (GrMethodCallExpression)factory.createExpressionFromText("foo()");
prototype.getInvokedExpression().replace(app.getInvokedExpression());
final GrArgumentList pList = prototype.getArgumentList();
LOG.assertTrue(pList != null);
final PsiElement anchor = pList.getRightParen();
for (PsiElement ch = list.getFirstChild(); ch != null; ch = ch.getNextSibling()) {
pList.addBefore(ch, anchor);
}
return prototype;
}
}
@@ -110,16 +110,15 @@ public class PsiImplUtil {
private static boolean isAfterIdentifier(PsiElement el) {
final PsiElement prev = GeeseUtil.getPreviousNonWhitespaceToken(el);
return prev != null && prev.getNode().getElementType() == GroovyTokenTypes.mIDENT;
return prev != null && prev.getNode().getElementType() == mIDENT;
}
public static GrExpression replaceExpression(GrExpression oldExpr, GrExpression newExpr, boolean removeUnnecessaryParentheses) {
PsiElement oldParent = oldExpr.getParent();
if (oldParent == null) throw new PsiInvalidElementAccessException(oldExpr);
if (newExpr instanceof GrApplicationStatement && !(oldExpr instanceof GrApplicationStatement)) {
GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(oldExpr.getProject());
newExpr = factory.createMethodCallByAppCall(((GrApplicationStatement)newExpr));
if (!(oldExpr instanceof GrApplicationStatement)) {
newExpr = ApplicationStatementUtil.convertToMethodCallExpression(newExpr);
}
// Remove unnecessary parentheses
@@ -30,13 +30,16 @@ import org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariableDeclaration;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrAssignmentExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
import org.jetbrains.plugins.groovy.lang.psi.api.util.GrStatementOwner;
import org.jetbrains.plugins.groovy.lang.psi.api.util.GrVariableDeclarationOwner;
import org.jetbrains.plugins.groovy.lang.psi.dataFlow.reachingDefs.VariableInfo;
import org.jetbrains.plugins.groovy.lang.psi.impl.ApplicationStatementUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
@@ -311,21 +314,8 @@ public class ExtractUtil {
boolean addReturn = !isVoid && expr != null && expr.getType() != null && expr.getType() != PsiType.VOID;
if (addReturn) {
buffer.append("return ");
if (expr instanceof GrApplicationStatement) {
final GrApplicationStatement appStatement = (GrApplicationStatement)expr;
buffer.append(appStatement.getInvokedExpression().getText());
buffer.append('(');
final GrCommandArgumentList argList = appStatement.getArgumentList();
if (argList != null) {
buffer.append(argList.getText());
}
buffer.append(')');
}
else {
buffer.append(expr.getText());
}
expr = ApplicationStatementUtil.convertToMethodCallExpression(expr);
buffer.append(expr.getText());
}
else {
buffer.append(expr != null ? expr.getText() : "");
@@ -113,7 +113,9 @@ public class GroovyExtractChooser {
throw new GrRefactoringError(GroovyRefactoringBundle.message("selected.block.should.represent.an.expression"));
}
if (ExtractUtil.isSingleExpression(statements) && statement0.getParent() instanceof GrAssignmentExpression && ((GrAssignmentExpression)statement0.getParent()).getLValue()==statement0) {
if (ExtractUtil.isSingleExpression(statements) &&
statement0.getParent() instanceof GrAssignmentExpression &&
((GrAssignmentExpression)statement0.getParent()).getLValue() == statement0) {
throw new GrRefactoringError(GroovyRefactoringBundle.message("selected.expression.should.not.be.lvalue"));
}
@@ -107,9 +107,7 @@ public abstract class GrIntroduceHandlerBase<Settings extends GrIntroduceSetting
final PsiElement resolved = resolveResult.getElement();
return resolved instanceof PsiMethod && !resolveResult.isInvokedOnProperty() || resolved instanceof PsiClass;
}
if (expression instanceof GrApplicationStatement) {
return !PsiUtil.isExpressionStatement(expression);
}
if (expression instanceof GrClosableBlock && expression.getParent() instanceof GrStringInjection) return true;
return false;
@@ -15,6 +15,8 @@
*/
package org.jetbrains.plugins.groovy.refactoring.introduce.parameter;
import com.intellij.openapi.application.AccessToken;
import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.ui.Splitter;
import com.intellij.openapi.ui.VerticalFlowLayout;
import com.intellij.openapi.util.Ref;
@@ -44,7 +46,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames;
import org.jetbrains.plugins.groovy.refactoring.GrRefactoringError;
import org.jetbrains.plugins.groovy.refactoring.GroovyNameSuggestionUtil;
import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringBundle;
@@ -281,7 +282,14 @@ public class GrIntroduceParameterDialog extends RefactoringDialog implements GrI
}
final ExtractClosureHelperImpl mockHelper = new ExtractClosureHelperImpl(myInfo, "__test___n_", false, new TIntArrayList(), false, 0);
final PsiType returnType = ExtractClosureProcessorBase.generateClosure(mockHelper).getReturnType();
final PsiType returnType;
final AccessToken token = WriteAction.start();
try {
returnType = ExtractClosureProcessorBase.generateClosure(mockHelper).getReturnType();
}
finally {
token.finish();
}
box.addClosureTypesFrom(returnType, mockHelper.getContext());
if (expr == null && var == null) {
@@ -401,12 +409,11 @@ public class GrIntroduceParameterDialog extends RefactoringDialog implements GrI
protected void doAction() {
saveSettings();
final GrParametersOwner toReplaceIn = myInfo.getToReplaceIn();
final PsiType selectedType = myTypeComboBox.getSelectedType();
final GrExpression expr = findExpr();
final GrVariable var = findVar();
if ((expr == null && var == null) || selectedType != null && selectedType.equalsToText(GroovyCommonClassNames.GROOVY_LANG_CLOSURE)) {
if (myTypeComboBox.isClosureSelected()) {
GrIntroduceParameterSettings settings = new ExtractClosureHelperImpl(myInfo,
myNameSuggestionsField.getEnteredName(),
myDeclareFinalCheckBox.isSelected(),
@@ -59,8 +59,7 @@ import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringUtil;
* Date: Apr 18, 2009 3:16:24 PM
*/
public class GroovyIntroduceParameterMethodUsagesProcessor implements IntroduceParameterMethodUsagesProcessor {
private static final Logger LOG = Logger
.getInstance("#org.jetbrains.plugins.groovy.refactoring.introduce.parameter.java2groovy.GroovyIntroduceParameterMethodUsagesProcessor");
private static final Logger LOG = Logger.getInstance(GroovyIntroduceParameterMethodUsagesProcessor.class);
private static boolean isGroovyUsage(UsageInfo usage) {
final PsiElement el = usage.getElement();
@@ -115,7 +114,8 @@ public class GroovyIntroduceParameterMethodUsagesProcessor implements IntroduceP
GrExpression newArg = addClosureToCall(initializer, argList);
if (newArg == null) {
newArg = (GrExpression)argList.addAfter(initializer, anchor);
final PsiElement dummy = argList.addAfter(factory.createExpressionFromText("1"), anchor);
newArg = ((GrExpression)dummy).replaceWithExpression((GrExpression)initializer, true);
}
final PsiMethod methodToReplaceIn = data.getMethodToReplaceIn();
new OldReferencesResolver(callExpression, newArg, methodToReplaceIn, data.getReplaceFieldsWithGetters(), initializer,
@@ -253,6 +253,20 @@ class Some {
}
}
}
''')
}
void testAppStatement() {
doTest('''
void foo() {
def s = <selection><caret>"zxcvbn".substring 2 charAt(1)</selection>
}
foo()
''', '''
void foo(Closure<Character> closure) {
def s = <selection><caret>closure()</selection>
}
foo {return "zxcvbn".substring(2).charAt(1)}
''')
}
}
@@ -16,14 +16,13 @@
package org.jetbrains.plugins.groovy.refactoring.extract.method;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.impl.source.PostprocessReformattingAspect;
import com.intellij.refactoring.util.CommonRefactoringUtil;
import org.jetbrains.plugins.groovy.GroovyFileType;
import org.jetbrains.plugins.groovy.LightGroovyTestCase;
import org.jetbrains.plugins.groovy.util.TestUtils;
import java.util.List;
import com.intellij.openapi.util.text.StringUtil
import com.intellij.psi.impl.source.PostprocessReformattingAspect
import com.intellij.refactoring.util.CommonRefactoringUtil
import org.jetbrains.plugins.groovy.GroovyFileType
import org.jetbrains.plugins.groovy.LightGroovyTestCase
import org.jetbrains.plugins.groovy.util.TestUtils
/**
* @author ilyas
@@ -31,29 +30,29 @@ import java.util.List;
public class ExtractMethodTest extends LightGroovyTestCase {
@Override
protected String getBasePath() {
return TestUtils.getTestDataPath() + "groovy/refactoring/extractMethod/";
return TestUtils.testDataPath + "groovy/refactoring/extractMethod/";
}
private void doAntiTest(String errorMessage) throws Exception {
private void doAntiTest(String errorMessage) {
GroovyExtractMethodHandler handler = configureFromText(readInput().get(0));
try {
handler.invoke(getProject(), myFixture.getEditor(), myFixture.getFile(), null);
handler.invoke(project, myFixture.editor, myFixture.file, null);
assertTrue(false);
}
catch (CommonRefactoringUtil.RefactoringErrorHintException e) {
assertEquals(errorMessage, e.getLocalizedMessage());
assertEquals(errorMessage, e.localizedMessage);
}
}
private List<String> readInput() {
return TestUtils.readInput(getTestDataPath() + getTestName(true) + ".test");
return TestUtils.readInput(testDataPath + getTestName(true) + ".test");
}
private void doTest() {
final List<String> data = readInput();
GroovyExtractMethodHandler handler = configureFromText(data.get(0));
handler.invoke(getProject(), myFixture.getEditor(), myFixture.getFile(), null);
PostprocessReformattingAspect.getInstance(getProject()).doPostponedFormatting();
handler.invoke(project, myFixture.editor, myFixture.file, null);
PostprocessReformattingAspect.getInstance(project).doPostponedFormatting();
myFixture.checkResult(StringUtil.trimEnd(data.get(1), "\n"));
}
@@ -64,7 +63,7 @@ public class ExtractMethodTest extends LightGroovyTestCase {
fileText = TestUtils.removeEndMarker(fileText);
myFixture.configureByText(GroovyFileType.GROOVY_FILE_TYPE, fileText);
myFixture.getEditor().getSelectionModel().setSelection(startOffset, endOffset);
myFixture.editor.selectionModel.setSelection(startOffset, endOffset);
return new GroovyExtractMethodHandler();
}
@@ -114,4 +113,5 @@ public class ExtractMethodTest extends LightGroovyTestCase {
public void testWildCardReturnType() {doTest();}
public void testParamChangedInsideExtractedMethod() {doTest();}
public void testTerribleAppStatement() {doTest()}
}
@@ -295,4 +295,5 @@ public class GrIntroduceParameterTest extends LightCodeInsightFixtureTestCase {
public void testClosureArgWithEmptyArgList() {doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, true, false);}
public void testScriptMethod() {doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, true, false);}
public void testAppStatement() {doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, false);}
}
@@ -0,0 +1,11 @@
def foo() {
def s = <begin>"zxcvbn".substring 2 charAt(1)<end>
}
-----
def foo() {
def s = testMethod()
}
private char testMethod() {
return "zxcvbn".substring(2).charAt(1)
}
@@ -0,0 +1 @@
new A().foo("zxcvbn".substring(2).charAt(1))
@@ -0,0 +1,5 @@
class A {
void foo() {
def s = <selection>"zxcvbn".substring(2).charAt(1)</selection>
}
}
@@ -1 +1 @@
new A().foo(27 + 4.5)
new A().foo(27+ 4.5)