remove obsolete dialog
[idea/community.git] / jps / jps-builders / src / org / jetbrains / jps / incremental / instrumentation / BaseInstrumentingBuilder.java
1 /*
2  * Copyright 2000-2012 JetBrains s.r.o.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 package org.jetbrains.jps.incremental.instrumentation;
17
18 import com.intellij.compiler.instrumentation.FailSafeClassReader;
19 import com.intellij.compiler.instrumentation.InstrumentationClassFinder;
20 import com.intellij.compiler.instrumentation.InstrumenterClassWriter;
21 import com.intellij.openapi.diagnostic.Logger;
22 import com.intellij.openapi.util.Key;
23 import org.jetbrains.annotations.Nullable;
24 import org.jetbrains.jps.ModuleChunk;
25 import org.jetbrains.jps.incremental.*;
26 import org.jetbrains.jps.incremental.messages.BuildMessage;
27 import org.jetbrains.jps.incremental.messages.CompilerMessage;
28 import org.jetbrains.org.objectweb.asm.ClassReader;
29 import org.jetbrains.org.objectweb.asm.ClassWriter;
30
31 /**
32  * @author Eugene Zhuravlev
33  *         Date: 11/25/12
34  */
35 public abstract class BaseInstrumentingBuilder extends ClassProcessingBuilder {
36   private static final Logger LOG = Logger.getInstance("#org.jetbrains.jps.incremental.instrumentation.BaseInstrumentingBuilder");
37   // every instance of builder must have its own marker!
38   private final Key<Boolean> IS_INSTRUMENTED_KEY = Key.create("_instrumentation_marker_" + getPresentableName());
39
40   public BaseInstrumentingBuilder() {
41     super(BuilderCategory.CLASS_INSTRUMENTER);
42   }
43
44   @Override
45   protected final ExitCode performBuild(CompileContext context, ModuleChunk chunk, InstrumentationClassFinder finder, OutputConsumer outputConsumer) {
46     ExitCode exitCode = ExitCode.NOTHING_DONE;
47     for (CompiledClass compiledClass : outputConsumer.getCompiledClasses().values()) {
48       if (Utils.IS_TEST_MODE || LOG.isDebugEnabled()) {
49         LOG.info("checking " + compiledClass + " by " + getClass());
50       }
51       final BinaryContent originalContent = compiledClass.getContent();
52       final ClassReader reader = new FailSafeClassReader(originalContent.getBuffer(), originalContent.getOffset(), originalContent.getLength());
53       final int version = getClassFileVersion(reader);
54       if (IS_INSTRUMENTED_KEY.get(compiledClass, Boolean.FALSE) || !canInstrument(compiledClass, version)) {
55         // do not instrument the same content twice
56         continue;
57       }
58       final ClassWriter writer = new InstrumenterClassWriter(reader, getAsmClassWriterFlags(version), finder);
59       try {
60         if (Utils.IS_TEST_MODE || LOG.isDebugEnabled()) {
61           LOG.info("instrumenting " + compiledClass + " by " + getClass());
62         }
63         final BinaryContent instrumented = instrument(context, compiledClass, reader, writer, finder);
64         if (instrumented != null) {
65           compiledClass.setContent(instrumented);
66           finder.cleanCachedData(compiledClass.getClassName());
67           IS_INSTRUMENTED_KEY.set(compiledClass, Boolean.TRUE);
68           exitCode = ExitCode.OK;
69         }
70       }
71       catch (Throwable e) {
72         LOG.info(e);
73         final String message = e.getMessage();
74         if (message != null) {
75           context.processMessage(new CompilerMessage(getPresentableName(), BuildMessage.Kind.ERROR, message, compiledClass.getSourceFile().getPath()));
76         }
77         else {
78           context.processMessage(new CompilerMessage(getPresentableName(), e));
79         }
80       }
81     }
82     return exitCode;
83   }
84
85   protected abstract boolean canInstrument(CompiledClass compiledClass, int classFileVersion);
86
87   @Nullable
88   protected abstract BinaryContent instrument(CompileContext context,
89                                               CompiledClass compiled,
90                                               ClassReader reader,
91                                               ClassWriter writer,
92                                               InstrumentationClassFinder finder);
93
94 }