diff --git a/java/compiler/impl/src/com/intellij/compiler/CompilerMessageImpl.java b/java/compiler/impl/src/com/intellij/compiler/CompilerMessageImpl.java index 350f7ec4d4ee..bb155766fa40 100644 --- a/java/compiler/impl/src/com/intellij/compiler/CompilerMessageImpl.java +++ b/java/compiler/impl/src/com/intellij/compiler/CompilerMessageImpl.java @@ -15,14 +15,12 @@ */ package com.intellij.compiler; -import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.compiler.CompilerBundle; import com.intellij.openapi.compiler.CompilerMessage; import com.intellij.openapi.compiler.CompilerMessageCategory; import com.intellij.openapi.fileEditor.OpenFileDescriptor; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.vfs.VirtualFileManager; import com.intellij.pom.Navigatable; import org.jetbrains.annotations.Nullable; @@ -36,10 +34,14 @@ public final class CompilerMessageImpl implements CompilerMessage { private final int myRow; private final int myColumn; + public CompilerMessageImpl(Project project, CompilerMessageCategory category, String message) { + this(project, category, message, null, -1, -1, null); + } + public CompilerMessageImpl(Project project, CompilerMessageCategory category, String message, - final String url, + @Nullable final VirtualFile file, int row, int column, @Nullable final Navigatable navigatable) { @@ -49,11 +51,7 @@ public final class CompilerMessageImpl implements CompilerMessage { myMessage = message == null ? "" : message; myRow = row; myColumn = column; - ApplicationManager.getApplication().runReadAction(new Runnable() { - public void run() { - myFile = url == null ? null : VirtualFileManager.getInstance().findFileByUrl(url); - } - }); + myFile = file; } public CompilerMessageCategory getCategory() { diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompileContextExProxy.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompileContextExProxy.java index 50794c80684d..98c2d65161b2 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/CompileContextExProxy.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompileContextExProxy.java @@ -181,7 +181,7 @@ public class CompileContextExProxy implements CompileContextEx { myDelegate.commitZip(outputDir); } - public void assignModule(@NotNull VirtualFile root, @NotNull Module module, boolean isTestSource) { - myDelegate.assignModule(root, module, isTestSource); + public void assignModule(@NotNull VirtualFile root, @NotNull Module module, boolean isTestSource, com.intellij.openapi.compiler.Compiler compiler) { + myDelegate.assignModule(root, module, isTestSource, compiler); } } diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompileContextImpl.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompileContextImpl.java index 7fc2bb45ccfb..a7611f5e273e 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/CompileContextImpl.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompileContextImpl.java @@ -25,7 +25,9 @@ import com.intellij.compiler.CompilerConfiguration; import com.intellij.compiler.CompilerMessageImpl; import com.intellij.compiler.make.DependencyCache; import com.intellij.compiler.progress.CompilerTask; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.compiler.*; +import com.intellij.openapi.compiler.Compiler; import com.intellij.openapi.compiler.ex.CompileContextEx; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.module.Module; @@ -36,9 +38,12 @@ import com.intellij.openapi.roots.CompilerModuleExtension; import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.UserDataHolderBase; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; import com.intellij.pom.Navigatable; import com.intellij.util.containers.HashMap; import com.intellij.util.containers.HashSet; @@ -67,6 +72,7 @@ public class CompileContextImpl extends UserDataHolderBase implements CompileCon private String myRebuildReason; private final Map myRootToModuleMap = new HashMap(); private final Map> myModuleToRootsMap = new HashMap>(); + private final Map> myOutputRootToSourceGeneratorMap = new HashMap>(); private final Set myGeneratedTestRoots = new java.util.HashSet(); private VirtualFile[] myOutputDirectories; private Set myTestOutputDirectories; @@ -250,16 +256,41 @@ public class CompileContextImpl extends UserDataHolderBase implements CompileCon } public void addMessage(CompilerMessageCategory category, String message, String url, int lineNum, int columnNum) { - CompilerMessageImpl msg = new CompilerMessageImpl(myProject, category, message, url, lineNum, columnNum, null); + CompilerMessageImpl msg = new CompilerMessageImpl(myProject, category, message, findPresentableFileForMessage(url), lineNum, columnNum, null); addMessage(msg); } public void addMessage(CompilerMessageCategory category, String message, String url, int lineNum, int columnNum, Navigatable navigatable) { - CompilerMessageImpl msg = new CompilerMessageImpl(myProject, category, message, url, lineNum, columnNum, navigatable); + CompilerMessageImpl msg = new CompilerMessageImpl(myProject, category, message, findPresentableFileForMessage(url), lineNum, columnNum, navigatable); addMessage(msg); } + @Nullable + private VirtualFile findPresentableFileForMessage(final String url) { + if (url == null) { + return null; + } + final VirtualFileManager fileManager = VirtualFileManager.getInstance(); + return ApplicationManager.getApplication().runReadAction(new Computable() { + @Override + public VirtualFile compute() { + final VirtualFile file = fileManager.findFileByUrl(url); + if (file != null) { + for (final Map.Entry> entry : myOutputRootToSourceGeneratorMap.entrySet()) { + final VirtualFile root = entry.getKey(); + if (VfsUtil.isAncestor(root, file, false)) { + final Pair pair = entry.getValue(); + final VirtualFile presentableFile = pair.getFirst().getPresentableFile(CompileContextImpl.this, pair.getSecond(), root, file); + return presentableFile != null? presentableFile : file; + } + } + } + return file; + } + }); + } + public void addMessage(CompilerMessage msg) { Collection messages = myMessages.get(msg.getCategory()); if (messages == null) { @@ -313,7 +344,7 @@ public class CompileContextImpl extends UserDataHolderBase implements CompileCon return myTask.getIndicator(); } - public void assignModule(@NotNull VirtualFile root, @NotNull Module module, final boolean isTestSource) { + public void assignModule(@NotNull VirtualFile root, @NotNull Module module, final boolean isTestSource, @Nullable Compiler compiler) { try { myRootToModuleMap.put(root, module); Set set = myModuleToRootsMap.get(module); @@ -325,6 +356,9 @@ public class CompileContextImpl extends UserDataHolderBase implements CompileCon if (isTestSource) { myGeneratedTestRoots.add(root); } + if (compiler instanceof SourceGeneratingCompiler) { + myOutputRootToSourceGeneratorMap.put(root, new Pair((SourceGeneratingCompiler)compiler, module)); + } } finally { myModuleToRootsCache.remove(module); diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java index ed5bf54c4460..0b802cb3a9bc 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java @@ -203,9 +203,10 @@ public class CompileDriver { for (Map.Entry, Pair> entry : myGenerationCompilerModuleToOutputDirMap.entrySet()) { final Pair outputs = entry.getValue(); - Module module = entry.getKey().getSecond(); - compileContext.assignModule(outputs.getFirst(), module, false); - compileContext.assignModule(outputs.getSecond(), module, true); + final Pair key = entry.getKey(); + final Module module = key.getSecond(); + compileContext.assignModule(outputs.getFirst(), module, false, key.getFirst()); + compileContext.assignModule(outputs.getSecond(), module, true, key.getFirst()); } final Ref status = new Ref(); @@ -391,7 +392,7 @@ public class CompileDriver { continue; } context.addScope(new FileSetCompileScope(Collections.singletonList(vFile), new Module[]{module})); - context.assignModule(vFile, module, false); + context.assignModule(vFile, module, false, null); } } @@ -422,9 +423,10 @@ public class CompileDriver { compileContext.putUserData(COMPILATION_START_TIMESTAMP, LocalTimeCounter.currentTime()); for (Map.Entry, Pair> entry : myGenerationCompilerModuleToOutputDirMap.entrySet()) { final Pair outputs = entry.getValue(); - final Module module = entry.getKey().getSecond(); - compileContext.assignModule(outputs.getFirst(), module, false); - compileContext.assignModule(outputs.getSecond(), module, true); + final Pair key = entry.getKey(); + final Module module = key.getSecond(); + compileContext.assignModule(outputs.getFirst(), module, false, key.getFirst()); + compileContext.assignModule(outputs.getSecond(), module, true, key.getFirst()); } attachAnnotationProcessorsOutputDirectories(compileContext); @@ -530,8 +532,8 @@ public class CompileDriver { if (compileContext.isRebuildRequested()) { ApplicationManager.getApplication().invokeLater(new Runnable() { public void run() { - doRebuild(callback, new CompilerMessageImpl(myProject, CompilerMessageCategory.INFORMATION, compileContext.getRebuildReason(), - null, -1, -1, null), false, compileContext.getCompileScope()); + final CompilerMessageImpl msg = new CompilerMessageImpl(myProject, CompilerMessageCategory.INFORMATION, compileContext.getRebuildReason()); + doRebuild(callback, msg, false, compileContext.getCompileScope()); } }, ModalityState.NON_MODAL); } @@ -675,7 +677,7 @@ public class CompileDriver { final ProgressIndicator progressIndicator = context.getProgressIndicator(); - final int totalCount = all.length + myGenerationCompilerModuleToOutputDirMap.size() * 2; + //final int totalCount = all.length + myGenerationCompilerModuleToOutputDirMap.size() * 2; progressIndicator.pushState(); progressIndicator.setText("Inspecting output directories..."); try { diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/DummySourceGeneratingCompiler.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/DummySourceGeneratingCompiler.java index 154fe5aa2a08..5fd91b01196f 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/DummySourceGeneratingCompiler.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/DummySourceGeneratingCompiler.java @@ -47,6 +47,11 @@ public class DummySourceGeneratingCompiler implements SourceGeneratingCompiler{ myProject = project; } + @Override + public VirtualFile getPresentableFile(CompileContext context, Module module, VirtualFile outputRoot, VirtualFile generatedFile) { + return null; + } + public GenerationItem[] getGenerationItems(CompileContext context) { final Module module = findMyModule(); return new GenerationItem[] { diff --git a/java/compiler/impl/src/com/intellij/compiler/progress/CompilerTask.java b/java/compiler/impl/src/com/intellij/compiler/progress/CompilerTask.java index dc31998d72e3..03dbd9709375 100644 --- a/java/compiler/impl/src/com/intellij/compiler/progress/CompilerTask.java +++ b/java/compiler/impl/src/com/intellij/compiler/progress/CompilerTask.java @@ -495,10 +495,8 @@ public class CompilerTask extends Task.Backgroundable { if (myErrorTreeView != null) { final boolean shouldRetainView = myErrorCount > 0 || myWarningCount > 0 && !myErrorTreeView.isHideWarnings(); if (shouldRetainView) { - addMessage(new CompilerMessageImpl(myProject, CompilerMessageCategory.STATISTICS, - CompilerBundle.message("statistics.error.count", myErrorCount), null, -1, -1, null)); - addMessage(new CompilerMessageImpl(myProject, CompilerMessageCategory.STATISTICS, - CompilerBundle.message("statistics.warnings.count", myWarningCount), null, -1, -1, null)); + addMessage(new CompilerMessageImpl(myProject, CompilerMessageCategory.STATISTICS, CompilerBundle.message("statistics.error.count", myErrorCount))); + addMessage(new CompilerMessageImpl(myProject, CompilerMessageCategory.STATISTICS, CompilerBundle.message("statistics.warnings.count", myWarningCount))); //activateMessageView(); myErrorTreeView.selectFirstMessage(); } diff --git a/java/compiler/impl/src/com/intellij/openapi/compiler/ex/CompileContextEx.java b/java/compiler/impl/src/com/intellij/openapi/compiler/ex/CompileContextEx.java index 239433a3d813..d91e61949790 100644 --- a/java/compiler/impl/src/com/intellij/openapi/compiler/ex/CompileContextEx.java +++ b/java/compiler/impl/src/com/intellij/openapi/compiler/ex/CompileContextEx.java @@ -19,8 +19,8 @@ import com.intellij.compiler.make.DependencyCache; import com.intellij.openapi.compiler.CompileContext; import com.intellij.openapi.compiler.CompileScope; import com.intellij.openapi.compiler.CompilerMessage; -import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.module.Module; +import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -62,5 +62,5 @@ public interface CompileContextEx extends CompileContext { void commitZip(String outputDir) throws IOException; - void assignModule(@NotNull VirtualFile root, @NotNull Module module, boolean isTestSource); + void assignModule(@NotNull VirtualFile root, @NotNull Module module, boolean isTestSource, @Nullable com.intellij.openapi.compiler.Compiler compiler); } diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/SourceGeneratingCompiler.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/SourceGeneratingCompiler.java index 9738560be6ff..4c0b646658f6 100644 --- a/java/compiler/openapi/src/com/intellij/openapi/compiler/SourceGeneratingCompiler.java +++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/SourceGeneratingCompiler.java @@ -15,6 +15,9 @@ */ package com.intellij.openapi.compiler; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.vfs.VirtualFile; + /** * A tag interface indicating that the compiler will generate Java sources. * This affects the order of compiler calls. @@ -22,4 +25,18 @@ package com.intellij.openapi.compiler; * SourceGeneratingCompiler -> SourceInstrumentingCompiler -> TranslatingCompiler -> ClassInstrumentingCompiler -> ClassPostProcessingCompiler -> PackagingCompiler -> Validator */ public interface SourceGeneratingCompiler extends GeneratingCompiler { + + /** + * Used by make subsystem to obtain the file that should be opened in the editor instead of generated file if there were errors found + * while compiling the generated file + * + * + * @param context current compile context + * @param module the module to which the generated file was attributed + * @param outputRoot the compiler output root + * @param generatedFile - the file that was generated by this compiler + * @return substituting file that should be used for navigation in UI or null if no such substitutor is available + * + */ + VirtualFile getPresentableFile(CompileContext context, Module module, VirtualFile outputRoot, VirtualFile generatedFile); } diff --git a/plugins/android/src/org/jetbrains/android/compiler/AndroidAptCompiler.java b/plugins/android/src/org/jetbrains/android/compiler/AndroidAptCompiler.java index 6c50011ea084..193c9f9c0f2a 100644 --- a/plugins/android/src/org/jetbrains/android/compiler/AndroidAptCompiler.java +++ b/plugins/android/src/org/jetbrains/android/compiler/AndroidAptCompiler.java @@ -55,6 +55,11 @@ import java.util.Map; public class AndroidAptCompiler implements SourceGeneratingCompiler { private static final GenerationItem[] EMPTY_GENERATION_ITEM_ARRAY = {}; + @Override + public VirtualFile getPresentableFile(CompileContext context, Module module, VirtualFile outputRoot, VirtualFile generatedFile) { + return null; + } + public static boolean isToCompileModule(Module module, AndroidFacetConfiguration configuration) { if (!(configuration.RUN_PROCESS_RESOURCES_MAVEN_TASK && AndroidMavenUtil.isMavenizedModule(module))) { return true; diff --git a/plugins/android/src/org/jetbrains/android/compiler/AndroidIdlCompiler.java b/plugins/android/src/org/jetbrains/android/compiler/AndroidIdlCompiler.java index 6cb88f079c9e..d17c6dc39211 100644 --- a/plugins/android/src/org/jetbrains/android/compiler/AndroidIdlCompiler.java +++ b/plugins/android/src/org/jetbrains/android/compiler/AndroidIdlCompiler.java @@ -60,6 +60,11 @@ public class AndroidIdlCompiler implements SourceGeneratingCompiler { myProject = project; } + @Override + public VirtualFile getPresentableFile(CompileContext context, Module module, VirtualFile outputRoot, VirtualFile generatedFile) { + return null; + } + public GenerationItem[] getGenerationItems(CompileContext context) { return ApplicationManager.getApplication().runReadAction(new PrepareAction(context)); } diff --git a/plugins/android/src/org/jetbrains/android/compiler/AndroidIncludingCompiler.java b/plugins/android/src/org/jetbrains/android/compiler/AndroidIncludingCompiler.java index 9f396ae929bc..bb10469d8718 100644 --- a/plugins/android/src/org/jetbrains/android/compiler/AndroidIncludingCompiler.java +++ b/plugins/android/src/org/jetbrains/android/compiler/AndroidIncludingCompiler.java @@ -48,6 +48,11 @@ import java.util.Map; public class AndroidIncludingCompiler implements SourceGeneratingCompiler { private static final Logger LOG = Logger.getInstance("#org.jetbrains.android.compiler.AndroidIncludingCompiler"); + @Override + public VirtualFile getPresentableFile(CompileContext context, Module module, VirtualFile outputRoot, VirtualFile generatedFile) { + return null; + } + @Override public GenerationItem[] getGenerationItems(final CompileContext context) { return ApplicationManager.getApplication().runReadAction(new Computable() { diff --git a/plugins/android/src/org/jetbrains/android/compiler/AndroidMavenResourcesCompiler.java b/plugins/android/src/org/jetbrains/android/compiler/AndroidMavenResourcesCompiler.java index dde3f776ca44..a8b9523fc7cb 100644 --- a/plugins/android/src/org/jetbrains/android/compiler/AndroidMavenResourcesCompiler.java +++ b/plugins/android/src/org/jetbrains/android/compiler/AndroidMavenResourcesCompiler.java @@ -52,6 +52,11 @@ import java.util.Map; public class AndroidMavenResourcesCompiler implements SourceGeneratingCompiler { private static final GenerationItem[] EMPTY_GENERATION_ITEM_ARRAY = {}; + @Override + public VirtualFile getPresentableFile(CompileContext context, Module module, VirtualFile outputRoot, VirtualFile generatedFile) { + return null; + } + public GenerationItem[] getGenerationItems(CompileContext context) { return ApplicationManager.getApplication().runReadAction(new PrepareAction(context)); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/generator/GroovycStubGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/generator/GroovycStubGenerator.java index f38127c091fd..d57961996d00 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/generator/GroovycStubGenerator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/generator/GroovycStubGenerator.java @@ -123,7 +123,7 @@ public class GroovycStubGenerator extends GroovyCompilerBase { assert tempOutput != null; cleanDirectory(tempOutput); - ((CompileContextEx)compileContext).assignModule(tempOutput, module, tests); + ((CompileContextEx)compileContext).assignModule(tempOutput, module, tests, this); if (GroovyCompilerConfiguration.getInstance(myProject).isUseGroovycStubs()) { runGroovycCompiler(compileContext, module, toCompile, true, tempOutput, sink, tests);