mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge branch 'master' of git.labs.intellij.net:idea/community
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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -366,7 +366,7 @@ public class JavaDocUtil {
|
||||
String s = fixupMatcher.group(1);
|
||||
|
||||
//[db] that's workaround to avoid internal bug
|
||||
if (!s.equals("\\")) {
|
||||
if (!s.equals("\\") && !secondSymbols.contains(s)) {
|
||||
secondSymbols.addFirst(s);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,11 +31,14 @@ import com.intellij.psi.impl.source.SourceTreeToPsiMap;
|
||||
import com.intellij.psi.impl.source.jsp.jspJava.JspxImportStatement;
|
||||
import com.intellij.psi.impl.source.resolve.ResolveClassUtil;
|
||||
import com.intellij.psi.impl.source.resolve.reference.impl.providers.JavaClassReference;
|
||||
import com.intellij.psi.impl.source.tree.ElementType;
|
||||
import com.intellij.psi.impl.source.tree.JavaElementType;
|
||||
import com.intellij.psi.jsp.JspFile;
|
||||
import com.intellij.psi.jsp.JspSpiUtil;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.LocalSearchScope;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
@@ -59,8 +62,14 @@ public class ImportHelper{
|
||||
}
|
||||
|
||||
public PsiImportList prepareOptimizeImportsResult(@NotNull final PsiJavaFile file) {
|
||||
// Java parser works in a way that comments may be included to the import list, e.g.:
|
||||
// import a;
|
||||
// /* comment */
|
||||
// import b;
|
||||
// We want to preserve those comments then.
|
||||
List<String> comments = new ArrayList<String>();
|
||||
// Note: this array may contain "<packageOrClassName>.*" for unresolved imports!
|
||||
List<Pair<String, Boolean>> names = new ArrayList<Pair<String, Boolean>>(collectNamesToImport(file));
|
||||
List<Pair<String, Boolean>> names = new ArrayList<Pair<String, Boolean>>(collectNamesToImport(file, comments));
|
||||
Collections.sort(names, new Comparator<Pair<String, Boolean>>() {
|
||||
public int compare(Pair<String, Boolean> o1, Pair<String, Boolean> o2) {
|
||||
return o1.getFirst().compareTo(o2.getFirst());
|
||||
@@ -131,15 +140,29 @@ public class ImportHelper{
|
||||
|
||||
try {
|
||||
StringBuilder text = buildImportListText(resultList, classesOrPackagesToImportOnDemand, classesToUseSingle);
|
||||
for (String comment : comments) {
|
||||
text.append("\n").append(comment);
|
||||
}
|
||||
String ext = StdFileTypes.JAVA.getDefaultExtension();
|
||||
PsiFileFactory factory = PsiFileFactory.getInstance(file.getProject());
|
||||
final PsiJavaFile dummyFile = (PsiJavaFile)factory.createFileFromText("_Dummy_." + ext, StdFileTypes.JAVA, text);
|
||||
CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(file.getProject());
|
||||
codeStyleManager.reformat(dummyFile);
|
||||
|
||||
PsiImportList result = dummyFile.getImportList();
|
||||
PsiImportList newImportList = dummyFile.getImportList();
|
||||
PsiImportList result = (PsiImportList)newImportList.copy();
|
||||
PsiImportList oldList = file.getImportList();
|
||||
if (oldList.isReplaceEquivalent(result)) return null;
|
||||
PsiElement firstPrevious = newImportList.getPrevSibling();
|
||||
while (firstPrevious != null && firstPrevious.getPrevSibling() != null) {
|
||||
firstPrevious = firstPrevious.getPrevSibling();
|
||||
}
|
||||
for (PsiElement element = firstPrevious; element != null && element != newImportList; element = element.getNextSibling()) {
|
||||
result.add(element.copy());
|
||||
}
|
||||
for (PsiElement element = newImportList.getNextSibling(); element != null; element = element.getNextSibling()) {
|
||||
result.add(element.copy());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
catch(IncorrectOperationException e) {
|
||||
@@ -603,17 +626,17 @@ public class ImportHelper{
|
||||
|
||||
@NotNull
|
||||
// returns list of (name, isImportStatic) pairs
|
||||
private static Collection<Pair<String,Boolean>> collectNamesToImport(@NotNull PsiJavaFile file){
|
||||
private static Collection<Pair<String,Boolean>> collectNamesToImport(@NotNull PsiJavaFile file, List<String> comments){
|
||||
Set<Pair<String,Boolean>> names = new THashSet<Pair<String,Boolean>>();
|
||||
|
||||
final JspFile jspFile = JspPsiUtil.getJspFile(file);
|
||||
collectNamesToImport(names, file, jspFile);
|
||||
collectNamesToImport(names, comments, file, jspFile);
|
||||
if (jspFile != null) {
|
||||
PsiFile[] files = ArrayUtil.mergeArrays(JspSpiUtil.getIncludingFiles(jspFile), JspSpiUtil.getIncludedFiles(jspFile), PsiFile.class);
|
||||
for (PsiFile includingFile : files) {
|
||||
final PsiFile javaRoot = includingFile.getViewProvider().getPsi(StdLanguages.JAVA);
|
||||
if (javaRoot instanceof PsiJavaFile && file != javaRoot) {
|
||||
collectNamesToImport(names, (PsiJavaFile)javaRoot, jspFile);
|
||||
collectNamesToImport(names, comments, (PsiJavaFile)javaRoot, jspFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -624,17 +647,19 @@ public class ImportHelper{
|
||||
}
|
||||
|
||||
private static void collectNamesToImport(@NotNull final Set<Pair<String, Boolean>> names,
|
||||
@NotNull List<String> comments,
|
||||
@NotNull final PsiJavaFile file,
|
||||
PsiFile context) {
|
||||
String packageName = file.getPackageName();
|
||||
|
||||
final PsiElement[] roots = file.getPsiRoots();
|
||||
for (PsiElement root : roots) {
|
||||
addNamesToImport(names, root, packageName, context);
|
||||
addNamesToImport(names, comments, root, packageName, context);
|
||||
}
|
||||
}
|
||||
|
||||
private static void addNamesToImport(@NotNull Set<Pair<String, Boolean>> names,
|
||||
@NotNull List<String> comments,
|
||||
@NotNull PsiElement scope,
|
||||
@NotNull String thisPackageName,
|
||||
PsiFile context){
|
||||
@@ -644,7 +669,15 @@ public class ImportHelper{
|
||||
stack.add(scope);
|
||||
while (!stack.isEmpty()) {
|
||||
final PsiElement child = stack.removeFirst();
|
||||
if (child instanceof PsiImportList) continue;
|
||||
if (child instanceof PsiImportList) {
|
||||
for (PsiElement element : child.getChildren()) {
|
||||
IElementType elementType = element.getNode().getElementType();
|
||||
if (!JavaElementType.IMPORT_STATEMENT.equals(elementType) && !ElementType.WHITE_SPACE_BIT_SET.contains(elementType)) {
|
||||
comments.add(element.getText());
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (child instanceof PsiLiteralExpression) continue;
|
||||
ContainerUtil.addAll(stack, child.getChildren());
|
||||
|
||||
|
||||
+2
-3
@@ -38,7 +38,6 @@ import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import gnu.trove.THashSet;
|
||||
import gnu.trove.TObjectHashingStrategy;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
@@ -589,7 +588,7 @@ public class JavaCodeStyleManagerImpl extends JavaCodeStyleManager {
|
||||
String[] names = getSuggestionsByName(propertyName, variableKind, false);
|
||||
final PsiExpression qualifierExpression = methodExpr.getQualifierExpression();
|
||||
if (qualifierExpression instanceof PsiReferenceExpression && ((PsiReferenceExpression)qualifierExpression).resolve() instanceof PsiVariable) {
|
||||
names = ArrayUtil.append(names, changeIfNotIdentifier(qualifierExpression.getText() + StringUtil.capitalize(propertyName)));
|
||||
names = ArrayUtil.append(names, StringUtil.sanitizeJavaIdentifier(changeIfNotIdentifier(qualifierExpression.getText() + StringUtil.capitalize(propertyName))));
|
||||
}
|
||||
return new NamesByExprInfo(propertyName, names);
|
||||
}
|
||||
@@ -945,7 +944,7 @@ public class JavaCodeStyleManagerImpl extends JavaCodeStyleManager {
|
||||
@NotNull
|
||||
public SuggestedNameInfo suggestUniqueVariableName(@NotNull final SuggestedNameInfo baseNameInfo, PsiElement place, boolean lookForward) {
|
||||
final String[] names = baseNameInfo.names;
|
||||
Set<String> uniqueNames = new HashSet<String>(names.length);
|
||||
final LinkedHashSet<String> uniqueNames = new LinkedHashSet<String>(names.length);
|
||||
for (String name : names) {
|
||||
uniqueNames.add(suggestUniqueVariableName(name, place, lookForward));
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ public class OptimizeImportsRefactoringHelper implements RefactoringHelper<Set<P
|
||||
public Set<PsiJavaFile> prepareOperation(final UsageInfo[] usages) {
|
||||
Set<PsiJavaFile> javaFiles = new HashSet<PsiJavaFile>();
|
||||
for (UsageInfo usage : usages) {
|
||||
if (usage.isNonCodeUsage) continue;
|
||||
final PsiElement element = usage.getElement();
|
||||
if (element != null) {
|
||||
final PsiFile file = element.getContainingFile();
|
||||
|
||||
+1
-1
@@ -400,7 +400,7 @@ public abstract class BaseExpressionToFieldHandler extends IntroduceHandlerBase
|
||||
return RefactoringUtil.getTypeByExpressionWithExpectedType(expr);
|
||||
}
|
||||
|
||||
public PsiClass getParentClass(PsiExpression initializerExpression) {
|
||||
public PsiClass getParentClass(@NotNull PsiExpression initializerExpression) {
|
||||
PsiElement element = initializerExpression.getUserData(ElementToWorkOn.PARENT);
|
||||
if (element == null) element = initializerExpression.getParent();
|
||||
PsiElement parent = element;
|
||||
|
||||
+5
-4
@@ -71,7 +71,7 @@ public class IntroduceConstantHandler extends BaseExpressionToFieldHandler {
|
||||
PsiLocalVariable local,
|
||||
PsiExpression[] occurences,
|
||||
boolean isStatic) {
|
||||
return IntroduceConstantHandler.this.showRefactoringDialog(project, editor, aClass, local.getInitializer(), local.getType(), occurences, null, null);
|
||||
return IntroduceConstantHandler.this.showRefactoringDialog(project, editor, aClass, local.getInitializer(), local.getType(), occurences, local, null);
|
||||
}
|
||||
};
|
||||
return localToFieldHandler.convertLocalToField(localVariable, editor);
|
||||
@@ -86,6 +86,7 @@ public class IntroduceConstantHandler extends BaseExpressionToFieldHandler {
|
||||
PsiExpression[] occurences,
|
||||
PsiElement anchorElement,
|
||||
PsiElement anchorElementIfAll) {
|
||||
final PsiMethod containingMethod = PsiTreeUtil.getParentOfType(expr != null ? expr : anchorElement, PsiMethod.class);
|
||||
for (PsiExpression occurrence : occurences) {
|
||||
if (RefactoringUtil.isAssignmentLHS(occurrence)) {
|
||||
String message =
|
||||
@@ -133,7 +134,7 @@ public class IntroduceConstantHandler extends BaseExpressionToFieldHandler {
|
||||
|
||||
final IntroduceConstantDialog dialog =
|
||||
new IntroduceConstantDialog(project, parentClass, expr, localVariable, false, occurences, getParentClass(),
|
||||
new TypeSelectorManagerImpl(project, type, expr, occurences));
|
||||
new TypeSelectorManagerImpl(project, type, containingMethod, expr, occurences));
|
||||
dialog.show();
|
||||
if (!dialog.isOK()) {
|
||||
if (occurences.length > 1) {
|
||||
@@ -161,7 +162,7 @@ public class IntroduceConstantHandler extends BaseExpressionToFieldHandler {
|
||||
|
||||
@Nullable
|
||||
private PsiElement isStaticFinalInitializer(PsiExpression expr) {
|
||||
PsiClass parentClass = getParentClass(expr);
|
||||
PsiClass parentClass = expr != null ? getParentClass(expr) : null;
|
||||
if (parentClass == null) return null;
|
||||
IsStaticFinalInitializerExpression visitor = new IsStaticFinalInitializerExpression(parentClass, expr);
|
||||
expr.accept(visitor);
|
||||
@@ -212,7 +213,7 @@ public class IntroduceConstantHandler extends BaseExpressionToFieldHandler {
|
||||
}
|
||||
}
|
||||
|
||||
public PsiClass getParentClass(PsiExpression initializerExpression) {
|
||||
public PsiClass getParentClass(@NotNull PsiExpression initializerExpression) {
|
||||
final PsiType type = initializerExpression.getType();
|
||||
|
||||
if (type != null && PsiUtil.isConstantExpression(initializerExpression)) {
|
||||
|
||||
+1
-21
@@ -20,7 +20,6 @@ import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.wm.WindowManager;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.refactoring.HelpID;
|
||||
@@ -28,7 +27,6 @@ import com.intellij.refactoring.RefactoringBundle;
|
||||
import com.intellij.refactoring.ui.TypeSelectorManagerImpl;
|
||||
import com.intellij.refactoring.util.CommonRefactoringUtil;
|
||||
import com.intellij.refactoring.util.occurences.*;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class IntroduceFieldHandler extends BaseExpressionToFieldHandler {
|
||||
@@ -96,13 +94,12 @@ public class IntroduceFieldHandler extends BaseExpressionToFieldHandler {
|
||||
final boolean currentMethodConstructor = containingMethod != null && containingMethod.isConstructor();
|
||||
final boolean allowInitInMethod = (!currentMethodConstructor || !isInSuperOrThis) && anchorElement instanceof PsiStatement;
|
||||
final boolean allowInitInMethodIfAll = (!currentMethodConstructor || !isInSuperOrThis) && anchorElementIfAll instanceof PsiStatement;
|
||||
type = checkIfTypeAccessible(type, project, parentClass, containingMethod);
|
||||
IntroduceFieldDialog dialog = new IntroduceFieldDialog(
|
||||
project, parentClass, expr, localVariable,
|
||||
currentMethodConstructor,
|
||||
false, declareStatic, occurencesNumber,
|
||||
allowInitInMethod, allowInitInMethodIfAll,
|
||||
new TypeSelectorManagerImpl(project, type, expr, occurences)
|
||||
new TypeSelectorManagerImpl(project, type, containingMethod, expr, occurences)
|
||||
);
|
||||
dialog.show();
|
||||
|
||||
@@ -125,23 +122,6 @@ public class IntroduceFieldHandler extends BaseExpressionToFieldHandler {
|
||||
dialog.getFieldType(), localVariable != null, (TargetDestination)null, false, false);
|
||||
}
|
||||
|
||||
private static PsiType checkIfTypeAccessible(PsiType type, Project project, PsiClass parentClass, PsiMethod containingMethod) {
|
||||
final PsiClass typeClass = PsiUtil.resolveClassInType(type);
|
||||
if (typeClass != null) {
|
||||
if (typeClass instanceof PsiTypeParameter) {
|
||||
if (ArrayUtil.find(parentClass.getTypeParameters(), typeClass) == -1) { //unknown type parameter
|
||||
type = PsiType.getJavaLangObject(PsiManager.getInstance(project), GlobalSearchScope.allScope(project));
|
||||
}
|
||||
} else if (PsiTreeUtil.isAncestor(containingMethod, typeClass, true)) { //local class type
|
||||
final PsiClassType[] superTypes = typeClass.getSuperTypes();
|
||||
if (superTypes.length > 0) {
|
||||
return checkIfTypeAccessible(superTypes[0], project, parentClass, containingMethod);
|
||||
}
|
||||
}
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
private static boolean isInSuperOrThis(PsiExpression occurence) {
|
||||
return !NotInSuperCallOccurenceFilter.INSTANCE.isOK(occurence) || !NotInThisCallFilter.INSTANCE.isOK(occurence);
|
||||
}
|
||||
|
||||
@@ -21,11 +21,14 @@ import com.intellij.codeInsight.ExpectedTypesProvider;
|
||||
import com.intellij.codeInsight.TailType;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.statistics.StatisticsInfo;
|
||||
import com.intellij.psi.statistics.StatisticsManager;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.refactoring.util.RefactoringHierarchyUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import gnu.trove.THashMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -35,7 +38,7 @@ import java.util.*;
|
||||
* @author dsl
|
||||
*/
|
||||
public class TypeSelectorManagerImpl implements TypeSelectorManager {
|
||||
private final PsiType myDefaultType;
|
||||
private PsiType myDefaultType;
|
||||
private final PsiExpression myMainOccurence;
|
||||
private final PsiExpression[] myOccurrences;
|
||||
private final PsiType[] myTypesForMain;
|
||||
@@ -47,27 +50,7 @@ public class TypeSelectorManagerImpl implements TypeSelectorManager {
|
||||
private ExpectedTypesProvider myExpectedTypesProvider;
|
||||
|
||||
public TypeSelectorManagerImpl(Project project, PsiType type, PsiExpression mainOccurence, PsiExpression[] occurrences) {
|
||||
myFactory = JavaPsiFacade.getInstance(project).getElementFactory();
|
||||
myDefaultType = type;
|
||||
myMainOccurence = mainOccurence;
|
||||
myOccurrences = occurrences;
|
||||
myExpectedTypesProvider = ExpectedTypesProvider.getInstance(project);
|
||||
|
||||
myOccurrenceClassProvider = createOccurrenceClassProvider();
|
||||
myTypesForMain = getTypesForMain();
|
||||
myTypesForAll = getTypesForAll(true);
|
||||
|
||||
myIsOneSuggestion =
|
||||
myTypesForMain.length == 1 && myTypesForAll.length == 1 &&
|
||||
myTypesForAll[0].equals(myTypesForMain[0]);
|
||||
if (myIsOneSuggestion) {
|
||||
myTypeSelector = new TypeSelector(myTypesForAll[0]);
|
||||
}
|
||||
else {
|
||||
myTypeSelector = new TypeSelector();
|
||||
}
|
||||
|
||||
|
||||
this(project, type, null, mainOccurence, occurrences);
|
||||
}
|
||||
|
||||
public TypeSelectorManagerImpl(Project project, PsiType type, PsiExpression[] occurrences) {
|
||||
@@ -94,10 +77,64 @@ public class TypeSelectorManagerImpl implements TypeSelectorManager {
|
||||
}
|
||||
}
|
||||
|
||||
public TypeSelectorManagerImpl(Project project,
|
||||
PsiType type,
|
||||
PsiMethod containingMethod,
|
||||
PsiExpression mainOccurence,
|
||||
PsiExpression[] occurrences) {
|
||||
myFactory = JavaPsiFacade.getInstance(project).getElementFactory();
|
||||
myDefaultType = type;
|
||||
myMainOccurence = mainOccurence;
|
||||
myOccurrences = occurrences;
|
||||
myExpectedTypesProvider = ExpectedTypesProvider.getInstance(project);
|
||||
|
||||
myOccurrenceClassProvider = createOccurrenceClassProvider();
|
||||
myTypesForMain = getTypesForMain();
|
||||
myTypesForAll = getTypesForAll(true);
|
||||
|
||||
if (containingMethod != null) {
|
||||
if (PsiUtil.resolveClassInType(type) != null) {
|
||||
myDefaultType = checkIfTypeAccessible(type, project, containingMethod);
|
||||
}
|
||||
}
|
||||
|
||||
myIsOneSuggestion =
|
||||
myTypesForMain.length == 1 && myTypesForAll.length == 1 &&
|
||||
myTypesForAll[0].equals(myTypesForMain[0]);
|
||||
if (myIsOneSuggestion) {
|
||||
myTypeSelector = new TypeSelector(myTypesForAll[0]);
|
||||
}
|
||||
else {
|
||||
myTypeSelector = new TypeSelector();
|
||||
}
|
||||
}
|
||||
|
||||
private PsiType checkIfTypeAccessible(PsiType type, Project project, PsiMethod containingMethod) {
|
||||
PsiClass parentClass = containingMethod.getContainingClass();
|
||||
final PsiClass typeClass = PsiUtil.resolveClassInType(type);
|
||||
if (typeClass != null) {
|
||||
if (typeClass instanceof PsiTypeParameter) {
|
||||
if (ArrayUtil.find(parentClass.getTypeParameters(), typeClass) == -1) { //unknown type parameter
|
||||
return PsiType.getJavaLangObject(PsiManager.getInstance(project), GlobalSearchScope.allScope(project));
|
||||
}
|
||||
} else if (PsiTreeUtil.isAncestor(containingMethod, typeClass, true)) { //local class type
|
||||
final int nextTypeIdx = ArrayUtil.find(myTypesForAll, type) + 1;
|
||||
if (nextTypeIdx < myTypesForAll.length) {
|
||||
return checkIfTypeAccessible(myTypesForAll[nextTypeIdx], project, containingMethod);
|
||||
}
|
||||
}
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
public PsiType[] getTypesForAll() {
|
||||
return myTypesForAll;
|
||||
}
|
||||
|
||||
public PsiType getDefaultType() {
|
||||
return myDefaultType;
|
||||
}
|
||||
|
||||
private ExpectedTypesProvider.ExpectedClassProvider createOccurrenceClassProvider() {
|
||||
final Set<PsiClass> occurrenceClasses = new HashSet<PsiClass>();
|
||||
for (final PsiExpression occurence : myOccurrences) {
|
||||
|
||||
@@ -15,14 +15,26 @@
|
||||
*/
|
||||
package com.intellij.testIntegration;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.testIntegration.createTest.CreateTestAction;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
|
||||
public class JavaTestCreator implements TestCreator {
|
||||
private static final Logger LOG = Logger.getInstance("com.intellij.testIntegration.JavaTestCreator");
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(Project project, Editor editor, PsiFile file) {
|
||||
CreateTestAction action = new CreateTestAction();
|
||||
PsiElement element = file.findElementAt(editor.getCaretModel().getOffset());
|
||||
|
||||
return action.isAvailableForElement(element);
|
||||
}
|
||||
|
||||
public void createTest(Project project, Editor editor, PsiFile file) {
|
||||
try {
|
||||
CreateTestAction action = new CreateTestAction();
|
||||
@@ -32,7 +44,7 @@ public class JavaTestCreator implements TestCreator {
|
||||
}
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
throw new RuntimeException(e);
|
||||
LOG.warn(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
class Test {
|
||||
void foo() {
|
||||
class C {}
|
||||
C c<caret>c;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
class Test {
|
||||
class C {}
|
||||
|
||||
void foo() {
|
||||
C c<caret>c;
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,13 @@
|
||||
package com.intellij.refactoring;
|
||||
|
||||
import com.intellij.JavaTestUtil;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.projectRoots.impl.JavaSdkImpl;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiJavaFile;
|
||||
import com.intellij.psi.PsiLocalVariable;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.refactoring.ui.TypeSelectorManagerImpl;
|
||||
import com.intellij.testFramework.LightCodeInsightTestCase;
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import com.intellij.util.VisibilityUtil;
|
||||
@@ -87,6 +88,37 @@ public class IntroduceConstantTest extends LightCodeInsightTestCase {
|
||||
checkResultByFile(BASE_PATH + getTestName(false) + "_after.java");
|
||||
}
|
||||
|
||||
public void testResultedType() throws Exception {
|
||||
checkDefaultType("java.lang.Object");
|
||||
}
|
||||
|
||||
public void testResultedTypeWhenNonLocal() throws Exception {
|
||||
checkDefaultType("Test.C");
|
||||
}
|
||||
|
||||
private void checkDefaultType(final String expectedType) throws Exception {
|
||||
configureByFile(BASE_PATH + getTestName(false) + ".java");
|
||||
new MockIntroduceConstantHandler(null){
|
||||
@Override
|
||||
protected Settings showRefactoringDialog(Project project,
|
||||
Editor editor,
|
||||
PsiClass parentClass,
|
||||
PsiExpression expr,
|
||||
PsiType type,
|
||||
PsiExpression[] occurences,
|
||||
PsiElement anchorElement,
|
||||
PsiElement anchorElementIfAll) {
|
||||
final TypeSelectorManagerImpl selectorManager =
|
||||
new TypeSelectorManagerImpl(project, type, PsiTreeUtil.getParentOfType(anchorElement, PsiMethod.class), expr, occurences);
|
||||
final PsiType psiType = selectorManager.getDefaultType();
|
||||
Assert.assertEquals(psiType.getCanonicalText(), expectedType);
|
||||
return new Settings("xxx", true, true, true,
|
||||
InitializationPlace.IN_FIELD_DECLARATION, getVisibility(), null, psiType, false,
|
||||
parentClass, false, false);
|
||||
}
|
||||
}.invoke(getProject(), getEditor(), getFile(), null);
|
||||
}
|
||||
|
||||
protected Sdk getProjectJDK() {
|
||||
return JavaSdkImpl.getMockJdk17("java 1.5");
|
||||
}
|
||||
|
||||
@@ -43,10 +43,19 @@ public class JarVersionDetectionUtil {
|
||||
@Nullable
|
||||
public static String detectJarVersion(@NotNull final String detectionClass, @NotNull Module module) {
|
||||
try {
|
||||
final ZipFile zipFile = getDetectionJar(detectionClass, module);
|
||||
if (zipFile == null) {
|
||||
return null;
|
||||
}
|
||||
return detectJarVersion(getDetectionJar(detectionClass, module));
|
||||
}
|
||||
catch (IOException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String detectJarVersion(ZipFile zipFile) {
|
||||
if (zipFile == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
final ZipEntry zipEntry = zipFile.getEntry(JarFile.MANIFEST_NAME);
|
||||
if (zipEntry == null) {
|
||||
return null;
|
||||
|
||||
@@ -21,5 +21,6 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiFile;
|
||||
|
||||
public interface TestCreator {
|
||||
boolean isAvailable(Project project, Editor editor, PsiFile file);
|
||||
void createTest(Project project, Editor editor, PsiFile file);
|
||||
}
|
||||
|
||||
@@ -16,15 +16,12 @@
|
||||
|
||||
package com.intellij.refactoring.rename;
|
||||
|
||||
import com.intellij.navigation.ItemPresentation;
|
||||
import com.intellij.navigation.NavigationItem;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiNamedElement;
|
||||
import com.intellij.refactoring.RefactoringBundle;
|
||||
import com.intellij.refactoring.rename.naming.AutomaticRenamer;
|
||||
@@ -250,7 +247,7 @@ public class AutomaticRenamingDialog extends DialogWrapper {
|
||||
case CHECK_COLUMN:
|
||||
return Boolean.valueOf(myShouldRename[rowIndex]);
|
||||
case OLD_NAME_COLUMN:
|
||||
return "<html>" + RefactoringUIUtil.getDescription(myRenames[rowIndex], true) + "</html>";
|
||||
return "<html><nobr>" + RefactoringUIUtil.getDescription(myRenames[rowIndex], true) + "</nobr></html>";
|
||||
case NEW_NAME_COLUMN:
|
||||
return myNewNames[rowIndex];
|
||||
default:
|
||||
|
||||
@@ -53,23 +53,25 @@ public class GotoTestOrCodeHandler extends GotoTargetHandler {
|
||||
}
|
||||
else {
|
||||
candidates = TestFinderHelper.findTestsForClass(selectedElement);
|
||||
actions.add(new AdditionalAction() {
|
||||
@Override
|
||||
public String getText() {
|
||||
return "Create New Test...";
|
||||
}
|
||||
final TestCreator creator = LanguageTestCreators.INSTANCE.forLanguage(file.getLanguage());
|
||||
if (creator != null && creator.isAvailable(file.getProject(), editor, file)) {
|
||||
actions.add(new AdditionalAction() {
|
||||
@Override
|
||||
public String getText() {
|
||||
return "Create New Test...";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Icon getIcon() {
|
||||
return IconLoader.getIcon("/actions/intentionBulb.png");
|
||||
}
|
||||
@Override
|
||||
public Icon getIcon() {
|
||||
return IconLoader.getIcon("/actions/intentionBulb.png");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
final TestCreator creator = LanguageTestCreators.INSTANCE.forLanguage(file.getLanguage());
|
||||
if (creator != null) creator.createTest(file.getProject(), editor, file);
|
||||
}
|
||||
});
|
||||
@Override
|
||||
public void execute() {
|
||||
creator.createTest(file.getProject(), editor, file);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return new GotoData(sourceElement, candidates.toArray(new PsiElement[candidates.size()]), actions);
|
||||
|
||||
+1
-1
@@ -65,7 +65,7 @@ public interface TextAnnotationGutterProvider {
|
||||
/***
|
||||
* enables annotation view modifications
|
||||
*/
|
||||
List<AnAction> getPopupActions(final Editor editor);
|
||||
List<AnAction> getPopupActions(final int line, final Editor editor);
|
||||
|
||||
/**
|
||||
* Called when the annotations are removed from the editor gutter.
|
||||
|
||||
+5
-1
@@ -1191,8 +1191,12 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
|
||||
DefaultActionGroup actionGroup = new DefaultActionGroup(EditorBundle.message("editor.annotations.action.group.name"), true);
|
||||
actionGroup.add(new CloseAnnotationsAction());
|
||||
final List<AnAction> addActions = new ArrayList<AnAction>();
|
||||
final Point p = e.getPoint();
|
||||
int line = myEditor.xyToLogicalPosition(new Point(0, (int)p.getY())).line;
|
||||
if (line >= myEditor.getDocument().getLineCount()) return;
|
||||
|
||||
for (TextAnnotationGutterProvider gutterProvider : myTextAnnotationGutters) {
|
||||
final List<AnAction> list = gutterProvider.getPopupActions(myEditor);
|
||||
final List<AnAction> list = gutterProvider.getPopupActions(line, myEditor);
|
||||
if (list != null) {
|
||||
for (AnAction action : list) {
|
||||
if (! addActions.contains(action)) {
|
||||
|
||||
@@ -59,7 +59,6 @@ import com.intellij.openapi.util.*;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.ui.GuiUtils;
|
||||
import com.intellij.ui.IdeBorderFactory;
|
||||
import com.intellij.ui.LightweightHint;
|
||||
import com.intellij.ui.components.JBScrollBar;
|
||||
import com.intellij.ui.components.JBScrollPane;
|
||||
@@ -72,6 +71,7 @@ import com.intellij.util.ui.EmptyClipboardOwner;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import com.intellij.util.ui.update.UiNotifyConnector;
|
||||
import gnu.trove.TIntArrayList;
|
||||
import gnu.trove.TIntHashSet;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -1203,12 +1203,18 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
myGutterComponent.repaint(0, yStartLine, myGutterComponent.getWidth(), yEndLine - yStartLine);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asks to repaint all logical lines from the given <code>[start; end]</code> range.
|
||||
*
|
||||
* @param startLine start logical line to repaint (inclusive)
|
||||
* @param endLine end logical line to repaint (inclusive)
|
||||
*/
|
||||
public void repaintLines(int startLine, int endLine) {
|
||||
if (!isShowing()) return;
|
||||
|
||||
Rectangle visibleArea = getScrollingModel().getVisibleArea();
|
||||
int yStartLine = logicalLineToY(startLine);
|
||||
int yEndLine = logicalLineToY(endLine) + getLineHeight() + WAVE_HEIGHT;
|
||||
int yEndLine = logicalPositionToXY(new LogicalPosition(endLine + 1, 0)).y + WAVE_HEIGHT;
|
||||
|
||||
myEditorComponent.repaintEditorComponent(visibleArea.x, yStartLine, visibleArea.x + visibleArea.width, yEndLine - yStartLine);
|
||||
myGutterComponent.repaint(0, yStartLine, myGutterComponent.getWidth(), yEndLine - yStartLine);
|
||||
@@ -1578,20 +1584,31 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
|
||||
int visibleLineNumber = clip.y / lineHeight;
|
||||
|
||||
int startLineNumber = xyToLogicalPosition(new Point(0, clip.y)).line;
|
||||
VisualPosition visualPosition = xyToVisualPosition(new Point(0, clip.y));
|
||||
LogicalPosition logicalPosition = visualToLogicalPosition(visualPosition);
|
||||
|
||||
Point position = new Point(0, visibleLineNumber * lineHeight);
|
||||
if (startLineNumber == 0 && myPrefixText != null) {
|
||||
if (visualPosition.line == 0 && myPrefixText != null) {
|
||||
position.x = drawBackground(g, myPrefixAttributes.getBackgroundColor(), new String(myPrefixText), position, myPrefixAttributes.getFontType(),
|
||||
defaultBackground, clip);
|
||||
}
|
||||
|
||||
if (startLineNumber >= myDocument.getLineCount() || startLineNumber < 0) {
|
||||
if (logicalPosition.line >= myDocument.getLineCount() || logicalPosition.line < 0) {
|
||||
if (position.x > 0) flushBackground(g, clip);
|
||||
return;
|
||||
}
|
||||
|
||||
int start = myDocument.getLineStartOffset(startLineNumber);
|
||||
int start = logicalPositionToOffset(logicalPosition);
|
||||
|
||||
// There is a possible case that we need to draw background from the start of soft wrap-introduced visual line. Given position
|
||||
// has valid 'y' coordinate then at it shouldn't be affected by soft wrap that corresponds to the visual line start offset.
|
||||
// Hence, we store information about soft wrap to be skipped for further processing and adjust 'x' coordinate value if necessary.
|
||||
TIntHashSet softWrapsToSkip = new TIntHashSet();
|
||||
TextChange softWrap = getSoftWrapModel().getSoftWrap(start);
|
||||
if (softWrap != null) {
|
||||
position.x = getSoftWrapModel().getSoftWrapIndentWidthInPixels(softWrap);
|
||||
softWrapsToSkip.add(softWrap.getStart());
|
||||
}
|
||||
|
||||
IterationState iterationState = new IterationState(this, start, paintSelection());
|
||||
|
||||
@@ -1620,7 +1637,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
FoldRegion collapsedFolderAt = myFoldingModel.getCollapsedRegionAtOffset(start);
|
||||
if (collapsedFolderAt == null) {
|
||||
position.x = drawSoftWrapAwareBackground(g, backColor, text, start, lEnd - lIterator.getSeparatorLength(), position, fontType,
|
||||
defaultBackground, clip);
|
||||
defaultBackground, clip, softWrapsToSkip);
|
||||
|
||||
if (lIterator.getLineNumber() < lastLineIndex) {
|
||||
if (backColor != null && !backColor.equals(defaultBackground)) {
|
||||
@@ -1653,11 +1670,13 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
if (hEnd > lEnd - lIterator.getSeparatorLength()) {
|
||||
position.x = drawSoftWrapAwareBackground(
|
||||
g, backColor, text, start, lEnd - lIterator.getSeparatorLength(), position, fontType,
|
||||
defaultBackground, clip
|
||||
defaultBackground, clip, softWrapsToSkip
|
||||
);
|
||||
}
|
||||
else {
|
||||
position.x = drawSoftWrapAwareBackground(g, backColor, text, start, hEnd, position, fontType, defaultBackground, clip);
|
||||
position.x = drawSoftWrapAwareBackground(
|
||||
g, backColor, text, start, hEnd, position, fontType, defaultBackground, clip, softWrapsToSkip
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1716,12 +1735,15 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
}
|
||||
|
||||
private int drawSoftWrapAwareBackground(Graphics g, Color backColor, CharSequence text, int start, int end, Point position,
|
||||
int fontType, Color defaultBackground, Rectangle clip)
|
||||
int fontType, Color defaultBackground, Rectangle clip, TIntHashSet processSoftWrap)
|
||||
{
|
||||
int startToUse = start;
|
||||
List<? extends TextChange> softWraps = getSoftWrapModel().getSoftWrapsForRange(start, end);
|
||||
for (TextChange softWrap : softWraps) {
|
||||
int softWrapStart = softWrap.getStart();
|
||||
if (processSoftWrap.contains(softWrapStart)) {
|
||||
continue;
|
||||
}
|
||||
if (startToUse < softWrapStart) {
|
||||
position.x = drawBackground(g, backColor, text.subSequence(startToUse, softWrapStart), position, fontType, defaultBackground, clip);
|
||||
}
|
||||
@@ -1739,7 +1761,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
int fontType, Color defaultBackground, Rectangle clip)
|
||||
{
|
||||
position.x = drawBackground(
|
||||
g, backColor, getSoftWrapModel().getMinDrawingWidthInPixels(SoftWrapDrawingType.BEFORE_SOFT_WRAP_LINE_FEED), position, fontType,
|
||||
g, backColor, getSoftWrapModel().getMinDrawingWidthInPixels(SoftWrapDrawingType.BEFORE_SOFT_WRAP_LINE_FEED), position,
|
||||
defaultBackground, clip
|
||||
);
|
||||
|
||||
@@ -1763,7 +1785,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
}
|
||||
|
||||
position.x = drawBackground(
|
||||
g, backColor, getSoftWrapModel().getMinDrawingWidthInPixels(SoftWrapDrawingType.AFTER_SOFT_WRAP), position, fontType,
|
||||
g, backColor, getSoftWrapModel().getMinDrawingWidthInPixels(SoftWrapDrawingType.AFTER_SOFT_WRAP), position,
|
||||
defaultBackground, clip
|
||||
);
|
||||
}
|
||||
@@ -1772,14 +1794,13 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
Rectangle clip)
|
||||
{
|
||||
int width = getTextSegmentWidth(text, position.x, fontType, clip);
|
||||
return drawBackground(g, backColor, width, position, fontType, defaultBackground, clip);
|
||||
return drawBackground(g, backColor, width, position, defaultBackground, clip);
|
||||
}
|
||||
|
||||
private int drawBackground(Graphics g,
|
||||
Color backColor,
|
||||
int width,
|
||||
Point position,
|
||||
int fontType,
|
||||
Color defaultBackground,
|
||||
Rectangle clip) {
|
||||
if (backColor != null && !backColor.equals(defaultBackground) && clip.intersects(position.x, position.y, width, getLineHeight())) {
|
||||
@@ -3400,7 +3421,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
myCommandProcessor.executeCommand(myProject, new DocumentRunnable(myDocument, myProject) {
|
||||
public void run() {
|
||||
int oldSelectionStart = mySelectionModel.getLeadSelectionOffset();
|
||||
LogicalPosition caretPosition = getCaretModel().getLogicalPosition();
|
||||
VisualPosition caretPosition = getCaretModel().getVisualPosition();
|
||||
int columnNumber = caretPosition.column;
|
||||
xPassedCycles++;
|
||||
if (xPassedCycles >= myXCycles) {
|
||||
@@ -3415,8 +3436,8 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
lineNumber += myDy;
|
||||
}
|
||||
|
||||
LogicalPosition pos = new LogicalPosition(lineNumber, columnNumber);
|
||||
getCaretModel().moveToLogicalPosition(pos);
|
||||
VisualPosition pos = new VisualPosition(lineNumber, columnNumber);
|
||||
getCaretModel().moveToVisualPosition(pos);
|
||||
getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
|
||||
|
||||
int newCaretOffset = getCaretModel().getOffset();
|
||||
@@ -4886,13 +4907,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
}
|
||||
int maxWidth = 0;
|
||||
for (int i = startToUse; i < endToUse; i++) {
|
||||
// TODO den unwrap
|
||||
try {
|
||||
maxWidth = Math.max(maxWidth, myLineWidths.getQuick(i));
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
maxWidth = Math.max(maxWidth, myLineWidths.getQuick(i));
|
||||
}
|
||||
|
||||
mySize = new Dimension(maxWidth, getLineHeight() * getVisibleLineCount());
|
||||
|
||||
+26
-1
@@ -21,7 +21,6 @@
|
||||
package com.intellij.execution.testframework;
|
||||
|
||||
import com.intellij.execution.Location;
|
||||
import com.intellij.execution.ui.ConsoleViewContentType;
|
||||
import com.intellij.openapi.actionSystem.DataKey;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
@@ -91,4 +90,30 @@ public abstract class AbstractTestProxy extends CompositePrintable {
|
||||
Disposer.dispose(proxy);
|
||||
}
|
||||
}
|
||||
|
||||
public static void flushOutput(AbstractTestProxy testProxy) {
|
||||
testProxy.flush();
|
||||
|
||||
AbstractTestProxy parent = testProxy.getParent();
|
||||
while (parent != null) {
|
||||
final List<? extends AbstractTestProxy> children = parent.getChildren();
|
||||
if (!testProxy.isInProgress() && testProxy.equals(children.get(children.size() - 1))) {
|
||||
parent.flush();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
testProxy = parent;
|
||||
parent = parent.getParent();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getExceptionMark() {
|
||||
if (myExceptionMark == 0 && getChildren().size() > 0) {
|
||||
return getChildren().get(0).getExceptionMark();
|
||||
}
|
||||
return myExceptionMark;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
+180
-11
@@ -15,42 +15,211 @@
|
||||
*/
|
||||
package com.intellij.execution.testframework;
|
||||
|
||||
import com.intellij.execution.filters.HyperlinkInfo;
|
||||
import com.intellij.execution.testframework.stacktrace.DiffHyperlink;
|
||||
import com.intellij.execution.ui.ConsoleViewContentType;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.util.io.IOUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class CompositePrintable implements Printable, Disposable {
|
||||
public static final String NEW_LINE = "\n";
|
||||
|
||||
protected final ArrayList<Printable> myNestedPrintables = new ArrayList<Printable>();
|
||||
protected final List<Printable> myNestedPrintables = new ArrayList<Printable>();
|
||||
private PrintablesWrapper myWrapper;
|
||||
protected int myExceptionMark;
|
||||
|
||||
public void flush() {
|
||||
if (myWrapper == null) {
|
||||
try {
|
||||
myWrapper = new PrintablesWrapper(File.createTempFile("frst", "scd"));
|
||||
}
|
||||
catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
if (myWrapper != null) {
|
||||
synchronized (myNestedPrintables) {
|
||||
myWrapper.flash(myNestedPrintables);
|
||||
clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void printOn(final Printer printer) {
|
||||
printAllOn(myNestedPrintables, printer);
|
||||
if (myWrapper != null) {
|
||||
myWrapper.printOn(printer);
|
||||
}
|
||||
synchronized (myNestedPrintables) {
|
||||
for (int i = 0; i < myNestedPrintables.size(); i++) {
|
||||
if (i == getExceptionMark() && i > 0) printer.mark();
|
||||
myNestedPrintables.get(i).printOn(printer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addLast(final Printable printable) {
|
||||
myNestedPrintables.add(printable);
|
||||
synchronized (myNestedPrintables) {
|
||||
myNestedPrintables.add(printable);
|
||||
}
|
||||
}
|
||||
|
||||
protected void clear() {
|
||||
myNestedPrintables.clear();
|
||||
synchronized (myNestedPrintables) {
|
||||
myNestedPrintables.clear();
|
||||
}
|
||||
}
|
||||
|
||||
public int getCurrentSize() {
|
||||
return myNestedPrintables.size();
|
||||
}
|
||||
|
||||
public static <T extends Printable> void printAllOn(final List<T> printables, final Printer console) {
|
||||
for (final T printable : printables) {
|
||||
printable.printOn(console);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
clear();
|
||||
if (myWrapper != null) {
|
||||
myWrapper.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public int getExceptionMark() {
|
||||
return myExceptionMark;
|
||||
}
|
||||
|
||||
public void setExceptionMark(int exceptionMark) {
|
||||
myExceptionMark = exceptionMark;
|
||||
}
|
||||
|
||||
private static final Logger LOG = Logger.getInstance("#" + PrintablesWrapper.class.getName());
|
||||
|
||||
private class PrintablesWrapper {
|
||||
|
||||
@NonNls private static final String HYPERLINK = "hyperlink";
|
||||
private DataInputStream myReader;
|
||||
private ConsoleViewContentType myLastSelected;
|
||||
private final File myFile;
|
||||
|
||||
PrintablesWrapper(File file) {
|
||||
myFile = file;
|
||||
}
|
||||
|
||||
public void flash(List<Printable> printables) {
|
||||
final DataOutputStream fileWriter;
|
||||
try {
|
||||
fileWriter = new DataOutputStream(new FileOutputStream(myFile, true));
|
||||
|
||||
}
|
||||
catch (FileNotFoundException e) {
|
||||
LOG.error(e);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
for (final Printable printable : printables) {
|
||||
printable.printOn(new Printer() {
|
||||
@Override
|
||||
public void print(String text, ConsoleViewContentType contentType) {
|
||||
try {
|
||||
IOUtil.writeString(contentType.toString() + text, fileWriter);
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNewAvailable(Printable printable11) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printHyperlink(String text, HyperlinkInfo info) {
|
||||
if (info instanceof DiffHyperlink.DiffHyperlinkInfo) {
|
||||
final DiffHyperlink diffHyperlink = ((DiffHyperlink.DiffHyperlinkInfo)info).getPrintable();
|
||||
try {
|
||||
IOUtil.writeString(HYPERLINK, fileWriter);
|
||||
IOUtil.writeString(diffHyperlink.getLeft(), fileWriter);
|
||||
IOUtil.writeString(diffHyperlink.getRight(), fileWriter);
|
||||
IOUtil.writeString(diffHyperlink.getFilePath(), fileWriter);
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
else {
|
||||
print(text, ConsoleViewContentType.NORMAL_OUTPUT);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mark() {
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
fileWriter.close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void printOn(Printer console) {
|
||||
try {
|
||||
myReader = new DataInputStream(new FileInputStream(myFile));
|
||||
int lineNum = 0;
|
||||
while (myReader.available() > 0) {
|
||||
if (lineNum == CompositePrintable.this.getExceptionMark() && lineNum > 0) console.mark();
|
||||
final String line = IOUtil.readString(myReader);
|
||||
if (!isApplicable(console, line, ConsoleViewContentType.ERROR_OUTPUT)) {
|
||||
if (!isApplicable(console, line, ConsoleViewContentType.SYSTEM_OUTPUT)) {
|
||||
if (!isApplicable(console, line, ConsoleViewContentType.NORMAL_OUTPUT)) {
|
||||
if (line.startsWith(HYPERLINK)) {
|
||||
new DiffHyperlink(IOUtil.readString(myReader), IOUtil.readString(myReader), IOUtil.readString(myReader)).printOn(console);
|
||||
}
|
||||
else {
|
||||
console.print(line, myLastSelected != null ? myLastSelected : ConsoleViewContentType.NORMAL_OUTPUT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
lineNum++;
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
if (myReader != null) {
|
||||
myReader.close();
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isApplicable(Printer console, String line, ConsoleViewContentType contentType) {
|
||||
final String prefix = contentType.toString();
|
||||
if (line.startsWith(prefix)) {
|
||||
console.print(line.substring(prefix.length()), contentType);
|
||||
myLastSelected = contentType;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
FileUtil.delete(myFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+15
-5
@@ -38,11 +38,7 @@ public class DiffHyperlink implements Printable {
|
||||
protected final String myExpected;
|
||||
protected final String myActual;
|
||||
protected final String myFilePath;
|
||||
private final HyperlinkInfo myDiffHyperlink = new HyperlinkInfo() {
|
||||
public void navigate(final Project project) {
|
||||
openDiff(project);
|
||||
}
|
||||
};
|
||||
private final HyperlinkInfo myDiffHyperlink = new DiffHyperlinkInfo();
|
||||
|
||||
|
||||
public DiffHyperlink(final String expected, final String actual, final String filePath) {
|
||||
@@ -80,6 +76,10 @@ public class DiffHyperlink implements Printable {
|
||||
return myActual;
|
||||
}
|
||||
|
||||
public String getFilePath() {
|
||||
return myFilePath;
|
||||
}
|
||||
|
||||
public void printOn(final Printer printer) {
|
||||
if (hasMoreThanOneLine(myActual) || hasMoreThanOneLine(myExpected)) {
|
||||
printer.print(" ", ConsoleViewContentType.ERROR_OUTPUT);
|
||||
@@ -98,4 +98,14 @@ public class DiffHyperlink implements Printable {
|
||||
private static boolean hasMoreThanOneLine(final String string) {
|
||||
return string.indexOf('\n') != -1 || string.indexOf('\r') != -1;
|
||||
}
|
||||
|
||||
public class DiffHyperlinkInfo implements HyperlinkInfo {
|
||||
public void navigate(final Project project) {
|
||||
openDiff(project);
|
||||
}
|
||||
|
||||
public DiffHyperlink getPrintable() {
|
||||
return DiffHyperlink.this;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -31,11 +31,8 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.beans.Introspector;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.text.DateFormat;
|
||||
import java.util.*;
|
||||
import java.util.regex.MatchResult;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@@ -1608,6 +1605,19 @@ public class StringUtil {
|
||||
return "a" + Character.toUpperCase(c) + name.substring(1);
|
||||
}
|
||||
|
||||
public static String sanitizeJavaIdentifier(String name) {
|
||||
final StringBuilder result = new StringBuilder();
|
||||
|
||||
for (int i = 0; i < name.length(); i++) {
|
||||
final char ch = name.charAt(i);
|
||||
if (Character.isLetterOrDigit(ch)) {
|
||||
result.append(ch);
|
||||
}
|
||||
}
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
public static void assertValidSeparators(@NotNull CharSequence s) {
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
if (s.charAt(i) == '\r') {
|
||||
|
||||
@@ -72,7 +72,7 @@ public abstract class AbstractVcsHelper {
|
||||
showErrors(Arrays.asList(e), s);
|
||||
}
|
||||
|
||||
public abstract void showAnnotation(FileAnnotation annotation, VirtualFile file);
|
||||
public abstract void showAnnotation(FileAnnotation annotation, VirtualFile file, AbstractVcs vcs);
|
||||
|
||||
public abstract void showDifferences(final VcsFileRevision cvsVersionOn, final VcsFileRevision cvsVersionOn1, final File file);
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.intellij.openapi.vcs;
|
||||
import com.intellij.openapi.vcs.changes.committed.DecoratorManager;
|
||||
import com.intellij.openapi.vcs.changes.committed.VcsCommittedListsZipper;
|
||||
import com.intellij.openapi.vcs.changes.committed.VcsCommittedViewAuxiliary;
|
||||
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
|
||||
import com.intellij.openapi.vcs.versionBrowser.ChangeBrowserSettings;
|
||||
import com.intellij.openapi.vcs.versionBrowser.ChangesBrowserSettingsEditor;
|
||||
import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList;
|
||||
@@ -55,4 +56,7 @@ public interface CommittedChangesProvider<T extends CommittedChangeList, U exten
|
||||
* since may be different for different VCSs
|
||||
*/
|
||||
int getUnlimitedCountValue();
|
||||
|
||||
@Nullable
|
||||
T getOneList(final RepositoryLocation location, final VcsRevisionNumber number) throws VcsException;
|
||||
}
|
||||
|
||||
@@ -15,9 +15,7 @@
|
||||
*/
|
||||
package com.intellij.openapi.vcs.actions;
|
||||
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.ToggleAction;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.colors.ColorKey;
|
||||
@@ -36,23 +34,32 @@ import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.progress.Task;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.MessageType;
|
||||
import com.intellij.openapi.util.IconLoader;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.openapi.vcs.*;
|
||||
import com.intellij.openapi.vcs.annotate.*;
|
||||
import com.intellij.openapi.vcs.changes.BackgroundFromStartOption;
|
||||
import com.intellij.openapi.vcs.changes.Change;
|
||||
import com.intellij.openapi.vcs.changes.actions.ShowDiffAction;
|
||||
import com.intellij.openapi.vcs.changes.ui.ChangesComparator;
|
||||
import com.intellij.openapi.vcs.changes.ui.ChangesViewBalloonProblemNotifier;
|
||||
import com.intellij.openapi.vcs.history.VcsFileRevision;
|
||||
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
|
||||
import com.intellij.openapi.vcs.impl.BackgroundableActionEnabledHandler;
|
||||
import com.intellij.openapi.vcs.impl.ProjectLevelVcsManagerImpl;
|
||||
import com.intellij.openapi.vcs.impl.UpToDateLineNumberProviderImpl;
|
||||
import com.intellij.openapi.vcs.impl.VcsBackgroundableActions;
|
||||
import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.Consumer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
|
||||
@@ -152,7 +159,7 @@ public class AnnotateToggleAction extends ToggleAction implements DumbAware {
|
||||
final VirtualFile file = FileDocumentManager.getInstance().getFile(editor.getDocument());
|
||||
if (project == null) return;
|
||||
final ProjectLevelVcsManager plVcsManager = ProjectLevelVcsManager.getInstance(project);
|
||||
AbstractVcs vcs = plVcsManager.getVcsFor(file);
|
||||
final AbstractVcs vcs = plVcsManager.getVcsFor(file);
|
||||
if (vcs == null) return;
|
||||
final AnnotationProvider annotationProvider = vcs.getAnnotationProvider();
|
||||
|
||||
@@ -188,12 +195,16 @@ public class AnnotateToggleAction extends ToggleAction implements DumbAware {
|
||||
}
|
||||
if (fileAnnotationRef.isNull()) return;
|
||||
|
||||
doAnnotate(editor, project, file, fileAnnotationRef.get());
|
||||
doAnnotate(editor, project, file, fileAnnotationRef.get(), vcs);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void doAnnotate(final Editor editor, final Project project, final VirtualFile file, final FileAnnotation fileAnnotation) {
|
||||
public static void doAnnotate(final Editor editor,
|
||||
final Project project,
|
||||
final VirtualFile file,
|
||||
final FileAnnotation fileAnnotation,
|
||||
final AbstractVcs vcs) {
|
||||
String upToDateContent = fileAnnotation.getAnnotatedContent();
|
||||
|
||||
final UpToDateLineNumberProvider getUpToDateLineNumber = new UpToDateLineNumberProviderImpl(
|
||||
@@ -214,7 +225,14 @@ public class AnnotateToggleAction extends ToggleAction implements DumbAware {
|
||||
final HighlightAnnotationsActions highlighting = new HighlightAnnotationsActions(project, file, fileAnnotation, editorGutterComponentEx);
|
||||
final List<AnnotationFieldGutter> gutters = new ArrayList<AnnotationFieldGutter>();
|
||||
final AnnotationSourceSwitcher switcher = fileAnnotation.getAnnotationSourceSwitcher();
|
||||
final MyAnnotationPresentation presentation = new MyAnnotationPresentation(highlighting, switcher, editorGutterComponentEx, gutters);
|
||||
final MyAnnotationPresentation presentation;
|
||||
if (vcs.getCommittedChangesProvider() != null) {
|
||||
final ShowDiffFromAnnotation showDiff = new ShowDiffFromAnnotation(getUpToDateLineNumber, fileAnnotation, vcs, file);
|
||||
presentation = new MyAnnotationPresentation(highlighting, switcher, editorGutterComponentEx, gutters, showDiff);
|
||||
presentation.addLineNumberListener(showDiff);
|
||||
} else {
|
||||
presentation = new MyAnnotationPresentation(highlighting, switcher, editorGutterComponentEx, gutters);
|
||||
}
|
||||
|
||||
if (switcher != null) {
|
||||
|
||||
@@ -375,15 +393,25 @@ public class AnnotateToggleAction extends ToggleAction implements DumbAware {
|
||||
private final List<AnnotationFieldGutter> myGutters;
|
||||
private final List<AnAction> myActions;
|
||||
private MySwitchAnnotationSourceAction mySwitchAction;
|
||||
private final List<Consumer<Integer>> myPopupLineNumberListeners;
|
||||
|
||||
public MyAnnotationPresentation(@NotNull final HighlightAnnotationsActions highlighting, @Nullable final AnnotationSourceSwitcher switcher,
|
||||
final EditorGutterComponentEx gutter,
|
||||
List<AnnotationFieldGutter> gutters) {
|
||||
final EditorGutterComponentEx gutter, final List<AnnotationFieldGutter> gutters, final AnAction... actions) {
|
||||
myHighlighting = highlighting;
|
||||
mySwitcher = switcher;
|
||||
myGutters = gutters;
|
||||
myPopupLineNumberListeners = new LinkedList<Consumer<Integer>>();
|
||||
|
||||
myActions = new ArrayList<AnAction>(myHighlighting.getList());
|
||||
myActions = new ArrayList<AnAction>();
|
||||
myActions.add(Separator.getInstance());
|
||||
if (actions != null) {
|
||||
final List<AnAction> actionsList = Arrays.<AnAction>asList(actions);
|
||||
if (! actionsList.isEmpty()) {
|
||||
myActions.addAll(actionsList);
|
||||
myActions.add(new Separator());
|
||||
}
|
||||
}
|
||||
myActions.addAll(myHighlighting.getList());
|
||||
if (mySwitcher != null) {
|
||||
mySwitchAction = new MySwitchAnnotationSourceAction(mySwitcher, gutter);
|
||||
myActions.add(mySwitchAction);
|
||||
@@ -391,6 +419,10 @@ public class AnnotateToggleAction extends ToggleAction implements DumbAware {
|
||||
myActions.add(new ShowHideColorsAction(myGutters, gutter));
|
||||
}
|
||||
|
||||
public void addLineNumberListener(final Consumer<Integer> listener) {
|
||||
myPopupLineNumberListeners.add(listener);
|
||||
}
|
||||
|
||||
public EditorFontType getFontType(final int line) {
|
||||
return myHighlighting.isLineBold(line) ? EditorFontType.BOLD : EditorFontType.PLAIN;
|
||||
}
|
||||
@@ -400,7 +432,10 @@ public class AnnotateToggleAction extends ToggleAction implements DumbAware {
|
||||
return mySwitcher.getAnnotationSource(line).getColor();
|
||||
}
|
||||
|
||||
public List<AnAction> getActions() {
|
||||
public List<AnAction> getActions(int line) {
|
||||
for (Consumer<Integer> listener : myPopupLineNumberListeners) {
|
||||
listener.consume(line);
|
||||
}
|
||||
return myActions;
|
||||
}
|
||||
|
||||
@@ -443,4 +478,108 @@ public class AnnotateToggleAction extends ToggleAction implements DumbAware {
|
||||
myGutter.revalidateMarkup();
|
||||
}
|
||||
}
|
||||
|
||||
private static class ShowDiffFromAnnotation extends AnAction implements Consumer<Integer> {
|
||||
private final UpToDateLineNumberProvider myLineNumberProvider;
|
||||
private final FileAnnotation myFileAnnotation;
|
||||
private final AbstractVcs myVcs;
|
||||
private final VirtualFile myFile;
|
||||
private RepositoryLocation myLocationFor;
|
||||
private int currentLine;
|
||||
|
||||
private ShowDiffFromAnnotation(final UpToDateLineNumberProvider lineNumberProvider,
|
||||
final FileAnnotation fileAnnotation, final AbstractVcs vcs, final VirtualFile file) {
|
||||
super(VcsBundle.message("updated.info.tree.show.diff.text"), VcsBundle.message("updated.info.tree.show.diff.text"), IconLoader.getIcon("/actions/diff.png"));
|
||||
myLineNumberProvider = lineNumberProvider;
|
||||
myFileAnnotation = fileAnnotation;
|
||||
myVcs = vcs;
|
||||
myFile = file;
|
||||
final CommittedChangesProvider provider = myVcs.getCommittedChangesProvider();
|
||||
final VirtualFile root = ProjectLevelVcsManager.getInstance(vcs.getProject()).getVcsRootFor(file);
|
||||
myLocationFor = provider.getLocationFor(new FilePathImpl(root));
|
||||
currentLine = -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void consume(Integer integer) {
|
||||
currentLine = integer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(AnActionEvent e) {
|
||||
e.getPresentation().setVisible(getActualLineNumber(e) >= 0);
|
||||
}
|
||||
|
||||
private int getActualLineNumber(final AnActionEvent e) {
|
||||
final DataContext dc = e.getDataContext();
|
||||
if (currentLine < 0) return -1;
|
||||
return myLineNumberProvider.getLineNumber(currentLine);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
final int actualNumber = getActualLineNumber(e);
|
||||
if (actualNumber < 0) return;
|
||||
|
||||
final VcsRevisionNumber revisionNumber = myFileAnnotation.getLineRevisionNumber(actualNumber);
|
||||
if (revisionNumber != null) {
|
||||
final VcsException[] exc = new VcsException[1];
|
||||
final List<Change> changes = new LinkedList<Change>();
|
||||
ProgressManager.getInstance().run(new Task.Backgroundable(myVcs.getProject(),
|
||||
"Loading revision " + revisionNumber.asString() + " contents", true, BackgroundFromStartOption.getInstance()) {
|
||||
@Override
|
||||
public void run(@NotNull ProgressIndicator indicator) {
|
||||
final CommittedChangesProvider provider = myVcs.getCommittedChangesProvider();
|
||||
try {
|
||||
final CommittedChangeList cl = provider.getOneList(myLocationFor, revisionNumber);
|
||||
if (cl == null) {
|
||||
ChangesViewBalloonProblemNotifier.showMe(myVcs.getProject(), "Can not load data for show diff", MessageType.ERROR);
|
||||
return;
|
||||
}
|
||||
changes.addAll(cl.getChanges());
|
||||
Collections.sort(changes, ChangesComparator.getInstance());
|
||||
}
|
||||
catch (VcsException e1) {
|
||||
exc[0] = e1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
if (exc[0] != null) {
|
||||
ChangesViewBalloonProblemNotifier.showMe(myVcs.getProject(), "Can not show diff: " + exc[0].getMessage(), MessageType.ERROR);
|
||||
} else if (! changes.isEmpty()) {
|
||||
int idx = findSelfInList(changes);
|
||||
ShowDiffAction.showDiffForChange(changes.toArray(new Change[changes.size()]), idx, myVcs.getProject());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private int findSelfInList(List<Change> changes) {
|
||||
int idx = -1;
|
||||
final File ioFile = new File(myFile.getPath());
|
||||
for (int i = 0; i < changes.size(); i++) {
|
||||
final Change change = changes.get(i);
|
||||
if ((change.getAfterRevision() != null) && (change.getAfterRevision().getFile().getIOFile().equals(ioFile))) {
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (idx >= 0) return idx;
|
||||
idx = 0;
|
||||
// try to use name only
|
||||
final String name = ioFile.getName();
|
||||
for (int i = 0; i < changes.size(); i++) {
|
||||
final Change change = changes.get(i);
|
||||
if ((change.getAfterRevision() != null) && (change.getAfterRevision().getFile().getName().equals(name))) {
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return idx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,8 +99,8 @@ class AnnotationFieldGutter implements ActiveAnnotationGutter {
|
||||
return myPresentation.getColor(line);
|
||||
}
|
||||
|
||||
public List<AnAction> getPopupActions(final Editor editor) {
|
||||
return myPresentation.getActions();
|
||||
public List<AnAction> getPopupActions(int line, final Editor editor) {
|
||||
return myPresentation.getActions(line);
|
||||
}
|
||||
|
||||
public void gutterClosed() {
|
||||
|
||||
+2
-2
@@ -68,8 +68,8 @@ public class AnnotationGutterLineConvertorProxy implements ActiveAnnotationGutte
|
||||
return myDelegate.getBgColor(currentLine, editor);
|
||||
}
|
||||
|
||||
public List<AnAction> getPopupActions(Editor editor) {
|
||||
return myDelegate.getPopupActions(editor);
|
||||
public List<AnAction> getPopupActions(int line, Editor editor) {
|
||||
return myDelegate.getPopupActions(line, editor);
|
||||
}
|
||||
|
||||
public void gutterClosed() {
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.openapi.vcs.annotate;
|
||||
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.fileEditor.FileEditorManager;
|
||||
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.vcs.VcsBundle;
|
||||
import com.intellij.openapi.vcs.actions.AnnotateToggleAction;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
|
||||
public class Annotater {
|
||||
|
||||
private final Project myProject;
|
||||
private final VirtualFile myVirtualFile;
|
||||
private final FileAnnotation myFileAnnotation;
|
||||
|
||||
public Annotater(FileAnnotation fileAnnotation, Project project, VirtualFile virtualFile) {
|
||||
myFileAnnotation = fileAnnotation;
|
||||
myProject = project;
|
||||
myVirtualFile = virtualFile;
|
||||
}
|
||||
|
||||
public void showAnnotation() {
|
||||
OpenFileDescriptor openFileDescriptor = new OpenFileDescriptor(myProject, myVirtualFile);
|
||||
Editor editor = FileEditorManager.getInstance(myProject).openTextEditor(openFileDescriptor, true);
|
||||
if (editor == null) {
|
||||
Messages.showMessageDialog(VcsBundle.message("message.text.cannot.open.editor", myVirtualFile.getPresentableUrl()),
|
||||
VcsBundle.message("message.title.cannot.open.editor"), Messages.getInformationIcon());
|
||||
return;
|
||||
}
|
||||
|
||||
AnnotateToggleAction.doAnnotate(editor, myProject, myVirtualFile, myFileAnnotation);
|
||||
}
|
||||
|
||||
}
|
||||
+2
-1
@@ -18,10 +18,11 @@ package com.intellij.openapi.vcs.annotate;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.editor.colors.ColorKey;
|
||||
import com.intellij.openapi.editor.colors.EditorFontType;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface TextAnnotationPresentation {
|
||||
EditorFontType getFontType(int line);
|
||||
ColorKey getColor(int line);
|
||||
List<AnAction> getActions();
|
||||
List<AnAction> getActions(int line);
|
||||
}
|
||||
|
||||
+3
-2
@@ -18,6 +18,7 @@ package com.intellij.openapi.vcs.changes.committed;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vcs.AbstractVcs;
|
||||
import com.intellij.openapi.vcs.ProjectLevelVcsManager;
|
||||
import com.intellij.openapi.vcs.VcsType;
|
||||
import com.intellij.util.NotNullFunction;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -29,10 +30,10 @@ public class CommittedChangesVisibilityPredicate implements NotNullFunction<Proj
|
||||
public Boolean fun(final Project project) {
|
||||
final AbstractVcs[] abstractVcses = ProjectLevelVcsManager.getInstance(project).getAllActiveVcss();
|
||||
for(AbstractVcs vcs: abstractVcses) {
|
||||
if (vcs.getCommittedChangesProvider() != null) {
|
||||
if (vcs.getCommittedChangesProvider() != null && VcsType.centralized.equals(vcs.getType())) {
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
}
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+6
@@ -19,6 +19,7 @@ package com.intellij.openapi.vcs.changes.committed;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vcs.*;
|
||||
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
|
||||
import com.intellij.openapi.vcs.versionBrowser.ChangeBrowserSettings;
|
||||
import com.intellij.openapi.vcs.versionBrowser.ChangesBrowserSettingsEditor;
|
||||
import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList;
|
||||
@@ -151,6 +152,11 @@ public class CompositeCommittedChangesProvider implements CommittedChangesProvid
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommittedChangeList getOneList(RepositoryLocation location, VcsRevisionNumber number) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public static class CompositeChangeBrowserSettings extends ChangeBrowserSettings {
|
||||
private final Map<AbstractVcs, ChangeBrowserSettings> myMap;
|
||||
private final Set<AbstractVcs> myEnabledVcs = new HashSet<AbstractVcs>();
|
||||
|
||||
+3
-2
@@ -16,9 +16,10 @@
|
||||
package com.intellij.openapi.vcs.changes.committed;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vcs.ProjectLevelVcsManager;
|
||||
import com.intellij.openapi.vcs.AbstractVcs;
|
||||
import com.intellij.openapi.vcs.CachingCommittedChangesProvider;
|
||||
import com.intellij.openapi.vcs.ProjectLevelVcsManager;
|
||||
import com.intellij.openapi.vcs.VcsType;
|
||||
import com.intellij.util.NotNullFunction;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -30,7 +31,7 @@ public class IncomingChangesVisibilityPredicate implements NotNullFunction<Proje
|
||||
public Boolean fun(final Project project) {
|
||||
final AbstractVcs[] abstractVcses = ProjectLevelVcsManager.getInstance(project).getAllActiveVcss();
|
||||
for(AbstractVcs vcs: abstractVcses) {
|
||||
if (vcs.getCommittedChangesProvider() instanceof CachingCommittedChangesProvider) {
|
||||
if (vcs.getCommittedChangesProvider() instanceof CachingCommittedChangesProvider && VcsType.centralized.equals(vcs.getType())) {
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -36,6 +36,7 @@ public class TableLinkMouseListener extends AbstractBaseTagMouseListener {
|
||||
JTable table = (JTable)e.getSource();
|
||||
int row = table.rowAtPoint(e.getPoint());
|
||||
int column = table.columnAtPoint(e.getPoint());
|
||||
if (row == -1 || column == -1) return null;
|
||||
TableCellRenderer cellRenderer = table.getCellRenderer(row, column);
|
||||
if (cellRenderer instanceof DualView.TableCellRendererWrapper) {
|
||||
cellRenderer = ((DualView.TableCellRendererWrapper) cellRenderer).getRenderer();
|
||||
|
||||
@@ -111,7 +111,7 @@ public class FileHistoryPanelImpl<S extends CommittedChangeList, U extends Chang
|
||||
private String myOriginalComment = "";
|
||||
private final DefaultActionGroup myPopupActions;
|
||||
|
||||
private final Project myProject;
|
||||
private final AbstractVcs myVcs;
|
||||
private final VcsHistoryProvider myProvider;
|
||||
private final AnnotationProvider myAnnotationProvider;
|
||||
private VcsHistorySession myHistorySession;
|
||||
@@ -265,20 +265,20 @@ public class FileHistoryPanelImpl<S extends CommittedChangeList, U extends Chang
|
||||
private static final DateFormat DATE_FORMAT = SimpleDateFormat.getDateTimeInstance(SimpleDateFormat.SHORT, SimpleDateFormat.SHORT);
|
||||
private final Map<VcsFileRevision, VirtualFile> myRevisionToVirtualFile = new HashMap<VcsFileRevision, VirtualFile>();
|
||||
|
||||
public FileHistoryPanelImpl(Project project,
|
||||
FilePath filePath, final String repositoryPath, VcsHistorySession session,
|
||||
public FileHistoryPanelImpl(AbstractVcs vcs,
|
||||
FilePath filePath, VcsHistorySession session,
|
||||
VcsHistoryProvider provider,
|
||||
AnnotationProvider annotationProvider,
|
||||
ContentManager contentManager, final Runnable refresher) {
|
||||
super(contentManager, provider.getHelpId() != null ? provider.getHelpId() : "reference.versionControl.toolwindow.history");
|
||||
myVcs = vcs;
|
||||
myProvider = provider;
|
||||
myAnnotationProvider = annotationProvider;
|
||||
myProject = project;
|
||||
myRefresher = refresher;
|
||||
myHistorySession = session;
|
||||
myFilePath = filePath;
|
||||
|
||||
COLUMNS = createColumnList(project, provider, session);
|
||||
COLUMNS = createColumnList(myVcs.getProject(), provider, session);
|
||||
|
||||
myComments = new JEditorPane(UIUtil.HTML_MIME, "");
|
||||
myComments.setPreferredSize(new Dimension(150, 100));
|
||||
@@ -298,11 +298,11 @@ public class FileHistoryPanelImpl<S extends CommittedChangeList, U extends Chang
|
||||
@NonNls String storageKey = "FileHistory." + provider.getClass().getName();
|
||||
if (treeHistoryProvider != null) {
|
||||
myDualView = new DualView(new TreeNodeOnVcsRevision(null, treeHistoryProvider.createTreeOn(myHistorySession.getRevisionList())),
|
||||
COLUMNS, storageKey, project);
|
||||
COLUMNS, storageKey, myVcs.getProject());
|
||||
}
|
||||
else {
|
||||
myDualView = new DualView(new TreeNodeOnVcsRevision(null, wrapWithTreeElements(myHistorySession.getRevisionList())), COLUMNS,
|
||||
storageKey, project);
|
||||
storageKey, myVcs.getProject());
|
||||
myDualView.switchToTheFlatMode();
|
||||
}
|
||||
final TableLinkMouseListener listener = new TableLinkMouseListener();
|
||||
@@ -330,7 +330,7 @@ public class FileHistoryPanelImpl<S extends CommittedChangeList, U extends Chang
|
||||
// todo react to event?
|
||||
myUpdateAlarm.addRequest(new Runnable() {
|
||||
public void run() {
|
||||
if (myProject.isDisposed()) {
|
||||
if (myVcs.getProject().isDisposed()) {
|
||||
return;
|
||||
}
|
||||
final boolean refresh = (! myInRefresh) && myHistorySession.shouldBeRefreshed();
|
||||
@@ -556,7 +556,7 @@ public class FileHistoryPanelImpl<S extends CommittedChangeList, U extends Chang
|
||||
revision = getFirstSelectedRevision();
|
||||
final String message = revision.getCommitMessage();
|
||||
myOriginalComment = message;
|
||||
@NonNls final String text = IssueLinkHtmlRenderer.formatTextIntoHtml(myProject, message);
|
||||
@NonNls final String text = IssueLinkHtmlRenderer.formatTextIntoHtml(myVcs.getProject(), message);
|
||||
myComments.setText(text);
|
||||
myComments.setCaretPosition(0);
|
||||
}
|
||||
@@ -584,7 +584,7 @@ public class FileHistoryPanelImpl<S extends CommittedChangeList, U extends Chang
|
||||
if (content2 == null) throw new VcsException("Failed to load content for revision " + right.getRevisionNumber().asString());
|
||||
|
||||
|
||||
SimpleDiffRequest diffData = new SimpleDiffRequest(myProject, myFilePath.getPresentableUrl());
|
||||
SimpleDiffRequest diffData = new SimpleDiffRequest(myVcs.getProject(), myFilePath.getPresentableUrl());
|
||||
|
||||
diffData.addHint(DiffTool.HINT_SHOW_FRAME);
|
||||
|
||||
@@ -693,7 +693,7 @@ public class FileHistoryPanelImpl<S extends CommittedChangeList, U extends Chang
|
||||
}
|
||||
|
||||
private VcsConfiguration getConfiguration() {
|
||||
return VcsConfiguration.getInstance(myProject);
|
||||
return VcsConfiguration.getInstance(myVcs.getProject());
|
||||
}
|
||||
|
||||
private DefaultActionGroup createPopupActions() {
|
||||
@@ -757,7 +757,7 @@ public class FileHistoryPanelImpl<S extends CommittedChangeList, U extends Chang
|
||||
}
|
||||
|
||||
private void refreshImpl() {
|
||||
new AbstractCalledLater(myProject, ModalityState.NON_MODAL) {
|
||||
new AbstractCalledLater(myVcs.getProject(), ModalityState.NON_MODAL) {
|
||||
public void run() {
|
||||
if (myInRefresh) return;
|
||||
myInRefresh = true;
|
||||
@@ -806,12 +806,12 @@ public class FileHistoryPanelImpl<S extends CommittedChangeList, U extends Chang
|
||||
|
||||
int selectionSize = sel.size();
|
||||
if (selectionSize > 1) {
|
||||
showDifferences(myProject, sel.get(0), sel.get(sel.size() - 1));
|
||||
showDifferences(myVcs.getProject(), sel.get(0), sel.get(sel.size() - 1));
|
||||
}
|
||||
else if (selectionSize == 1) {
|
||||
final VcsRevisionNumber currentRevisionNumber = myHistorySession.getCurrentRevisionNumber();
|
||||
if (currentRevisionNumber != null) {
|
||||
showDifferences(myProject, getFirstSelectedRevision(), new CurrentRevision(myFilePath.getVirtualFile(), currentRevisionNumber));
|
||||
showDifferences(myVcs.getProject(), getFirstSelectedRevision(), new CurrentRevision(myFilePath.getVirtualFile(), currentRevisionNumber));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -880,7 +880,7 @@ public class FileHistoryPanelImpl<S extends CommittedChangeList, U extends Chang
|
||||
protected void actionPerformed() {
|
||||
final VcsFileRevision revision = getFirstSelectedRevision();
|
||||
if (getVirtualFile() != null) {
|
||||
if (!new ReplaceFileConfirmationDialog(myProject, VcsBundle.message("acton.name.get.revision"))
|
||||
if (!new ReplaceFileConfirmationDialog(myVcs.getProject(), VcsBundle.message("acton.name.get.revision"))
|
||||
.confirmFor(new VirtualFile[]{getVirtualFile()})) {
|
||||
return;
|
||||
}
|
||||
@@ -926,14 +926,14 @@ public class FileHistoryPanelImpl<S extends CommittedChangeList, U extends Chang
|
||||
};
|
||||
}
|
||||
if (refresh != null) {
|
||||
ProgressManager.getInstance().runProcessWithProgressSynchronously(refresh, "Refreshing files...", false, myProject);
|
||||
ProgressManager.getInstance().runProcessWithProgressSynchronously(refresh, "Refreshing files...", false, myVcs.getProject());
|
||||
}
|
||||
}
|
||||
|
||||
private void getVersion(final VcsFileRevision revision) {
|
||||
final VirtualFile file = getVirtualFile();
|
||||
if ((file != null) && !file.isWritable()) {
|
||||
if (ReadonlyStatusHandler.getInstance(myProject).ensureFilesWritable(file).hasReadonlyFiles()) {
|
||||
if (ReadonlyStatusHandler.getInstance(myVcs.getProject()).ensureFilesWritable(file).hasReadonlyFiles()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -961,7 +961,7 @@ public class FileHistoryPanelImpl<S extends CommittedChangeList, U extends Chang
|
||||
try {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
public void run() {
|
||||
CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
|
||||
CommandProcessor.getInstance().executeCommand(myVcs.getProject(), new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
write(finalRevisionContent);
|
||||
@@ -975,7 +975,7 @@ public class FileHistoryPanelImpl<S extends CommittedChangeList, U extends Chang
|
||||
}
|
||||
});
|
||||
if (file != null) {
|
||||
VcsDirtyScopeManager.getInstance(myProject).fileDirty(file);
|
||||
VcsDirtyScopeManager.getInstance(myVcs.getProject()).fileDirty(file);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
@@ -1027,7 +1027,7 @@ public class FileHistoryPanelImpl<S extends CommittedChangeList, U extends Chang
|
||||
private void writeContentToDocument(final Document document, byte[] revisionContent) throws IOException {
|
||||
final String content = StringUtil.convertLineSeparators(new String(revisionContent, myFilePath.getCharset().name()));
|
||||
|
||||
CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
|
||||
CommandProcessor.getInstance().executeCommand(myVcs.getProject(), new Runnable() {
|
||||
public void run() {
|
||||
document.replaceString(0, document.getTextLength(), content);
|
||||
}
|
||||
@@ -1053,7 +1053,7 @@ public class FileHistoryPanelImpl<S extends CommittedChangeList, U extends Chang
|
||||
boolean enabled = revision != null && revVFile != null && !fileType.isBinary();
|
||||
|
||||
if (enabled) {
|
||||
final ProjectLevelVcsManager plVcsManager = ProjectLevelVcsManager.getInstance(myProject);
|
||||
final ProjectLevelVcsManager plVcsManager = ProjectLevelVcsManager.getInstance(myVcs.getProject());
|
||||
enabled &= (! (((ProjectLevelVcsManagerImpl) plVcsManager).getBackgroundableActionHandler(
|
||||
VcsBackgroundableActions.ANNOTATE).isInProgress(key(revVFile, revision))));
|
||||
}
|
||||
@@ -1070,14 +1070,14 @@ public class FileHistoryPanelImpl<S extends CommittedChangeList, U extends Chang
|
||||
final VirtualFile revisionVirtualFile = e.getData(VcsDataKeys.VCS_VIRTUAL_FILE);
|
||||
if ((revision == null) || (revisionVirtualFile == null)) return;
|
||||
|
||||
final BackgroundableActionEnabledHandler handler = ((ProjectLevelVcsManagerImpl) ProjectLevelVcsManager.getInstance(myProject)).
|
||||
final BackgroundableActionEnabledHandler handler = ((ProjectLevelVcsManagerImpl) ProjectLevelVcsManager.getInstance(myVcs.getProject())).
|
||||
getBackgroundableActionHandler(VcsBackgroundableActions.ANNOTATE);
|
||||
handler.register(key(revisionVirtualFile, revision));
|
||||
|
||||
final Ref<FileAnnotation> fileAnnotationRef = new Ref<FileAnnotation>();
|
||||
final Ref<VcsException> exceptionRef = new Ref<VcsException>();
|
||||
|
||||
ProgressManager.getInstance().run(new Task.Backgroundable(myProject, VcsBundle.message("retrieving.annotations"), true,
|
||||
ProgressManager.getInstance().run(new Task.Backgroundable(myVcs.getProject(), VcsBundle.message("retrieving.annotations"), true,
|
||||
BackgroundFromStartOption.getInstance()) {
|
||||
public void run(@NotNull ProgressIndicator indicator) {
|
||||
try {
|
||||
@@ -1102,7 +1102,7 @@ public class FileHistoryPanelImpl<S extends CommittedChangeList, U extends Chang
|
||||
}
|
||||
if (fileAnnotationRef.isNull()) return;
|
||||
|
||||
AbstractVcsHelper.getInstance(myProject).showAnnotation(fileAnnotationRef.get(), revisionVirtualFile);
|
||||
AbstractVcsHelper.getInstance(myProject).showAnnotation(fileAnnotationRef.get(), revisionVirtualFile, myVcs);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1118,14 +1118,14 @@ public class FileHistoryPanelImpl<S extends CommittedChangeList, U extends Chang
|
||||
}
|
||||
VirtualFile virtualFileForRevision = createVirtualFileForRevision(firstSelectedRevision);
|
||||
if (virtualFileForRevision != null) {
|
||||
return new OpenFileDescriptor(myProject, virtualFileForRevision);
|
||||
return new OpenFileDescriptor(myVcs.getProject(), virtualFileForRevision);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else if (PlatformDataKeys.PROJECT.is(dataId)) {
|
||||
return myProject;
|
||||
return myVcs.getProject();
|
||||
}
|
||||
else if (VcsDataKeys.VCS_FILE_REVISION.is(dataId)) {
|
||||
return firstSelectedRevision;
|
||||
|
||||
@@ -27,7 +27,10 @@ import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.diff.*;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.fileEditor.FileEditorManager;
|
||||
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.fileTypes.FileTypeManager;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
@@ -41,7 +44,7 @@ import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.Getter;
|
||||
import com.intellij.openapi.vcs.*;
|
||||
import com.intellij.openapi.vcs.annotate.Annotater;
|
||||
import com.intellij.openapi.vcs.actions.AnnotateToggleAction;
|
||||
import com.intellij.openapi.vcs.annotate.AnnotationProvider;
|
||||
import com.intellij.openapi.vcs.annotate.FileAnnotation;
|
||||
import com.intellij.openapi.vcs.changes.BackgroundFromStartOption;
|
||||
@@ -160,7 +163,7 @@ public class AbstractVcsHelperImpl extends AbstractVcsHelper {
|
||||
private FileHistoryPanelImpl ensureHistoryPanelCreated() {
|
||||
if (myFileHistoryPanel == null) {
|
||||
ContentManager contentManager = ProjectLevelVcsManagerEx.getInstanceEx(myVcs.getProject()).getContentManager();
|
||||
myFileHistoryPanel = new FileHistoryPanelImpl(myVcs.getProject(), myPath, myRepositoryPath, mySession, myVcsHistoryProvider,
|
||||
myFileHistoryPanel = new FileHistoryPanelImpl(myVcs, myPath, mySession, myVcsHistoryProvider,
|
||||
myAnnotationProvider, contentManager, myRefresher);
|
||||
}
|
||||
return myFileHistoryPanel;
|
||||
@@ -436,8 +439,16 @@ public class AbstractVcsHelperImpl extends AbstractVcsHelper {
|
||||
return exceptions;
|
||||
}
|
||||
|
||||
public void showAnnotation(FileAnnotation annotation, VirtualFile file) {
|
||||
new Annotater(annotation, myProject, file).showAnnotation();
|
||||
public void showAnnotation(FileAnnotation annotation, VirtualFile file, AbstractVcs vcs) {
|
||||
OpenFileDescriptor openFileDescriptor = new OpenFileDescriptor(myProject, file);
|
||||
Editor editor = FileEditorManager.getInstance(myProject).openTextEditor(openFileDescriptor, true);
|
||||
if (editor == null) {
|
||||
Messages.showMessageDialog(VcsBundle.message("message.text.cannot.open.editor", file.getPresentableUrl()),
|
||||
VcsBundle.message("message.title.cannot.open.editor"), Messages.getInformationIcon());
|
||||
return;
|
||||
}
|
||||
|
||||
AnnotateToggleAction.doAnnotate(editor, myProject, file, annotation, vcs);
|
||||
}
|
||||
|
||||
public void showDifferences(final VcsFileRevision version1, final VcsFileRevision version2, final File file) {
|
||||
|
||||
+35
@@ -130,6 +130,41 @@ public class CvsCommittedChangesProvider implements CachingCommittedChangesProvi
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public CvsChangeList getOneList(RepositoryLocation location, final VcsRevisionNumber number) throws VcsException {
|
||||
CvsRepositoryLocation cvsLocation = (CvsRepositoryLocation) location;
|
||||
final String module = cvsLocation.getModuleName();
|
||||
final CvsEnvironment connectionSettings = cvsLocation.getEnvironment();
|
||||
if (connectionSettings.isOffline()) {
|
||||
return null;
|
||||
}
|
||||
final CvsChangeListsBuilder builder = new CvsChangeListsBuilder(module, connectionSettings, myProject, cvsLocation.getRootFile());
|
||||
|
||||
final CvsChangeList[] result = new CvsChangeList[1];
|
||||
final CvsResult executionResult = runRLogOperation(connectionSettings, module, new Date(1000), null, new Consumer<LogInformationWrapper>() {
|
||||
public void consume(LogInformationWrapper wrapper) {
|
||||
if (result[0] != null) return;
|
||||
final List<RevisionWrapper> wrappers = builder.revisionWrappersFromLog(wrapper);
|
||||
if (wrappers != null) {
|
||||
for (RevisionWrapper revisionWrapper : wrappers) {
|
||||
if (Comparing.equal(revisionWrapper.getRevision().getNumber(), number.asString())) {
|
||||
result[0] = builder.addRevision(revisionWrapper);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (executionResult.isCanceled()) {
|
||||
throw new ProcessCanceledException();
|
||||
}
|
||||
else if (! executionResult.hasNoErrors()) {
|
||||
throw executionResult.composeError();
|
||||
}
|
||||
return result[0];
|
||||
}
|
||||
|
||||
public List<CvsChangeList> getCommittedChanges(ChangeBrowserSettings settings, RepositoryLocation location, final int maxCount) throws VcsException {
|
||||
CvsRepositoryLocation cvsLocation = (CvsRepositoryLocation) location;
|
||||
return loadCommittedChanges(settings, cvsLocation.getModuleName(), cvsLocation.getEnvironment(), cvsLocation.getRootFile());
|
||||
|
||||
@@ -172,9 +172,10 @@ public class BrowserPanel extends JPanel implements DataProvider, CvsTabbedWindo
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
VcsVirtualFile vcsVirtualFile = (VcsVirtualFile)getCvsVirtualFile();
|
||||
try {
|
||||
final FileAnnotation annotation = CvsVcs2.getInstance(myProject)
|
||||
final CvsVcs2 vcs = CvsVcs2.getInstance(myProject);
|
||||
final FileAnnotation annotation = vcs
|
||||
.createAnnotation(vcsVirtualFile, vcsVirtualFile.getRevision(), myCvsRootConfiguration);
|
||||
AbstractVcsHelper.getInstance(myProject).showAnnotation(annotation, vcsVirtualFile);
|
||||
AbstractVcsHelper.getInstance(myProject).showAnnotation(annotation, vcsVirtualFile, vcs);
|
||||
}
|
||||
catch (VcsException e1) {
|
||||
AbstractVcsHelper.getInstance(myProject).showError(e1, CvsBundle.message("operation.name.annotate"));
|
||||
|
||||
@@ -171,7 +171,7 @@ public class CvsHistoryProvider implements VcsHistoryProvider {
|
||||
|
||||
@Nullable
|
||||
public VcsRevisionNumber calcCurrentRevisionNumber() {
|
||||
return getCurrentRevision(myFilePath);
|
||||
return myFilePath == null ? null : getCurrentRevision(myFilePath);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -338,8 +338,7 @@ public class GitVcs extends AbstractVcs<CommittedChangeList> {
|
||||
*/
|
||||
@Override
|
||||
public CommittedChangesProvider getCommittedChangesProvider() {
|
||||
// TODO Temporary disabled: return myCommittedChangeListProvider;
|
||||
return null;
|
||||
return myCommittedChangeListProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -49,7 +49,7 @@ import java.util.List;
|
||||
/**
|
||||
* The provider for committed change lists
|
||||
*/
|
||||
public class GitCommittedChangeListProvider implements CachingCommittedChangesProvider<CommittedChangeList, ChangeBrowserSettings> {
|
||||
public class GitCommittedChangeListProvider implements CommittedChangesProvider<CommittedChangeList, ChangeBrowserSettings> {
|
||||
/**
|
||||
* the logger
|
||||
*/
|
||||
@@ -224,6 +224,29 @@ public class GitCommittedChangeListProvider implements CachingCommittedChangesPr
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommittedChangeList getOneList(RepositoryLocation location, final VcsRevisionNumber number) throws VcsException {
|
||||
final GitRepositoryLocation l = (GitRepositoryLocation)location;
|
||||
VirtualFile root = LocalFileSystem.getInstance().findFileByIoFile(l.getRoot());
|
||||
if (root == null) {
|
||||
throw new VcsException("The repository does not exists anymore: " + l.getRoot());
|
||||
}
|
||||
|
||||
final CommittedChangeList[] result = new CommittedChangeList[1];
|
||||
GitUtil.getLocalCommittedChanges(myProject, root, new Consumer<GitSimpleHandler>() {
|
||||
public void consume(GitSimpleHandler h) {
|
||||
h.addParameters("-n1");
|
||||
h.addParameters(number.asString());
|
||||
}
|
||||
}, new Consumer<CommittedChangeList>() {
|
||||
@Override
|
||||
public void consume(CommittedChangeList committedChangeList) {
|
||||
result[0] = committedChangeList;
|
||||
}
|
||||
}, false);
|
||||
return result[0];
|
||||
}
|
||||
|
||||
public int getFormatVersion() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -155,20 +155,25 @@ public class GitProjectLogManager {
|
||||
content.setCloseable(false);
|
||||
cvcm.addContent(content);
|
||||
newKeys.put(root, content);
|
||||
|
||||
new CalculateContinuation<String>().calculateAndContinue(new ThrowableComputable<String, Exception>() {
|
||||
public String compute() throws Exception {
|
||||
return getCaption(baseDir, root);
|
||||
|
||||
new AbstractCalledLater(myProject, ModalityState.NON_MODAL) {
|
||||
@Override
|
||||
public void run() {
|
||||
new CalculateContinuation<String>().calculateAndContinue(new ThrowableComputable<String, Exception>() {
|
||||
public String compute() throws Exception {
|
||||
return getCaption(baseDir, root);
|
||||
}
|
||||
}, new CatchingConsumer<String, Exception>() {
|
||||
public void consume(Exception e) {
|
||||
//should not
|
||||
LOG.info(e);
|
||||
}
|
||||
public void consume(final String caption) {
|
||||
content.setDisplayName(caption);
|
||||
}
|
||||
});
|
||||
}
|
||||
}, new CatchingConsumer<String, Exception>() {
|
||||
public void consume(Exception e) {
|
||||
//should not
|
||||
LOG.info(e);
|
||||
}
|
||||
public void consume(final String caption) {
|
||||
content.setDisplayName(caption);
|
||||
}
|
||||
});
|
||||
}.callMe();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
@@ -44,6 +44,7 @@ public class GroovyImportOptimizerRefactoringHelper implements RefactoringHelper
|
||||
public Set<GroovyFile> prepareOperation(UsageInfo[] usages) {
|
||||
Set<GroovyFile> files = new HashSet<GroovyFile>();
|
||||
for (UsageInfo usage : usages) {
|
||||
if (usage.isNonCodeUsage) continue;
|
||||
final PsiElement element = usage.getElement();
|
||||
if (element != null) {
|
||||
final PsiFile file = element.getContainingFile();
|
||||
|
||||
@@ -268,4 +268,18 @@ public class HgCachingCommitedChangesProvider
|
||||
public int getUnlimitedCountValue() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommittedChangeList getOneList(RepositoryLocation location, VcsRevisionNumber number) throws VcsException {
|
||||
final ChangeBrowserSettings settings = createDefaultSettings();
|
||||
settings.USE_CHANGE_AFTER_FILTER = true;
|
||||
settings.USE_CHANGE_BEFORE_FILTER = true;
|
||||
settings.CHANGE_AFTER = number.asString();
|
||||
settings.CHANGE_BEFORE = number.asString();
|
||||
final List<CommittedChangeList> list = getCommittedChanges(settings, location, 1);
|
||||
if (list.size() == 1) {
|
||||
return list.get(0);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -265,7 +265,7 @@ public abstract class TestObject implements JavaCommandLine {
|
||||
consoleView.initUI();
|
||||
consoleView.attachToProcess(handler);
|
||||
unboundOutputRoot.setPrinter(consoleView.getPrinter());
|
||||
|
||||
Disposer.register(consoleView, unboundOutputRoot);
|
||||
final TestsPacketsReceiver packetsReceiver = new TestsPacketsReceiver(consoleView) {
|
||||
@Override
|
||||
public void notifyStart(TestProxy root) {
|
||||
|
||||
@@ -232,6 +232,7 @@ public class TestsPacketsReceiver implements PacketProcessor, Disposable {
|
||||
}
|
||||
|
||||
static void complete(TestProxy testProxy) {
|
||||
testProxy.flush();
|
||||
final int magnitude = testProxy.getState().getMagnitude();
|
||||
|
||||
TestProxy parent = testProxy.getParent();
|
||||
@@ -240,8 +241,9 @@ public class TestsPacketsReceiver implements PacketProcessor, Disposable {
|
||||
final List<TestProxy> children = parent.getChildren();
|
||||
final TestState parentState = parent.getState();
|
||||
LOG.assertTrue(parentState instanceof SuiteState);
|
||||
if (child.equals(children.get(children.size() - 1))) {
|
||||
if (!child.isInProgress() && child.equals(children.get(children.size() - 1))) {
|
||||
((SuiteState)parentState).setRunning(false);
|
||||
parent.flush();
|
||||
}
|
||||
((SuiteState)parentState).updateMagnitude(magnitude);
|
||||
child = parent;
|
||||
|
||||
@@ -24,4 +24,6 @@ public interface MavenFacadeLogger extends Remote {
|
||||
void warn(Throwable e) throws RemoteException;
|
||||
|
||||
void error(Throwable e) throws RemoteException;
|
||||
|
||||
void print(String s) throws RemoteException;
|
||||
}
|
||||
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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 org.jetbrains.idea.maven.facade.embedder;
|
||||
|
||||
import org.apache.maven.artifact.repository.ArtifactRepository;
|
||||
import org.apache.maven.artifact.repository.metadata.*;
|
||||
import org.jetbrains.idea.maven.model.MavenId;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class CustomRepositoryMetadataManager extends DefaultRepositoryMetadataManager {
|
||||
private Map<MavenId, File> myProjectIdToFileMap;
|
||||
|
||||
public void customize(Map<MavenId, File> projectIdToFileMap) {
|
||||
myProjectIdToFileMap = projectIdToFileMap;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
myProjectIdToFileMap = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resolve(RepositoryMetadata metadata, List remoteRepositories, ArtifactRepository localRepository)
|
||||
throws RepositoryMetadataResolutionException {
|
||||
super.resolve(metadata, remoteRepositories, localRepository);
|
||||
|
||||
Map<MavenId, File> map = myProjectIdToFileMap;
|
||||
if (map == null) return;
|
||||
|
||||
Metadata data = metadata.getMetadata();
|
||||
Versioning versioning = data.getVersioning();
|
||||
if (versioning == null) {
|
||||
data.setVersioning(versioning = new Versioning());
|
||||
}
|
||||
|
||||
for (MavenId each : map.keySet()) {
|
||||
if (each.equals(data.getGroupId(), data.getArtifactId())) {
|
||||
versioning.addVersion(each.getVersion());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
@@ -24,8 +24,10 @@ import org.apache.maven.artifact.Artifact;
|
||||
import org.apache.maven.artifact.InvalidRepositoryException;
|
||||
import org.apache.maven.artifact.factory.ArtifactFactory;
|
||||
import org.apache.maven.artifact.manager.WagonManager;
|
||||
import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
|
||||
import org.apache.maven.artifact.repository.ArtifactRepository;
|
||||
import org.apache.maven.artifact.repository.ArtifactRepositoryFactory;
|
||||
import org.apache.maven.artifact.repository.metadata.RepositoryMetadataManager;
|
||||
import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
|
||||
import org.apache.maven.artifact.resolver.ArtifactResolutionException;
|
||||
import org.apache.maven.artifact.resolver.ArtifactResolver;
|
||||
@@ -554,6 +556,7 @@ public class MavenFacadeEmbedderImpl extends RemoteObject implements MavenFacade
|
||||
MavenEmbedder.setImplementation(c, ArtifactFactory.class, CustomArtifactFactory.class);
|
||||
MavenEmbedder.setImplementation(c, ProjectArtifactFactory.class, CustomArtifactFactory.class);
|
||||
MavenEmbedder.setImplementation(c, ArtifactResolver.class, CustomArtifactResolver.class);
|
||||
MavenEmbedder.setImplementation(c, RepositoryMetadataManager.class, CustomRepositoryMetadataManager.class);
|
||||
MavenEmbedder.setImplementation(c, WagonManager.class, CustomWagonManager.class);
|
||||
MavenEmbedder.setImplementation(c, ModelInterpolator.class, CustomModelInterpolator.class);
|
||||
}
|
||||
@@ -580,6 +583,7 @@ public class MavenFacadeEmbedderImpl extends RemoteObject implements MavenFacade
|
||||
((CustomArtifactFactory)getComponent(ArtifactFactory.class)).customize();
|
||||
((CustomArtifactFactory)getComponent(ProjectArtifactFactory.class)).customize();
|
||||
((CustomArtifactResolver)getComponent(ArtifactResolver.class)).customize(projectIdToFileMap, strict);
|
||||
((CustomRepositoryMetadataManager)getComponent(RepositoryMetadataManager.class)).customize(projectIdToFileMap);
|
||||
((CustomWagonManager)getComponent(WagonManager.class)).customize(strict);
|
||||
|
||||
setConsoleAndLogger(logger, process);
|
||||
@@ -604,6 +608,7 @@ public class MavenFacadeEmbedderImpl extends RemoteObject implements MavenFacade
|
||||
((CustomArtifactFactory)getComponent(ProjectArtifactFactory.class)).reset();
|
||||
((CustomArtifactFactory)getComponent(ArtifactFactory.class)).reset();
|
||||
((CustomArtifactResolver)getComponent(ArtifactResolver.class)).reset();
|
||||
((CustomRepositoryMetadataManager)getComponent(RepositoryMetadataManager.class)).reset();
|
||||
((CustomWagonManager)getComponent(WagonManager.class)).reset();
|
||||
}
|
||||
catch (Exception e) {
|
||||
|
||||
+9
@@ -53,4 +53,13 @@ public class MavenFacadeLoggerWrapper {
|
||||
throw new RuntimeException(e1);
|
||||
}
|
||||
}
|
||||
|
||||
public void print(String o) {
|
||||
try {
|
||||
myWrappee.print(o);
|
||||
}
|
||||
catch (RemoteException e1) {
|
||||
throw new RuntimeException(e1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,6 +168,7 @@ public class MavenFacadeManager {
|
||||
}
|
||||
}
|
||||
params.getVMParametersList().addParametersString("-Djava.awt.headless=true -Xmx512m");
|
||||
//params.getVMParametersList().addParametersString("-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5009");
|
||||
return params;
|
||||
}
|
||||
|
||||
@@ -346,6 +347,10 @@ public class MavenFacadeManager {
|
||||
public void error(Throwable e) {
|
||||
MavenLog.LOG.error(e);
|
||||
}
|
||||
|
||||
public void print(String s) {
|
||||
System.out.println(s);
|
||||
}
|
||||
}
|
||||
|
||||
private static class RemoteMavenFacadeDownloadListener extends RemoteObject implements MavenFacadeDownloadListener {
|
||||
|
||||
+67
-2
@@ -187,7 +187,7 @@ public class DependenciesImportingTest extends MavenImportingTestCase {
|
||||
assertModuleLibDeps("project", "Maven: group:lib:1");
|
||||
}
|
||||
|
||||
public void testIntermoduleDependencies() throws Exception {
|
||||
public void testInterModuleDependencies() throws Exception {
|
||||
createProjectPom("<groupId>test</groupId>" +
|
||||
"<artifactId>project</artifactId>" +
|
||||
"<packaging>pom</packaging>" +
|
||||
@@ -196,7 +196,6 @@ public class DependenciesImportingTest extends MavenImportingTestCase {
|
||||
"<modules>" +
|
||||
" <module>m1</module>" +
|
||||
" <module>m2</module>" +
|
||||
" <module>m3</module>" +
|
||||
"</modules>");
|
||||
|
||||
createModulePom("m1", "<groupId>test</groupId>" +
|
||||
@@ -259,6 +258,72 @@ public class DependenciesImportingTest extends MavenImportingTestCase {
|
||||
assertModuleModuleDeps("m1", "m2");
|
||||
}
|
||||
|
||||
public void testInterModuleDependenciesWithVersionRanges() throws Exception {
|
||||
createProjectPom("<groupId>test</groupId>" +
|
||||
"<artifactId>project</artifactId>" +
|
||||
"<packaging>pom</packaging>" +
|
||||
"<version>1</version>" +
|
||||
|
||||
"<modules>" +
|
||||
" <module>m1</module>" +
|
||||
" <module>m2</module>" +
|
||||
"</modules>");
|
||||
|
||||
createModulePom("m1", "<groupId>test</groupId>" +
|
||||
"<artifactId>m1</artifactId>" +
|
||||
"<version>1</version>" +
|
||||
|
||||
"<dependencies>" +
|
||||
" <dependency>" +
|
||||
" <groupId>test</groupId>" +
|
||||
" <artifactId>m2</artifactId>" +
|
||||
" <version>[1, 2]</version>" +
|
||||
" </dependency>" +
|
||||
"</dependencies>");
|
||||
|
||||
createModulePom("m2", "<groupId>test</groupId>" +
|
||||
"<artifactId>m2</artifactId>" +
|
||||
"<version>1</version>");
|
||||
|
||||
importProject();
|
||||
assertModules("project", "m1", "m2");
|
||||
|
||||
assertModuleModuleDeps("m1", "m2");
|
||||
}
|
||||
|
||||
public void testInterSnapshotModuleDependenciesWithVersionRanges() throws Exception {
|
||||
createProjectPom("<groupId>test</groupId>" +
|
||||
"<artifactId>project</artifactId>" +
|
||||
"<packaging>pom</packaging>" +
|
||||
"<version>1</version>" +
|
||||
|
||||
"<modules>" +
|
||||
" <module>m1</module>" +
|
||||
" <module>m2</module>" +
|
||||
"</modules>");
|
||||
|
||||
createModulePom("m1", "<groupId>test</groupId>" +
|
||||
"<artifactId>m1</artifactId>" +
|
||||
"<version>1</version>" +
|
||||
|
||||
"<dependencies>" +
|
||||
" <dependency>" +
|
||||
" <groupId>test</groupId>" +
|
||||
" <artifactId>m2</artifactId>" +
|
||||
" <version>[, 1-SNAPSHOT]</version>" +
|
||||
" </dependency>" +
|
||||
"</dependencies>");
|
||||
|
||||
createModulePom("m2", "<groupId>test</groupId>" +
|
||||
"<artifactId>m2</artifactId>" +
|
||||
"<version>1-SNAPSHOT</version>");
|
||||
|
||||
importProject();
|
||||
assertModules("project", "m1", "m2");
|
||||
|
||||
assertModuleModuleDeps("m1", "m2");
|
||||
}
|
||||
|
||||
public void testInterModuleDependenciesWithoutModuleGroup() throws Exception {
|
||||
createProjectPom("<groupId>test</groupId>" +
|
||||
"<artifactId>project</artifactId>" +
|
||||
|
||||
+104
-4
@@ -39,17 +39,17 @@ import com.intellij.util.ThrowableConsumer;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import com.intellij.util.messages.MessageBusConnection;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.svn.SvnAuthenticationNotifier;
|
||||
import org.jetbrains.idea.svn.SvnBundle;
|
||||
import org.jetbrains.idea.svn.SvnUtil;
|
||||
import org.jetbrains.idea.svn.SvnVcs;
|
||||
import org.jetbrains.idea.svn.actions.ConfigureBranchesAction;
|
||||
import org.tmatesoft.svn.core.ISVNLogEntryHandler;
|
||||
import org.tmatesoft.svn.core.SVNException;
|
||||
import org.tmatesoft.svn.core.SVNLogEntry;
|
||||
import org.tmatesoft.svn.core.SVNURL;
|
||||
import org.tmatesoft.svn.core.*;
|
||||
import org.tmatesoft.svn.core.io.SVNRepository;
|
||||
import org.tmatesoft.svn.core.wc.SVNInfo;
|
||||
import org.tmatesoft.svn.core.wc.SVNLogClient;
|
||||
import org.tmatesoft.svn.core.wc.SVNRevision;
|
||||
import org.tmatesoft.svn.core.wc.SVNWCClient;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
@@ -490,6 +490,106 @@ public class SvnCommittedChangesProvider implements CachingCommittedChangesProvi
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SvnChangeList getOneList(final RepositoryLocation location, VcsRevisionNumber number) throws VcsException {
|
||||
final String url = ((SvnRepositoryLocation)location).getURL();
|
||||
final long revision;
|
||||
try {
|
||||
revision = Long.parseLong(number.asString());
|
||||
} catch (NumberFormatException e) {
|
||||
throw new VcsException(e);
|
||||
}
|
||||
|
||||
final SvnChangeList[] result = new SvnChangeList[1];
|
||||
final SVNLogClient logger;
|
||||
final SVNRevision revisionBefore;
|
||||
final SVNURL repositoryUrl;
|
||||
final SVNURL svnurl;
|
||||
try {
|
||||
logger = myVcs.createLogClient();
|
||||
revisionBefore = SVNRevision.create(revision);
|
||||
|
||||
svnurl = SVNURL.parseURIEncoded(url);
|
||||
final SVNWCClient client = myVcs.createWCClient();
|
||||
SVNInfo info = client.doInfo(svnurl, SVNRevision.UNDEFINED, SVNRevision.HEAD);
|
||||
if (info == null) {
|
||||
throw new VcsException("Can not get repository URL");
|
||||
}
|
||||
repositoryUrl = info.getRepositoryRootURL();
|
||||
}
|
||||
catch (SVNException e) {
|
||||
throw new VcsException(e);
|
||||
}
|
||||
|
||||
tryExactHit((SvnRepositoryLocation)location, result, logger, revisionBefore, repositoryUrl, svnurl);
|
||||
if (result[0] == null) {
|
||||
tryByRoot(result, logger, revisionBefore, repositoryUrl);
|
||||
if (result[0] == null) {
|
||||
tryStepByStep((SvnRepositoryLocation)location, result, logger, revisionBefore, repositoryUrl, svnurl);
|
||||
}
|
||||
}
|
||||
return result[0];
|
||||
}
|
||||
|
||||
private void tryByRoot(SvnChangeList[] result, SVNLogClient logger, SVNRevision revisionBefore, SVNURL repositoryUrl) throws VcsException {
|
||||
final boolean authorized = SvnAuthenticationNotifier.passiveValidation(myProject, repositoryUrl);
|
||||
if (! authorized) return;
|
||||
tryExactHit(new SvnRepositoryLocation(repositoryUrl.toString()), result, logger, revisionBefore, repositoryUrl, repositoryUrl);
|
||||
}
|
||||
|
||||
private void tryStepByStep(final SvnRepositoryLocation svnRepositoryLocation,
|
||||
final SvnChangeList[] result,
|
||||
SVNLogClient logger,
|
||||
final SVNRevision revisionBefore, final SVNURL repositoryUrl, SVNURL svnurl) throws VcsException {
|
||||
try {
|
||||
logger.doLog(svnurl, null, SVNRevision.UNDEFINED, SVNRevision.HEAD, revisionBefore,
|
||||
false, true, true, 0, null,
|
||||
new ISVNLogEntryHandler() {
|
||||
public void handleLogEntry(SVNLogEntry logEntry) {
|
||||
if (myProject.isDisposed()) throw new ProcessCanceledException();
|
||||
if (logEntry.getDate() == null) {
|
||||
// do not add lists without info - this situation is possible for lists where there are paths that user has no rights to observe
|
||||
return;
|
||||
}
|
||||
if (logEntry.getRevision() == revisionBefore.getNumber()) {
|
||||
result[0] = new SvnChangeList(myVcs, svnRepositoryLocation, logEntry, repositoryUrl.toString());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (SVNException e) {
|
||||
throw new VcsException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void tryExactHit(final SvnRepositoryLocation location,
|
||||
final SvnChangeList[] result,
|
||||
SVNLogClient logger,
|
||||
SVNRevision revisionBefore,
|
||||
final SVNURL repositoryUrl, SVNURL svnurl) throws VcsException {
|
||||
try {
|
||||
logger.doLog(svnurl, null, SVNRevision.UNDEFINED, revisionBefore, revisionBefore,
|
||||
false, true, false, 1, null,
|
||||
new ISVNLogEntryHandler() {
|
||||
public void handleLogEntry(SVNLogEntry logEntry) {
|
||||
if (myProject.isDisposed()) throw new ProcessCanceledException();
|
||||
if (logEntry.getDate() == null) {
|
||||
// do not add lists without info - this situation is possible for lists where there are paths that user has no rights to observe
|
||||
return;
|
||||
}
|
||||
result[0] = new SvnChangeList(myVcs, (SvnRepositoryLocation) location, logEntry, repositoryUrl.toString());
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (SVNException e) {
|
||||
if (SVNErrorCode.FS_CATEGORY == e.getErrorMessage().getErrorCode().getCategory()) {
|
||||
// pass to step by step looking for revision
|
||||
return;
|
||||
}
|
||||
throw new VcsException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public int getFormatVersion() {
|
||||
return VERSION_WITH_REPLACED_PATHS;
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -49,6 +49,7 @@ import com.intellij.openapi.roots.ModuleRootManager;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.ui.MessageType;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.Getter;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
@@ -131,6 +132,7 @@ public class TestNGRunnableState extends JavaCommandLineState {
|
||||
executor);
|
||||
console.initUI();
|
||||
unboundOutputRoot.setPrinter(console.getPrinter());
|
||||
Disposer.register(console, unboundOutputRoot);
|
||||
for (RunConfigurationExtension ext : Extensions.getExtensions(RunConfigurationExtension.EP_NAME)) {
|
||||
ext.handleStartProcess(config, processHandler);
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@ public class TestNGRemoteListener implements IRemoteSuiteListener, IRemoteTestLi
|
||||
}
|
||||
|
||||
public void onFinish(SuiteMessage suiteMessage) {
|
||||
unboundOutputRoot.flush();
|
||||
console.finish();
|
||||
final TestNGResults view = console.getResultsView();
|
||||
if (view != null) {
|
||||
|
||||
@@ -17,26 +17,18 @@ package com.theoryinpractice.testng.model;
|
||||
|
||||
import com.intellij.execution.Location;
|
||||
import com.intellij.execution.PsiLocation;
|
||||
import com.intellij.execution.stacktrace.StackTraceLine;
|
||||
import com.intellij.execution.testframework.AbstractTestProxy;
|
||||
import com.intellij.execution.testframework.Filter;
|
||||
import com.intellij.execution.testframework.Printable;
|
||||
import com.intellij.execution.testframework.Printer;
|
||||
import com.intellij.execution.ui.ConsoleViewContentType;
|
||||
import com.intellij.ide.util.EditSourceUtil;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diff.LineTokenizer;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.pom.Navigatable;
|
||||
import com.intellij.psi.*;
|
||||
import com.theoryinpractice.testng.ui.TestNGConsoleView;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.testng.remote.strprotocol.MessageHelper;
|
||||
import org.testng.remote.strprotocol.TestResultMessage;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -49,7 +41,6 @@ public class TestProxy extends AbstractTestProxy {
|
||||
private TestProxy parent;
|
||||
private SmartPsiElementPointer psiElement;
|
||||
private boolean inProgress;
|
||||
private int myExceptionMark;
|
||||
private boolean myTearDownFailure;
|
||||
|
||||
public TestProxy() {}
|
||||
@@ -220,24 +211,6 @@ public class TestProxy extends AbstractTestProxy {
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getExceptionMark() {//todo
|
||||
if (myExceptionMark == 0 && getChildCount() > 0) {
|
||||
return getChildAt(0).getExceptionMark();
|
||||
}
|
||||
return myExceptionMark;
|
||||
}
|
||||
|
||||
public void setExceptionMark(int exceptionMark) {
|
||||
myExceptionMark = exceptionMark;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printOn(Printer printer) {
|
||||
for (int i = 0; i < myNestedPrintables.size(); i++) {
|
||||
if (i == myExceptionMark && i > 0) printer.mark();
|
||||
myNestedPrintables.get(i).printOn(printer);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isInterrupted() {
|
||||
return !isInProgress() && inProgress;
|
||||
|
||||
@@ -109,19 +109,20 @@ public class TestNGConsoleView extends BaseTestsOutputConsoleView {
|
||||
if (testNGResults != null) {
|
||||
int exceptionMark = myExceptionalMark == -1 ? 0 : myExceptionalMark;
|
||||
|
||||
final String stackTrace = result.getStackTrace();
|
||||
if (stackTrace != null && stackTrace.length() > 10) {
|
||||
exceptionMark = currentTest.getCurrentSize();
|
||||
//trim useless crud from stacktrace
|
||||
String trimmed = trimStackTrace(stackTrace);
|
||||
List<Printable> printables = getPrintables(result, trimmed);
|
||||
for (Printable printable : printables) {
|
||||
currentTest.addLast(printable);
|
||||
if (currentTest != null) {
|
||||
final String stackTrace = result.getStackTrace();
|
||||
if (stackTrace != null && stackTrace.length() > 10) {
|
||||
exceptionMark = currentTest.getCurrentSize();
|
||||
//trim useless crud from stacktrace
|
||||
List<Printable> printables = getPrintables(result);
|
||||
for (Printable printable : printables) {
|
||||
currentTest.addLast(printable);
|
||||
}
|
||||
}
|
||||
final TestProxy failedToStart = testNGResults.getFailedToStart();
|
||||
if (failedToStart != null) {
|
||||
currentTest.addChild(failedToStart);
|
||||
}
|
||||
}
|
||||
final TestProxy failedToStart = testNGResults.getFailedToStart();
|
||||
if (failedToStart != null) {
|
||||
currentTest.addChild(failedToStart);
|
||||
}
|
||||
testNGResults.addTestResult(result, exceptionMark);
|
||||
myExceptionalMark = -1;
|
||||
@@ -166,7 +167,8 @@ public class TestNGConsoleView extends BaseTestsOutputConsoleView {
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
private List<Printable> getPrintables(final TestResultMessage result, String s) {
|
||||
static List<Printable> getPrintables(final TestResultMessage result) {
|
||||
String s = trimStackTrace(result.getStackTrace());
|
||||
List<Printable> printables = new ArrayList<Printable>();
|
||||
//figure out if we have a diff we need to hyperlink
|
||||
Matcher matcher = COMPARISION_PATTERN.matcher(s);
|
||||
|
||||
@@ -56,7 +56,6 @@ import java.awt.event.MouseEvent;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class TestNGResults extends TestResultsPanel implements TestFrameworkRunningModel {
|
||||
@NonNls private static final String TESTNG_SPLITTER_PROPERTY = "TestNG.Splitter.Proportion";
|
||||
@@ -242,10 +241,18 @@ public class TestNGResults extends TestResultsPanel implements TestFrameworkRunn
|
||||
else {
|
||||
//do not remember testresultmessage: test hierarchy is not set
|
||||
testCase = new TestProxy(result.toDisplayString());
|
||||
final String stackTrace = result.getStackTrace();
|
||||
if (stackTrace != null) {
|
||||
final List<Printable> printables = TestNGConsoleView.getPrintables(result);
|
||||
for (Printable printable : printables) {
|
||||
testCase.addLast(printable);
|
||||
}
|
||||
}
|
||||
failedToStart = testCase;
|
||||
}
|
||||
|
||||
testCase.setExceptionMark(exceptionMark);
|
||||
AbstractTestProxy.flushOutput(testCase);
|
||||
|
||||
if (result.getResult() == MessageHelper.FAILED_TEST) {
|
||||
myStatusLine.setStatusColor(ColorProgressBar.RED);
|
||||
|
||||
@@ -26,20 +26,17 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ModifiableRootModel;
|
||||
import com.intellij.openapi.roots.ModuleRootManager;
|
||||
import com.intellij.openapi.roots.OrderRootType;
|
||||
import com.intellij.openapi.roots.libraries.JarVersionDetectionUtil;
|
||||
import com.intellij.openapi.roots.libraries.Library;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileManager;
|
||||
import com.intellij.openapi.vfs.*;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.jsp.jspJava.JspClass;
|
||||
import com.intellij.psi.javadoc.PsiDocComment;
|
||||
import com.intellij.psi.javadoc.PsiDocTag;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.TextOccurenceProcessor;
|
||||
import com.intellij.psi.search.UsageSearchContext;
|
||||
import com.intellij.psi.search.searches.AllClassesSearch;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.psi.util.PsiElementFilter;
|
||||
@@ -56,9 +53,11 @@ import org.testng.TestNG;
|
||||
import org.testng.annotations.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
/**
|
||||
* @author Hani Suleiman Date: Jul 20, 2005 Time: 1:37:36 PM
|
||||
@@ -68,6 +67,31 @@ public class TestNGUtil
|
||||
private static final Logger LOGGER = Logger.getInstance("TestNG Runner");
|
||||
public static final String TESTNG_GROUP_NAME = "TestNG";
|
||||
|
||||
public static boolean hasDocTagsSupport = hasDocTagsSupport();
|
||||
|
||||
private static boolean hasDocTagsSupport() {
|
||||
final String testngJarPath = PathUtil.getJarPathForClass(Test.class);
|
||||
if (testngJarPath != null) {
|
||||
final VirtualFile testngjar = LocalFileSystem.getInstance().findFileByPath(testngJarPath);
|
||||
if (testngjar != null ) {
|
||||
try {
|
||||
final VirtualFile jarRoot = JarFileSystem.getInstance().getJarRootForLocalFile(testngjar);
|
||||
if (jarRoot != null) {
|
||||
final ZipFile zipFile = JarFileSystem.getInstance().getJarFile(jarRoot);
|
||||
final String version = JarVersionDetectionUtil.detectJarVersion(zipFile);
|
||||
if (version != null && version.compareTo("5.12") > 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static final String TEST_ANNOTATION_FQN = Test.class.getName();
|
||||
public static final String[] CONFIG_ANNOTATIONS_FQN = {
|
||||
Configuration.class.getName(),
|
||||
@@ -145,12 +169,7 @@ public class TestNGUtil
|
||||
}
|
||||
|
||||
public static boolean hasTest(PsiModifierListOwner element, boolean checkDisabled) {
|
||||
return hasTest(element, checkDisabled, !element.getManager().getSearchHelper().processElementsWithWord(new TextOccurenceProcessor() {
|
||||
@Override
|
||||
public boolean execute(PsiElement element, int offsetInElement) {
|
||||
return false;
|
||||
}
|
||||
}, GlobalSearchScope.projectScope(element.getProject()), "testng.test", UsageSearchContext.IN_COMMENTS , true));
|
||||
return hasTest(element, checkDisabled, hasDocTagsSupport);
|
||||
}
|
||||
|
||||
public static boolean hasTest(PsiModifierListOwner element, boolean checkDisabled, boolean checkJavadoc) {
|
||||
|
||||
@@ -24,7 +24,6 @@ import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleUtil;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
@@ -492,8 +491,10 @@ public class XmlTagImpl extends XmlElementImpl implements XmlTag {
|
||||
ChangeUtil.copyElement((TreeElement)XmlChildRole.START_TAG_NAME_FINDER.findChild(dummyTag), charTableByTree));
|
||||
final ASTNode childByRole = XmlChildRole.CLOSING_TAG_NAME_FINDER.findChild(tag);
|
||||
if (childByRole != null) {
|
||||
tag.replaceChild(childByRole,
|
||||
ChangeUtil.copyElement((TreeElement)XmlChildRole.CLOSING_TAG_NAME_FINDER.findChild(dummyTag), charTableByTree));
|
||||
final TreeElement treeElement = (TreeElement)XmlChildRole.CLOSING_TAG_NAME_FINDER.findChild(dummyTag);
|
||||
if (treeElement != null) {
|
||||
tag.replaceChild(childByRole, ChangeUtil.copyElement(treeElement, charTableByTree));
|
||||
}
|
||||
}
|
||||
|
||||
return XmlTagNameChangedImpl.createXmlTagNameChanged(model, tag, oldName);
|
||||
|
||||
Reference in New Issue
Block a user