mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
new compiler api: persistent state splitted to source and output state
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -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();
|
||||
|
||||
+2
-3
@@ -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) {
|
||||
}
|
||||
}
|
||||
|
||||
+8
-7
@@ -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
|
||||
|
||||
+5
-9
@@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+3
-3
@@ -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;
|
||||
|
||||
+5
-6
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
+2
-4
@@ -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);
|
||||
}
|
||||
|
||||
+22
-18
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user