Merge remote-tracking branch 'origin/master'

This commit is contained in:
Roman Shevchenko
2016-08-17 15:46:50 +03:00
49 changed files with 354 additions and 217 deletions
@@ -38,10 +38,8 @@ abstract class BuildContext {
WindowsDistributionCustomizer windowsDistributionCustomizer
LinuxDistributionCustomizer linuxDistributionCustomizer
MacDistributionCustomizer macDistributionCustomizer
MacHostProperties macHostProperties
ProprietaryBuildTools proprietaryBuildTools
BuildOptions options
SignTool signTool
ScrambleTool scrambleTool
BundledJreManager bundledJreManager
/**
@@ -88,10 +86,10 @@ abstract class BuildContext {
public static BuildContext createContext(AntBuilder ant, JpsGantProjectBuilder projectBuilder, JpsProject project, JpsGlobal global,
String communityHome, String projectHome, String buildOutputRoot, ProductProperties productProperties,
BuildOptions options = new BuildOptions(), MacHostProperties macHostProperties = null, SignTool signTool = null,
ScrambleTool scrambleTool = null) {
ProprietaryBuildTools proprietaryBuildTools = ProprietaryBuildTools.DUMMY,
BuildOptions options = new BuildOptions()) {
return BuildContextImpl.create(ant, projectBuilder, project, global, communityHome, projectHome, buildOutputRoot, productProperties,
options, macHostProperties, signTool, scrambleTool)
proprietaryBuildTools, options)
}
/**
@@ -32,7 +32,8 @@ class IdeaCommunityBuilder {
IdeaCommunityBuilder(String home, String outputRootPath, GantBinding binding, BuildOptions options = new BuildOptions()) {
this.binding = binding
buildContext = BuildContext.createContext(binding.ant, binding.projectBuilder, binding.project, binding.global, home, home,
"$outputRootPath/release", new IdeaCommunityProperties(home), options)
"$outputRootPath/release", new IdeaCommunityProperties(home), ProprietaryBuildTools.DUMMY,
options)
}
IdeaCommunityBuilder(GantBinding binding, BuildContext buildContext) {
@@ -20,8 +20,6 @@ import groovy.transform.Immutable
/**
* @author nik
*
* The purpose of using Mac host is preparation and signing OS X specific artifacts.
* The necessary software for Mac host:
* OS X 10.9
@@ -88,7 +88,7 @@ public abstract class ProductProperties {
List<LibraryLicense> allLibraryLicenses = CommunityLibraryLicenses.LICENSES_LIST
/**
* If {@code true} the main product JAR file will be scrambled using {@link BuildContext#scrambleTool}
* If {@code true} the main product JAR file will be scrambled using {@link ProprietaryBuildTools#scrambleTool}
*/
boolean scrambleMainJar = false
@@ -0,0 +1,48 @@
/*
* Copyright 2000-2016 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.intellij.build
import groovy.transform.Canonical
import groovy.transform.CompileStatic
import groovy.transform.Immutable
/**
* Describes proprietary tools which are used to build the product. Pass the instance of this class {@link BuildContext#createContext} method.
*
* @author nik
*/
@CompileStatic
@Canonical
class ProprietaryBuildTools {
public static final ProprietaryBuildTools DUMMY = new ProprietaryBuildTools(null, null, null)
/**
* This tool is required to sign *.exe files in Windows distribution. If it is {@code null} the files won't be signed and Windows may show
* a warning when user tries to run them.
*/
SignTool signTool
/**
* This tool is used to scramble the main product JAR file if {@link ProductProperties#scrambleMainJar} is {@code true}
*/
ScrambleTool scrambleTool
/**
* Describes address and credentials of Mac machine which is used to sign and build *.dmg installer for Mac OS. If {@code null} only *.sit
* archive will be built.
*/
MacHostProperties macHostProperties
}
@@ -18,7 +18,7 @@ package org.jetbrains.intellij.build
import groovy.transform.CompileStatic
/**
* Implement this interfaces and pass the implementation to {@link BuildContext#createContext} method to support scrambling the product
* Implement this interfaces and pass the implementation to {@link ProprietaryBuildTools} constructor to support scrambling the product
* JAR files.
*
* @author nik
@@ -33,7 +33,7 @@ package org.jetbrains.intellij.build
import groovy.transform.CompileStatic
/**
* Implement this interfaces and pass the implementation to {@link BuildContext#createContext} method to sign the product's *.exe files.
* Implement this interfaces and pass the implementation to {@link ProprietaryBuildTools} constructor to sign the product's *.exe files.
*
* @author nik
*/
@@ -38,8 +38,8 @@ class BuildContextImpl extends BuildContext {
//todo[nik] construct buildOutputRoot automatically based on product name
static BuildContextImpl create(AntBuilder ant, JpsGantProjectBuilder projectBuilder, JpsProject project, JpsGlobal global,
String communityHome, String projectHome, String buildOutputRoot, ProductProperties productProperties,
BuildOptions options, MacHostProperties macHostProperties, SignTool signTool, ScrambleTool scrambleTool) {
String communityHome, String projectHome, String buildOutputRoot, ProductProperties productProperties,
ProprietaryBuildTools proprietaryBuildTools, BuildOptions options) {
BuildMessages messages = BuildMessagesImpl.create(projectBuilder, ant.project)
def jdk8Home = JdkUtils.computeJdkHome(messages, "jdk8Home", "$projectHome/build/jdk/1.8", "JDK_18_x64")
@@ -60,15 +60,14 @@ class BuildContextImpl extends BuildContext {
return new BuildContextImpl(ant, messages, paths, project, global, projectBuilder, productProperties,
windowsDistributionCustomizer, linuxDistributionCustomizer, macDistributionCustomizer,
macHostProperties, options, signTool, scrambleTool, outputDirectoriesToKeep)
proprietaryBuildTools, options, outputDirectoriesToKeep)
}
BuildContextImpl(AntBuilder ant, BuildMessages messages, BuildPaths paths, JpsProject project, JpsGlobal global,
JpsGantProjectBuilder projectBuilder, ProductProperties productProperties,
WindowsDistributionCustomizer windowsDistributionCustomizer, LinuxDistributionCustomizer linuxDistributionCustomizer,
MacDistributionCustomizer macDistributionCustomizer,
MacHostProperties macHostProperties, BuildOptions options, SignTool signTool, ScrambleTool scrambleTool,
List<String> outputDirectoriesToKeep) {
ProprietaryBuildTools proprietaryBuildTools, BuildOptions options, List<String> outputDirectoriesToKeep) {
this.ant = ant
this.messages = messages
this.paths = paths
@@ -76,11 +75,9 @@ class BuildContextImpl extends BuildContext {
this.global = global
this.projectBuilder = projectBuilder
this.productProperties = productProperties
this.macHostProperties = macHostProperties
this.proprietaryBuildTools = proprietaryBuildTools
bundledJreManager = new BundledJreManager(this, paths.buildOutputRoot)
this.options = options
this.signTool = signTool
this.scrambleTool = scrambleTool
this.outputDirectoriesToKeep = outputDirectoriesToKeep
bundledJreManager = new BundledJreManager(this, paths.buildOutputRoot)
@@ -212,9 +209,9 @@ class BuildContextImpl extends BuildContext {
@Override
void signExeFile(String path) {
if (signTool != null) {
if (proprietaryBuildTools.signTool != null) {
messages.progress("Signing $path")
signTool.signExeFile(path, this)
proprietaryBuildTools.signTool.signExeFile(path, this)
messages.info("Signing done")
}
else {
@@ -238,7 +235,7 @@ class BuildContextImpl extends BuildContext {
def messages = messages.forkForParallelTask(taskName)
def child = new BuildContextImpl(ant, messages, paths, project, global, projectBuilder, productProperties,
windowsDistributionCustomizer, linuxDistributionCustomizer, macDistributionCustomizer,
macHostProperties, options, signTool, scrambleTool, outputDirectoriesToKeep)
proprietaryBuildTools, options, outputDirectoriesToKeep)
child.bundledJreManager.baseDirectoryForJre = bundledJreManager.baseDirectoryForJre
return child
}
@@ -272,11 +272,11 @@ idea.fatal.error.notification=disabled
new DistributionJARsBuilder(buildContext, includedModules, allPlugins).buildJARs()
}
if (buildContext.productProperties.scrambleMainJar) {
if (buildContext.scrambleTool != null) {
buildContext.scrambleTool.scramble(buildContext.productProperties.productLayout.mainJarName, buildContext)
if (buildContext.proprietaryBuildTools.scrambleTool != null) {
buildContext.proprietaryBuildTools.scrambleTool.scramble(buildContext.productProperties.productLayout.mainJarName, buildContext)
}
else {
buildContext.messages.warning("Scrambling skipped: 'srambleTool' isn't defined")
buildContext.messages.warning("Scrambling skipped: 'scrambleTool' isn't defined")
}
}
buildDistributions()
@@ -347,7 +347,7 @@ idea.fatal.error.notification=disabled
}
else {
List<String> modulesToBuild = ((moduleNames as Set<String>) + DistributionJARsBuilder.ADDITIONAL_MODULES_TO_COMPILE
+ buildContext.scrambleTool?.additionalModulesToCompile ?: []) as List<String>
+ buildContext.proprietaryBuildTools.scrambleTool?.additionalModulesToCompile ?: []) as List<String>
List<String> invalidModules = modulesToBuild.findAll {buildContext.findModule(it) == null}
if (!invalidModules.empty) {
buildContext.messages.warning("The following modules won't be compiled: $invalidModules")
@@ -129,8 +129,8 @@ class DistributionJARsBuilder {
Set<String> usedJars = collectUsedJars(includedModules, []) - productLayout.additionalJarsToUnpackIntoMainJar.collect {FileUtil.toSystemIndependentName(it)}
if (buildContext.scrambleTool != null) {
def forbiddenJarNames = buildContext.scrambleTool.namesOfJarsRequiredToBeScrambled
if (buildContext.proprietaryBuildTools.scrambleTool != null) {
def forbiddenJarNames = buildContext.proprietaryBuildTools.scrambleTool.namesOfJarsRequiredToBeScrambled
def forbiddenJars = usedJars.findAll { forbiddenJarNames.contains(PathUtilRt.getFileName(it)) }
if (!forbiddenJars.empty) {
buildContext.messages.error("The following JARs cannot be included into the product 'lib' directory, they need to be scrambled with the main jar: ${forbiddenJars}")
@@ -61,13 +61,13 @@ class MacDistributionBuilder {
layoutMacApp(ideaPropertiesFile, customIdeaProperties, docTypes)
customizer.copyAdditionalFiles(buildContext, macDistPath)
def macZipPath = buildMacZip()
if (buildContext.macHostProperties == null) {
if (buildContext.proprietaryBuildTools.macHostProperties == null) {
buildContext.messages.info("A Mac OS build agent isn't configured, dmg artifact won't be produced")
buildContext.notifyArtifactBuilt(macZipPath)
}
else {
buildContext.executeStep("Build dmg artifact for Mac OS X", BuildOptions.MAC_DMG_STEP) {
MacDmgBuilder.signAndBuildDmg(buildContext, customizer, buildContext.macHostProperties, macZipPath)
MacDmgBuilder.signAndBuildDmg(buildContext, customizer, buildContext.proprietaryBuildTools.macHostProperties, macZipPath)
buildContext.ant.delete(file: macZipPath)
}
}
@@ -117,7 +117,6 @@ public abstract class SuspendContextImpl extends XSuspendContext implements Susp
@Nullable
public EventSet getEventSet() {
assertNotResumed();
return myEventSet;
}
@@ -363,25 +363,23 @@ public abstract class DebuggerUtilsEx extends DebuggerUtils {
}
@NotNull
public static List<Pair<Breakpoint, Event>> getEventDescriptors(SuspendContextImpl suspendContext) {
public static List<Pair<Breakpoint, Event>> getEventDescriptors(@Nullable SuspendContextImpl suspendContext) {
DebuggerManagerThreadImpl.assertIsManagerThread();
if(suspendContext == null) {
return Collections.emptyList();
}
final EventSet events = suspendContext.getEventSet();
if(events == null) {
return Collections.emptyList();
}
final List<Pair<Breakpoint, Event>> eventDescriptors = new SmartList<>();
final RequestManagerImpl requestManager = suspendContext.getDebugProcess().getRequestsManager();
for (final Event event : events) {
final Requestor requestor = requestManager.findRequestor(event.request());
if (requestor instanceof Breakpoint) {
eventDescriptors.add(Pair.create((Breakpoint)requestor, event));
if (suspendContext != null) {
EventSet events = suspendContext.getEventSet();
if (!ContainerUtil.isEmpty(events)) {
List<Pair<Breakpoint, Event>> eventDescriptors = ContainerUtil.newSmartList();
RequestManagerImpl requestManager = suspendContext.getDebugProcess().getRequestsManager();
for (Event event : events) {
Requestor requestor = requestManager.findRequestor(event.request());
if (requestor instanceof Breakpoint) {
eventDescriptors.add(Pair.create((Breakpoint)requestor, event));
}
}
return eventDescriptors;
}
}
return eventDescriptors;
return Collections.emptyList();
}
public static TextWithImports getEditorText(final Editor editor) {
@@ -1187,6 +1187,12 @@ public class InferenceSession {
@NotNull
private PsiSubstitutor resolveSubset(Collection<InferenceVariable> vars, PsiSubstitutor substitutor) {
if (myErased) {
for (InferenceVariable var : vars) {
substitutor = substitutor.put(var, null);
}
}
for (InferenceVariable var : vars) {
final PsiType instantiation = var.getInstantiation();
final PsiType type = instantiation == PsiType.NULL ? checkBoundsConsistency(substitutor, var) : instantiation;
@@ -1228,12 +1234,7 @@ public class InferenceSession {
type = PsiType.getJavaLangRuntimeException(myManager, GlobalSearchScope.allScope(myManager.getProject()));
}
else {
if (myErased) {
type = null;
}
else {
type = var.getBounds(InferenceBound.UPPER).size() == 1 ? myPolicy.getInferredTypeWithNoConstraint(myManager, upperBound).first : upperBound;
}
type = var.getBounds(InferenceBound.UPPER).size() == 1 ? myPolicy.getInferredTypeWithNoConstraint(myManager, upperBound).first : upperBound;
}
if (type instanceof PsiIntersectionType) {
@@ -7,8 +7,8 @@ public class Sample {
<B> B bar(G<B> gb) {return null;}
void f(G1 g1) {
<error descr="Incompatible types. Found: 'java.lang.Object', required: 'Sample.G<java.lang.String>'">G<String> l11 = bar(g1);</error>
<error descr="Incompatible types. Found: 'java.lang.Object', required: 'java.lang.String'">String l1 = bar(g1);</error>
G<String> l11 = bar<error descr="'bar(Sample.G<B>)' in 'Sample' cannot be applied to '(Sample.G1)'">(g1)</error>;
String l1 = bar<error descr="'bar(Sample.G<B>)' in 'Sample' cannot be applied to '(Sample.G1)'">(g1)</error>;
Object o = bar(g1);
}
}
@@ -6,7 +6,7 @@ class Test {
}
void m(List l){
<error descr="Incompatible types. Found: 'java.lang.Object', required: 'boolean'">boolean foo = foo(l);</error>
<error descr="Incompatible types. Found: 'java.lang.Object', required: 'java.lang.String'">String s = foo(l);</error>
boolean foo = foo<error descr="'foo(java.util.List<T>)' in 'Test' cannot be applied to '(java.util.List)'">(l)</error>;
String s = foo<error descr="'foo(java.util.List<T>)' in 'Test' cannot be applied to '(java.util.List)'">(l)</error>;
}
}
@@ -0,0 +1,19 @@
import java.util.function.Consumer;
interface A<T> {
void locateDefinition();
}
class Test {
public static <T extends A> void bar(final T member, final Consumer<T> processor) {}
public static <T extends A<?>> void bar1(final T member, final Consumer<T> processor) {}
public static <T extends A<T>> void bar2(final T member, final Consumer<T> processor) {}
public static void foo(final A member) {
bar(member, symbol -> symbol.locateDefinition());
bar1(member, symbol -> symbol.locateDefinition());
bar2(member, symbol -> symbol.locateDefinition());
}
}
@@ -4,7 +4,7 @@ import java.util.Set;
abstract class Test {
public void foo(List list) {
set<error descr="Ambiguous method call: both 'Test.set(Set<List>, List)' and 'Test.set(Set, List)' match">(get(), list)</error>;
set<error descr="Ambiguous method call: both 'Test.set(Set<List>, List)' and 'Test.set(Set<Object>, List<?>)' match">(get(), list)</error>;
}
abstract <Y> Set<Y> get();
@@ -331,6 +331,10 @@ public class NewLambdaHighlightingTest extends LightDaemonAnalyzerTestCase {
doTest();
}
public void testUncheckedConstraintOnInferenceVariableWithProperUpperBound() throws Exception {
doTest();
}
private void doTest() {
doTest(false);
}
@@ -425,7 +425,7 @@ public abstract class ComponentManagerImpl extends UserDataHolderBase implements
BaseComponent loadedComponent = myNameToComponent.get(componentName);
// component may have been already loaded by PicoContainer, so fire error only if components are really different
if (!instance.equals(loadedComponent)) {
LOG.error("Component name collision: " + componentName + " " + loadedComponent.getClass() + " and " + instance.getClass());
LOG.error("Component name collision: " + componentName + " " + (loadedComponent == null ? "null" : loadedComponent.getClass()) + " and " + instance.getClass());
}
}
else {
@@ -69,8 +69,4 @@ class PasswordSafeConfigurableUi : ConfigurableUi<PasswordSafeSettings> {
return ProviderType.MASTER_PASSWORD
}
}
}
interface PasswordSafeSettingsListener {
fun typeChanged(oldValue: PasswordSafeSettings.ProviderType, newValue: PasswordSafeSettings.ProviderType)
}
@@ -112,6 +112,8 @@ class PasswordSafeImpl(/* public - backward compatibility */val settings: Passwo
finally {
(currentProvider as? FileCredentialStore)?.let { it.clear() }
}
ApplicationManager.getApplication().messageBus.syncPublisher(PasswordSafeSettings.TOPIC).credentialStoreCleared()
}
// public - backward compatibility
@@ -0,0 +1,11 @@
package com.intellij.credentialStore;
import org.jetbrains.annotations.NotNull;
public interface PasswordSafeSettingsListener {
default void typeChanged(@NotNull PasswordSafeSettings.ProviderType oldValue, @NotNull PasswordSafeSettings.ProviderType newValue) {
}
default void credentialStoreCleared() {
}
}
@@ -800,7 +800,7 @@ public class CommonCodeStyleSettings {
public int CALL_PARAMETERS_WRAP = DO_NOT_WRAP;
public boolean PREFER_PARAMETERS_WRAP = false;
public boolean CALL_PARAMETERS_LPAREN_ON_NEXT_LINE = false;
public boolean CALL_PARAMETERS_LPAREN_ON_NEXT_LINE = false; // misnamed, actually means: wrap AFTER lparen
public boolean CALL_PARAMETERS_RPAREN_ON_NEXT_LINE = false;
public int METHOD_PARAMETERS_WRAP = DO_NOT_WRAP;
@@ -81,6 +81,9 @@ public class FormattingModelDumper {
if (block instanceof ASTBlock) {
builder.append(((ASTBlock)block).getNode().getElementType());
}
else {
builder.append(block.getClass().getSimpleName());
}
dumpBlockProperties(block, builder);
builder.append(">\n");
}
@@ -73,8 +73,8 @@ public class FileChooserFactoryImpl extends FileChooserFactory {
private static boolean useNativeMacChooser(final FileChooserDescriptor descriptor) {
return SystemInfo.isMac &&
SystemProperties.getBooleanProperty("native.mac.file.chooser.enabled", true) &&
Registry.is("ide.mac.file.chooser.native") /*&&
!DialogWrapper.isMultipleModalDialogs()*/;
Registry.is("ide.mac.file.chooser.native") &&
SystemInfo.isJetbrainsJvm;
}
@NotNull
@@ -29,6 +29,7 @@ import com.intellij.util.ContentUtilEx;
import com.intellij.util.NotNullFunction;
import com.intellij.util.ui.EmptyIcon;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.WatermarkIcon;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -152,7 +153,8 @@ public class TabbedContentTabLabel extends ContentTabLabel {
if (nextTabWithName.getFirst().equals(ContentUtilEx.getTabNameWithoutPrefix(myContent, tabName))) {
JComponent tab = nextTabWithName.getSecond();
if (tab instanceof Iconable) {
jLabel.setIcon(((Iconable)tab).getIcon(Iconable.ICON_FLAG_VISIBILITY));
Icon baseIcon = ((Iconable)tab).getIcon(Iconable.ICON_FLAG_VISIBILITY);
jLabel.setIcon(isSelected() || baseIcon == null ? baseIcon : new WatermarkIcon(baseIcon, .5f));
}
}
}
@@ -102,8 +102,12 @@ public class MacPathChooserDialog implements PathChooserDialog, FileChooserDialo
@Override
public void choose(@Nullable VirtualFile toSelect, @NotNull Consumer<List<VirtualFile>> callback) {
String path = toSelect != null ? toSelect.getCanonicalPath() : null;
myFileDialog.setFile(path);
if (toSelect != null && toSelect.getParent() != null) {
myFileDialog.setDirectory(toSelect.getParent().getCanonicalPath());
myFileDialog.setFile(toSelect.getPath());
}
myFileDialog.setMultipleMode(myFileChooserDescriptor.isChooseMultiple());
final CommandProcessorEx commandProcessor =
ApplicationManager.getApplication() != null ? (CommandProcessorEx)CommandProcessor.getInstance() : null;
@@ -59,3 +59,5 @@ krasa.nonProjectFilesUnlocker 1.0 1.1
com.chrisrm.idea.MaterialThemeUI 0.2.0 0.1.9
com.hasintech.intellij.angularTemplates 1.0.2 1.1.2
com.jetbrains.plugins.jade 144.2931 142.4651 141.506 140.2144 140.1212 140.216 138.1744 133.74 130.1520 121.390 122.668 121.185
com.jetbrains.ec2manager 1.0.5 1.0.4 1.0.3 1.0.2 1.0.1 1.0 0.3.4 0.3.4 0.3.2 0.3.1 0.3.0 0.2.0 0.1.2 0.1.1 0.1.0
AAHack 0.1
@@ -118,6 +118,10 @@ public abstract class FileAnnotation {
return getRevisions();
}
public VcsFileRevision getRevisionByDescription(VcsRevisionDescription description) {
return (VcsFileRevision)description;
}
public abstract boolean revisionsNotEmpty();
@Nullable
@@ -3,7 +3,7 @@ package com.intellij.openapi.vcs.actions;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.vcs.AbstractVcs;
import com.intellij.openapi.vcs.annotate.FileAnnotation;
import com.intellij.openapi.vcs.history.VcsFileRevision;
import com.intellij.openapi.vcs.history.VcsRevisionDescription;
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
import com.intellij.util.containers.HashMap;
import org.jetbrains.annotations.NotNull;
@@ -14,19 +14,19 @@ import java.util.List;
import java.util.Map;
class AnnotateCurrentRevisionAction extends AnnotateRevisionAction {
@Nullable private final List<VcsFileRevision> myRevisions;
@Nullable private final List<VcsRevisionDescription> myRevisions;
public AnnotateCurrentRevisionAction(@NotNull FileAnnotation annotation, @NotNull AbstractVcs vcs) {
super("Annotate Revision", "Annotate selected revision in new tab", AllIcons.Actions.Annotate,
annotation, vcs);
List<VcsFileRevision> revisions = annotation.getRevisions();
List<? extends VcsRevisionDescription> revisions = annotation.getRevisionDescriptions();
if (revisions == null) {
myRevisions = null;
return;
}
Map<VcsRevisionNumber, VcsFileRevision> map = new HashMap<>();
for (VcsFileRevision revision : revisions) {
Map<VcsRevisionNumber, VcsRevisionDescription> map = new HashMap<>();
for (VcsRevisionDescription revision : revisions) {
map.put(revision.getRevisionNumber(), revision);
}
@@ -38,7 +38,7 @@ class AnnotateCurrentRevisionAction extends AnnotateRevisionAction {
@Override
@Nullable
public List<VcsFileRevision> getRevisions() {
public List<VcsRevisionDescription> getRevisions() {
return myRevisions;
}
}
@@ -6,6 +6,7 @@ import com.intellij.openapi.localVcs.UpToDateLineNumberProvider;
import com.intellij.openapi.vcs.AbstractVcs;
import com.intellij.openapi.vcs.annotate.FileAnnotation;
import com.intellij.openapi.vcs.history.VcsFileRevision;
import com.intellij.openapi.vcs.history.VcsRevisionDescription;
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.HashMap;
@@ -17,23 +18,23 @@ import java.util.List;
import java.util.Map;
class AnnotatePreviousRevisionAction extends AnnotateRevisionAction {
@Nullable private final List<VcsFileRevision> myRevisions;
@Nullable private final VcsFileRevision myLastRevision;
@Nullable private final List<VcsRevisionDescription> myRevisions;
@Nullable private final VcsRevisionDescription myLastRevision;
public AnnotatePreviousRevisionAction(@NotNull FileAnnotation annotation, @NotNull AbstractVcs vcs) {
super("Annotate Previous Revision", "Annotate successor of selected revision in new tab", AllIcons.Actions.Annotate,
annotation, vcs);
List<VcsFileRevision> revisions = annotation.getRevisions();
List<? extends VcsRevisionDescription> revisions = annotation.getRevisionDescriptions();
if (revisions == null) {
myRevisions = null;
myLastRevision = null;
return;
}
Map<VcsRevisionNumber, VcsFileRevision> map = new HashMap<>();
Map<VcsRevisionNumber, VcsRevisionDescription> map = new HashMap<>();
for (int i = 0; i < revisions.size(); i++) {
VcsFileRevision revision = revisions.get(i);
VcsFileRevision previousRevision = i + 1 < revisions.size() ? revisions.get(i + 1) : null;
VcsRevisionDescription revision = revisions.get(i);
VcsRevisionDescription previousRevision = i + 1 < revisions.size() ? revisions.get(i + 1) : null;
map.put(revision.getRevisionNumber(), previousRevision);
}
@@ -47,7 +48,7 @@ class AnnotatePreviousRevisionAction extends AnnotateRevisionAction {
@Override
@Nullable
public List<VcsFileRevision> getRevisions() {
public List<VcsRevisionDescription> getRevisions() {
return myRevisions;
}
@@ -55,7 +56,7 @@ class AnnotatePreviousRevisionAction extends AnnotateRevisionAction {
@Override
protected VcsFileRevision getFileRevision(@NotNull AnActionEvent e) {
if (getCurrentLine() == UpToDateLineNumberProvider.ABSENT_LINE_NUMBER) {
return myLastRevision;
return myAnnotation.getRevisionByDescription(myLastRevision);
}
return super.getFileRevision(e);
}
@@ -13,6 +13,7 @@ import com.intellij.openapi.vcs.annotate.FileAnnotation;
import com.intellij.openapi.vcs.annotate.UpToDateLineNumberListener;
import com.intellij.openapi.vcs.history.VcsFileRevision;
import com.intellij.openapi.vcs.history.VcsFileRevisionEx;
import com.intellij.openapi.vcs.history.VcsRevisionDescription;
import com.intellij.openapi.vcs.vfs.VcsFileSystem;
import com.intellij.openapi.vcs.vfs.VcsVirtualFile;
import com.intellij.openapi.vfs.VirtualFile;
@@ -24,7 +25,7 @@ import javax.swing.*;
import java.util.List;
abstract class AnnotateRevisionAction extends AnnotateRevisionActionBase implements DumbAware, UpToDateLineNumberListener {
@NotNull private final FileAnnotation myAnnotation;
@NotNull protected final FileAnnotation myAnnotation;
@NotNull private final AbstractVcs myVcs;
private int currentLine;
@@ -48,17 +49,13 @@ abstract class AnnotateRevisionAction extends AnnotateRevisionActionBase impleme
return;
}
if (getRevisions() == null) {
e.getPresentation().setEnabledAndVisible(false);
return;
}
e.getPresentation().setVisible(true);
super.update(e);
}
@Nullable
protected abstract List<VcsFileRevision> getRevisions();
protected abstract List<VcsRevisionDescription> getRevisions();
@Nullable
protected AbstractVcs getVcs(@NotNull AnActionEvent e) {
@@ -89,7 +86,14 @@ abstract class AnnotateRevisionAction extends AnnotateRevisionActionBase impleme
@Nullable
@Override
protected VcsFileRevision getFileRevision(@NotNull AnActionEvent e) {
List<VcsFileRevision> revisions = getRevisions();
VcsRevisionDescription description = getRevisionDescription(e);
return description == null ? null : myAnnotation.getRevisionByDescription(description);
}
@Nullable
@Override
protected VcsRevisionDescription getRevisionDescription(@NotNull AnActionEvent e) {
List<VcsRevisionDescription> revisions = getRevisions();
assert revisions != null;
if (currentLine < 0 || currentLine >= revisions.size()) return null;
@@ -18,6 +18,7 @@ import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.annotate.AnnotationProvider;
import com.intellij.openapi.vcs.annotate.FileAnnotation;
import com.intellij.openapi.vcs.history.VcsFileRevision;
import com.intellij.openapi.vcs.history.VcsRevisionDescription;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.diff.Diff;
import com.intellij.util.diff.FilesTooBigForDiffException;
@@ -43,6 +44,11 @@ public abstract class AnnotateRevisionActionBase extends AnAction {
@Nullable
protected abstract VcsFileRevision getFileRevision(@NotNull AnActionEvent e);
@Nullable
protected VcsRevisionDescription getRevisionDescription(@NotNull AnActionEvent e) {
return getFileRevision(e);
};
@Nullable
protected Editor getEditor(@NotNull AnActionEvent e) {
return null;
@@ -60,19 +66,14 @@ public abstract class AnnotateRevisionActionBase extends AnAction {
public boolean isEnabled(@NotNull AnActionEvent e) {
if (e.getProject() == null) return false;
VcsFileRevision fileRevision = getFileRevision(e);
VcsRevisionDescription fileRevision = getRevisionDescription(e);
if (fileRevision == null) return false;
VirtualFile file = getFile(e);
if (file == null) return false;
AbstractVcs vcs = getVcs(e);
if (vcs == null) return false;
AnnotationProvider provider = vcs.getCachingAnnotationProvider();
if (provider == null || !provider.isAnnotationValid(fileRevision)) return false;
if (VcsAnnotateUtil.getBackgroundableLock(vcs.getProject(), file).isLocked()) return false;
if (provider == null || (fileRevision instanceof VcsFileRevision) && !provider.isAnnotationValid((VcsFileRevision)fileRevision)) return false;
return true;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* Copyright 2000-2016 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.
@@ -54,7 +54,7 @@ public abstract class XDebugView implements Disposable {
protected abstract void clear();
public abstract void processSessionEvent(@NotNull SessionEvent event);
public abstract void processSessionEvent(@NotNull SessionEvent event, @NotNull XDebugSession session);
@Nullable
protected static XDebugSession getSession(@NotNull EventObject e) {
@@ -15,7 +15,7 @@
*/
package com.intellij.xdebugger.impl.frame;
import com.intellij.ui.AppUIUtil;
import com.intellij.xdebugger.XDebugSession;
import com.intellij.xdebugger.XDebugSessionListener;
import org.jetbrains.annotations.NotNull;
@@ -24,13 +24,15 @@ import org.jetbrains.annotations.NotNull;
*/
public class XDebugViewSessionListener implements XDebugSessionListener {
private final XDebugView myDebugView;
private final XDebugSession mySession;
public XDebugViewSessionListener(@NotNull XDebugView debugView) {
public XDebugViewSessionListener(@NotNull XDebugView debugView, @NotNull XDebugSession session) {
myDebugView = debugView;
mySession = session;
}
private void onSessionEvent(final @NotNull XDebugView.SessionEvent event) {
AppUIUtil.invokeOnEdt(() -> myDebugView.processSessionEvent(event));
private void onSessionEvent(@NotNull XDebugView.SessionEvent event) {
myDebugView.processSessionEvent(event, mySession);
}
@Override
@@ -35,6 +35,7 @@ import com.intellij.xdebugger.frame.XExecutionStack;
import com.intellij.xdebugger.frame.XStackFrame;
import com.intellij.xdebugger.frame.XSuspendContext;
import com.intellij.xdebugger.impl.actions.XDebuggerActions;
import com.intellij.xdebugger.impl.ui.DebuggerUIUtil;
import gnu.trove.TObjectIntHashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -200,64 +201,66 @@ public class XFramesView extends XDebugView {
}
@Override
public void processSessionEvent(@NotNull final SessionEvent event) {
public void processSessionEvent(@NotNull SessionEvent event, @NotNull XDebugSession session) {
myRefresh = event == SessionEvent.SETTINGS_CHANGED;
if (event == SessionEvent.BEFORE_RESUME) {
return;
}
XDebugSession session = getSession(getMainPanel());
XStackFrame currentStackFrame = session.getCurrentStackFrame();
XSuspendContext suspendContext = session.getSuspendContext();
if (event == SessionEvent.FRAME_CHANGED) {
XStackFrame currentStackFrame = session == null ? null : session.getCurrentStackFrame();
if (currentStackFrame != null) {
myFramesList.setSelectedValue(currentStackFrame, true);
mySelectedFrameIndex = myFramesList.getSelectedIndex();
myExecutionStacksWithSelection.put(mySelectedStack, mySelectedFrameIndex);
DebuggerUIUtil.invokeLater(() -> {
if (event == SessionEvent.FRAME_CHANGED) {
if (currentStackFrame != null) {
myFramesList.setSelectedValue(currentStackFrame, true);
mySelectedFrameIndex = myFramesList.getSelectedIndex();
myExecutionStacksWithSelection.put(mySelectedStack, mySelectedFrameIndex);
}
return;
}
return;
}
if (event != SessionEvent.SETTINGS_CHANGED) {
mySelectedFrameIndex = 0;
mySelectedStack = null;
myVisibleRect = null;
}
else {
myVisibleRect = myFramesList.getVisibleRect();
}
if (event != SessionEvent.SETTINGS_CHANGED) {
mySelectedFrameIndex = 0;
mySelectedStack = null;
myVisibleRect = null;
}
else {
myVisibleRect = myFramesList.getVisibleRect();
}
myListenersEnabled = false;
for (StackFramesListBuilder builder : myBuilders.values()) {
builder.dispose();
}
myBuilders.clear();
XSuspendContext suspendContext = session == null ? null : session.getSuspendContext();
if (suspendContext == null) {
requestClear();
return;
}
myListenersEnabled = false;
for (StackFramesListBuilder builder : myBuilders.values()) {
builder.dispose();
}
myBuilders.clear();
if (event == SessionEvent.PAUSED) {
// clear immediately
cancelClear();
clear();
}
if (suspendContext == null) {
requestClear();
return;
}
XExecutionStack[] executionStacks = suspendContext.getExecutionStacks();
addExecutionStacks(Arrays.asList(executionStacks));
if (event == SessionEvent.PAUSED) {
// clear immediately
cancelClear();
clear();
}
XExecutionStack activeExecutionStack = mySelectedStack != null ? mySelectedStack : suspendContext.getActiveExecutionStack();
myThreadComboBox.setSelectedItem(activeExecutionStack);
myThreadsPanel.removeAll();
myThreadsPanel.add(myToolbar.getComponent(), BorderLayout.EAST);
final boolean invisible = executionStacks.length == 1 && StringUtil.isEmpty(executionStacks[0].getDisplayName());
if (!invisible) {
myThreadsPanel.add(myThreadComboBox, BorderLayout.CENTER);
}
myToolbar.setAddSeparatorFirst(!invisible);
updateFrames(activeExecutionStack, session);
XExecutionStack[] executionStacks = suspendContext.getExecutionStacks();
addExecutionStacks(Arrays.asList(executionStacks));
XExecutionStack activeExecutionStack = mySelectedStack != null ? mySelectedStack : suspendContext.getActiveExecutionStack();
myThreadComboBox.setSelectedItem(activeExecutionStack);
myThreadsPanel.removeAll();
myThreadsPanel.add(myToolbar.getComponent(), BorderLayout.EAST);
final boolean invisible = executionStacks.length == 1 && StringUtil.isEmpty(executionStacks[0].getDisplayName());
if (!invisible) {
myThreadsPanel.add(myThreadComboBox, BorderLayout.CENTER);
}
myToolbar.setAddSeparatorFirst(!invisible);
updateFrames(activeExecutionStack, session);
});
}
@Override
@@ -17,6 +17,7 @@ package com.intellij.xdebugger.impl.frame;
import com.intellij.openapi.project.Project;
import com.intellij.ui.AppUIUtil;
import com.intellij.xdebugger.XDebugSession;
import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
import com.intellij.xdebugger.frame.XStackFrame;
import org.jetbrains.annotations.NotNull;
@@ -41,6 +42,6 @@ public class XStandaloneVariablesView extends XVariablesViewBase {
}
@Override
public void processSessionEvent(@NotNull SessionEvent event) {
public void processSessionEvent(@NotNull SessionEvent event, @NotNull XDebugSession session) {
}
}
@@ -18,6 +18,7 @@ package com.intellij.xdebugger.impl.frame;
import com.intellij.ide.DataManager;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataProvider;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
@@ -30,6 +31,7 @@ import com.intellij.xdebugger.XDebugSession;
import com.intellij.xdebugger.XSourcePosition;
import com.intellij.xdebugger.frame.XStackFrame;
import com.intellij.xdebugger.impl.XDebugSessionImpl;
import com.intellij.xdebugger.impl.ui.DebuggerUIUtil;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueContainerNode;
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
@@ -65,26 +67,31 @@ public class XVariablesView extends XVariablesViewBase implements DataProvider {
}
@Override
public void processSessionEvent(@NotNull final SessionEvent event) {
XDebugSession session = getSession(getPanel());
XStackFrame stackFrame = session == null ? null : session.getCurrentStackFrame();
XDebuggerTree tree = getTree();
public void processSessionEvent(@NotNull SessionEvent event, @NotNull XDebugSession session) {
if (ApplicationManager.getApplication().isDispatchThread()) { // mark nodes obsolete asap
getTree().markNodesObsolete();
}
if (event == SessionEvent.BEFORE_RESUME || event == SessionEvent.SETTINGS_CHANGED) {
saveCurrentTreeState(stackFrame);
if (event == SessionEvent.BEFORE_RESUME) {
return;
XStackFrame stackFrame = session.getCurrentStackFrame();
DebuggerUIUtil.invokeLater(() -> {
XDebuggerTree tree = getTree();
if (event == SessionEvent.BEFORE_RESUME || event == SessionEvent.SETTINGS_CHANGED) {
saveCurrentTreeState(stackFrame);
if (event == SessionEvent.BEFORE_RESUME) {
return;
}
}
}
tree.markNodesObsolete();
if (stackFrame != null) {
cancelClear();
buildTreeAndRestoreState(stackFrame);
}
else {
requestClear();
}
tree.markNodesObsolete();
if (stackFrame != null) {
cancelClear();
buildTreeAndRestoreState(stackFrame);
}
else {
requestClear();
}
});
}
@Override
@@ -66,8 +66,8 @@ public abstract class XVariablesViewBase extends XDebugView {
protected XVariablesViewBase(@NotNull Project project, @NotNull XDebuggerEditorsProvider editorsProvider, @Nullable XValueMarkers<?, ?> markers) {
myTreePanel = new XDebuggerTreePanel(
project, editorsProvider, this, null, this instanceof XWatchesView ? XDebuggerActions.WATCHES_TREE_POPUP_GROUP : XDebuggerActions.VARIABLES_TREE_POPUP_GROUP, markers);
myTreePanel.getTree().getEmptyText().setText(XDebuggerBundle.message("debugger.variables.not.available"));
DnDManager.getInstance().registerSource(myTreePanel, myTreePanel.getTree());
getTree().getEmptyText().setText(XDebuggerBundle.message("debugger.variables.not.available"));
DnDManager.getInstance().registerSource(myTreePanel, getTree());
}
protected void buildTreeAndRestoreState(@NotNull final XStackFrame stackFrame) {
@@ -115,10 +115,12 @@ public abstract class XVariablesViewBase extends XDebugView {
}
protected void saveCurrentTreeState(@Nullable XStackFrame stackFrame) {
disposeTreeRestorer();
removeSelectionListener();
myFrameEqualityObject = stackFrame != null ? stackFrame.getEqualityObject() : null;
myTreeState = XDebuggerTreeState.saveState(myTreePanel.getTree());
if (myTreeRestorer == null || myTreeRestorer.isFinished()) {
myTreeState = XDebuggerTreeState.saveState(getTree());
}
disposeTreeRestorer();
}
private void removeSelectionListener() {
@@ -140,7 +142,8 @@ public abstract class XVariablesViewBase extends XDebugView {
}
}
public XDebuggerTree getTree() {
@NotNull
public final XDebuggerTree getTree() {
return myTreePanel.getTree();
}
@@ -152,7 +155,7 @@ public abstract class XVariablesViewBase extends XDebugView {
public void dispose() {
disposeTreeRestorer();
removeSelectionListener();
DnDManager.getInstance().unregisterSource(myTreePanel, myTreePanel.getTree());
DnDManager.getInstance().unregisterSource(myTreePanel, getTree());
}
private class MySelectionListener implements SelectionListener {
@@ -229,7 +229,7 @@ public class XDebugSessionTab extends DebuggerSessionTabBase {
public void rebuildViews() {
AppUIUtil.invokeLaterIfProjectAlive(myProject, () -> {
for (XDebugView view : myViews.values()) {
view.processSessionEvent(XDebugView.SessionEvent.SETTINGS_CHANGED);
view.processSessionEvent(XDebugView.SessionEvent.SETTINGS_CHANGED, mySession);
}
});
}
@@ -302,7 +302,7 @@ public class XDebugSessionTab extends DebuggerSessionTabBase {
private static void attachViewToSession(@NotNull XDebugSessionImpl session, @Nullable XDebugView view) {
if (view != null) {
session.addSessionListener(new XDebugViewSessionListener(view), view);
session.addSessionListener(new XDebugViewSessionListener(view, session), view);
}
}
@@ -385,9 +385,6 @@ public class XDebuggerTree extends DnDAwareTree implements DataProvider, Disposa
removeTreeListener(this); // remove the listener on first match
}
}
@Override
public void childrenLoaded(@NotNull XDebuggerTreeNode node, @NotNull List<XValueContainerNode<?>> children, boolean last) {}
});
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2016 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.
@@ -26,7 +26,9 @@ import java.util.List;
* @author nik
*/
public interface XDebuggerTreeListener {
void nodeLoaded(@NotNull RestorableStateNode node, final String name);
default void nodeLoaded(@NotNull RestorableStateNode node, final String name) {
}
void childrenLoaded(@NotNull XDebuggerTreeNode node, @NotNull List<XValueContainerNode<?>> children, final boolean last);
default void childrenLoaded(@NotNull XDebuggerTreeNode node, @NotNull List<XValueContainerNode<?>> children, final boolean last) {
}
}
@@ -44,6 +44,7 @@ public class XDebuggerTreeRestorer implements XDebuggerTreeListener, TreeSelecti
private boolean myStopRestoringSelection;
private boolean myInsideRestoring;
private TreePath mySelectionPath;
private boolean myFinished;
public XDebuggerTreeRestorer(final XDebuggerTree tree, Rectangle lastVisibleNodeRect) {
myTree = tree;
@@ -55,7 +56,7 @@ public class XDebuggerTreeRestorer implements XDebuggerTreeListener, TreeSelecti
}
private void restoreChildren(final XDebuggerTreeNode treeNode, final XDebuggerTreeState.NodeInfo nodeInfo) {
if (!treeNode.isLeaf() && nodeInfo.isExpanded()) {
if (nodeInfo.isExpanded()) {
myTree.expandPath(treeNode.getPath());
treeNode.getLoadedChildren().forEach(child -> restoreNode(child, nodeInfo));
myNode2State.put(treeNode, nodeInfo);
@@ -75,7 +76,7 @@ public class XDebuggerTreeRestorer implements XDebuggerTreeListener, TreeSelecti
if (treeNode instanceof RestorableStateNode) {
RestorableStateNode node = (RestorableStateNode)treeNode;
if (node.isComputed()) {
doRestoreNode(node, parentInfo.removeChild(node.getName()));
doRestoreNode(node, parentInfo.getChild(node));
}
else {
myNode2ParentState.put(node, parentInfo);
@@ -98,7 +99,9 @@ public class XDebuggerTreeRestorer implements XDebuggerTreeListener, TreeSelecti
}
}
restoreChildren((XDebuggerTreeNode)treeNode, nodeInfo);
if (!(treeNode.isComputed() && treeNode.isLeaf())) { // do not restore computed leafs children
restoreChildren((XDebuggerTreeNode)treeNode, nodeInfo);
}
}
else {
if (!checkExtendedModified(treeNode)) {
@@ -146,13 +149,14 @@ public class XDebuggerTreeRestorer implements XDebuggerTreeListener, TreeSelecti
public void nodeLoaded(@NotNull final RestorableStateNode node, final String name) {
XDebuggerTreeState.NodeInfo parentInfo = myNode2ParentState.remove(node);
if (parentInfo != null) {
doRestoreNode(node, parentInfo.removeChild(node.getName()));
doRestoreNode(node, parentInfo.getChild(node));
}
disposeIfFinished();
}
private void disposeIfFinished() {
if (myNode2ParentState.isEmpty() && myNode2State.isEmpty()) {
myFinished = true;
if (myLastVisibleNodeRect != null) {
myTree.scrollRectToVisible(myLastVisibleNodeRect);
}
@@ -181,6 +185,10 @@ public class XDebuggerTreeRestorer implements XDebuggerTreeListener, TreeSelecti
myTree.removeTreeSelectionListener(this);
}
public boolean isFinished() {
return myFinished;
}
@Override
public void valueChanged(TreeSelectionEvent e) {
if (!myInsideRestoring) {
@@ -18,10 +18,7 @@ package com.intellij.xdebugger.impl.ui.tree;
import com.intellij.ui.TreeSpeedSearch;
import com.intellij.util.ObjectUtils;
import com.intellij.util.containers.Convertor;
import com.intellij.xdebugger.impl.ui.tree.nodes.RestorableStateNode;
import com.intellij.xdebugger.impl.ui.tree.nodes.XDebuggerTreeNode;
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueContainerNode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.tree.TreeNode;
@@ -29,11 +26,9 @@ import javax.swing.tree.TreePath;
import java.util.LinkedList;
import java.util.List;
class XDebuggerTreeSpeedSearch extends TreeSpeedSearch implements XDebuggerTreeListener {
class XDebuggerTreeSpeedSearch extends TreeSpeedSearch {
public XDebuggerTreeSpeedSearch(XDebuggerTree tree, Convertor<TreePath, String> toStringConvertor) {
super(tree, toStringConvertor, true);
//((XDebuggerTree)myComponent).addTreeListener(this);
}
@Nullable
@@ -161,12 +156,4 @@ class XDebuggerTreeSpeedSearch extends TreeSpeedSearch implements XDebuggerTreeL
TreePath path = node instanceof XDebuggerTreeNode ? ((XDebuggerTreeNode)node).getPath() : null;
return isMatchingElement(path, string) ? path : null;
}
@Override
public void nodeLoaded(@NotNull RestorableStateNode node, String name) {
}
@Override
public void childrenLoaded(@NotNull XDebuggerTreeNode node, @NotNull List<XValueContainerNode<?>> children, boolean last) {
}
}
@@ -16,17 +16,19 @@
package com.intellij.xdebugger.impl.ui.tree;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.util.Comparing;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
import com.intellij.xdebugger.XNamedTreeNode;
import com.intellij.xdebugger.impl.ui.tree.nodes.RestorableStateNode;
import com.intellij.xdebugger.impl.ui.tree.nodes.XDebuggerTreeNode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import java.awt.*;
import java.util.Collection;
import java.util.List;
/**
@@ -126,16 +128,30 @@ public class XDebuggerTreeState {
}
@Nullable
public NodeInfo removeChild(String name) {
public NodeInfo getChild(XNamedTreeNode node) {
String name = node.getName();
if (myChildren == null) {
return null;
}
Collection<NodeInfo> infos = myChildren.get(name);
NodeInfo item = ContainerUtil.getFirstItem(infos);
if (item != null) {
infos.remove(item);
List<NodeInfo> infos = (List<NodeInfo>)myChildren.get(name);
if (infos.size() > 1) {
TreeNode parent = node.getParent();
if (parent instanceof XDebuggerTreeNode) {
int idx = 0;
for (XDebuggerTreeNode treeNode : ((XDebuggerTreeNode)parent).getLoadedChildren()) {
if (treeNode == node) {
break;
}
if (treeNode instanceof XNamedTreeNode && Comparing.equal(((XNamedTreeNode)treeNode).getName(), name)) {
idx++;
}
}
if (idx < infos.size()) {
return infos.get(idx);
}
}
}
return item;
return ContainerUtil.getFirstItem(infos);
}
}
}
@@ -54,6 +54,7 @@ public class GitAnnotationProvider implements AnnotationProviderEx, VcsCacheable
private final Project myProject;
@NonNls private static final String AUTHOR_KEY = "author";
@NonNls private static final String COMMITTER_TIME_KEY = "committer-time";
@NonNls private static final String FILENAME_KEY = "filename";
private static final Logger LOG = Logger.getInstance(GitAnnotationProvider.class);
public GitAnnotationProvider(@NotNull Project project) {
@@ -114,9 +115,6 @@ public class GitAnnotationProvider implements AnnotationProviderEx, VcsCacheable
@NotNull
@Override
public FileAnnotation annotate(@NotNull final FilePath path, @NotNull final VcsRevisionNumber revision) throws VcsException {
setProgressIndicatorText(GitBundle.message("getting.history", path.getName()));
List<VcsFileRevision> revisions = GitHistoryUtils.history(myProject, path, null, revision);
GitFileRevision fileRevision = new GitFileRevision(myProject, path, (GitRevisionNumber)revision);
VcsVirtualFile file = new VcsVirtualFile(path.getPath(), fileRevision, VcsFileSystem.getInstance());
@@ -132,7 +130,8 @@ public class GitAnnotationProvider implements AnnotationProviderEx, VcsCacheable
private GitFileAnnotation annotate(@NotNull final FilePath repositoryFilePath,
@Nullable final VcsRevisionNumber revision,
@NotNull final VirtualFile file) throws VcsException {
GitSimpleHandler h = new GitSimpleHandler(myProject, GitUtil.getGitRoot(repositoryFilePath), GitCommand.BLAME);
VirtualFile root = GitUtil.getGitRoot(repositoryFilePath);
GitSimpleHandler h = new GitSimpleHandler(myProject, root, GitCommand.BLAME);
h.setStdoutSuppressed(true);
h.setCharset(file.getCharset());
h.addParameters("--porcelain", "-l", "-t", "-w");
@@ -145,13 +144,13 @@ public class GitAnnotationProvider implements AnnotationProviderEx, VcsCacheable
h.endOptions();
h.addRelativePaths(repositoryFilePath);
String output = h.run();
return parseAnnotations(revision, file, output);
return parseAnnotations(revision, file, output, root);
}
@NotNull
private GitFileAnnotation parseAnnotations(@Nullable VcsRevisionNumber revision,
@NotNull VirtualFile file,
@NotNull String output) throws VcsException {
@NotNull String output, VirtualFile root) throws VcsException {
try {
List<LineInfo> lines = new ArrayList<>();
HashMap<String, LineInfo> commits = new HashMap<>();
@@ -176,6 +175,7 @@ public class GitAnnotationProvider implements AnnotationProviderEx, VcsCacheable
GitRevisionNumber revisionNumber = null;
Date committerDate = null;
String author = null;
String path = null;
while (s.hasMoreData() && !s.startsWith('\t')) {
String key = s.spaceToken();
@@ -187,8 +187,11 @@ public class GitAnnotationProvider implements AnnotationProviderEx, VcsCacheable
committerDate = GitUtil.parseTimestamp(value);
revisionNumber = new GitRevisionNumber(commitHash, committerDate);
}
if (FILENAME_KEY.equals(key)) {
path = value;
}
}
commit = new LineInfo(committerDate, revisionNumber, author);
commit = new LineInfo(committerDate, revisionNumber, author, root.getPath() + "/" + path);
commits.put(commitHash, commit);
}
// parse line
@@ -245,7 +248,7 @@ public class GitAnnotationProvider implements AnnotationProviderEx, VcsCacheable
if (vcsFileRevision == null) {
return null;
}
lines.add(new LineInfo(vcsFileRevision.getRevisionDate(), revision, vcsFileRevision.getAuthor()));
lines.add(new LineInfo(vcsFileRevision.getRevisionDate(), revision, vcsFileRevision.getAuthor(), ((LineInfo)vcsFileRevision).getPath()));
}
return new GitFileAnnotation(myProject, virtualFile, revisionNumber, lines);
}
@@ -18,8 +18,10 @@ package git4idea.annotate;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.VcsKey;
import com.intellij.openapi.vcs.actions.VcsContextFactory;
import com.intellij.openapi.vcs.annotate.*;
import com.intellij.openapi.vcs.changes.ContentRevision;
import com.intellij.openapi.vcs.history.VcsFileRevision;
@@ -167,6 +169,13 @@ public class GitFileAnnotation extends FileAnnotation {
return myRevisions;
}
@Override
public VcsFileRevision getRevisionByDescription(VcsRevisionDescription description) {
LineInfo lineInfo = (LineInfo)description;
FilePath path = VcsContextFactory.SERVICE.getInstance().createFilePath(lineInfo.getPath(), false);
return new GitFileRevision(myProject, path, (GitRevisionNumber)description.getRevisionNumber());
}
@Override
public boolean revisionsNotEmpty() {
return !myRevisions.isEmpty();
@@ -250,11 +259,13 @@ public class GitFileAnnotation extends FileAnnotation {
private final Date myDate;
private final GitRevisionNumber myRevision;
private final String myAuthor;
private final String myPath;
public LineInfo(Date date, GitRevisionNumber revision, String author) {
public LineInfo(Date date, GitRevisionNumber revision, String author, String path) {
myDate = date;
myRevision = revision;
myAuthor = author;
myPath = path;
}
public Date getRevisionDate() {
@@ -274,6 +285,10 @@ public class GitFileAnnotation extends FileAnnotation {
public String getCommitMessage() {
return null;
}
public String getPath() {
return myPath;
}
}
@NotNull
@@ -85,9 +85,9 @@ public class IDEARemoteTestNG extends TestNG {
private void attachListeners(IDEATestNGRemoteListener listener) {
addListener((Object)new IDEATestNGSuiteListener(listener));
addListener((Object)new IDEATestNGTestListener(listener));
final IDEATestNGConfigurationListener configurationListener = new IDEATestNGConfigurationListener(listener);
addListener((Object)configurationListener);
try {
final IDEATestNGConfigurationListener configurationListener = new IDEATestNGConfigurationListener(listener);
addListener((Object)configurationListener);
addListener((Object)new IDEATestNGInvokedMethodListener(listener));
configurationListener.setIgnoreStarted();
}