new compiler api: persistent state splitted to source and output state

This commit is contained in:
nik
2010-08-09 16:35:04 +04:00
parent f482610910
commit 1d0c520e41
17 changed files with 221 additions and 114 deletions
+1
View 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>
@@ -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 {
@@ -15,14 +15,17 @@
*/
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();
}
@@ -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();
}
@@ -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);
@@ -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;
@@ -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);
}
}
}
@@ -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;
}
}
@@ -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();
@@ -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) {
}
}
@@ -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
@@ -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());
}
}
@@ -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;
@@ -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);
}
}
@@ -15,18 +15,16 @@
*/
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;
}
}
@@ -15,10 +15,7 @@
*/
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);
}
@@ -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());
}
}