new compiler api: persistent state splitted to source and output state
authornik <Nikolay.Chashnikov@jetbrains.com>
Mon, 9 Aug 2010 11:08:06 +0000 (15:08 +0400)
committernik <Nikolay.Chashnikov@jetbrains.com>
Mon, 9 Aug 2010 12:35:04 +0000 (16:35 +0400)
17 files changed:
java/compiler/impl/compiler-impl.iml
java/compiler/impl/src/com/intellij/compiler/impl/CompilerCacheManager.java
java/compiler/impl/src/com/intellij/compiler/impl/NewCompilerRunner.java
java/compiler/impl/src/com/intellij/compiler/impl/newApi/CompileItem.java
java/compiler/impl/src/com/intellij/compiler/impl/newApi/CompilerInstance.java
java/compiler/impl/src/com/intellij/compiler/impl/newApi/NewCompiler.java
java/compiler/impl/src/com/intellij/compiler/impl/newApi/NewCompilerCache.java
java/compiler/impl/src/com/intellij/compiler/impl/newApi/NewCompilerItemState.java [new file with mode: 0644]
java/compiler/impl/src/com/intellij/compiler/impl/newApi/NewCompilerPersistentData.java
java/compiler/impl/src/com/intellij/compiler/impl/newApi/SingleTargetCompilerInstance.java
java/compiler/impl/src/com/intellij/compiler/impl/newApi/VirtualFileCompileItem.java
java/compiler/impl/src/com/intellij/compiler/impl/newApi/VirtualFileStateExternalizer.java
java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactCompilerCompileItem.java
java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactPackagingItemExternalizer.java
java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactPackagingItemOutputState.java
java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactsCompiler.java
java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactsCompilerInstance.java

index 4f7473c9ff2a75e913beeb769c497528fd077e28..a65d7e10171d8c425cd56487f8ca18d3192c3abb 100644 (file)
@@ -31,6 +31,7 @@
     <orderEntry type="module" module-name="jsp-openapi" />
     <orderEntry type="module" module-name="java-impl" />
     <orderEntry type="module" module-name="idea-ui" />
+    <orderEntry type="library" name="Guava" level="project" />
   </component>
   <component name="copyright">
     <Base>
index 4afce35c12ac18b133a53143ad1cb388a70b7078..b93583556588c7271d72f96cc7bd73d8cb5fa099 100644 (file)
@@ -44,7 +44,7 @@ import java.util.Map;
 public class CompilerCacheManager implements ProjectComponent {
   private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.CompilerCacheManager");
   private final Map<Compiler, Object> myCompilerToCacheMap = new HashMap<Compiler, Object>();
-  private final Map<NewCompiler<?,?>, NewCompilerCache<?,?>> myNewCachesMap = new HashMap<NewCompiler<?,?>, NewCompilerCache<?,?>>();
+  private final Map<NewCompiler<?,?,?>, NewCompilerCache<?,?,?>> myNewCachesMap = new HashMap<NewCompiler<?,?,?>, NewCompilerCache<?,?,?>>();
   private final List<Disposable> myCacheDisposables = new ArrayList<Disposable>();
   private final File myCachesRoot;
   private final Runnable myShutdownTask = new Runnable() {
@@ -90,10 +90,11 @@ public class CompilerCacheManager implements ProjectComponent {
     return dir;
   }
 
-  public synchronized <Key, State> NewCompilerCache<Key, State> getNewCompilerCache(NewCompiler<Key, State> compiler) throws IOException {
-    NewCompilerCache<?, ?> cache = myNewCachesMap.get(compiler);
+  public synchronized <Key, SourceState, OutputState> NewCompilerCache<Key, SourceState, OutputState>
+                             getNewCompilerCache(NewCompiler<Key, SourceState, OutputState> compiler) throws IOException {
+    NewCompilerCache<?,?,?> cache = myNewCachesMap.get(compiler);
     if (cache == null) {
-      final NewCompilerCache<?, ?> newCache = new NewCompilerCache<Key, State>(compiler, NewCompilerRunner.getNewCompilerCacheDir(myProject, compiler));
+      final NewCompilerCache<?,?,?> newCache = new NewCompilerCache<Key, SourceState, OutputState>(compiler, NewCompilerRunner.getNewCompilerCacheDir(myProject, compiler));
       myNewCachesMap.put(compiler, newCache);
       myCacheDisposables.add(new Disposable() {
         @Override
@@ -104,7 +105,7 @@ public class CompilerCacheManager implements ProjectComponent {
       cache = newCache;
     }
     //noinspection unchecked
-    return (NewCompilerCache<Key, State>)cache;
+    return (NewCompilerCache<Key, SourceState, OutputState>)cache;
   }
 
   public synchronized FileProcessingCompilerStateCache getFileProcessingCompilerCache(FileProcessingCompiler compiler) throws IOException {
index a5dc5e2ffc24886d1460f93e43e9232697e52ed6..1b7e3438d5ea9ae10fa8ddfa1211d25798759cab 100644 (file)
  */
 package com.intellij.compiler.impl;
 
+import com.google.common.base.Throwables;
 import com.intellij.compiler.impl.newApi.*;
 import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.ReadAction;
+import com.intellij.openapi.application.Result;
+import com.intellij.openapi.application.RunResult;
 import com.intellij.openapi.compiler.*;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.progress.ProcessCanceledException;
 import com.intellij.openapi.project.DumbService;
 import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Pair;
 import com.intellij.openapi.util.Ref;
 import com.intellij.util.CommonProcessors;
 import com.intellij.util.Processor;
@@ -43,7 +46,7 @@ public class NewCompilerRunner {
   private CompileContext myContext;
   private final boolean myForceCompile;
   private final boolean myOnlyCheckStatus;
-  private final NewCompiler<?,?>[] myCompilers;
+  private final NewCompiler<?,?,?>[] myCompilers;
   private final Project myProject;
 
   public NewCompilerRunner(CompileContext context, CompilerManager compilerManager, boolean forceCompile, boolean onlyCheckStatus) {
@@ -57,7 +60,7 @@ public class NewCompilerRunner {
   public boolean invokeCompilers(NewCompiler.CompileOrderPlace place) throws CompileDriver.ExitException {
     boolean didSomething = false;
     try {
-      for (NewCompiler<?, ?> compiler : myCompilers) {
+      for (NewCompiler<?,?,?> compiler : myCompilers) {
         if (compiler.getOrderPlace().equals(place)) {
           didSomething = invokeCompiler(compiler);
         }
@@ -81,13 +84,13 @@ public class NewCompilerRunner {
     return didSomething;
   }
 
-  private <T extends BuildTarget, Key, State> boolean invokeCompiler(NewCompiler<Key, State> compiler) throws IOException, CompileDriver.ExitException {
+  private <Key, SourceState, OutputState> boolean invokeCompiler(NewCompiler<Key, SourceState, OutputState> compiler) throws IOException, CompileDriver.ExitException {
     return invokeCompiler(compiler, compiler.createInstance(myContext));
   }
 
-  private <T extends BuildTarget, Item extends CompileItem<Key, State>, Key, State>
-  boolean invokeCompiler(NewCompiler<Key, State> compiler, CompilerInstance<T, Item, Key, State> instance) throws IOException, CompileDriver.ExitException {
-    NewCompilerCache<Key, State> cache = CompilerCacheManager.getInstance(myProject).getNewCompilerCache(compiler);
+  private <T extends BuildTarget, Item extends CompileItem<Key, SourceState, OutputState>, Key, SourceState, OutputState>
+  boolean invokeCompiler(NewCompiler<Key, SourceState, OutputState> compiler, CompilerInstance<T, Item, Key, SourceState, OutputState> instance) throws IOException, CompileDriver.ExitException {
+    NewCompilerCache<Key, SourceState, OutputState> cache = CompilerCacheManager.getInstance(myProject).getNewCompilerCache(compiler);
     NewCompilerPersistentData data = new NewCompilerPersistentData(getNewCompilerCacheDir(myProject, compiler), compiler.getVersion());
     if (data.isVersionChanged()) {
       LOG.info("Clearing cache for " + compiler.getDescription());
@@ -106,10 +109,10 @@ public class NewCompilerRunner {
         }
         List<Key> keys = new ArrayList<Key>();
         cache.processSources(id, new CommonProcessors.CollectProcessor<Key>(keys));
-        List<Pair<Key, State>> obsoleteSources = new ArrayList<Pair<Key, State>>();
+        List<NewCompilerItemState<Key, SourceState, OutputState>> obsoleteSources = new ArrayList<NewCompilerItemState<Key,SourceState,OutputState>>();
         for (Key key : keys) {
-          final State state = cache.getState(id, key);
-          obsoleteSources.add(Pair.create(key, state));
+          final NewCompilerCache.PersistentStateData<SourceState, OutputState> state = cache.getState(id, key);
+          obsoleteSources.add(new NewCompilerItemState<Key,SourceState,OutputState>(key, state.mySourceState, state.myOutputState));
         }
         instance.processObsoleteTarget(target, obsoleteSources);
         if (myContext.getMessageCount(CompilerMessageCategory.ERROR) > 0) {
@@ -131,23 +134,24 @@ public class NewCompilerRunner {
     return didSomething;
   }
 
-  public static File getNewCompilerCacheDir(Project project, NewCompiler<?, ?> compiler) {
+  public static File getNewCompilerCacheDir(Project project, NewCompiler<?,?,?> compiler) {
     return new File(CompilerPaths.getCacheStoreDirectory(project), compiler.getId());
   }
 
-  private <T extends BuildTarget, Item extends CompileItem<Key, State>, Key, State>
-  boolean processTarget(T target, final int targetId, final NewCompiler<Key, State> compiler, final CompilerInstance<T, Item, Key, State> instance,
-                        final NewCompilerCache<Key, State> cache) throws IOException, CompileDriver.ExitException {
+  private <T extends BuildTarget, Item extends CompileItem<Key, SourceState, OutputState>, Key, SourceState, OutputState>
+  boolean processTarget(T target, final int targetId, final NewCompiler<Key, SourceState, OutputState> compiler, final CompilerInstance<T, Item, Key, SourceState, OutputState> instance,
+                        final NewCompilerCache<Key, SourceState, OutputState> cache) throws IOException, CompileDriver.ExitException {
     if (LOG.isDebugEnabled()) {
       LOG.debug("Processing target '" + target + "' (id=" + targetId + ")");
     }
     final List<Item> items = instance.getItems(target);
     if (myContext.getMessageCount(CompilerMessageCategory.ERROR) > 0) return true;
 
-    final List<Pair<Item, State>> toProcess = new ArrayList<Pair<Item, State>>();
+    final List<NewCompilerItemState<Item, SourceState, OutputState>> toProcess = new ArrayList<NewCompilerItemState<Item,SourceState,OutputState>>();
     final THashSet<Key> keySet = new THashSet<Key>(new SourceItemHashingStrategy<Key>(compiler));
     final Ref<IOException> exception = Ref.create(null);
     DumbService.getInstance(myProject).waitForSmartMode();
+    final Map<Item, SourceState> sourceStates = new HashMap<Item,SourceState>();
     ApplicationManager.getApplication().runReadAction(new Runnable() {
       @Override
       public void run() {
@@ -155,9 +159,13 @@ public class NewCompilerRunner {
           for (Item item : items) {
             final Key key = item.getKey();
             keySet.add(key);
-            State output = cache.getState(targetId, key);
-            if (myForceCompile || output == null || !item.isUpToDate(output)) {
-              toProcess.add(Pair.create(item, output));
+            final NewCompilerCache.PersistentStateData<SourceState, OutputState> data = cache.getState(targetId, key);
+            SourceState sourceState = data != null ? data.mySourceState : null;
+            final OutputState outputState = data != null ? data.myOutputState : null;
+            if (myForceCompile || sourceState == null || !item.isSourceUpToDate(sourceState)
+                               || outputState == null || !item.isOutputUpToDate(outputState)) {
+              sourceStates.put(item, item.computeSourceState());
+              toProcess.add(new NewCompilerItemState<Item, SourceState, OutputState>(item, sourceState, outputState));
             }
           }
         }
@@ -193,9 +201,10 @@ public class NewCompilerRunner {
       throw new CompileDriver.ExitException(CompileDriver.ExitStatus.CANCELLED);
     }
 
-    List<Pair<Key, State>> obsoleteItems = new ArrayList<Pair<Key, State>>();
+    List<NewCompilerItemState<Key, SourceState, OutputState>> obsoleteItems = new ArrayList<NewCompilerItemState<Key,SourceState,OutputState>>();
     for (Key key : toRemove) {
-      obsoleteItems.add(Pair.create(key, cache.getState(targetId, key)));
+      final NewCompilerCache.PersistentStateData<SourceState, OutputState> data = cache.getState(targetId, key);
+      obsoleteItems.add(new NewCompilerItemState<Key,SourceState,OutputState>(key, data.mySourceState, data.myOutputState));
     }
 
     final List<Item> processedItems = new ArrayList<Item>();
@@ -218,9 +227,19 @@ public class NewCompilerRunner {
       cache.remove(targetId, key);
     }
     CompilerUtil.refreshIOFiles(toRefresh);
-    for (Item item : processedItems) {
-      cache.putOutput(targetId, item.getKey(), item.computeState());
-    }
+
+    final RunResult runResult = new ReadAction() {
+      protected void run(final Result result) throws Throwable {
+        for (Item item : processedItems) {
+          SourceState sourceState = sourceStates.get(item);
+          if (sourceState == null) {
+            sourceState = item.computeSourceState();
+          }
+          cache.putState(targetId, item.getKey(), sourceState, item.computeOutputState());
+        }
+      }
+    }.executeSilently();
+    Throwables.propagateIfPossible(runResult.getThrowable(), IOException.class);
 
     return true;
 
@@ -229,7 +248,7 @@ public class NewCompilerRunner {
   private class SourceItemHashingStrategy<S> implements TObjectHashingStrategy<S> {
     private KeyDescriptor<S> myKeyDescriptor;
 
-    public SourceItemHashingStrategy(NewCompiler<S, ?> compiler) {
+    public SourceItemHashingStrategy(NewCompiler<S, ?, ?> compiler) {
       myKeyDescriptor = compiler.getItemKeyDescriptor();
     }
 
index fb941ca3e4b2a535bf37f392e98cee9dbb9bbb8a..df5eb2fbfc14bbc3ca766b0d118f97a70e186d99 100644 (file)
@@ -20,12 +20,18 @@ import org.jetbrains.annotations.NotNull;
 /**
  * @author nik
  */
-public abstract class CompileItem<Key, State> {
+public abstract class CompileItem<Key, SourceState, OutputState> {
   @NotNull
   public abstract Key getKey();
 
-  public abstract boolean isUpToDate(@NotNull State state);
+  public abstract boolean isSourceUpToDate(@NotNull SourceState state);
 
   @NotNull
-  public abstract State computeState();
+  public abstract SourceState computeSourceState();
+
+
+  public abstract boolean isOutputUpToDate(@NotNull OutputState state);
+
+  @NotNull
+  public abstract OutputState computeOutputState();
 }
index 2e9f9cf5959316358e91f91d40a484a524087017..f5a9df2d41f013a50051bc952e5de00788b70d7a 100644 (file)
@@ -17,7 +17,6 @@ package com.intellij.compiler.impl.newApi;
 
 import com.intellij.openapi.compiler.CompileContext;
 import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Pair;
 import org.jetbrains.annotations.NotNull;
 
 import java.io.File;
@@ -26,7 +25,7 @@ import java.util.List;
 /**
  * @author nik
  */
-public abstract class CompilerInstance<T extends BuildTarget, Item extends CompileItem<Key, State>, Key, State> {
+public abstract class CompilerInstance<T extends BuildTarget, Item extends CompileItem<Key, SourceState, OutputState>, Key, SourceState, OutputState> {
   protected final CompileContext myContext;
 
   protected CompilerInstance(CompileContext context) {
@@ -43,16 +42,16 @@ public abstract class CompilerInstance<T extends BuildTarget, Item extends Compi
   @NotNull
   public abstract List<T> getSelectedTargets();
 
-  public abstract void processObsoleteTarget(@NotNull String targetId, @NotNull List<Pair<Key, State>> obsoleteItems);
+  public abstract void processObsoleteTarget(@NotNull String targetId, @NotNull List<NewCompilerItemState<Key, SourceState, OutputState>> obsoleteItems);
 
 
   @NotNull
   public abstract List<Item> getItems(@NotNull T target);
 
-  public abstract void processItems(@NotNull T target, @NotNull List<Pair<Item, State>> changedItems, @NotNull List<Pair<Key, State>> obsoleteItems,
+  public abstract void processItems(@NotNull T target, @NotNull List<NewCompilerItemState<Item, SourceState, OutputState>> changedItems, @NotNull List<NewCompilerItemState<Key, SourceState, OutputState>> obsoleteItems,
                                     @NotNull OutputConsumer<Item> consumer);
 
-  public interface OutputConsumer<Item extends CompileItem<?,?>> {
+  public interface OutputConsumer<Item extends CompileItem<?,?,?>> {
     void addFileToRefresh(@NotNull File file);
 
     void addProcessedItem(@NotNull Item sourceItem);
index b82b8bf9d84ca3caf05e181c0ebf3eceacaf13f4..11c770a624615c43c61b704814b8cdc03772cc44 100644 (file)
@@ -24,7 +24,7 @@ import org.jetbrains.annotations.NotNull;
 /**
  * @author nik
  */
-public abstract class NewCompiler<Key, State> implements Compiler {
+public abstract class NewCompiler<Key, SourceState, OutputState> implements Compiler {
   private final String myId;
   private final int myVersion;
   private final CompileOrderPlace myOrderPlace;
@@ -38,10 +38,12 @@ public abstract class NewCompiler<Key, State> implements Compiler {
   @NotNull
   public abstract KeyDescriptor<Key> getItemKeyDescriptor();
   @NotNull
-  public abstract DataExternalizer<State> getItemStateExternalizer();
+  public abstract DataExternalizer<SourceState> getSourceStateExternalizer();
+  @NotNull
+  public abstract DataExternalizer<OutputState> getOutputStateExternalizer();
 
   @NotNull
-  public abstract CompilerInstance<?, ? extends CompileItem<Key, State>, Key, State> createInstance(@NotNull CompileContext context);
+  public abstract CompilerInstance<?, ? extends CompileItem<Key, SourceState, OutputState>, Key, SourceState, OutputState> createInstance(@NotNull CompileContext context);
 
   public final String getId() {
     return myId;
index 0b6ea2ecc3e0682336600f1d6e127cd14c9918fc..6982e084a52bc6d7d5d89c4785af8495de29e966 100644 (file)
@@ -17,6 +17,7 @@ package com.intellij.compiler.impl.newApi;
 
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.util.Processor;
+import com.intellij.util.io.DataExternalizer;
 import com.intellij.util.io.KeyDescriptor;
 import com.intellij.util.io.PersistentHashMap;
 
@@ -28,28 +29,25 @@ import java.io.IOException;
 /**
  * @author nik
  */
-public class NewCompilerCache<Key, State> {
+public class NewCompilerCache<Key, SourceState, OutputState> {
   private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.newApi.NewCompilerCache");
-  private PersistentHashMap<KeyAndTargetData<Key>, State> myPersistentMap;
+  private PersistentHashMap<KeyAndTargetData<Key>, PersistentStateData<SourceState, OutputState>> myPersistentMap;
   private File myCacheFile;
-  private final NewCompiler<Key, State> myCompiler;
+  private final NewCompiler<Key, SourceState, OutputState> myCompiler;
 
-  public NewCompilerCache(NewCompiler<Key, State> compiler, final File compilerCacheDir) throws IOException {
+  public NewCompilerCache(NewCompiler<Key, SourceState, OutputState> compiler, final File compilerCacheDir) throws IOException {
     myCompiler = compiler;
     myCacheFile = new File(compilerCacheDir, "timestamps");
     createMap();
   }
 
   private void createMap() throws IOException {
-    myPersistentMap = new PersistentHashMap<KeyAndTargetData<Key>, State>(myCacheFile, new SourceItemDataDescriptor(myCompiler.getItemKeyDescriptor()),
-                                                                  myCompiler.getItemStateExternalizer());
+    myPersistentMap = new PersistentHashMap<KeyAndTargetData<Key>, PersistentStateData<SourceState,OutputState>>(myCacheFile, new SourceItemDataDescriptor(myCompiler.getItemKeyDescriptor()),
+                                                                  new PersistentStateDataExternalizer(myCompiler));
   }
 
   private KeyAndTargetData<Key> getKeyAndTargetData(Key key, int target) {
-    KeyAndTargetData<Key> data = new KeyAndTargetData<Key>();
-    data.myTarget = target;
-    data.myKey = key;
-    return data;
+    return new KeyAndTargetData<Key>(target, key);
   }
 
   public void wipe() throws IOException {
@@ -75,7 +73,7 @@ public class NewCompilerCache<Key, State> {
     myPersistentMap.remove(getKeyAndTargetData(key, targetId));
   }
 
-  public State getState(int targetId, Key key) throws IOException {
+  public PersistentStateData<SourceState, OutputState> getState(int targetId, Key key) throws IOException {
     return myPersistentMap.get(getKeyAndTargetData(key, targetId));
   }
 
@@ -88,16 +86,31 @@ public class NewCompilerCache<Key, State> {
     });
   }
 
-  public void putOutput(int targetId, Key key, State outputItem) throws IOException {
-    myPersistentMap.put(getKeyAndTargetData(key, targetId), outputItem);
+  public void putState(int targetId, Key key, SourceState sourceState, OutputState outputState) throws IOException {
+    myPersistentMap.put(getKeyAndTargetData(key, targetId), new PersistentStateData<SourceState,OutputState>(sourceState, outputState));
   }
 
 
   private static class KeyAndTargetData<Key> {
-    public int myTarget;
-    public Key myKey;
+    public final int myTarget;
+    public final Key myKey;
+
+    private KeyAndTargetData(int target, Key key) {
+      myTarget = target;
+      myKey = key;
+    }
   }
 
+  public static class PersistentStateData<SourceState, OutputState> {
+    public final SourceState mySourceState;
+    public final OutputState myOutputState;
+
+    private PersistentStateData(SourceState sourceState, OutputState outputState) {
+      mySourceState = sourceState;
+      myOutputState = outputState;
+    }
+  }
+  
   private class SourceItemDataDescriptor implements KeyDescriptor<KeyAndTargetData<Key>> {
     private final KeyDescriptor<Key> myKeyDescriptor;
 
@@ -129,4 +142,27 @@ public class NewCompilerCache<Key, State> {
       return getKeyAndTargetData(item, target);
     }
   }
+
+  private class PersistentStateDataExternalizer implements DataExternalizer<PersistentStateData<SourceState, OutputState>> {
+    private DataExternalizer<SourceState> mySourceStateExternalizer;
+    private DataExternalizer<OutputState> myOutputStateExternalizer;
+
+    public PersistentStateDataExternalizer(NewCompiler<Key,SourceState,OutputState> compiler) {
+      mySourceStateExternalizer = compiler.getSourceStateExternalizer();
+      myOutputStateExternalizer = compiler.getOutputStateExternalizer();
+    }
+
+    @Override
+    public void save(DataOutput out, PersistentStateData<SourceState, OutputState> value) throws IOException {
+      mySourceStateExternalizer.save(out, value.mySourceState);
+      myOutputStateExternalizer.save(out, value.myOutputState);
+    }
+
+    @Override
+    public PersistentStateData<SourceState, OutputState> read(DataInput in) throws IOException {
+      SourceState sourceState = mySourceStateExternalizer.read(in);
+      OutputState outputState = myOutputStateExternalizer.read(in);
+      return new PersistentStateData<SourceState,OutputState>(sourceState, outputState);
+    }
+  }
 }
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/newApi/NewCompilerItemState.java b/java/compiler/impl/src/com/intellij/compiler/impl/newApi/NewCompilerItemState.java
new file mode 100644 (file)
index 0000000..4dd7084
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2000-2010 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.compiler.impl.newApi;
+
+/**
+ * @author nik
+ */
+public class NewCompilerItemState<Item, SourceState, OutputState> {
+  private final Item myItem;
+  private final SourceState mySourceState;
+  private final OutputState myOutputState;
+
+  public NewCompilerItemState(Item item, SourceState sourceState, OutputState outputState) {
+    myItem = item;
+    mySourceState = sourceState;
+    myOutputState = outputState;
+  }
+
+  public Item getItem() {
+    return myItem;
+  }
+
+  public SourceState getSourceState() {
+    return mySourceState;
+  }
+
+  public OutputState getOutputState() {
+    return myOutputState;
+  }
+}
index 1746c334cf77b717e3fa378a2ec76f62fe521c3e..703a206c7d1fb3302689a69ce2b990de1daab08d 100644 (file)
@@ -30,7 +30,7 @@ import java.util.Set;
  */
 public class NewCompilerPersistentData {
   private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.newApi.NewCompilerPersistentData");
-  private static final int VERSION = 0;
+  private static final int VERSION = 1;
   private File myFile;
   private Map<String, Integer> myTarget2Id = new HashMap<String, Integer>();
   private TIntHashSet myUsedIds = new TIntHashSet();
index 359366e70bb4f0043711844b53dfa851f7fec085..4e5b5fb51dd65249d34e550d01c051549a77a981 100644 (file)
@@ -16,7 +16,6 @@
 package com.intellij.compiler.impl.newApi;
 
 import com.intellij.openapi.compiler.CompileContext;
-import com.intellij.openapi.util.Pair;
 import org.jetbrains.annotations.NotNull;
 
 import java.util.Collections;
@@ -25,7 +24,7 @@ import java.util.List;
 /**
  * @author nik
  */
-public abstract class SingleTargetCompilerInstance<Item extends CompileItem<S,O>, S, O> extends CompilerInstance<BuildTarget, Item, S, O> {
+public abstract class SingleTargetCompilerInstance<Item extends CompileItem<K,S,O>, K,S, O> extends CompilerInstance<BuildTarget, Item, K, S, O> {
   protected SingleTargetCompilerInstance(CompileContext context) {
     super(context);
   }
@@ -43,6 +42,6 @@ public abstract class SingleTargetCompilerInstance<Item extends CompileItem<S,O>
   }
 
   @Override
-  public void processObsoleteTarget(@NotNull String targetId, @NotNull List<Pair<S, O>> obsoleteItems) {
+  public void processObsoleteTarget(@NotNull String targetId, @NotNull List<NewCompilerItemState<K, S, O>> obsoleteItems) {
   }
 }
index a2c0b7055c9fed4baa16cab3b0ef98df7531fe7d..9131318960e6c965c13acc33c2d57ae31eb5aab0 100644 (file)
@@ -23,7 +23,7 @@ import org.jetbrains.annotations.NotNull;
 /**
  * @author nik
  */
-public abstract class VirtualFileCompileItem<State extends VirtualFilePersistentState> extends CompileItem<String, State> {
+public abstract class VirtualFileCompileItem<OutputState> extends CompileItem<String, VirtualFilePersistentState, OutputState> {
   public static final KeyDescriptor<String> KEY_DESCRIPTOR = new EnumeratorStringDescriptor();
   protected final VirtualFile myFile;
 
@@ -36,15 +36,16 @@ public abstract class VirtualFileCompileItem<State extends VirtualFilePersistent
     return myFile;
   }
 
+  @NotNull
   @Override
-  public final boolean isUpToDate(@NotNull State state) {
-    if (myFile.getTimeStamp() != state.getSourceTimestamp()) {
-      return false;
-    }
-    return isStateUpToDate(state);
+  public VirtualFilePersistentState computeSourceState() {
+    return new VirtualFilePersistentState(myFile.getTimeStamp());
   }
 
-  protected abstract boolean isStateUpToDate(State state);
+  @Override
+  public boolean isSourceUpToDate(@NotNull VirtualFilePersistentState state) {
+    return myFile.getTimeStamp() == state.getSourceTimestamp();
+  }
 
   @NotNull
   @Override
index 6ca46010897923d00d53eb7db5b6ec2f741da277..08c9176c99f45fdde523d687a708a16ba527be82 100644 (file)
@@ -24,21 +24,17 @@ import java.io.IOException;
 /**
 * @author nik
 */
-public abstract class VirtualFileStateExternalizer<State extends VirtualFilePersistentState> implements DataExternalizer<State> {
-  protected abstract void doSave(DataOutput out, State value) throws IOException;
-
-  protected abstract State doRead(DataInput in, long sourceTimestamp) throws IOException;
+public class VirtualFileStateExternalizer implements DataExternalizer<VirtualFilePersistentState> {
+  public static VirtualFileStateExternalizer INSTANCE = new VirtualFileStateExternalizer();
 
   @Override
-  public final void save(DataOutput out, State value) throws IOException {
+  public void save(DataOutput out, VirtualFilePersistentState value) throws IOException {
     out.writeLong(value.getSourceTimestamp());
-    doSave(out, value);
   }
 
   @Override
-  public final State read(DataInput in) throws IOException {
-    final long sourceTimestamp = in.readLong();
-    return doRead(in, sourceTimestamp);
+  public VirtualFilePersistentState read(DataInput in) throws IOException {
+    return new VirtualFilePersistentState(in.readLong());
   }
 
 }
index 517bef7e89d3f7d848f108f23a4026e7a2c5e342..05113499af2a3d20f9cbd9e90f614f0e8610486b 100644 (file)
@@ -46,7 +46,7 @@ public class ArtifactCompilerCompileItem extends VirtualFileCompileItem<Artifact
 
   @NotNull
   @Override
-  public ArtifactPackagingItemOutputState computeState() {
+  public ArtifactPackagingItemOutputState computeOutputState() {
     final SmartList<Pair<String, Long>> pairs = new SmartList<Pair<String, Long>>();
     for (DestinationInfo destination : myDestinations) {
       destination.update();
@@ -54,11 +54,11 @@ public class ArtifactCompilerCompileItem extends VirtualFileCompileItem<Artifact
       long timestamp = outputFile != null ? outputFile.getTimeStamp() : -1;
       pairs.add(Pair.create(destination.getOutputPath(), timestamp));
     }
-    return new ArtifactPackagingItemOutputState(myFile.getTimeStamp(), pairs);
+    return new ArtifactPackagingItemOutputState(pairs);
   }
 
   @Override
-  public boolean isStateUpToDate(ArtifactPackagingItemOutputState state) {
+  public boolean isOutputUpToDate(@NotNull ArtifactPackagingItemOutputState state) {
     final SmartList<Pair<String, Long>> cachedDestinations = state.myDestinations;
     if (cachedDestinations.size() != myDestinations.size()) {
       return false;
index f1adc4c406e1e4ea4e9225c7d0204b80dc2d8435..030e9484ba2680f332dc68e8460e67ebfb78dd18 100644 (file)
@@ -15,9 +15,9 @@
  */
 package com.intellij.packaging.impl.compiler;
 
-import com.intellij.compiler.impl.newApi.VirtualFileStateExternalizer;
 import com.intellij.openapi.util.Pair;
 import com.intellij.util.SmartList;
+import com.intellij.util.io.DataExternalizer;
 import com.intellij.util.io.IOUtil;
 
 import java.io.DataInput;
@@ -27,12 +27,11 @@ import java.io.IOException;
 /**
 * @author nik
 */
-public class ArtifactPackagingItemExternalizer
-  extends VirtualFileStateExternalizer<ArtifactPackagingItemOutputState> {
+public class ArtifactPackagingItemExternalizer implements DataExternalizer<ArtifactPackagingItemOutputState> {
   private byte[] myBuffer = IOUtil.allocReadWriteUTFBuffer();
 
   @Override
-  protected void doSave(DataOutput out, ArtifactPackagingItemOutputState value) throws IOException {
+  public void save(DataOutput out, ArtifactPackagingItemOutputState value) throws IOException {
     out.writeInt(value.myDestinations.size());
     for (Pair<String, Long> pair : value.myDestinations) {
       IOUtil.writeUTFFast(myBuffer, out, pair.getFirst());
@@ -41,7 +40,7 @@ public class ArtifactPackagingItemExternalizer
   }
 
   @Override
-  protected ArtifactPackagingItemOutputState doRead(DataInput in, long sourceTimestamp) throws IOException {
+  public ArtifactPackagingItemOutputState read(DataInput in) throws IOException {
     int size = in.readInt();
     SmartList<Pair<String, Long>> destinations = new SmartList<Pair<String, Long>>();
     while (size-- > 0) {
@@ -49,6 +48,6 @@ public class ArtifactPackagingItemExternalizer
       long outputTimestamp = in.readLong();
       destinations.add(Pair.create(path, outputTimestamp));
     }
-    return new ArtifactPackagingItemOutputState(sourceTimestamp, destinations);
+    return new ArtifactPackagingItemOutputState(destinations);
   }
 }
index e93390d6bc72c808be13e3d50db98defea438e47..29ac0ae91918ca82d8dde9cf7a2bbae55e6c6508 100644 (file)
  */
 package com.intellij.packaging.impl.compiler;
 
-import com.intellij.compiler.impl.newApi.VirtualFilePersistentState;
 import com.intellij.openapi.util.Pair;
 import com.intellij.util.SmartList;
 
 /**
 * @author nik
 */
-public class ArtifactPackagingItemOutputState extends VirtualFilePersistentState {
+public class ArtifactPackagingItemOutputState {
   public final SmartList<Pair<String, Long>> myDestinations;
 
-  public ArtifactPackagingItemOutputState(long timestamp, SmartList<Pair<String, Long>> destinations) {
-    super(timestamp);
+  public ArtifactPackagingItemOutputState(SmartList<Pair<String, Long>> destinations) {
     myDestinations = destinations;
   }
 }
index b410fe456a786a88ca21ddebebec8826e9043c7a..b8cdb63fdb6ba8027f5430db3f0d313b32a49fa3 100644 (file)
  */
 package com.intellij.packaging.impl.compiler;
 
-import com.intellij.compiler.impl.newApi.CompileItem;
-import com.intellij.compiler.impl.newApi.CompilerInstance;
-import com.intellij.compiler.impl.newApi.NewCompiler;
-import com.intellij.compiler.impl.newApi.VirtualFileCompileItem;
+import com.intellij.compiler.impl.newApi.*;
 import com.intellij.openapi.compiler.CompileContext;
 import com.intellij.openapi.compiler.CompileScope;
 import com.intellij.openapi.compiler.CompilerManager;
@@ -35,7 +32,7 @@ import java.util.Set;
 /**
  * @author nik
  */
-public class ArtifactsCompiler extends NewCompiler<String, ArtifactPackagingItemOutputState> {
+public class ArtifactsCompiler extends NewCompiler<String, VirtualFilePersistentState, ArtifactPackagingItemOutputState> {
   static final Key<Set<String>> WRITTEN_PATHS_KEY = Key.create("artifacts_written_paths");
   static final Key<Set<Artifact>> AFFECTED_ARTIFACTS = Key.create("affected_artifacts");
 
@@ -57,13 +54,19 @@ public class ArtifactsCompiler extends NewCompiler<String, ArtifactPackagingItem
 
   @NotNull
   @Override
-  public DataExternalizer<ArtifactPackagingItemOutputState> getItemStateExternalizer() {
-    return ArtifactCompilerCompileItem.OUTPUT_EXTERNALIZER;
+  public DataExternalizer<VirtualFilePersistentState> getSourceStateExternalizer() {
+    return VirtualFileStateExternalizer.INSTANCE;
   }
 
   @NotNull
   @Override
-  public CompilerInstance<ArtifactBuildTarget, ? extends CompileItem<String, ArtifactPackagingItemOutputState>, String, ArtifactPackagingItemOutputState> createInstance(
+  public DataExternalizer<ArtifactPackagingItemOutputState> getOutputStateExternalizer() {
+    return new ArtifactPackagingItemExternalizer();
+  }
+
+  @NotNull
+  @Override
+  public CompilerInstance<ArtifactBuildTarget, ? extends CompileItem<String, VirtualFilePersistentState, ArtifactPackagingItemOutputState>, String, VirtualFilePersistentState, ArtifactPackagingItemOutputState> createInstance(
     @NotNull CompileContext context) {
     return new ArtifactsCompilerInstance(context);
   }
index 46c1ed0bab25ec91381609bdec96a65433d8efdc..5f995f90048bc4419a2b1f6ef129ed333fd5ad3d 100644 (file)
@@ -18,6 +18,8 @@ package com.intellij.packaging.impl.compiler;
 import com.intellij.compiler.CompilerManagerImpl;
 import com.intellij.compiler.impl.CompilerUtil;
 import com.intellij.compiler.impl.newApi.CompilerInstance;
+import com.intellij.compiler.impl.newApi.NewCompilerItemState;
+import com.intellij.compiler.impl.newApi.VirtualFilePersistentState;
 import com.intellij.compiler.impl.packagingCompiler.*;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.application.ReadAction;
@@ -31,7 +33,7 @@ import com.intellij.openapi.deployment.DeploymentUtil;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.module.Module;
 import com.intellij.openapi.module.ModuleManager;
-import com.intellij.openapi.progress.ProcessCanceledException;                                          
+import com.intellij.openapi.progress.ProcessCanceledException;
 import com.intellij.openapi.util.Pair;
 import com.intellij.openapi.util.Ref;
 import com.intellij.openapi.util.SystemInfo;
@@ -60,7 +62,7 @@ import java.util.*;
  * @author nik
  */
 public class ArtifactsCompilerInstance extends CompilerInstance<ArtifactBuildTarget, ArtifactCompilerCompileItem,
-  String, ArtifactPackagingItemOutputState> {
+  String, VirtualFilePersistentState, ArtifactPackagingItemOutputState> {
   private static final Logger LOG = Logger.getInstance("#com.intellij.packaging.impl.compiler.ArtifactsCompilerInstance");
   private ArtifactsProcessingItemsBuilderContext myBuilderContext;
 
@@ -117,8 +119,9 @@ public class ArtifactsCompilerInstance extends CompilerInstance<ArtifactBuildTar
   }
 
   @Override
-  public void processObsoleteTarget(@NotNull String targetId, @NotNull List<Pair<String, ArtifactPackagingItemOutputState>> obsoleteItems) {
-    deleteFiles(obsoleteItems, Collections.<Pair<ArtifactCompilerCompileItem, ArtifactPackagingItemOutputState>>emptyList());
+  public void processObsoleteTarget(@NotNull String targetId,
+                                    @NotNull List<NewCompilerItemState<String, VirtualFilePersistentState, ArtifactPackagingItemOutputState>> obsoleteItems) {
+    deleteFiles(obsoleteItems, Collections.<NewCompilerItemState<ArtifactCompilerCompileItem, VirtualFilePersistentState, ArtifactPackagingItemOutputState>>emptyList());
   }
 
   @NotNull
@@ -160,7 +163,7 @@ public class ArtifactsCompilerInstance extends CompilerInstance<ArtifactBuildTar
     rootElement.computeIncrementalCompilerInstructions(instructionCreator, resolvingContext, myBuilderContext, artifact.getArtifactType());
   }
 
-  private boolean doBuild(final List<Pair<ArtifactCompilerCompileItem, ArtifactPackagingItemOutputState>> changedItems,
+  private boolean doBuild(final List<NewCompilerItemState<ArtifactCompilerCompileItem, VirtualFilePersistentState, ArtifactPackagingItemOutputState>> changedItems,
                           final Set<ArtifactCompilerCompileItem> processedItems,
                           final @NotNull Set<String> writtenPaths, final Set<String> deletedJars) {
     final boolean testMode = ApplicationManager.getApplication().isUnitTestMode();
@@ -179,8 +182,8 @@ public class ArtifactsCompilerInstance extends CompilerInstance<ArtifactBuildTar
       }
 
       int i = 0;
-      for (final Pair<ArtifactCompilerCompileItem, ArtifactPackagingItemOutputState> item : changedItems) {
-        final ArtifactCompilerCompileItem sourceItem = item.getFirst();
+      for (final NewCompilerItemState<ArtifactCompilerCompileItem, VirtualFilePersistentState, ArtifactPackagingItemOutputState> item : changedItems) {
+        final ArtifactCompilerCompileItem sourceItem = item.getItem();
         myContext.getProgressIndicator().checkCanceled();
 
         final Ref<IOException> exception = Ref.create(null);
@@ -304,9 +307,10 @@ public class ArtifactsCompilerInstance extends CompilerInstance<ArtifactBuildTar
   }
 
   @Override
-  public void processItems(@NotNull ArtifactBuildTarget target, @NotNull final List<Pair<ArtifactCompilerCompileItem, ArtifactPackagingItemOutputState>> changedItems,
-    @NotNull List<Pair<String, ArtifactPackagingItemOutputState>> obsoleteItems,
-    @NotNull final OutputConsumer<ArtifactCompilerCompileItem> consumer) {
+  public void processItems(@NotNull ArtifactBuildTarget target,
+                           @NotNull final List<NewCompilerItemState<ArtifactCompilerCompileItem, VirtualFilePersistentState, ArtifactPackagingItemOutputState>> changedItems,
+                           @NotNull List<NewCompilerItemState<String, VirtualFilePersistentState, ArtifactPackagingItemOutputState>> obsoleteItems,
+                           @NotNull OutputConsumer<ArtifactCompilerCompileItem> consumer) {
 
     final THashSet<String> deletedJars = deleteFiles(obsoleteItems, changedItems);
 
@@ -333,8 +337,8 @@ public class ArtifactsCompilerInstance extends CompilerInstance<ArtifactBuildTar
     myContext.putUserData(ArtifactsCompiler.WRITTEN_PATHS_KEY, writtenPaths);
   }
 
-  private THashSet<String> deleteFiles(List<Pair<String, ArtifactPackagingItemOutputState>> obsoleteItems,
-                                       List<Pair<ArtifactCompilerCompileItem, ArtifactPackagingItemOutputState>> changedItems) {
+  private THashSet<String> deleteFiles(List<NewCompilerItemState<String, VirtualFilePersistentState, ArtifactPackagingItemOutputState>> obsoleteItems,
+                                       List<NewCompilerItemState<ArtifactCompilerCompileItem, VirtualFilePersistentState, ArtifactPackagingItemOutputState>> changedItems) {
     myContext.getProgressIndicator().setText(CompilerBundle.message("packaging.compiler.message.deleting.outdated.files"));
 
     final boolean testMode = ApplicationManager.getApplication().isUnitTestMode();
@@ -345,21 +349,21 @@ public class ArtifactsCompilerInstance extends CompilerInstance<ArtifactBuildTar
     }
 
     Set<String> pathToDelete = new THashSet<String>();
-    for (Pair<ArtifactCompilerCompileItem, ArtifactPackagingItemOutputState> item : changedItems) {
-      final ArtifactPackagingItemOutputState cached = item.getSecond();
+    for (NewCompilerItemState<ArtifactCompilerCompileItem, VirtualFilePersistentState, ArtifactPackagingItemOutputState> item : changedItems) {
+      final ArtifactPackagingItemOutputState cached = item.getOutputState();
       if (cached != null) {
         for (Pair<String, Long> destination : cached.myDestinations) {
           pathToDelete.add(destination.getFirst());
         }
       }
     }
-    for (Pair<ArtifactCompilerCompileItem, ArtifactPackagingItemOutputState> item : changedItems) {
-      for (DestinationInfo destination : item.getFirst().getDestinations()) {
+    for (NewCompilerItemState<ArtifactCompilerCompileItem, VirtualFilePersistentState, ArtifactPackagingItemOutputState> item : changedItems) {
+      for (DestinationInfo destination : item.getItem().getDestinations()) {
         pathToDelete.remove(destination.getOutputPath());
       }
     }
-    for (Pair<String, ArtifactPackagingItemOutputState> item : obsoleteItems) {
-      for (Pair<String, Long> destination : item.getSecond().myDestinations) {
+    for (NewCompilerItemState<String, VirtualFilePersistentState, ArtifactPackagingItemOutputState> item : obsoleteItems) {
+      for (Pair<String, Long> destination : item.getOutputState().myDestinations) {
         pathToDelete.add(destination.getFirst());
       }
     }