invoke translating compilers per-module chunk
[fedora-idea.git] / java / compiler / impl / src / com / intellij / compiler / impl / javaCompiler / AnnotationProcessingCompiler.java
blobc8fa49fc14cbd6b16ed462c01a156a70a8843fdb
1 /*
2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 * @author: Eugene Zhuravlev
19 * Date: Jan 17, 2003
20 * Time: 3:22:59 PM
22 package com.intellij.compiler.impl.javaCompiler;
24 import com.intellij.compiler.CompilerConfiguration;
25 import com.intellij.compiler.CompilerConfigurationImpl;
26 import com.intellij.compiler.CompilerException;
27 import com.intellij.compiler.impl.javaCompiler.javac.JavacCompiler;
28 import com.intellij.compiler.make.CacheCorruptedException;
29 import com.intellij.openapi.application.ApplicationManager;
30 import com.intellij.openapi.compiler.*;
31 import com.intellij.openapi.compiler.ex.CompileContextEx;
32 import com.intellij.openapi.diagnostic.Logger;
33 import com.intellij.openapi.fileTypes.StdFileTypes;
34 import com.intellij.openapi.module.Module;
35 import com.intellij.openapi.project.Project;
36 import com.intellij.openapi.vfs.VirtualFile;
37 import com.intellij.util.Chunk;
38 import org.jetbrains.annotations.NotNull;
40 import java.io.DataInput;
41 import java.io.IOException;
42 import java.util.*;
44 public class AnnotationProcessingCompiler implements SourceProcessingCompiler{
45 private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.javaCompiler.JavaCompiler");
46 private final Project myProject;
48 public AnnotationProcessingCompiler(Project project) {
49 myProject = project;
52 @NotNull
53 public String getDescription() {
54 return CompilerBundle.message("annotation.processing.compiler.description");
57 @NotNull
58 public ProcessingItem[] getProcessingItems(CompileContext context) {
59 final CompilerConfiguration config = CompilerConfiguration.getInstance(myProject);
60 if (!config.isAnnotationProcessorsEnabled()) {
61 return ProcessingItem.EMPTY_ARRAY;
63 final VirtualFile[] files = context.getCompileScope().getFiles(StdFileTypes.JAVA, true);
64 final List<ProcessingItem> items = new ArrayList<ProcessingItem>(files.length);
65 final Set<Module> excludedModules = config.getExcludedModules();
66 for (final VirtualFile file : files) {
67 if (excludedModules.size() != 0 && excludedModules.contains(context.getModuleByFile(file))) {
68 continue;
70 if (config.isExcludedFromCompilation(file)) {
71 continue;
73 items.add(new MyProcessingItem(file));
75 return items.toArray(new ProcessingItem[items.size()]);
78 public ProcessingItem[] process(CompileContext context, ProcessingItem[] items) {
79 final VirtualFile[] files = new VirtualFile[items.length];
80 for (int idx = 0; idx < items.length; idx++) {
81 files[idx] = items[idx].getFile();
83 compile(context, files);
84 return context.getMessageCount(CompilerMessageCategory.ERROR) == 0? items : ProcessingItem.EMPTY_ARRAY;
87 public ValidityState createValidityState(DataInput in) throws IOException {
88 return null;
91 private void compile(final CompileContext context, final VirtualFile[] files) {
92 final JavacCompiler javacCompiler = getBackEndCompiler();
93 final boolean processorMode = javacCompiler.setAnnotationProcessorMode(true);
94 final Chunk<Module> dummyChunk = new Chunk<Module>(Collections.<Module>emptySet()); // TODO!
95 final BackendCompilerWrapper wrapper = new BackendCompilerWrapper(dummyChunk, myProject, Arrays.asList(files), (CompileContextEx)context, javacCompiler, DummySink.INSTANCE);
96 try {
97 wrapper.compile();
99 catch (CompilerException e) {
100 context.addMessage(CompilerMessageCategory.ERROR, e.getMessage(), null, -1, -1);
102 catch (CacheCorruptedException e) {
103 LOG.info(e);
104 context.requestRebuildNextTime(e.getMessage());
106 finally {
107 javacCompiler.setAnnotationProcessorMode(processorMode);
108 final Set<VirtualFile> dirsToRefresh = new HashSet<VirtualFile>();
109 ApplicationManager.getApplication().runReadAction(new Runnable() {
110 public void run() {
111 final Set<Module> modules = new HashSet<Module>();
112 for (VirtualFile file : files) {
113 final Module module = context.getModuleByFile(file);
114 if (module != null) {
115 modules.add(module);
118 for (Module module : modules) {
119 dirsToRefresh.add(context.getModuleOutputDirectory(module));
120 dirsToRefresh.add(context.getModuleOutputDirectoryForTests(module));
121 // todo: Some annotation processors put files into the source code. So need to refresh module source roots.
122 // It is an open question whether we shall support such processors
123 //dirsToRefresh.addAll(Arrays.asList(ModuleRootManager.getInstance(module).getSourceRoots()));
127 for (VirtualFile root : dirsToRefresh) {
128 root.refresh(false, true);
133 public boolean validateConfiguration(CompileScope scope) {
134 final JavacCompiler compiler = getBackEndCompiler();
135 final boolean previousValue = compiler.setAnnotationProcessorMode(true);
136 try {
137 return compiler.checkCompiler(scope);
139 finally {
140 compiler.setAnnotationProcessorMode(previousValue);
144 private JavacCompiler getBackEndCompiler() {
145 CompilerConfigurationImpl configuration = (CompilerConfigurationImpl)CompilerConfiguration.getInstance(myProject);
146 return configuration.getJavacCompiler();
149 private static class MyProcessingItem implements ProcessingItem {
150 private final VirtualFile myFile;
152 public MyProcessingItem(VirtualFile file) {
153 myFile = file;
156 @NotNull
157 public VirtualFile getFile() {
158 return myFile;
161 public ValidityState getValidityState() {
162 return null;
166 private static class DummySink implements TranslatingCompiler.OutputSink {
167 public static final DummySink INSTANCE = new DummySink();
168 public void add(String outputRoot, Collection<TranslatingCompiler.OutputItem> items, VirtualFile[] filesToRecompile) {