From 67c889af812bc7eb10f172a63ec70eded69587e3 Mon Sep 17 00:00:00 2001
From: Roman Shevchenko
Date: Wed, 3 Sep 2014 12:52:55 +0400
Subject: [PATCH 01/60] java-decompiler: hide synthetic field assignment
---
.../java/decompiler/main/EnumProcessor.java | 85 +++++--------------
.../decompiler/exps/AssignmentExprent.java | 22 +++--
.../java/decompiler/SingleClassesTest.java | 2 +-
3 files changed, 38 insertions(+), 71 deletions(-)
diff --git a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/EnumProcessor.java b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/EnumProcessor.java
index fcdeaf164520..d6ae2b956ad6 100644
--- a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/EnumProcessor.java
+++ b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/EnumProcessor.java
@@ -15,97 +15,58 @@
*/
package org.jetbrains.java.decompiler.main;
-import org.jetbrains.java.decompiler.code.CodeConstants;
-import org.jetbrains.java.decompiler.main.ClassesProcessor.ClassNode;
import org.jetbrains.java.decompiler.main.rels.ClassWrapper;
import org.jetbrains.java.decompiler.main.rels.MethodWrapper;
import org.jetbrains.java.decompiler.modules.decompiler.exps.Exprent;
import org.jetbrains.java.decompiler.modules.decompiler.exps.InvocationExprent;
-import org.jetbrains.java.decompiler.modules.decompiler.exps.NewExprent;
import org.jetbrains.java.decompiler.modules.decompiler.exps.VarExprent;
import org.jetbrains.java.decompiler.modules.decompiler.stats.Statement;
import org.jetbrains.java.decompiler.modules.decompiler.vars.VarVersionPaar;
import org.jetbrains.java.decompiler.struct.StructClass;
import org.jetbrains.java.decompiler.struct.StructField;
import org.jetbrains.java.decompiler.struct.StructMethod;
-import org.jetbrains.java.decompiler.struct.gen.FieldDescriptor;
-import org.jetbrains.java.decompiler.struct.gen.VarType;
import org.jetbrains.java.decompiler.util.InterpreterUtil;
public class EnumProcessor {
public static void clearEnum(ClassWrapper wrapper) {
-
StructClass cl = wrapper.getClassStruct();
- // hide values() and valueOf()
- for (StructMethod meth : cl.getMethods()) {
-
- String name = meth.getName();
- int flag = 0;
+ // hide values/valueOf methods and super() invocations
+ for (MethodWrapper method : wrapper.getMethods()) {
+ StructMethod mt = method.methodStruct;
+ String name = mt.getName();
+ String descriptor = mt.getDescriptor();
if ("values".equals(name)) {
- flag = 1;
+ if (descriptor.equals("()[L" + cl.qualifiedName + ";")) {
+ wrapper.getHideMembers().add(InterpreterUtil.makeUniqueKey(name, descriptor));
+ }
}
else if ("valueOf".equals(name)) {
- flag = 2;
- }
-
- if (flag > 0) {
- String[] arr = meth.getDescriptor().split("[()]");
- String par = arr[1];
-
- if ((flag == 1 && par.length() == 0) ||
- flag == 2 && "Ljava/lang/String;".equals(par)) {
- wrapper.getHideMembers().add(InterpreterUtil.makeUniqueKey(name, meth.getDescriptor()));
+ if (descriptor.equals("(Ljava/lang/String;)L" + cl.qualifiedName + ";")) {
+ wrapper.getHideMembers().add(InterpreterUtil.makeUniqueKey(name, descriptor));
}
}
- }
-
- // hide all super invocations
- for (MethodWrapper meth : wrapper.getMethods()) {
- if ("".equals(meth.methodStruct.getName())) {
- Statement firstdata = findFirstData(meth.root);
- if (firstdata == null || firstdata.getExprents().isEmpty()) {
- return;
- }
-
- Exprent exprent = firstdata.getExprents().get(0);
- if (exprent.type == Exprent.EXPRENT_INVOCATION) {
- InvocationExprent invexpr = (InvocationExprent)exprent;
- if (isInvocationSuperConstructor(invexpr, meth, wrapper)) {
- firstdata.getExprents().remove(0);
+ else if ("".equals(name)) {
+ Statement firstData = findFirstData(method.root);
+ if (firstData != null && !firstData.getExprents().isEmpty()) {
+ Exprent exprent = firstData.getExprents().get(0);
+ if (exprent.type == Exprent.EXPRENT_INVOCATION) {
+ InvocationExprent invexpr = (InvocationExprent)exprent;
+ if (isInvocationSuperConstructor(invexpr, method, wrapper)) {
+ firstData.getExprents().remove(0);
+ }
}
}
}
}
- // hide dummy synthetic fields of enum constants
+ // hide synthetic fields of enum and it's constants
for (StructField fd : cl.getFields()) {
- if (fd.hasModifier(CodeConstants.ACC_ENUM)) {
- Exprent initializer =
- wrapper.getStaticFieldInitializers().getWithKey(InterpreterUtil.makeUniqueKey(fd.getName(), fd.getDescriptor()));
- if (initializer != null && initializer.type == Exprent.EXPRENT_NEW) {
- NewExprent nexpr = (NewExprent)initializer;
- if (nexpr.isAnonymous()) {
- ClassNode child = DecompilerContext.getClassProcessor().getMapRootClasses().get(nexpr.getNewtype().value);
- hideDummyFieldInConstant(child.wrapper);
- }
- }
- }
- }
- }
-
- private static void hideDummyFieldInConstant(ClassWrapper wrapper) {
- StructClass cl = wrapper.getClassStruct();
- for (StructField fd : cl.getFields()) {
- if (fd.isSynthetic()) {
- FieldDescriptor descr = FieldDescriptor.parseDescriptor(fd.getDescriptor());
- VarType ret = descr.type;
-
- if (ret.type == CodeConstants.TYPE_OBJECT && ret.arraydim == 1 && cl.qualifiedName.equals(ret.value)) {
- wrapper.getHideMembers().add(InterpreterUtil.makeUniqueKey(fd.getName(), fd.getDescriptor()));
- }
+ String descriptor = fd.getDescriptor();
+ if (fd.isSynthetic() && descriptor.equals("[L" + cl.qualifiedName + ";")) {
+ wrapper.getHideMembers().add(InterpreterUtil.makeUniqueKey(fd.getName(), descriptor));
}
}
}
diff --git a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AssignmentExprent.java b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AssignmentExprent.java
index 6c6b1f3171f0..87906247072f 100644
--- a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AssignmentExprent.java
+++ b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AssignmentExprent.java
@@ -20,7 +20,6 @@ import org.jetbrains.java.decompiler.main.ClassesProcessor.ClassNode;
import org.jetbrains.java.decompiler.main.DecompilerContext;
import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor;
import org.jetbrains.java.decompiler.modules.decompiler.vars.CheckTypesResult;
-import org.jetbrains.java.decompiler.struct.StructClass;
import org.jetbrains.java.decompiler.struct.StructField;
import org.jetbrains.java.decompiler.struct.gen.VarType;
import org.jetbrains.java.decompiler.util.InterpreterUtil;
@@ -105,26 +104,33 @@ public class AssignmentExprent extends Exprent {
}
public String toJava(int indent) {
-
VarType leftType = left.getExprType();
VarType rightType = right.getExprType();
- boolean fieldInStatInit = false;
+ boolean fieldInClassInit = false, hiddenField = false;
if (left.type == Exprent.EXPRENT_FIELD) { // first assignment to a final field. Field name without "this" in front of it
FieldExprent field = (FieldExprent)left;
ClassNode node = ((ClassNode)DecompilerContext.getProperty(DecompilerContext.CURRENT_CLASS_NODE));
if (node != null) {
- StructClass cl = node.classStruct;
- StructField fd = cl.getField(field.getName(), field.getDescriptor().descriptorString);
- if (fd != null && field.isStatic() && fd.hasModifier(CodeConstants.ACC_FINAL)) {
- fieldInStatInit = true;
+ StructField fd = node.classStruct.getField(field.getName(), field.getDescriptor().descriptorString);
+ if (fd != null) {
+ if (field.isStatic() && fd.hasModifier(CodeConstants.ACC_FINAL)) {
+ fieldInClassInit = true;
+ }
+ if (node.wrapper.getHideMembers().contains(InterpreterUtil.makeUniqueKey(fd.getName(), fd.getDescriptor()))) {
+ hiddenField = true;
+ }
}
}
}
+ if (hiddenField) {
+ return "";
+ }
+
StringBuilder buffer = new StringBuilder();
- if (fieldInStatInit) {
+ if (fieldInClassInit) {
buffer.append(((FieldExprent)left).getName());
}
else {
diff --git a/plugins/java-decompiler/engine/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/plugins/java-decompiler/engine/test/org/jetbrains/java/decompiler/SingleClassesTest.java
index 02fb6123aa4c..f6146c972d8a 100644
--- a/plugins/java-decompiler/engine/test/org/jetbrains/java/decompiler/SingleClassesTest.java
+++ b/plugins/java-decompiler/engine/test/org/jetbrains/java/decompiler/SingleClassesTest.java
@@ -65,7 +65,7 @@ public class SingleClassesTest {
@Test public void testMethodParameters() { doTest("TestMethodParameters"); }
@Test public void testCodeConstructs() { doTest("TestCodeConstructs"); }
@Test public void testConstants() { doTest("TestConstants"); }
- //@Test public void testEnum() { doTest("TestEnum"); }
+ @Test public void testEnum() { doTest("TestEnum"); }
private void doTest(final String testName) {
try {
From 165fc2e974020beafd616b18471ef152275477d0 Mon Sep 17 00:00:00 2001
From: Roman Shevchenko
Date: Wed, 3 Sep 2014 13:00:51 +0400
Subject: [PATCH 02/60] java-decompiler: cleanups
- better signatures
- accurate suppression
- unused symbols
- typos
---
.../java/decompiler/main/AssertProcessor.java | 2 +-
.../main/ClassReference14Processor.java | 4 +-
.../java/decompiler/main/ClassWriter.java | 6 +-
.../decompiler/main/ClassesProcessor.java | 20 +++----
.../java/decompiler/main/EnumProcessor.java | 6 +-
.../java/decompiler/main/Fernflower.java | 55 +++++++------------
.../main/decompiler/ConsoleDecompiler.java | 4 +-
.../main/decompiler/IdeDecompiler.java | 2 +-
.../main/extern/IFernflowerPreferences.java | 5 +-
.../decompiler/main/rels/ClassWrapper.java | 19 ++++---
.../main/rels/NestedClassProcessor.java | 4 +-
.../main/rels/NestedMemberAccess.java | 2 +-
.../decompiler/exps/AssignmentExprent.java | 2 +-
.../java/decompiler/util/InterpreterUtil.java | 23 +++-----
14 files changed, 68 insertions(+), 86 deletions(-)
diff --git a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/AssertProcessor.java b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/AssertProcessor.java
index da703fd98221..a58b68903563 100644
--- a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/AssertProcessor.java
+++ b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/AssertProcessor.java
@@ -60,7 +60,7 @@ public class AssertProcessor {
if (res) {
// hide the helper field
- wrapper.getHideMembers().add(key);
+ wrapper.getHiddenMembers().add(key);
}
}
}
diff --git a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/ClassReference14Processor.java b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/ClassReference14Processor.java
index 4552b1d309e0..3807d2e80a27 100644
--- a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/ClassReference14Processor.java
+++ b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/ClassReference14Processor.java
@@ -114,7 +114,7 @@ public class ClassReference14Processor {
if (!setFound.isEmpty()) {
for (ClassWrapper wrp : setFound) {
StructMethod mt = mapClassMeths.get(wrp).methodStruct;
- wrp.getHideMembers().add(InterpreterUtil.makeUniqueKey(mt.getName(), mt.getDescriptor()));
+ wrp.getHiddenMembers().add(InterpreterUtil.makeUniqueKey(mt.getName(), mt.getDescriptor()));
}
}
}
@@ -276,7 +276,7 @@ public class ClassReference14Processor {
invexpr.getStringDescriptor().equals(meth.methodStruct.getDescriptor())) {
if (invexpr.getLstParameters().get(0).type == Exprent.EXPRENT_CONST) {
- wrapper.getHideMembers()
+ wrapper.getHiddenMembers()
.add(InterpreterUtil.makeUniqueKey(fd.getName(), fd.getDescriptor())); // hide synthetic field
return ((ConstExprent)invexpr.getLstParameters().get(0)).getValue().toString();
}
diff --git a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/ClassWriter.java b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/ClassWriter.java
index c6dc7a415f64..ffc57d830dbd 100644
--- a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/ClassWriter.java
+++ b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/ClassWriter.java
@@ -239,7 +239,7 @@ public class ClassWriter {
if ((!isSynthetic || !DecompilerContext.getOption(IFernflowerPreferences.REMOVE_SYNTHETIC)) &&
(!isBridge || !DecompilerContext.getOption(IFernflowerPreferences.REMOVE_BRIDGE)) &&
- !wrapper.getHideMembers().contains(InterpreterUtil.makeUniqueKey(mt.getName(), mt.getDescriptor()))) {
+ !wrapper.getHiddenMembers().contains(InterpreterUtil.makeUniqueKey(mt.getName(), mt.getDescriptor()))) {
if (!mthidden && (!firstmt || node.type != ClassNode.CLASS_ANONYMOUS)) {
bufstrwriter.write(DecompilerContext.getNewLineSeparator());
firstmt = false;
@@ -260,7 +260,7 @@ public class ClassWriter {
// fields
for (StructField fd : cl.getFields()) {
boolean hide = fd.isSynthetic() && DecompilerContext.getOption(IFernflowerPreferences.REMOVE_SYNTHETIC) ||
- wrapper.getHideMembers().contains(InterpreterUtil.makeUniqueKey(fd.getName(), fd.getDescriptor()));
+ wrapper.getHiddenMembers().contains(InterpreterUtil.makeUniqueKey(fd.getName(), fd.getDescriptor()));
if (!hide) {
boolean isEnum = fd.hasModifier(CodeConstants.ACC_ENUM) && DecompilerContext.getOption(IFernflowerPreferences.DECOMPILE_ENUM);
if (isEnum) {
@@ -308,7 +308,7 @@ public class ClassWriter {
StructClass innerCl = inner.classStruct;
boolean isSynthetic = (inner.access & CodeConstants.ACC_SYNTHETIC) != 0 || innerCl.isSynthetic();
boolean hide = isSynthetic && DecompilerContext.getOption(IFernflowerPreferences.REMOVE_SYNTHETIC) ||
- wrapper.getHideMembers().contains(innerCl.qualifiedName);
+ wrapper.getHiddenMembers().contains(innerCl.qualifiedName);
if (!hide) {
writer.write(DecompilerContext.getNewLineSeparator());
classToJava(inner, writer, indent + 1);
diff --git a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java
index a16e4e0dc590..034efb180776 100644
--- a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java
+++ b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java
@@ -235,7 +235,7 @@ public class ClassesProcessor {
}
- public void writeClass(StructContext context, StructClass cl, BufferedWriter outwriter) throws IOException {
+ public void writeClass(StructClass cl, BufferedWriter writer) throws IOException {
ClassNode root = mapRootClasses.get(cl.qualifiedName);
if (root.type != ClassNode.CLASS_ROOT) {
@@ -270,20 +270,20 @@ public class ClassesProcessor {
int index = cl.qualifiedName.lastIndexOf("/");
if (index >= 0) {
String packageName = cl.qualifiedName.substring(0, index).replace('/', '.');
- outwriter.write("package ");
- outwriter.write(packageName);
- outwriter.write(";");
- outwriter.write(DecompilerContext.getNewLineSeparator());
- outwriter.write(DecompilerContext.getNewLineSeparator());
+ writer.write("package ");
+ writer.write(packageName);
+ writer.write(";");
+ writer.write(DecompilerContext.getNewLineSeparator());
+ writer.write(DecompilerContext.getNewLineSeparator());
}
DecompilerContext.setProperty(DecompilerContext.CURRENT_CLASS_NODE, root);
- DecompilerContext.getImportCollector().writeImports(outwriter);
- outwriter.write(DecompilerContext.getNewLineSeparator());
+ DecompilerContext.getImportCollector().writeImports(writer);
+ writer.write(DecompilerContext.getNewLineSeparator());
- outwriter.write(strwriter.toString());
- outwriter.flush();
+ writer.write(strwriter.toString());
+ writer.flush();
}
finally {
destroyWrappers(root);
diff --git a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/EnumProcessor.java b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/EnumProcessor.java
index d6ae2b956ad6..be408e8bbc3b 100644
--- a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/EnumProcessor.java
+++ b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/EnumProcessor.java
@@ -40,12 +40,12 @@ public class EnumProcessor {
if ("values".equals(name)) {
if (descriptor.equals("()[L" + cl.qualifiedName + ";")) {
- wrapper.getHideMembers().add(InterpreterUtil.makeUniqueKey(name, descriptor));
+ wrapper.getHiddenMembers().add(InterpreterUtil.makeUniqueKey(name, descriptor));
}
}
else if ("valueOf".equals(name)) {
if (descriptor.equals("(Ljava/lang/String;)L" + cl.qualifiedName + ";")) {
- wrapper.getHideMembers().add(InterpreterUtil.makeUniqueKey(name, descriptor));
+ wrapper.getHiddenMembers().add(InterpreterUtil.makeUniqueKey(name, descriptor));
}
}
else if ("".equals(name)) {
@@ -66,7 +66,7 @@ public class EnumProcessor {
for (StructField fd : cl.getFields()) {
String descriptor = fd.getDescriptor();
if (fd.isSynthetic() && descriptor.equals("[L" + cl.qualifiedName + ";")) {
- wrapper.getHideMembers().add(InterpreterUtil.makeUniqueKey(fd.getName(), descriptor));
+ wrapper.getHiddenMembers().add(InterpreterUtil.makeUniqueKey(fd.getName(), descriptor));
}
}
}
diff --git a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/Fernflower.java b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/Fernflower.java
index 6d60f6ebf426..67596be00278 100644
--- a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/Fernflower.java
+++ b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/Fernflower.java
@@ -28,81 +28,66 @@ import org.jetbrains.java.decompiler.struct.lazy.LazyLoader;
import java.io.BufferedWriter;
import java.io.StringWriter;
-import java.util.HashMap;
+import java.util.Map;
public class Fernflower implements IDecompiledData {
- public static final String version = "v0.8.4";
-
- private StructContext structcontext;
-
- private ClassesProcessor clprocessor;
-
- public Fernflower(IBytecodeProvider provider, IDecompilatSaver saver, HashMap propertiesCustom) {
-
- structcontext = new StructContext(saver, this, new LazyLoader(provider));
+ private StructContext structContext;
+ private ClassesProcessor classesProcessor;
+ public Fernflower(IBytecodeProvider provider, IDecompilatSaver saver, Map propertiesCustom) {
+ structContext = new StructContext(saver, this, new LazyLoader(provider));
DecompilerContext.initContext(propertiesCustom);
DecompilerContext.setCounterContainer(new CounterContainer());
}
public void decompileContext() {
-
if (DecompilerContext.getOption(IFernflowerPreferences.RENAME_ENTITIES)) {
- new IdentifierConverter().rename(structcontext);
+ new IdentifierConverter().rename(structContext);
}
- clprocessor = new ClassesProcessor(structcontext);
+ classesProcessor = new ClassesProcessor(structContext);
- DecompilerContext.setClassProcessor(clprocessor);
- DecompilerContext.setStructContext(structcontext);
+ DecompilerContext.setClassProcessor(classesProcessor);
+ DecompilerContext.setStructContext(structContext);
- structcontext.saveContext();
+ structContext.saveContext();
}
public void clearContext() {
DecompilerContext.setCurrentContext(null);
}
- public String getClassEntryName(StructClass cl, String entryname) {
-
- ClassNode node = clprocessor.getMapRootClasses().get(cl.qualifiedName);
+ public String getClassEntryName(StructClass cl, String entryName) {
+ ClassNode node = classesProcessor.getMapRootClasses().get(cl.qualifiedName);
if (node.type != ClassNode.CLASS_ROOT) {
return null;
}
else {
if (DecompilerContext.getOption(IFernflowerPreferences.RENAME_ENTITIES)) {
String simple_classname = cl.qualifiedName.substring(cl.qualifiedName.lastIndexOf('/') + 1);
- return entryname.substring(0, entryname.lastIndexOf('/') + 1) + simple_classname + ".java";
+ return entryName.substring(0, entryName.lastIndexOf('/') + 1) + simple_classname + ".java";
}
else {
- return entryname.substring(0, entryname.lastIndexOf(".class")) + ".java";
+ return entryName.substring(0, entryName.lastIndexOf(".class")) + ".java";
}
}
}
- public StructContext getStructcontext() {
- return structcontext;
+ public StructContext getStructContext() {
+ return structContext;
}
public String getClassContent(StructClass cl) {
-
- String res = null;
-
try {
- StringWriter strwriter = new StringWriter();
- clprocessor.writeClass(structcontext, cl, new BufferedWriter(strwriter));
-
- res = strwriter.toString();
- }
- catch (ThreadDeath ex) {
- throw ex;
+ StringWriter writer = new StringWriter();
+ classesProcessor.writeClass(cl, new BufferedWriter(writer));
+ return writer.toString();
}
catch (Throwable ex) {
DecompilerContext.getLogger().writeMessage("Class " + cl.qualifiedName + " couldn't be fully decompiled.", ex);
+ return null;
}
-
- return res;
}
}
diff --git a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/decompiler/ConsoleDecompiler.java b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/decompiler/ConsoleDecompiler.java
index bfb4e70eec49..d499324dab9c 100644
--- a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/decompiler/ConsoleDecompiler.java
+++ b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/decompiler/ConsoleDecompiler.java
@@ -128,7 +128,7 @@ public class ConsoleDecompiler implements IBytecodeProvider, IDecompilatSaver {
}
public void addSpace(File file, boolean isOwn) throws IOException {
- fernflower.getStructcontext().addSpace(file, isOwn);
+ fernflower.getStructContext().addSpace(file, isOwn);
}
public void decompileContext(File root) {
@@ -213,7 +213,7 @@ public class ConsoleDecompiler implements IBytecodeProvider, IDecompilatSaver {
ZipOutputStream out = mapArchiveStreams.get(filename);
out.putNextEntry(new ZipEntry(entryName));
- InterpreterUtil.copyInputStream(in, out);
+ InterpreterUtil.copyStream(in, out);
in.close();
}
}
diff --git a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/decompiler/IdeDecompiler.java b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/decompiler/IdeDecompiler.java
index dab59e973bfe..212a8bd4bc71 100644
--- a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/decompiler/IdeDecompiler.java
+++ b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/decompiler/IdeDecompiler.java
@@ -40,7 +40,7 @@ public class IdeDecompiler {
}
public void addSpace(File file, boolean isOwn) throws IOException {
- fernflower.getStructcontext().addSpace(file, isOwn);
+ fernflower.getStructContext().addSpace(file, isOwn);
}
public void decompileContext() {
diff --git a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java
index 4ef8ba9f8d48..c942bad4961b 100644
--- a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java
+++ b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java
@@ -15,6 +15,8 @@
*/
package org.jetbrains.java.decompiler.main.extern;
+import org.jetbrains.java.decompiler.util.InterpreterUtil;
+
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@@ -75,10 +77,9 @@ public interface IFernflowerPreferences {
put(IDEA_NOT_NULL_ANNOTATION, "1");
put(LAMBDA_TO_ANONYMOUS_CLASS, "0");
- boolean win = System.getProperty("os.name", "").startsWith("Windows");
put(MAX_PROCESSING_METHOD, "0");
put(RENAME_ENTITIES, "0");
- put(NEW_LINE_SEPARATOR, (win ? "0" : "1"));
+ put(NEW_LINE_SEPARATOR, (InterpreterUtil.IS_WINDOWS ? "0" : "1"));
put(INDENT_STRING, " ");
}});
}
diff --git a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java
index cbaf227d98f2..ae251b9473ec 100644
--- a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java
+++ b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java
@@ -36,17 +36,14 @@ import org.jetbrains.java.decompiler.util.VBStyleCollection;
import java.io.IOException;
import java.util.HashSet;
+import java.util.Set;
public class ClassWrapper {
private StructClass classStruct;
-
- private HashSet hideMembers = new HashSet();
-
+ private Set hiddenMembers = new HashSet();
private VBStyleCollection staticFieldInitializers = new VBStyleCollection();
-
private VBStyleCollection dynamicFieldInitializers = new VBStyleCollection();
-
private VBStyleCollection methods = new VBStyleCollection();
@@ -54,7 +51,6 @@ public class ClassWrapper {
this.classStruct = classStruct;
}
- @SuppressWarnings("deprecation")
public void init() throws IOException {
DecompilerContext.setProperty(DecompilerContext.CURRENT_CLASS, classStruct);
@@ -111,7 +107,7 @@ public class ClassWrapper {
if (System.currentTimeMillis() >= stopAt) {
String message = "Processing time limit exceeded for method " + mt.getName() + ", execution interrupted.";
DecompilerContext.getLogger().writeMessage(message, IFernflowerLogger.ERROR);
- mtthread.stop();
+ killThread(mtthread);
isError = true;
break;
}
@@ -180,6 +176,11 @@ public class ClassWrapper {
DecompilerContext.getLogger().endClass();
}
+ @SuppressWarnings("deprecation")
+ private static void killThread(Thread thread) {
+ thread.stop();
+ }
+
public MethodWrapper getMethodWrapper(String name, String descriptor) {
return methods.getWithKey(InterpreterUtil.makeUniqueKey(name, descriptor));
}
@@ -192,8 +193,8 @@ public class ClassWrapper {
return methods;
}
- public HashSet getHideMembers() {
- return hideMembers;
+ public Set getHiddenMembers() {
+ return hiddenMembers;
}
public VBStyleCollection getStaticFieldInitializers() {
diff --git a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java
index 003bdc21e9cb..3757d7eb1991 100644
--- a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java
+++ b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java
@@ -50,7 +50,7 @@ public class NestedClassProcessor {
if (node.type == ClassNode.CLASS_LAMBDA && !node.lambda_information.is_method_reference) {
ClassNode node_content = DecompilerContext.getClassProcessor().getMapRootClasses().get(node.classStruct.qualifiedName);
if (node_content != null && node_content.wrapper != null) {
- node_content.wrapper.getHideMembers().add(node.lambda_information.content_method_key);
+ node_content.wrapper.getHiddenMembers().add(node.lambda_information.content_method_key);
}
}
@@ -528,7 +528,7 @@ public class NestedClassProcessor {
// hide synthetic field
if (clnode == child) { // fields higher up the chain were already handled with their classes
StructField fd = child.classStruct.getFields().getWithKey(entr.getKey());
- child.wrapper.getHideMembers().add(InterpreterUtil.makeUniqueKey(fd.getName(), fd.getDescriptor()));
+ child.wrapper.getHiddenMembers().add(InterpreterUtil.makeUniqueKey(fd.getName(), fd.getDescriptor()));
}
}
}
diff --git a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/rels/NestedMemberAccess.java b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/rels/NestedMemberAccess.java
index f61de8585d62..7e5eaa54326a 100644
--- a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/rels/NestedMemberAccess.java
+++ b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/rels/NestedMemberAccess.java
@@ -440,7 +440,7 @@ public class NestedMemberAccess {
}
}
if (hide) {
- node.wrapper.getHideMembers().add(InterpreterUtil.makeUniqueKey(invexpr.getName(), invexpr.getStringDescriptor()));
+ node.wrapper.getHiddenMembers().add(InterpreterUtil.makeUniqueKey(invexpr.getName(), invexpr.getStringDescriptor()));
}
}
diff --git a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AssignmentExprent.java b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AssignmentExprent.java
index 87906247072f..8ff9fe5a448a 100644
--- a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AssignmentExprent.java
+++ b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AssignmentExprent.java
@@ -117,7 +117,7 @@ public class AssignmentExprent extends Exprent {
if (field.isStatic() && fd.hasModifier(CodeConstants.ACC_FINAL)) {
fieldInClassInit = true;
}
- if (node.wrapper.getHideMembers().contains(InterpreterUtil.makeUniqueKey(fd.getName(), fd.getDescriptor()))) {
+ if (node.wrapper.getHiddenMembers().contains(InterpreterUtil.makeUniqueKey(fd.getName(), fd.getDescriptor()))) {
hiddenField = true;
}
}
diff --git a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/util/InterpreterUtil.java b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/util/InterpreterUtil.java
index 89e11c0cb1d1..cc4e4bdbfe4c 100644
--- a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/util/InterpreterUtil.java
+++ b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/util/InterpreterUtil.java
@@ -25,6 +25,10 @@ import java.util.HashSet;
import java.util.List;
public class InterpreterUtil {
+ public static final boolean IS_WINDOWS = System.getProperty("os.name", "").startsWith("Windows");
+
+ private static final int CHANNEL_WINDOW_SIZE = IS_WINDOWS ? 64 * 1024 * 1024 - (32 * 1024) : 64 * 1024 * 1024; // magic number for Windows
+ private static final int BUFFER_SIZE = 16* 1024;
public static void copyFile(File in, File out) throws IOException {
FileInputStream inStream = new FileInputStream(in);
@@ -33,12 +37,9 @@ public class InterpreterUtil {
try {
FileChannel inChannel = inStream.getChannel();
FileChannel outChannel = outStream.getChannel();
- // magic number for Windows, 64Mb - 32Kb)
- int maxCount = (64 * 1024 * 1024) - (32 * 1024);
- long size = inChannel.size();
- long position = 0;
+ long size = inChannel.size(), position = 0;
while (position < size) {
- position += inChannel.transferTo(position, maxCount, outChannel);
+ position += inChannel.transferTo(position, CHANNEL_WINDOW_SIZE, outChannel);
}
}
finally {
@@ -50,11 +51,9 @@ public class InterpreterUtil {
}
}
- public static void copyInputStream(InputStream in, OutputStream out) throws IOException {
-
- byte[] buffer = new byte[1024];
+ public static void copyStream(InputStream in, OutputStream out) throws IOException {
+ byte[] buffer = new byte[BUFFER_SIZE];
int len;
-
while ((len = in.read(buffer)) >= 0) {
out.write(buffer, 0, len);
}
@@ -69,9 +68,7 @@ public class InterpreterUtil {
return buf.toString();
}
-
public static boolean equalSets(Collection> c1, Collection> c2) {
-
if (c1 == null) {
return c2 == null;
}
@@ -93,7 +90,6 @@ public class InterpreterUtil {
}
public static boolean equalObjectArrays(Object[] first, Object[] second) {
-
if (first == null || second == null) {
return equalObjects(first, second);
}
@@ -113,12 +109,11 @@ public class InterpreterUtil {
}
public static boolean equalLists(List> first, List> second) {
-
if (first == null) {
return second == null;
}
else if (second == null) {
- return first == null;
+ return false;
}
if (first.size() == second.size()) {
From c642cd471d90756d3439586df89d6d4ee08e02d6 Mon Sep 17 00:00:00 2001
From: Vladimir Krivosheev
Date: Wed, 3 Sep 2014 15:17:08 +0200
Subject: [PATCH 03/60] CR-IC-6201 remove OPTIONS macros
---
.../openapi/components/impl/stores/ApplicationStoreImpl.java | 2 --
1 file changed, 2 deletions(-)
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ApplicationStoreImpl.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ApplicationStoreImpl.java
index a00533d3244b..86ccd77be20d 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ApplicationStoreImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ApplicationStoreImpl.java
@@ -36,7 +36,6 @@ class ApplicationStoreImpl extends ComponentStoreImpl implements IApplicationSto
private static final String XML_EXTENSION = ".xml";
private static final String DEFAULT_STORAGE_SPEC = StoragePathMacros.APP_CONFIG + "/" + PathManager.DEFAULT_OPTIONS_FILE_NAME + XML_EXTENSION;
- private static final String OPTIONS_MACRO = "OPTIONS";
private static final String ROOT_ELEMENT_NAME = "application";
private final ApplicationImpl myApplication;
@@ -95,7 +94,6 @@ class ApplicationStoreImpl extends ComponentStoreImpl implements IApplicationSto
@Override
public void setOptionsPath(final String path) {
myStateStorageManager.addMacro(StoragePathMacros.getMacroName(StoragePathMacros.APP_CONFIG), path);
- myStateStorageManager.addMacro(OPTIONS_MACRO, path);
}
@Override
From 1e4279043944b2cb045ec408337f41ca7e96ddde Mon Sep 17 00:00:00 2001
From: Vladimir Krivosheev
Date: Wed, 3 Sep 2014 16:30:47 +0200
Subject: [PATCH 04/60] =?UTF-8?q?FileBasedStorage=20=E2=80=94=C2=A0we=20do?=
=?UTF-8?q?n't=20need=20to=20wrap=20java=20file=20into=20IFile=20We=20don'?=
=?UTF-8?q?t=20use=20it=20and,=20even,=20even=20if=20we=20will=20decide=20?=
=?UTF-8?q?to=20use=20it,=20we=20will=20use=20our=20virtual=20file=20syste?=
=?UTF-8?q?m?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../stores/ProjectWithModulesStoreImpl.java | 13 ++--
.../roots/impl/storage/ClasspathStorage.java | 21 +++---
.../impl/stores/ComponentStoreImpl.java | 7 +-
.../impl/stores/CompoundSaveSession.java | 10 +--
.../impl/stores/DefaultProjectStoreImpl.java | 10 +--
.../impl/stores/DirectoryBasedStorage.java | 72 +++++++++----------
.../impl/stores/FileBasedStorage.java | 21 +++---
.../impl/stores/IComponentStore.java | 12 ++--
.../impl/stores/ProjectStoreImpl.java | 27 +++----
.../impl/stores/StateStorageManager.java | 8 +--
.../impl/stores/StateStorageManagerImpl.java | 5 +-
.../components/impl/stores/StorageUtil.java | 35 +++++----
.../impl/stores/XmlElementStorage.java | 8 +--
.../project/impl/ProjectManagerImpl.java | 7 +-
.../impl/XmlElementStorageTest.java | 9 ++-
.../openapi/components/StateStorage.java | 6 +-
.../impl/stores/DirectoryStorageData.java | 50 ++++++-------
17 files changed, 146 insertions(+), 175 deletions(-)
diff --git a/platform/lang-impl/src/com/intellij/openapi/components/impl/stores/ProjectWithModulesStoreImpl.java b/platform/lang-impl/src/com/intellij/openapi/components/impl/stores/ProjectWithModulesStoreImpl.java
index eb03fa86fdab..c109c8c0e14d 100644
--- a/platform/lang-impl/src/com/intellij/openapi/components/impl/stores/ProjectWithModulesStoreImpl.java
+++ b/platform/lang-impl/src/com/intellij/openapi/components/impl/stores/ProjectWithModulesStoreImpl.java
@@ -25,10 +25,10 @@ import com.intellij.openapi.module.impl.ModuleImpl;
import com.intellij.openapi.project.impl.ProjectImpl;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.util.io.fs.IFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@@ -102,15 +102,13 @@ public class ProjectWithModulesStoreImpl extends ProjectStoreImpl {
@NotNull
@Override
- public List getAllStorageFiles(final boolean includingSubStructures) {
- final List result = super.getAllStorageFiles(includingSubStructures);
-
+ public List getAllStorageFiles(final boolean includingSubStructures) {
+ List result = super.getAllStorageFiles(includingSubStructures);
if (includingSubStructures) {
for (SaveSession moduleSaveSession : myModuleSaveSessions) {
result.addAll(moduleSaveSession.getAllStorageFiles(true));
}
}
-
return result;
}
@@ -172,10 +170,9 @@ public class ProjectWithModulesStoreImpl extends ProjectStoreImpl {
}
@Override
- protected void collectSubfilesToSave(final List result) throws IOException {
+ protected void collectSubFilesToSave(final List result) throws IOException {
for (SaveSession moduleSaveSession : myModuleSaveSessions) {
- final List moduleFiles = moduleSaveSession.getAllStorageFilesToSave(true);
- result.addAll(moduleFiles);
+ result.addAll(moduleSaveSession.getAllStorageFilesToSave(true));
}
}
}
diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/storage/ClasspathStorage.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/storage/ClasspathStorage.java
index b1f034d2dcb2..8f197a4950f8 100644
--- a/platform/lang-impl/src/com/intellij/openapi/roots/impl/storage/ClasspathStorage.java
+++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/storage/ClasspathStorage.java
@@ -39,8 +39,6 @@ import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.*;
import com.intellij.openapi.vfs.tracker.VirtualFileTracker;
import com.intellij.util.containers.ContainerUtil;
-import com.intellij.util.io.fs.FileSystem;
-import com.intellij.util.io.fs.IFile;
import com.intellij.util.messages.MessageBus;
import org.jdom.Element;
import org.jetbrains.annotations.Nls;
@@ -192,10 +190,9 @@ public class ClasspathStorage implements StateStorage {
return session;
}
- private static void convert2Io(List list, ArrayList virtualFiles) {
+ private static void convert2Io(List list, ArrayList virtualFiles) {
for (VirtualFile virtualFile : virtualFiles) {
- final File ioFile = VfsUtilCore.virtualToIoFile(virtualFile);
- list.add(FileSystem.FILE_SYSTEM.createFile(ioFile.getAbsolutePath()));
+ list.add(VfsUtilCore.virtualToIoFile(virtualFile));
}
}
@@ -384,12 +381,12 @@ public class ClasspathStorage implements StateStorage {
}
@Override
- public Set getClasspath(final ModifiableRootModel model, final Element element) throws IOException, InvalidDataException {
+ public Set getClasspath(final ModifiableRootModel model, final Element element) throws InvalidDataException {
throw new InvalidDataException(getDescription());
}
@Override
- public void setClasspath(ModuleRootModel model) throws IOException, WriteExternalException {
+ public void setClasspath(ModuleRootModel model) throws WriteExternalException {
throw new WriteExternalException(getDescription());
}
};
@@ -426,9 +423,9 @@ public class ClasspathStorage implements StateStorage {
@NotNull
@Override
- public Collection getStorageFilesToSave() throws StateStorageException {
+ public Collection getStorageFilesToSave() throws StateStorageException {
if (needsSave()) {
- final List list = new ArrayList();
+ final List list = new ArrayList();
final ArrayList virtualFiles = new ArrayList();
getFileSet().listModifiedFiles(virtualFiles);
convert2Io(list, virtualFiles);
@@ -441,9 +438,9 @@ public class ClasspathStorage implements StateStorage {
@NotNull
@Override
- public List getAllStorageFiles() {
- final List list = new ArrayList();
- final ArrayList virtualFiles = new ArrayList();
+ public List getAllStorageFiles() {
+ List list = new ArrayList();
+ ArrayList virtualFiles = new ArrayList();
getFileSet().listFiles(virtualFiles);
convert2Io(list, virtualFiles);
return list;
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentStoreImpl.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentStoreImpl.java
index c6208e8ffc15..ed63bf12d4c4 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentStoreImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentStoreImpl.java
@@ -29,12 +29,12 @@ import com.intellij.openapi.util.*;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.ArrayUtil;
import com.intellij.util.ReflectionUtil;
-import com.intellij.util.io.fs.IFile;
import gnu.trove.THashMap;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import java.io.File;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.*;
@@ -354,7 +354,7 @@ public abstract class ComponentStoreImpl implements IComponentStore {
@NotNull
@Override
- public List getAllStorageFilesToSave(final boolean includingSubStructures) throws IOException {
+ public List getAllStorageFilesToSave(final boolean includingSubStructures) throws IOException {
try {
return myStorageManagerSaveSession.getAllStorageFilesToSave();
}
@@ -443,10 +443,9 @@ public abstract class ComponentStoreImpl implements IComponentStore {
@NotNull
@Override
- public List getAllStorageFiles(final boolean includingSubStructures) {
+ public List getAllStorageFiles(final boolean includingSubStructures) {
return myStorageManagerSaveSession.getAllStorageFiles();
}
-
}
@Override
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/CompoundSaveSession.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/CompoundSaveSession.java
index 51cc717726f3..aacdb58aeeec 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/CompoundSaveSession.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/CompoundSaveSession.java
@@ -18,9 +18,9 @@ package com.intellij.openapi.components.impl.stores;
import com.intellij.openapi.components.StateStorage;
import com.intellij.openapi.components.StateStorageException;
import com.intellij.util.SmartList;
-import com.intellij.util.io.fs.IFile;
import gnu.trove.THashMap;
+import java.io.File;
import java.util.List;
import java.util.Map;
@@ -36,8 +36,8 @@ public class CompoundSaveSession {
}
}
- public List getAllStorageFilesToSave() throws StateStorageException {
- List result = new SmartList();
+ public List getAllStorageFilesToSave() throws StateStorageException {
+ List result = new SmartList();
for (StateStorage.SaveSession saveSession : mySaveSessions.values()) {
result.addAll(saveSession.getStorageFilesToSave());
}
@@ -70,8 +70,8 @@ public class CompoundSaveSession {
return mySaveSessions.get(storage);
}
- public List getAllStorageFiles() {
- List result = new SmartList();
+ public List getAllStorageFiles() {
+ List result = new SmartList();
for (StateStorage.SaveSession saveSession : mySaveSessions.values()) {
result.addAll(saveSession.getAllStorageFiles());
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DefaultProjectStoreImpl.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DefaultProjectStoreImpl.java
index 03f01e291f7d..aa3635dd09c2 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DefaultProjectStoreImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DefaultProjectStoreImpl.java
@@ -21,12 +21,12 @@ import com.intellij.openapi.project.impl.ProjectImpl;
import com.intellij.openapi.project.impl.ProjectManagerImpl;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.util.io.fs.IFile;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
@@ -101,13 +101,13 @@ public class DefaultProjectStoreImpl extends ProjectStoreImpl {
@NotNull
@Override
- public Collection getStorageFilesToSave() throws StateStorageException {
+ public Collection getStorageFilesToSave() throws StateStorageException {
return Collections.emptyList();
}
@NotNull
@Override
- public List getAllStorageFiles() {
+ public List getAllStorageFiles() {
return Collections.emptyList();
}
}
@@ -239,13 +239,13 @@ public class DefaultProjectStoreImpl extends ProjectStoreImpl {
@NotNull
@Override
- public List getAllStorageFilesToSave() throws StateStorageException {
+ public List getAllStorageFilesToSave() throws StateStorageException {
return Collections.emptyList();
}
@NotNull
@Override
- public List getAllStorageFiles() {
+ public List getAllStorageFiles() {
return Collections.emptyList();
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DirectoryBasedStorage.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DirectoryBasedStorage.java
index 8a210c321c3c..9774271e61c7 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DirectoryBasedStorage.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DirectoryBasedStorage.java
@@ -26,7 +26,8 @@ import com.intellij.openapi.util.WriteExternalException;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.*;
import com.intellij.openapi.vfs.tracker.VirtualFileTracker;
-import com.intellij.util.io.fs.IFile;
+import com.intellij.util.SmartList;
+import com.intellij.util.containers.SmartHashSet;
import com.intellij.util.messages.MessageBus;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
@@ -37,16 +38,13 @@ import java.io.File;
import java.io.IOException;
import java.util.*;
-import static com.intellij.util.io.fs.FileSystem.FILE_SYSTEM;
-
//todo: support missing plugins
//todo: support storage data
public class DirectoryBasedStorage implements StateStorage, Disposable {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.components.impl.stores.DirectoryBasedStorage");
- private static final IFile[] EMPTY_FILES = new IFile[0];
private final TrackingPathMacroSubstitutor myPathMacroSubstitutor;
- private final IFile myDir;
+ private final File myDir;
private final StateSplitter mySplitter;
private final FileTypeManager myFileTypeManager;
@@ -59,7 +57,7 @@ public class DirectoryBasedStorage implements StateStorage, Disposable {
@NotNull Disposable parentDisposable,
@NotNull PicoContainer picoContainer) {
myPathMacroSubstitutor = pathMacroSubstitutor;
- myDir = FILE_SYSTEM.createFile(dir);
+ myDir = new File(dir);
mySplitter = splitter;
Disposer.register(parentDisposable, this);
@@ -180,31 +178,27 @@ public class DirectoryBasedStorage implements StateStorage, Disposable {
@Override
public void save() throws StateStorageException {
assert mySession == this;
- final Set currentNames = new HashSet();
-
- IFile[] children = myDir.exists() ? myDir.listFiles() : EMPTY_FILES;
- for (IFile child : children) {
- final String fileName = child.getName();
- if (!myFileTypeManager.isFileIgnored(fileName) && StringUtil.endsWithIgnoreCase(fileName, ".xml")) {
- currentNames.add(fileName);
+ final Set currentNames = new SmartHashSet();
+ File[] children = myDir.listFiles();
+ if (children != null) {
+ for (File child : children) {
+ final String fileName = child.getName();
+ if (!myFileTypeManager.isFileIgnored(fileName) && StringUtil.endsWithIgnoreCase(fileName, ".xml")) {
+ currentNames.add(fileName);
+ }
}
}
myStorageData.process(new DirectoryStorageData.StorageDataProcessor() {
@Override
- public void process(final String componentName, final IFile file, final Element element) {
+ public void process(final String componentName, final File file, final Element element) {
currentNames.remove(file.getName());
if (myPathMacroSubstitutor != null) {
myPathMacroSubstitutor.collapsePaths(element);
}
- if (file.getTimeStamp() <= myStorageData.getLastTimeStamp()) {
- if (!myDir.exists()) {
- myDir.createParentDirs();
- myDir.mkDir();
- }
-
+ if (file.lastModified() <= myStorageData.getLastTimeStamp()) {
StorageUtil.save(file, element, MySaveSession.this, false);
myStorageData.updateLastTimestamp(file);
}
@@ -217,9 +211,8 @@ public class DirectoryBasedStorage implements StateStorage, Disposable {
public void run() {
if (myDir.exists()) {
for (String name : currentNames) {
- IFile child = myDir.getChild(name);
-
- if (child.getTimeStamp() > myStorageData.getLastTimeStamp()) {
+ File child = new File(myDir, name);
+ if (child.lastModified() > myStorageData.getLastTimeStamp()) {
// do not touch new files during VC update (which aren't read yet)
// now got an opposite problem: file is recreated if was removed by VC during update.
return;
@@ -272,23 +265,26 @@ public class DirectoryBasedStorage implements StateStorage, Disposable {
@Override
@NotNull
- public Collection getStorageFilesToSave() throws StateStorageException {
+ public Collection getStorageFilesToSave() throws StateStorageException {
assert mySession == this;
if (!myDir.exists()) return getAllStorageFiles();
assert myDir.isDirectory() : myDir.getPath();
- final List filesToSave = new ArrayList();
-
- IFile[] children = myDir.listFiles();
- final Set currentChildNames = new HashSet();
- for (IFile child : children) {
- if (!myFileTypeManager.isFileIgnored(child.getName())) currentChildNames.add(child.getName());
+ final List filesToSave = new ArrayList();
+ final Set currentChildNames = new SmartHashSet();
+ File[] children = myDir.listFiles();
+ if (children != null) {
+ for (File child : children) {
+ if (!myFileTypeManager.isFileIgnored(child.getName())) {
+ currentChildNames.add(child.getName());
+ }
+ }
}
myStorageData.process(new DirectoryStorageData.StorageDataProcessor() {
@Override
- public void process(final String componentName, final IFile file, final Element element) {
+ public void process(final String componentName, final File file, final Element element) {
if (currentChildNames.contains(file.getName())) {
currentChildNames.remove(file.getName());
@@ -305,8 +301,7 @@ public class DirectoryBasedStorage implements StateStorage, Disposable {
});
for (String childName : currentChildNames) {
- final IFile child = myDir.getChild(childName);
- filesToSave.add(child);
+ filesToSave.add(new File(myDir, childName));
}
return filesToSave;
@@ -314,8 +309,8 @@ public class DirectoryBasedStorage implements StateStorage, Disposable {
@Override
@NotNull
- public List getAllStorageFiles() {
- return new ArrayList(myStorageData.getAllStorageFiles().keySet());
+ public List getAllStorageFiles() {
+ return new SmartList(myStorageData.getAllStorageFiles().keySet());
}
}
@@ -327,13 +322,12 @@ public class DirectoryBasedStorage implements StateStorage, Disposable {
}
@Override
- public void setState(@NotNull final Object component, final String componentName, @NotNull final Object state, final Storage storageSpec)
- throws StateStorageException {
+ public void setState(@NotNull final Object component, final String componentName, @NotNull final Object state, final Storage storageSpec) {
assert mySession == this;
setState(componentName, state, storageSpec);
}
- private void setState(final String componentName, @NotNull Object state, final Storage storageSpec) throws StateStorageException {
+ private void setState(final String componentName, @NotNull Object state, final Storage storageSpec) {
try {
final Element element = DefaultStateSerializer.serializeState(state, storageSpec);
if (element != null) {
@@ -345,7 +339,7 @@ public class DirectoryBasedStorage implements StateStorage, Disposable {
statePart.setAttribute(StorageData.NAME, componentName);
statePart.addContent(e.detach());
- myStorageData.put(componentName, myDir.getChild(name), statePart, false);
+ myStorageData.put(componentName, new File(myDir, name), statePart, false);
}
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileBasedStorage.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileBasedStorage.java
index 757d174f86d2..88a227168e5e 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileBasedStorage.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileBasedStorage.java
@@ -33,8 +33,6 @@ import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.*;
import com.intellij.openapi.vfs.tracker.VirtualFileTracker;
-import com.intellij.util.io.fs.FileSystem;
-import com.intellij.util.io.fs.IFile;
import com.intellij.util.messages.MessageBus;
import org.jdom.Document;
import org.jdom.Element;
@@ -52,12 +50,12 @@ import java.util.Collections;
import java.util.List;
public class FileBasedStorage extends XmlElementStorage {
- private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.components.impl.stores.FileBasedStorage");
+ private static final Logger LOG = Logger.getInstance(FileBasedStorage.class);
private static boolean ourConfigDirectoryRefreshed = false;
private final String myFilePath;
- private final IFile myFile;
+ private final File myFile;
private final String myRootElementName;
private volatile VirtualFile myCachedVirtualFile;
@@ -76,16 +74,13 @@ public class FileBasedStorage extends XmlElementStorage {
myRootElementName = rootElementName;
myFilePath = filePath;
- myFile = FileSystem.FILE_SYSTEM.createFile(myFilePath);
+ myFile = new File(filePath);
VirtualFileTracker virtualFileTracker = ServiceManager.getService(VirtualFileTracker.class);
MessageBus messageBus = (MessageBus)picoContainer.getComponentInstanceOfType(MessageBus.class);
if (virtualFileTracker != null && messageBus != null) {
- final String path = myFile.getAbsolutePath();
- final String fileUrl = LocalFileSystem.PROTOCOL_PREFIX + path.replace(File.separatorChar, '/');
-
final Listener listener = messageBus.syncPublisher(STORAGE_TOPIC);
- virtualFileTracker.addTracker(fileUrl, new VirtualFileAdapter() {
+ virtualFileTracker.addTracker(LocalFileSystem.PROTOCOL_PREFIX + myFile.getAbsolutePath().replace(File.separatorChar, '/'), new VirtualFileAdapter() {
@Override
public void fileMoved(@NotNull VirtualFileMoveEvent event) {
myCachedVirtualFile = null;
@@ -178,7 +173,7 @@ public class FileBasedStorage extends XmlElementStorage {
@NotNull
@Override
- public Collection getStorageFilesToSave() {
+ public Collection getStorageFilesToSave() {
if (needsSave()) {
if (LOG.isDebugEnabled()) {
LOG.info("File " + myFileSpec + " needs save; hash=" + myUpToDateHash + "; currentHash=" + calcHash() + "; " +
@@ -193,7 +188,7 @@ public class FileBasedStorage extends XmlElementStorage {
@NotNull
@Override
- public List getAllStorageFiles() {
+ public List getAllStorageFiles() {
return Collections.singletonList(myFile);
}
}
@@ -243,7 +238,7 @@ public class FileBasedStorage extends XmlElementStorage {
}
public File getFile() {
- return new File(myFile.getPath());
+ return myFile;
}
@Override
@@ -324,7 +319,7 @@ public class FileBasedStorage extends XmlElementStorage {
public File updateFileExternallyFromStreamProviders() throws IOException {
Element element = getElement(loadData(true, null));
if (element == null) {
- myFile.delete();
+ FileUtil.delete(myFile);
return null;
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/IComponentStore.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/IComponentStore.java
index 0427a8be15ab..93a65a2eb50b 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/IComponentStore.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/IComponentStore.java
@@ -19,10 +19,10 @@ import com.intellij.openapi.components.StateStorage;
import com.intellij.openapi.components.StateStorageException;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.util.io.fs.IFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Set;
@@ -54,17 +54,19 @@ public interface IComponentStore {
interface SaveSession {
@NotNull
- List getAllStorageFilesToSave(final boolean includingSubStructures) throws IOException;
+ List getAllStorageFilesToSave(final boolean includingSubStructures) throws IOException;
+
@NotNull
SaveSession save() throws IOException;
+
void finishSave();
+
void reset();
@Nullable
- Set analyzeExternalChanges(@NotNull Set> changedFiles);
+ Set analyzeExternalChanges(@NotNull Set> changedFiles);
@NotNull
- List getAllStorageFiles(final boolean includingSubStructures);
+ List getAllStorageFiles(final boolean includingSubStructures);
}
-
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ProjectStoreImpl.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ProjectStoreImpl.java
index 66a6aec7ad21..e73814ed5a31 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ProjectStoreImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ProjectStoreImpl.java
@@ -39,9 +39,8 @@ import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.io.FileUtilRt;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.*;
+import com.intellij.util.SmartList;
import com.intellij.util.containers.OrderedSet;
-import com.intellij.util.io.fs.FileSystem;
-import com.intellij.util.io.fs.IFile;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jetbrains.annotations.NonNls;
@@ -67,7 +66,6 @@ class ProjectStoreImpl extends BaseFileConfigurableStoreImpl implements IProject
protected ProjectImpl myProject;
private StorageScheme myScheme = StorageScheme.DEFAULT;
- private String myCachedLocation;
private String myPresentableUrl;
ProjectStoreImpl(final ProjectImpl project) {
@@ -202,7 +200,6 @@ class ProjectStoreImpl extends BaseFileConfigurableStoreImpl implements IProject
}, ModalityState.defaultModalityState());
}
- myCachedLocation = null;
myPresentableUrl = null;
}
@@ -479,19 +476,16 @@ class ProjectStoreImpl extends BaseFileConfigurableStoreImpl implements IProject
@NotNull
@Override
- public List getAllStorageFilesToSave(final boolean includingSubStructures) throws IOException {
- List result = new ArrayList();
-
+ public List getAllStorageFilesToSave(final boolean includingSubStructures) throws IOException {
+ List result = new SmartList();
if (includingSubStructures) {
- collectSubfilesToSave(result);
+ collectSubFilesToSave(result);
}
-
result.addAll(super.getAllStorageFilesToSave(false));
-
return result;
}
- protected void collectSubfilesToSave(final List result) throws IOException { }
+ protected void collectSubFilesToSave(final List result) throws IOException { }
@NotNull
@Override
@@ -523,10 +517,10 @@ class ProjectStoreImpl extends BaseFileConfigurableStoreImpl implements IProject
return ApplicationManager.getApplication().runReadAction(new Computable() {
@Override
public ReadonlyStatusHandler.OperationStatus compute() {
- final List filesToSave;
+ final List filesToSave;
try {
filesToSave = getAllStorageFilesToSave(true);
- final Iterator iterator = filesToSave.iterator();
+ final Iterator iterator = filesToSave.iterator();
while (iterator.hasNext()) {
if (!iterator.next().exists()) {
iterator.remove();
@@ -543,14 +537,12 @@ class ProjectStoreImpl extends BaseFileConfigurableStoreImpl implements IProject
if (myProject.isToSaveProjectName()) {
final VirtualFile baseDir = getProjectBaseDir();
if (baseDir != null && baseDir.isValid()) {
- filesToSave.add(FileSystem.FILE_SYSTEM
- .createFile(new File(new File(baseDir.getPath(), Project.DIRECTORY_STORE_FOLDER), ProjectImpl.NAME_FILE).getPath()));
+ filesToSave.add(new File(new File(baseDir.getPath(), Project.DIRECTORY_STORE_FOLDER), ProjectImpl.NAME_FILE));
}
}
- for (IFile file : filesToSave) {
+ for (File file : filesToSave) {
final VirtualFile virtualFile = LocalFileSystem.getInstance().findFileByIoFile(file);
-
if (virtualFile != null) {
virtualFile.refresh(false, false);
if (virtualFile.isValid() && !virtualFile.isWritable()) {
@@ -688,6 +680,7 @@ class ProjectStoreImpl extends BaseFileConfigurableStoreImpl implements IProject
return StateSplitter.class;
}
+ @NotNull
@Override
public Class extends Annotation> annotationType() {
throw new UnsupportedOperationException("Method annotationType not implemented in " + getClass());
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManager.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManager.java
index 92560821612b..79e079303281 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManager.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManager.java
@@ -19,10 +19,10 @@ import com.intellij.openapi.components.*;
import com.intellij.openapi.options.StreamProvider;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.util.io.fs.IFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import java.io.File;
import java.util.Collection;
import java.util.List;
import java.util.Set;
@@ -82,11 +82,11 @@ public interface StateStorageManager {
Set analyzeExternalChanges(@NotNull Set> files);
@NotNull
- List getAllStorageFilesToSave() throws StateStorageException;
+ List getAllStorageFilesToSave() throws StateStorageException;
@NotNull
- List getAllStorageFiles();
+ List getAllStorageFiles();
void save() throws StateStorageException;
}
-}
\ No newline at end of file
+}
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManagerImpl.java
index a870112bd19b..ba50efaad0c4 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManagerImpl.java
@@ -29,7 +29,6 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.ObjectUtils;
import com.intellij.util.PathUtilRt;
import com.intellij.util.SmartList;
-import com.intellij.util.io.fs.IFile;
import gnu.trove.THashMap;
import gnu.trove.THashSet;
import gnu.trove.TObjectLongHashMap;
@@ -440,14 +439,14 @@ public abstract class StateStorageManagerImpl implements StateStorageManager, Di
@Override
@NotNull
- public List getAllStorageFilesToSave() throws StateStorageException {
+ public List getAllStorageFilesToSave() throws StateStorageException {
assert mySession == this;
return myCompoundSaveSession.getAllStorageFilesToSave();
}
@Override
@NotNull
- public List getAllStorageFiles() {
+ public List getAllStorageFiles() {
return myCompoundSaveSession.getAllStorageFiles();
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StorageUtil.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StorageUtil.java
index 477176dbb9fc..ba8029f5bef6 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StorageUtil.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StorageUtil.java
@@ -37,7 +37,6 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.SystemProperties;
import com.intellij.util.UniqueFileNamesProvider;
import com.intellij.util.containers.ContainerUtil;
-import com.intellij.util.io.fs.IFile;
import com.intellij.util.ui.UIUtil;
import org.jdom.Document;
import org.jdom.Element;
@@ -128,9 +127,9 @@ public class StorageUtil {
* Due to historical reasons files in ROOT_CONFIG don’t wrapped into document (xml prolog) opposite to files in APP_CONFIG
*/
@Nullable
- static VirtualFile save(@NotNull IFile file, @Nullable Parent element, Object requestor, boolean wrapAsDocument) throws StateStorageException {
+ static VirtualFile save(@NotNull File file, @Nullable Parent element, Object requestor, boolean wrapAsDocument) throws StateStorageException {
if (isEmpty(element)) {
- file.delete();
+ FileUtil.delete(file);
return null;
}
@@ -145,7 +144,7 @@ public class StorageUtil {
}
}
else {
- file.createParentDirs();
+ FileUtil.createParentDirs(file);
byteOut = writeToBytes(document, SystemProperties.getLineSeparator());
}
@@ -179,28 +178,26 @@ public class StorageUtil {
}
@NotNull
- static VirtualFile getOrCreateVirtualFile(final Object requestor, final IFile ioFile) throws IOException {
- VirtualFile vFile = getVirtualFile(ioFile);
-
- if (vFile == null) {
- vFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(ioFile);
+ static VirtualFile getOrCreateVirtualFile(@Nullable Object requestor, @NotNull File ioFile) throws IOException {
+ VirtualFile virtualFile = getVirtualFile(ioFile);
+ if (virtualFile == null) {
+ virtualFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(ioFile);
}
- if (vFile == null) {
- final IFile parentFile = ioFile.getParentFile();
- final VirtualFile parentVFile =
- LocalFileSystem.getInstance().refreshAndFindFileByIoFile(parentFile); // need refresh if the directory has just been created
- if (parentVFile == null) {
- throw new IOException(ProjectBundle.message("project.configuration.save.file.not.found", parentFile.getPath()));
+ if (virtualFile == null) {
+ File parentFile = ioFile.getParentFile();
+ // need refresh if the directory has just been created
+ VirtualFile parentVirtualFile = parentFile == null ? null : LocalFileSystem.getInstance().refreshAndFindFileByIoFile(parentFile);
+ if (parentVirtualFile == null) {
+ throw new IOException(ProjectBundle.message("project.configuration.save.file.not.found", parentFile == null ? "" : parentFile.getPath()));
}
- vFile = parentVFile.createChildData(requestor, ioFile.getName());
+ virtualFile = parentVirtualFile.createChildData(requestor, ioFile.getName());
}
-
- return vFile;
+ return virtualFile;
}
@Nullable
- static VirtualFile getVirtualFile(final IFile ioFile) {
+ static VirtualFile getVirtualFile(@NotNull File ioFile) {
return LocalFileSystem.getInstance().findFileByIoFile(ioFile);
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/XmlElementStorage.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/XmlElementStorage.java
index ccb0b6fc08ed..c75e99dc1806 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/XmlElementStorage.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/XmlElementStorage.java
@@ -26,7 +26,6 @@ import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.openapi.vfs.SafeWriteRequestor;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.util.io.fs.IFile;
import gnu.trove.THashMap;
import gnu.trove.THashSet;
import gnu.trove.TObjectLongHashMap;
@@ -37,12 +36,13 @@ import org.jdom.filter.ElementFilter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
public abstract class XmlElementStorage implements StateStorage, Disposable {
- private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.components.impl.stores.XmlElementStorage");
+ private static final Logger LOG = Logger.getInstance(XmlElementStorage.class);
private static final String ATTR_NAME = "name";
private static final String VERSION_FILE_SUFFIX = ".ver";
@@ -235,13 +235,13 @@ public abstract class XmlElementStorage implements StateStorage, Disposable {
@NotNull
@Override
- public Collection getStorageFilesToSave() throws StateStorageException {
+ public Collection getStorageFilesToSave() throws StateStorageException {
return Collections.emptySet();
}
@NotNull
@Override
- public List getAllStorageFiles() {
+ public List getAllStorageFiles() {
return Collections.emptyList();
}
};
diff --git a/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java
index e7b20959369e..b5243e7c7ec9 100644
--- a/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java
@@ -57,7 +57,6 @@ import com.intellij.util.ArrayUtil;
import com.intellij.util.TimeoutUtil;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.HashMap;
-import com.intellij.util.io.fs.IFile;
import com.intellij.util.messages.MessageBus;
import com.intellij.util.messages.MessageBusConnection;
import com.intellij.util.ui.UIUtil;
@@ -922,9 +921,9 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
IProjectStore projectStore = projectImpl.getStateStore();
final String location = projectImpl.getPresentableUrl();
- final List original;
+ final List original;
try {
- final IComponentStore.SaveSession saveSession = projectStore.startSave();
+ IComponentStore.SaveSession saveSession = projectStore.startSave();
original = saveSession.getAllStorageFiles(true);
saveSession.finishSave();
}
@@ -937,7 +936,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
application.runWriteAction(new Runnable() {
@Override
public void run() {
- for (final IFile originalFile : original) {
+ for (File originalFile : original) {
restoreCopy(LocalFileSystem.getInstance().refreshAndFindFileByIoFile(originalFile));
}
}
diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/components/impl/XmlElementStorageTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/components/impl/XmlElementStorageTest.java
index 5900b67db6bd..e5b586022ec4 100644
--- a/platform/platform-tests/testSrc/com/intellij/openapi/components/impl/XmlElementStorageTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/openapi/components/impl/XmlElementStorageTest.java
@@ -24,11 +24,11 @@ import com.intellij.openapi.components.impl.stores.ComponentVersionProvider;
import com.intellij.openapi.components.impl.stores.XmlElementStorage;
import com.intellij.openapi.util.Disposer;
import com.intellij.testFramework.LightPlatformLangTestCase;
-import com.intellij.util.io.fs.IFile;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import java.io.File;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@@ -108,16 +108,15 @@ public class XmlElementStorageTest extends LightPlatformLangTestCase {
@NotNull
@Override
- public Collection getStorageFilesToSave() throws StateStorageException {
- return needsSave() ? getAllStorageFiles() : Collections.emptyList();
+ public Collection getStorageFilesToSave() throws StateStorageException {
+ return needsSave() ? getAllStorageFiles() : Collections.emptyList();
}
@NotNull
@Override
- public List getAllStorageFiles() {
+ public List getAllStorageFiles() {
throw new UnsupportedOperationException("Method getAllStorageFiles not implemented in " + getClass());
}
-
};
}
}
diff --git a/platform/projectModel-api/src/com/intellij/openapi/components/StateStorage.java b/platform/projectModel-api/src/com/intellij/openapi/components/StateStorage.java
index 134821d7e326..e6c51699806f 100644
--- a/platform/projectModel-api/src/com/intellij/openapi/components/StateStorage.java
+++ b/platform/projectModel-api/src/com/intellij/openapi/components/StateStorage.java
@@ -19,11 +19,11 @@ package com.intellij.openapi.components;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileEvent;
-import com.intellij.util.io.fs.IFile;
import com.intellij.util.messages.Topic;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import java.io.File;
import java.util.Collection;
import java.util.List;
import java.util.Set;
@@ -57,10 +57,10 @@ public interface StateStorage {
Set analyzeExternalChanges(@NotNull Set> changedFiles);
@NotNull
- Collection getStorageFilesToSave() throws StateStorageException;
+ Collection getStorageFilesToSave() throws StateStorageException;
@NotNull
- List getAllStorageFiles();
+ List getAllStorageFiles();
}
interface Listener {
diff --git a/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/DirectoryStorageData.java b/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/DirectoryStorageData.java
index 6cb899798949..8ea0e1ef935f 100644
--- a/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/DirectoryStorageData.java
+++ b/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/DirectoryStorageData.java
@@ -23,8 +23,6 @@ import com.intellij.openapi.util.JDOMUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.PairConsumer;
-import com.intellij.util.io.fs.FileSystem;
-import com.intellij.util.io.fs.IFile;
import gnu.trove.THashMap;
import org.jdom.Document;
import org.jdom.Element;
@@ -37,9 +35,9 @@ import java.io.IOException;
import java.util.*;
public class DirectoryStorageData {
- private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.components.impl.stores.DirectoryStorageData");
+ private static final Logger LOG = Logger.getInstance(DirectoryStorageData.class);
- private Map> myStates = new HashMap>();
+ private Map> myStates = new THashMap>();
private long myLastTimestamp = 0;
private DirectoryStorageData myOriginalData;
@@ -79,7 +77,7 @@ public class DirectoryStorageData {
pathMacroSubstitutor.addUnknownMacros(componentName, unknownMacros);
}
- put(componentName, FileSystem.FILE_SYSTEM.createFile(file.getPath()), element, true);
+ put(componentName, new File(file.getPath()), element, true);
}
catch (IOException e) {
LOG.info("Unable to load state", e);
@@ -90,21 +88,23 @@ public class DirectoryStorageData {
}
}
- public void put(final String componentName, final IFile file, final Element element, final boolean updateTimestamp) {
+ public void put(final String componentName, File file, final Element element, final boolean updateTimestamp) {
LOG.assertTrue(componentName != null, String.format("Component name should not be null for file: %s", file == null ? "NULL!" : file.getPath()));
- Map stateMap = myStates.get(componentName);
+ Map stateMap = myStates.get(componentName);
if (stateMap == null) {
- stateMap = new HashMap();
+ stateMap = new THashMap();
myStates.put(componentName, stateMap);
}
stateMap.put(file, element);
- if (updateTimestamp) updateLastTimestamp(file);
+ if (updateTimestamp) {
+ updateLastTimestamp(file);
+ }
}
- public void updateLastTimestamp(final IFile file) {
- myLastTimestamp = Math.max(myLastTimestamp, file.getTimeStamp());
+ public void updateLastTimestamp(File file) {
+ myLastTimestamp = Math.max(myLastTimestamp, file.lastModified());
if (myOriginalData != null) {
myOriginalData.myLastTimestamp = myLastTimestamp;
}
@@ -114,22 +114,22 @@ public class DirectoryStorageData {
return myLastTimestamp;
}
- public Map getAllStorageFiles() {
- final Map allStorageFiles = new THashMap();
+ public Map getAllStorageFiles() {
+ final Map allStorageFiles = new THashMap();
process(new StorageDataProcessor() {
@Override
- public void process(final String componentName, final IFile file, final Element element) {
- allStorageFiles.put(file, file.getTimeStamp());
+ public void process(final String componentName, final File file, final Element element) {
+ allStorageFiles.put(file, file.lastModified());
}
});
return allStorageFiles;
}
- public void processComponent(@NotNull final String componentName, @NotNull final PairConsumer consumer) {
- final Map map = myStates.get(componentName);
+ public void processComponent(@NotNull final String componentName, @NotNull final PairConsumer consumer) {
+ final Map map = myStates.get(componentName);
if (map != null) {
- for (IFile file : map.keySet()) {
+ for (File file : map.keySet()) {
consumer.consume(file, map.get(file));
}
}
@@ -137,10 +137,10 @@ public class DirectoryStorageData {
public void process(@NotNull final StorageDataProcessor processor) {
for (final String componentName : myStates.keySet()) {
- processComponent(componentName, new PairConsumer() {
+ processComponent(componentName, new PairConsumer() {
@Override
- public void consume(final IFile iFile, final Element element) {
- processor.process(componentName, iFile, element);
+ public void consume(File file, Element element) {
+ processor.process(componentName, file, element);
}
});
}
@@ -149,7 +149,7 @@ public class DirectoryStorageData {
@Override
protected DirectoryStorageData clone() {
final DirectoryStorageData result = new DirectoryStorageData();
- result.myStates = new HashMap>(myStates);
+ result.myStates = new HashMap>(myStates);
result.myLastTimestamp = myLastTimestamp;
result.myOriginalData = this;
return result;
@@ -171,9 +171,9 @@ public class DirectoryStorageData {
@Nullable
public T getMergedState(String componentName, Class stateClass, StateSplitter splitter, @Nullable T mergeInto) {
final List subElements = new ArrayList();
- processComponent(componentName, new PairConsumer() {
+ processComponent(componentName, new PairConsumer() {
@Override
- public void consume(final IFile iFile, final Element element) {
+ public void consume(File file, Element element) {
final List children = element.getChildren();
assert children.size() == 1 : JDOMUtil.writeElement(element, File.separator);
final Element subElement = (Element)children.get(0);
@@ -190,6 +190,6 @@ public class DirectoryStorageData {
}
interface StorageDataProcessor {
- void process(String componentName, IFile file, Element element);
+ void process(String componentName, File file, Element element);
}
}
From ff821de9627f810f3b8033f3a7604288fa2cf780 Mon Sep 17 00:00:00 2001
From: Vladimir Krivosheev
Date: Wed, 3 Sep 2014 16:42:34 +0200
Subject: [PATCH 05/60] remove deprecated class
---
.../stores/RoamingTypeExtensionPointBean.java | 29 -------------------
1 file changed, 29 deletions(-)
delete mode 100644 platform/platform-impl/src/com/intellij/openapi/components/impl/stores/RoamingTypeExtensionPointBean.java
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/RoamingTypeExtensionPointBean.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/RoamingTypeExtensionPointBean.java
deleted file mode 100644
index ff5d16361228..000000000000
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/RoamingTypeExtensionPointBean.java
+++ /dev/null
@@ -1,29 +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.components.impl.stores;
-
-import com.intellij.util.xmlb.annotations.Attribute;
-
-/**
- * @deprecated use {@link com.intellij.openapi.components.RoamingType#DISABLED}
- */
-@Deprecated
-public class RoamingTypeExtensionPointBean {
- @Attribute("component")
- public String componentName;
- @Attribute("type")
- public String roamingType;
-}
From e7f37d871e83ada860cbe26e91e07df189be21fd Mon Sep 17 00:00:00 2001
From: Vladimir Krivosheev
Date: Wed, 3 Sep 2014 16:43:53 +0200
Subject: [PATCH 06/60] we must return empty element instead of null
---
.../src/com/intellij/promoter/ShortcutPromoterManager.java | 4 ----
1 file changed, 4 deletions(-)
diff --git a/plugins/ShortcutPromoter/src/com/intellij/promoter/ShortcutPromoterManager.java b/plugins/ShortcutPromoter/src/com/intellij/promoter/ShortcutPromoterManager.java
index 227d96245080..8b192a78beb7 100644
--- a/plugins/ShortcutPromoter/src/com/intellij/promoter/ShortcutPromoterManager.java
+++ b/plugins/ShortcutPromoter/src/com/intellij/promoter/ShortcutPromoterManager.java
@@ -97,10 +97,6 @@ public class ShortcutPromoterManager implements ApplicationComponent, AnActionLi
@Nullable
@Override
public Element getState() {
- if (myState.isEmpty()) {
- return null;
- }
-
final Element actions = new Element("actions");
for (String id : myState.keySet()) {
final Element action = new Element("action");
From c4ac9ba0ffaca6274832eb2dc90b2b9118d8c099 Mon Sep 17 00:00:00 2001
From: Vladimir Krivosheev
Date: Wed, 3 Sep 2014 16:55:42 +0200
Subject: [PATCH 07/60] overrides
---
.../src/com/intellij/ide/RecentDirectoryProjectsManager.java | 2 ++
1 file changed, 2 insertions(+)
diff --git a/platform/platform-impl/src/com/intellij/ide/RecentDirectoryProjectsManager.java b/platform/platform-impl/src/com/intellij/ide/RecentDirectoryProjectsManager.java
index 4189b6adf98b..6b7893fe6b4a 100644
--- a/platform/platform-impl/src/com/intellij/ide/RecentDirectoryProjectsManager.java
+++ b/platform/platform-impl/src/com/intellij/ide/RecentDirectoryProjectsManager.java
@@ -45,6 +45,7 @@ public class RecentDirectoryProjectsManager extends RecentProjectsManagerBase {
super(messageBus);
}
+ @Override
@Nullable
protected String getProjectPath(@NotNull Project project) {
final ProjectBaseDirectory baseDir = ProjectBaseDirectory.getInstance(project);
@@ -52,6 +53,7 @@ public class RecentDirectoryProjectsManager extends RecentProjectsManagerBase {
return baseDirVFile != null ? FileUtil.toSystemDependentName(baseDirVFile.getPath()) : null;
}
+ @Override
protected void doOpenProject(@NotNull String projectPath, Project projectToClose, boolean forceOpenInNewFrame) {
final VirtualFile projectDir = LocalFileSystem.getInstance().findFileByPath(FileUtil.toSystemIndependentName(projectPath));
if (projectDir != null) {
From e3557f2570e8d7875fecf07712e69ecfaa6dfef8 Mon Sep 17 00:00:00 2001
From: Konstantin Bulenkov
Date: Tue, 2 Sep 2014 13:48:13 +0200
Subject: [PATCH 08/60] update NavBar after LaF change
---
.../ide/navigationToolbar/NavBarListener.java | 18 ++++++++++++++++--
.../navigationToolbar/ui/AbstractNavBarUI.java | 4 ++--
2 files changed, 18 insertions(+), 4 deletions(-)
diff --git a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarListener.java b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarListener.java
index 3fe38cea2ed3..12d24e42547f 100644
--- a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarListener.java
+++ b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarListener.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -18,6 +18,8 @@ package com.intellij.ide.navigationToolbar;
import com.intellij.ProjectTopics;
import com.intellij.ide.actions.CopyAction;
import com.intellij.ide.actions.CutAction;
+import com.intellij.ide.ui.LafManager;
+import com.intellij.ide.ui.LafManagerListener;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.ex.AnActionListener;
@@ -57,7 +59,8 @@ import java.util.List;
*/
public class NavBarListener extends WolfTheProblemSolver.ProblemListener
implements ActionListener, FocusListener, FileStatusListener, AnActionListener, FileEditorManagerListener,
- PsiTreeChangeListener, ModuleRootListener, NavBarModelListener, PropertyChangeListener, KeyListener, WindowFocusListener {
+ PsiTreeChangeListener, ModuleRootListener, NavBarModelListener, PropertyChangeListener, KeyListener, WindowFocusListener,
+ LafManagerListener {
private static final String LISTENER = "NavBarListener";
private static final String BUS = "NavBarMessageBus";
private final NavBarPanel myPanel;
@@ -89,6 +92,8 @@ public class NavBarListener extends WolfTheProblemSolver.ProblemListener
if (window != null) {
window.addWindowFocusListener(listener);
}
+ } else {
+ LafManager.getInstance().addLafManagerListener(listener);
}
}
@@ -107,6 +112,7 @@ public class NavBarListener extends WolfTheProblemSolver.ProblemListener
if (connection != null) {
connection.disconnect();
}
+ LafManager.getInstance().removeLafManagerListener(listener);
}
}
@@ -355,6 +361,14 @@ public class NavBarListener extends WolfTheProblemSolver.ProblemListener
});
}
+ @Override
+ public void lookAndFeelChanged(LafManager source) {
+ myPanel.getNavBarUI().clearItems();
+ myPanel.revalidate();
+ myPanel.repaint();
+ }
+
+
@Override
public void windowLostFocus(WindowEvent e) {
final Window window = e.getWindow();
diff --git a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/ui/AbstractNavBarUI.java b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/ui/AbstractNavBarUI.java
index 1201e146869d..5e0f6e58d106 100644
--- a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/ui/AbstractNavBarUI.java
+++ b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/ui/AbstractNavBarUI.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -40,7 +40,7 @@ import java.util.Map;
*/
public abstract class AbstractNavBarUI implements NavBarUI {
- private final Map> myCache = new THashMap>();
+ private final static Map> myCache = new THashMap>();
private enum ImageType {
INACTIVE, NEXT_ACTIVE, ACTIVE, INACTIVE_FLOATING, NEXT_ACTIVE_FLOATING, ACTIVE_FLOATING,
From d749a3720b859340424ed13ab3a6cb726a09ae2f Mon Sep 17 00:00:00 2001
From: Konstantin Bulenkov
Date: Tue, 2 Sep 2014 14:07:06 +0200
Subject: [PATCH 09/60] cleanup
---
.../ide/navigationToolbar/NavBarListener.java | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarListener.java b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarListener.java
index 12d24e42547f..e0a0d946c9c5 100644
--- a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarListener.java
+++ b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarListener.java
@@ -369,16 +369,12 @@ public class NavBarListener extends WolfTheProblemSolver.ProblemListener
}
- @Override
- public void windowLostFocus(WindowEvent e) {
- final Window window = e.getWindow();
- final Window oppositeWindow = e.getOppositeWindow();
- }
-
//---- Ignored
@Override
- public void windowGainedFocus(WindowEvent e) {
- }
+ public void windowLostFocus(WindowEvent e) {}
+
+ @Override
+ public void windowGainedFocus(WindowEvent e) {}
@Override
public void keyTyped(KeyEvent e) {}
From 2d9c069a0c880ed4eb1321797c0df52406589ecc Mon Sep 17 00:00:00 2001
From: Vladimir Krivosheev
Date: Wed, 3 Sep 2014 17:06:41 +0200
Subject: [PATCH 10/60] cleanup
---
.../intellij/ide/RecentDirectoryProjectsManager.java | 5 ++---
.../impl/stores/StateStorageManagerImpl.java | 10 +++++-----
2 files changed, 7 insertions(+), 8 deletions(-)
diff --git a/platform/platform-impl/src/com/intellij/ide/RecentDirectoryProjectsManager.java b/platform/platform-impl/src/com/intellij/ide/RecentDirectoryProjectsManager.java
index 6b7893fe6b4a..cf10681f82a5 100644
--- a/platform/platform-impl/src/com/intellij/ide/RecentDirectoryProjectsManager.java
+++ b/platform/platform-impl/src/com/intellij/ide/RecentDirectoryProjectsManager.java
@@ -36,9 +36,8 @@ import org.jetbrains.annotations.Nullable;
name = "RecentDirectoryProjectsManager",
roamingType = RoamingType.DISABLED,
storages = {
- @Storage(
- file = StoragePathMacros.APP_CONFIG + "/other.xml"
- )}
+ @Storage(file = StoragePathMacros.APP_CONFIG + "/other.xml")
+ }
)
public class RecentDirectoryProjectsManager extends RecentProjectsManagerBase {
public RecentDirectoryProjectsManager(MessageBus messageBus) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManagerImpl.java
index ba50efaad0c4..4c935059cd39 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManagerImpl.java
@@ -24,6 +24,7 @@ import com.intellij.openapi.options.CurrentUserHolder;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.JDOMUtil;
import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.io.FileUtilRt;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.ObjectUtils;
@@ -423,7 +424,8 @@ public abstract class StateStorageManagerImpl implements StateStorageManager, Di
@Override
@Nullable
public StateStorage getOldStorage(Object component, String componentName, StateStorageOperation operation) throws StateStorageException {
- return getFileStateStorage(getOldStorageSpec(component, componentName, operation));
+ String oldStorageSpec = getOldStorageSpec(component, componentName, operation);
+ return oldStorageSpec == null ? null : getFileStateStorage(oldStorageSpec);
}
@Nullable
@@ -505,10 +507,7 @@ public abstract class StateStorageManagerImpl implements StateStorageManager, Di
if (!isDirty) return;
String filePath = getNotNullVersionsFilePath();
if (filePath != null) {
- File dir = new File(filePath).getParentFile();
- if (!dir.isDirectory() && !dir.mkdirs()) {
- LOG.warn("Unable to create: " + dir);
- }
+ FileUtilRt.createParentDirs(new File(filePath));
try {
JDOMUtil.writeDocument(new Document(createComponentVersionsXml(getComponentVersions())), filePath, "\n");
isDirty = false;
@@ -545,6 +544,7 @@ public abstract class StateStorageManagerImpl implements StateStorageManager, Di
return root;
}
+ @SuppressWarnings("deprecation")
private static class OldStreamProviderManager extends StreamProvider implements CurrentUserHolder {
private final List myStreamProviders = new SmartList();
From 0738bfccb3ea65996eb908c8afc5a57510cf4e8c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Yann=20C=C3=A9bron?=
Date: Wed, 3 Sep 2014 17:13:58 +0200
Subject: [PATCH 11/60] IDEA-128588 Context menu in editor does not open during
indexing
---
plugins/devkit/src/testAssistant/TestLocationDataRule.java | 3 +++
1 file changed, 3 insertions(+)
diff --git a/plugins/devkit/src/testAssistant/TestLocationDataRule.java b/plugins/devkit/src/testAssistant/TestLocationDataRule.java
index 6dccd0f808da..74c9d34c5a96 100644
--- a/plugins/devkit/src/testAssistant/TestLocationDataRule.java
+++ b/plugins/devkit/src/testAssistant/TestLocationDataRule.java
@@ -23,6 +23,7 @@ import com.intellij.execution.junit2.info.MethodLocation;
import com.intellij.ide.impl.dataRules.GetDataRule;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataProvider;
+import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
@@ -58,6 +59,8 @@ public class TestLocationDataRule implements GetDataRule {
@NotNull
protected static List collectRelativeLocations(Project project, VirtualFile file) {
+ if (DumbService.isDumb(project)) return Collections.emptyList();
+
final List locations = new ArrayList();
final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();
if (fileIndex.isInContent(file) && !fileIndex.isInSource(file) && !fileIndex.isInLibraryClasses(file)) {
From d12a369f4e65b6c3d156406db17488f1e099e222 Mon Sep 17 00:00:00 2001
From: "Egor.Ushakov"
Date: Wed, 3 Sep 2014 18:38:18 +0400
Subject: [PATCH 12/60] removed unused arrays settings
---
.../DebuggerDataViewsConfigurable.java | 31 ++++++++++---------
1 file changed, 16 insertions(+), 15 deletions(-)
diff --git a/java/debugger/impl/src/com/intellij/debugger/settings/DebuggerDataViewsConfigurable.java b/java/debugger/impl/src/com/intellij/debugger/settings/DebuggerDataViewsConfigurable.java
index 452a924aed00..8785e687eff3 100644
--- a/java/debugger/impl/src/com/intellij/debugger/settings/DebuggerDataViewsConfigurable.java
+++ b/java/debugger/impl/src/com/intellij/debugger/settings/DebuggerDataViewsConfigurable.java
@@ -53,7 +53,7 @@ public class DebuggerDataViewsConfigurable implements SearchableConfigurable {
private JCheckBox myCbShowObjectId;
private StateRestoringCheckBox myCbShowStaticFinalFields;
- private final ArrayRendererConfigurable myArrayRendererConfigurable;
+ //private final ArrayRendererConfigurable myArrayRendererConfigurable;
private JCheckBox myCbEnableAlternateViews;
private JCheckBox myCbEnableToString;
@@ -66,12 +66,12 @@ public class DebuggerDataViewsConfigurable implements SearchableConfigurable {
public DebuggerDataViewsConfigurable(@Nullable Project project) {
myProject = project;
- myArrayRendererConfigurable = new ArrayRendererConfigurable(NodeRendererSettings.getInstance().getArrayRenderer());
+ //myArrayRendererConfigurable = new ArrayRendererConfigurable(NodeRendererSettings.getInstance().getArrayRenderer());
}
@Override
public void disposeUIResources() {
- myArrayRendererConfigurable.disposeUIResources();
+ //myArrayRendererConfigurable.disposeUIResources();
myToStringFilterEditor = null;
myProject = null;
}
@@ -165,13 +165,14 @@ public class DebuggerDataViewsConfigurable implements SearchableConfigurable {
panel.add(showPanel, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 3, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(4, 0, 0, 0), 0, 0));
- final JPanel arraysPanel = new JPanel(new BorderLayout(0, UIUtil.DEFAULT_VGAP));
- final JComponent arraysComponent = myArrayRendererConfigurable.createComponent();
- assert arraysComponent != null;
- arraysPanel.add(arraysComponent, BorderLayout.CENTER);
- arraysPanel.add(myCbHideNullArrayElements, BorderLayout.SOUTH);
- arraysPanel.setBorder(IdeBorderFactory.createTitledBorder("Arrays", true));
- panel.add(arraysPanel, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 3, 1, 1.0, 0.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
+ //final JPanel arraysPanel = new JPanel(new BorderLayout(0, UIUtil.DEFAULT_VGAP));
+ //final JComponent arraysComponent = myArrayRendererConfigurable.createComponent();
+ //assert arraysComponent != null;
+ //arraysPanel.add(arraysComponent, BorderLayout.CENTER);
+ //arraysPanel.add(myCbHideNullArrayElements, BorderLayout.SOUTH);
+ //arraysPanel.setBorder(IdeBorderFactory.createTitledBorder("Arrays", true));
+ //panel.add(arraysPanel, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 3, 1, 1.0, 0.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
+ panel.add(myCbHideNullArrayElements, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 3, 1, 1.0, 0.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
panel.add(myCbEnableAlternateViews, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(4, 0, 0, 10), 0, 0));
// starting 4-th row
@@ -209,7 +210,7 @@ public class DebuggerDataViewsConfigurable implements SearchableConfigurable {
myAutoTooltip.save();
- myArrayRendererConfigurable.apply();
+ //myArrayRendererConfigurable.apply();
rendererSettings.fireRenderersChanged();
}
@@ -250,7 +251,7 @@ public class DebuggerDataViewsConfigurable implements SearchableConfigurable {
myRbFromList.setEnabled(toStringEnabled);
myRbAllThatOverride.setEnabled(toStringEnabled);
- myArrayRendererConfigurable.reset();
+ //myArrayRendererConfigurable.reset();
}
@Override
@@ -266,9 +267,9 @@ public class DebuggerDataViewsConfigurable implements SearchableConfigurable {
}
private boolean areDefaultRenderersModified() {
- if (myArrayRendererConfigurable.isModified()) {
- return true;
- }
+ //if (myArrayRendererConfigurable.isModified()) {
+ // return true;
+ //}
final NodeRendererSettings rendererSettings = NodeRendererSettings.getInstance();
From 431cc71898a2657a797cccad43460d102e285bf7 Mon Sep 17 00:00:00 2001
From: "Vladimir.Orlov"
Date: Wed, 3 Sep 2014 19:21:43 +0400
Subject: [PATCH 13/60] updated help_id for PyCharm Education
---
python/edu/build/pycharm_edu_build.gant | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/python/edu/build/pycharm_edu_build.gant b/python/edu/build/pycharm_edu_build.gant
index 28d829e68b34..b1fbedd83483 100644
--- a/python/edu/build/pycharm_edu_build.gant
+++ b/python/edu/build/pycharm_edu_build.gant
@@ -405,7 +405,7 @@ private layoutMac(Map _args, String target) {
args.icns = "$pythonCommunityHome/resources/PyCharmCore.icns"
args.bundleIdentifier = "com.jetbrains.pycharm"
args.platform_prefix = "PyCharmEdu"
- args.help_id = "PY"
+ args.help_id = "PE"
args."idea.properties.path" = "${paths.distAll}/bin/idea.properties"
args."idea.properties" = ["idea.no.jre.check": true, "ide.mac.useNativeClipboard": "false"];
layoutMacApp(target, ch, args)
From 4c8623b4d49131ce52c7f44be5e7e0cd86b2a3c5 Mon Sep 17 00:00:00 2001
From: Anna Kozlova
Date: Wed, 3 Sep 2014 19:24:44 +0400
Subject: [PATCH 14/60] completion inside lambda: accept 'reference'
non-physical statements
---
java/java-psi-api/src/com/intellij/psi/LambdaUtil.java | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java
index 198bad10c1db..8ff42ca085a0 100644
--- a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java
+++ b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java
@@ -484,7 +484,8 @@ public class LambdaUtil {
(((PsiPrefixExpression)body).getOperationTokenType() == JavaTokenType.PLUSPLUS ||
((PsiPrefixExpression)body).getOperationTokenType() == JavaTokenType.MINUSMINUS) ||
body instanceof PsiPostfixExpression ||
- body instanceof PsiCallExpression;
+ body instanceof PsiCallExpression ||
+ body instanceof PsiReferenceExpression && !body.isPhysical();
}
public static class TypeParamsChecker extends PsiTypeVisitor {
From ba97617e23af5aef1b4b6337254fbd06216985ff Mon Sep 17 00:00:00 2001
From: Nadya Zabrodina
Date: Wed, 3 Sep 2014 17:52:20 +0400
Subject: [PATCH 15/60] Refactoring: common git&hg branchPopup and sync branch
settings moved to dvcs
* common methods and fields moved to parent class to dvcs;
* common branch sync settings interface added to unify several cases;
* generics for Repository added;
* annotations added;
---
.../com/intellij/dvcs/repo/Repository.java | 8 +-
.../intellij/dvcs/branch/DvcsBranchPopup.java | 174 ++++++++++++++++++
.../intellij/dvcs/branch/DvcsBranchSync.java | 9 +-
.../branch/DvcsMultiRootBranchConfig.java | 71 +++++++
.../dvcs/branch/DvcsSyncBranchSettings.java | 25 +++
.../src/git4idea/config/GitVcsPanel.java | 9 +-
.../src/git4idea/config/GitVcsSettings.java | 11 +-
.../src/git4idea/repo/GitRepositoryImpl.java | 8 +-
.../git4idea/ui/branch/GitBranchPopup.java | 163 +++-------------
.../ui/branch/GitMultiRootBranchConfig.java | 49 +----
.../tests/git4idea/log/GitRefManagerTest.java | 6 +
.../zmlx/hg4idea/repo/HgRepositoryImpl.java | 14 ++
12 files changed, 348 insertions(+), 199 deletions(-)
create mode 100644 platform/dvcs-impl/src/com/intellij/dvcs/branch/DvcsBranchPopup.java
rename plugins/git4idea/src/git4idea/ui/branch/GitBranchSyncSetting.java => platform/dvcs-impl/src/com/intellij/dvcs/branch/DvcsBranchSync.java (80%)
create mode 100644 platform/dvcs-impl/src/com/intellij/dvcs/branch/DvcsMultiRootBranchConfig.java
create mode 100644 platform/dvcs-impl/src/com/intellij/dvcs/branch/DvcsSyncBranchSettings.java
diff --git a/platform/dvcs-api/src/com/intellij/dvcs/repo/Repository.java b/platform/dvcs-api/src/com/intellij/dvcs/repo/Repository.java
index 47cc17866c08..c269d7ba993e 100644
--- a/platform/dvcs-api/src/com/intellij/dvcs/repo/Repository.java
+++ b/platform/dvcs-api/src/com/intellij/dvcs/repo/Repository.java
@@ -54,6 +54,8 @@ import org.jetbrains.annotations.Nullable;
public interface Repository extends Disposable {
+
+
/**
* Current state of the repository.
*/
@@ -83,9 +85,8 @@ public interface Repository extends Disposable {
/**
* Detached HEAD state, but not during rebase (for example, manual checkout of a commit hash).
*/
- DETACHED
+ DETACHED;
}
-
@NotNull
VirtualFile getRoot();
@@ -98,6 +99,9 @@ public interface Repository extends Disposable {
@NotNull
State getState();
+ @Nullable
+ String getCurrentBranchName();
+
@Nullable
AbstractVcs getVcs();
diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/branch/DvcsBranchPopup.java b/platform/dvcs-impl/src/com/intellij/dvcs/branch/DvcsBranchPopup.java
new file mode 100644
index 000000000000..a98cf27ab5d6
--- /dev/null
+++ b/platform/dvcs-impl/src/com/intellij/dvcs/branch/DvcsBranchPopup.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright 2000-2014 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.dvcs.branch;
+
+import com.intellij.dvcs.DvcsUtil;
+import com.intellij.dvcs.repo.AbstractRepositoryManager;
+import com.intellij.dvcs.repo.Repository;
+import com.intellij.dvcs.ui.BranchActionGroupPopup;
+import com.intellij.notification.Notification;
+import com.intellij.notification.NotificationListener;
+import com.intellij.openapi.actionSystem.ActionGroup;
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.DefaultActionGroup;
+import com.intellij.openapi.options.ShowSettingsUtil;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.popup.ListPopup;
+import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.vcs.AbstractVcs;
+import com.intellij.openapi.vcs.VcsNotifier;
+import com.intellij.ui.popup.list.ListPopupImpl;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import javax.swing.event.HyperlinkEvent;
+import java.util.List;
+
+public abstract class DvcsBranchPopup {
+ @NotNull protected final Project myProject;
+ @NotNull protected final AbstractRepositoryManager myRepositoryManager;
+ @NotNull protected final DvcsSyncBranchSettings myVcsSettings;
+ @NotNull protected final AbstractVcs myVcs;
+ @NotNull protected final DvcsMultiRootBranchConfig myMultiRootBranchConfig;
+
+ @NotNull protected final Repo myCurrentRepository;
+ @NotNull protected final ListPopupImpl myPopup;
+
+ protected DvcsBranchPopup(@NotNull Repo currentRepository,
+ @NotNull AbstractRepositoryManager repositoryManager,
+ @NotNull DvcsMultiRootBranchConfig multiRootBranchConfig,
+ @NotNull DvcsSyncBranchSettings vcsSettings,
+ @NotNull Condition preselectActionCondition) {
+ myProject = currentRepository.getProject();
+ myCurrentRepository = currentRepository;
+ myRepositoryManager = repositoryManager;
+ myVcs = currentRepository.getVcs();
+ myVcsSettings = vcsSettings;
+ myMultiRootBranchConfig = multiRootBranchConfig;
+ String title = createPopupTitle(currentRepository);
+ myPopup = new BranchActionGroupPopup(title, myProject, preselectActionCondition, createActions());
+
+ initBranchSyncPolicyIfNotInitialized();
+ setCurrentBranchInfo();
+ warnThatBranchesDivergedIfNeeded();
+ }
+
+ public ListPopup asListPopup() {
+ return myPopup;
+ }
+
+ private void initBranchSyncPolicyIfNotInitialized() {
+ if (myRepositoryManager.moreThanOneRoot() && myVcsSettings.getSyncSetting() == DvcsBranchSync.NOT_DECIDED) {
+ if (!myMultiRootBranchConfig.diverged()) {
+ notifyAboutSyncedBranches();
+ myVcsSettings.setSyncSetting(DvcsBranchSync.SYNC);
+ }
+ else {
+ myVcsSettings.setSyncSetting(DvcsBranchSync.DONT);
+ }
+ }
+ }
+
+ @NotNull
+ private String createPopupTitle(@NotNull Repo currentRepository) {
+ String title = myVcs.getDisplayName() + " Branches";
+ if (myRepositoryManager.moreThanOneRoot() &&
+ (myMultiRootBranchConfig.diverged() || myVcsSettings.getSyncSetting() == DvcsBranchSync.DONT)) {
+ title += " in " + DvcsUtil.getShortRepositoryName(currentRepository);
+ }
+ return title;
+ }
+
+ protected void setCurrentBranchInfo() {
+ String branchText = "Current branch : ";
+ myPopup.setAdText(branchText + myCurrentRepository.getCurrentBranchName(), SwingConstants.CENTER);
+ }
+
+ private void notifyAboutSyncedBranches() {
+ String description =
+ "You have several " + myVcs.getDisplayName() + "roots in the project and they all are checked out at the same branch. " +
+ "We've enabled synchronous branch control for the project.
" +
+ "If you wish to control branches in different roots separately, " +
+ "you may disable the setting.";
+ NotificationListener listener = new NotificationListener() {
+ @Override
+ public void hyperlinkUpdate(@NotNull Notification notification, @NotNull HyperlinkEvent event) {
+ if (event.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
+ ShowSettingsUtil.getInstance().showSettingsDialog(myProject, myVcs.getConfigurable().getDisplayName());
+ if (myVcsSettings.getSyncSetting() == DvcsBranchSync.DONT) {
+ notification.expire();
+ }
+ }
+ }
+ };
+ VcsNotifier.getInstance(myProject).notifyImportantInfo("Synchronous branch control enabled", description, listener);
+ }
+
+ @NotNull
+ private ActionGroup createActions() {
+ DefaultActionGroup popupGroup = new DefaultActionGroup(null, false);
+ AbstractRepositoryManager repositoryManager = myRepositoryManager;
+ if (repositoryManager.moreThanOneRoot()) {
+ if (userWantsSyncControl()) {
+ fillWithCommonRepositoryActions(popupGroup, repositoryManager);
+ }
+ else {
+ fillPopupWithCurrentRepositoryActions(popupGroup, createRepositoriesActions());
+ }
+ }
+ else {
+ fillPopupWithCurrentRepositoryActions(popupGroup, null);
+ }
+ popupGroup.addSeparator();
+ return popupGroup;
+ }
+
+ private boolean userWantsSyncControl() {
+ return (myVcsSettings.getSyncSetting() != DvcsBranchSync.DONT);
+ }
+
+ protected abstract void fillWithCommonRepositoryActions(@NotNull DefaultActionGroup popupGroup,
+ @NotNull AbstractRepositoryManager repositoryManager);
+
+ @NotNull
+ protected List filterRepositoriesNotOnThisBranch(@NotNull final String branch,
+ @NotNull List allRepositories) {
+ return ContainerUtil.filter(allRepositories, new Condition() {
+ @Override
+ public boolean value(Repo repository) {
+ return !branch.equals(repository.getCurrentBranchName());
+ }
+ });
+ }
+
+ private void warnThatBranchesDivergedIfNeeded() {
+ if (myRepositoryManager.moreThanOneRoot() && myMultiRootBranchConfig.diverged() && userWantsSyncControl()) {
+ myPopup.setWarning("Branches have diverged");
+ }
+ }
+
+ @NotNull
+ protected abstract DefaultActionGroup createRepositoriesActions();
+
+ protected boolean highlightCurrentRepo() {
+ return !userWantsSyncControl() || myMultiRootBranchConfig.diverged();
+ }
+
+ protected abstract void fillPopupWithCurrentRepositoryActions(@NotNull DefaultActionGroup popupGroup,
+ @Nullable DefaultActionGroup actions);
+}
diff --git a/plugins/git4idea/src/git4idea/ui/branch/GitBranchSyncSetting.java b/platform/dvcs-impl/src/com/intellij/dvcs/branch/DvcsBranchSync.java
similarity index 80%
rename from plugins/git4idea/src/git4idea/ui/branch/GitBranchSyncSetting.java
rename to platform/dvcs-impl/src/com/intellij/dvcs/branch/DvcsBranchSync.java
index bb9c7592f028..9fab273be2e1 100644
--- a/plugins/git4idea/src/git4idea/ui/branch/GitBranchSyncSetting.java
+++ b/platform/dvcs-impl/src/com/intellij/dvcs/branch/DvcsBranchSync.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -13,12 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package git4idea.ui.branch;
+package com.intellij.dvcs.branch;
-/**
- * @author Kirill Likhodedov
- */
-public enum GitBranchSyncSetting {
+public enum DvcsBranchSync {
SYNC,
DONT,
NOT_DECIDED
diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/branch/DvcsMultiRootBranchConfig.java b/platform/dvcs-impl/src/com/intellij/dvcs/branch/DvcsMultiRootBranchConfig.java
new file mode 100644
index 000000000000..ee24209167fa
--- /dev/null
+++ b/platform/dvcs-impl/src/com/intellij/dvcs/branch/DvcsMultiRootBranchConfig.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2000-2014 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.dvcs.branch;
+
+import com.intellij.dvcs.repo.Repository;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+
+public abstract class DvcsMultiRootBranchConfig {
+ @NotNull protected final Collection myRepositories;
+
+ public DvcsMultiRootBranchConfig(@NotNull Collection repositories) {
+ myRepositories = repositories;
+ }
+
+ public boolean diverged() {
+ return getCurrentBranch() == null;
+ }
+
+ @Nullable
+ public String getCurrentBranch() {
+ String commonBranch = null;
+ for (Repo repository : myRepositories) {
+ String branchName = repository.getCurrentBranchName();
+ if (branchName == null) {
+ return null;
+ }
+ // NB: if all repositories are in the rebasing state on the same branches, this branch is returned
+ if (commonBranch == null) {
+ commonBranch = branchName;
+ }
+ else if (!commonBranch.equals(branchName)) {
+ return null;
+ }
+ }
+ return commonBranch;
+ }
+
+ @Nullable
+ public Repository.State getState() {
+ Repository.State commonState = null;
+ for (Repo repository : myRepositories) {
+ Repository.State state = repository.getState();
+ if (commonState == null) {
+ commonState = state;
+ }
+ else if (!commonState.equals(state)) {
+ return null;
+ }
+ }
+ return commonState;
+ }
+
+ @NotNull
+ public abstract Collection getLocalBranchNames();
+}
diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/branch/DvcsSyncBranchSettings.java b/platform/dvcs-impl/src/com/intellij/dvcs/branch/DvcsSyncBranchSettings.java
new file mode 100644
index 000000000000..115872a66552
--- /dev/null
+++ b/platform/dvcs-impl/src/com/intellij/dvcs/branch/DvcsSyncBranchSettings.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2000-2014 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.dvcs.branch;
+
+import org.jetbrains.annotations.NotNull;
+
+public interface DvcsSyncBranchSettings {
+ @NotNull
+ DvcsBranchSync getSyncSetting();
+
+ void setSyncSetting(@NotNull DvcsBranchSync syncSetting);
+}
diff --git a/plugins/git4idea/src/git4idea/config/GitVcsPanel.java b/plugins/git4idea/src/git4idea/config/GitVcsPanel.java
index a8ebfe66140f..3a4cab90deb3 100644
--- a/plugins/git4idea/src/git4idea/config/GitVcsPanel.java
+++ b/plugins/git4idea/src/git4idea/config/GitVcsPanel.java
@@ -15,18 +15,17 @@
*/
package git4idea.config;
+import com.intellij.dvcs.branch.DvcsBranchSync;
import com.intellij.openapi.application.ApplicationNamesInfo;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
-import com.intellij.openapi.util.SystemInfo;
import com.intellij.ui.components.JBCheckBox;
import git4idea.GitVcs;
import git4idea.i18n.GitBundle;
import git4idea.repo.GitRepositoryManager;
-import git4idea.ui.branch.GitBranchSyncSetting;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
@@ -119,7 +118,7 @@ public class GitVcsPanel {
myGitField.setText(settings.getAppSettings().getPathToGit());
mySSHExecutableComboBox.setSelectedItem(settings.isIdeaSsh() ? IDEA_SSH : NATIVE_SSH);
myAutoUpdateIfPushRejected.setSelected(settings.autoUpdateIfPushRejected());
- mySyncBranchControl.setSelected(settings.getSyncSetting() == GitBranchSyncSetting.SYNC);
+ mySyncBranchControl.setSelected(settings.getSyncSetting() == DvcsBranchSync.SYNC);
myAutoCommitOnCherryPick.setSelected(settings.isAutoCommitOnCherryPick());
myWarnAboutCrlf.setSelected(settings.warnAboutCrlf());
}
@@ -133,7 +132,7 @@ public class GitVcsPanel {
return !settings.getAppSettings().getPathToGit().equals(getCurrentExecutablePath()) ||
(settings.isIdeaSsh() != IDEA_SSH.equals(mySSHExecutableComboBox.getSelectedItem())) ||
!settings.autoUpdateIfPushRejected() == myAutoUpdateIfPushRejected.isSelected() ||
- ((settings.getSyncSetting() == GitBranchSyncSetting.SYNC) != mySyncBranchControl.isSelected() ||
+ ((settings.getSyncSetting() == DvcsBranchSync.SYNC) != mySyncBranchControl.isSelected() ||
settings.isAutoCommitOnCherryPick() != myAutoCommitOnCherryPick.isSelected() ||
settings.warnAboutCrlf() != myWarnAboutCrlf.isSelected());
}
@@ -151,7 +150,7 @@ public class GitVcsPanel {
GitVcsApplicationSettings.SshExecutable.NATIVE_SSH);
settings.setAutoUpdateIfPushRejected(myAutoUpdateIfPushRejected.isSelected());
- settings.setSyncSetting(mySyncBranchControl.isSelected() ? GitBranchSyncSetting.SYNC : GitBranchSyncSetting.DONT);
+ settings.setSyncSetting(mySyncBranchControl.isSelected() ? DvcsBranchSync.SYNC : DvcsBranchSync.DONT);
settings.setAutoCommitOnCherryPick(myAutoCommitOnCherryPick.isSelected());
settings.setWarnAboutCrlf(myWarnAboutCrlf.isSelected());
}
diff --git a/plugins/git4idea/src/git4idea/config/GitVcsSettings.java b/plugins/git4idea/src/git4idea/config/GitVcsSettings.java
index 1b5860631e59..de268c372327 100644
--- a/plugins/git4idea/src/git4idea/config/GitVcsSettings.java
+++ b/plugins/git4idea/src/git4idea/config/GitVcsSettings.java
@@ -15,12 +15,13 @@
*/
package git4idea.config;
+import com.intellij.dvcs.branch.DvcsBranchSync;
+import com.intellij.dvcs.branch.DvcsSyncBranchSettings;
import com.intellij.lifecycle.PeriodicalTasksCloser;
import com.intellij.openapi.components.*;
import com.intellij.openapi.project.Project;
import com.intellij.util.ArrayUtil;
import git4idea.reset.GitResetMode;
-import git4idea.ui.branch.GitBranchSyncSetting;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -33,7 +34,7 @@ import java.util.Map;
* Git VCS settings
*/
@State(name = "Git.Settings", roamingType = RoamingType.DISABLED, storages = {@Storage(file = StoragePathMacros.WORKSPACE_FILE)})
-public class GitVcsSettings implements PersistentStateComponent {
+public class GitVcsSettings implements PersistentStateComponent, DvcsSyncBranchSettings {
private static final int PREVIOUS_COMMIT_AUTHORS_LIMIT = 16; // Limit for previous commit authors
@@ -56,7 +57,7 @@ public class GitVcsSettings implements PersistentStateComponent RECENT_BRANCH_BY_REPOSITORY = new HashMap();
public String RECENT_COMMON_BRANCH = null;
@@ -128,11 +129,11 @@ public class GitVcsSettings implements PersistentStateComponent
*/
-class GitBranchPopup {
-
- private final Project myProject;
- private final GitRepositoryManager myRepositoryManager;
- private final GitVcsSettings myVcsSettings;
- private final GitVcs myVcs;
- private final GitMultiRootBranchConfig myMultiRootBranchConfig;
-
- private final GitRepository myCurrentRepository;
- private final ListPopupImpl myPopup;
-
- ListPopup asListPopup() {
- return myPopup;
- }
+class GitBranchPopup extends DvcsBranchPopup {
/**
* @param currentRepository Current repository, which means the repository of the currently open or selected file.
* In the case of synchronized branch operations current repository matter much less, but sometimes is used,
* for example, it is preselected in the repositories combobox in the compare branches dialog.
*/
- static GitBranchPopup getInstance(@NotNull Project project, @NotNull GitRepository currentRepository) {
- return new GitBranchPopup(project, currentRepository);
- }
-
- private GitBranchPopup(@NotNull Project project, @NotNull GitRepository currentRepository) {
- myProject = project;
- myCurrentRepository = currentRepository;
- myRepositoryManager = GitUtil.getRepositoryManager(project);
- myVcs = GitVcs.getInstance(project);
- myVcsSettings = GitVcsSettings.getInstance(myProject);
-
- myMultiRootBranchConfig = new GitMultiRootBranchConfig(myRepositoryManager.getRepositories());
-
- String title = createPopupTitle(currentRepository);
-
+ static GitBranchPopup getInstance(@NotNull final Project project, @NotNull GitRepository currentRepository) {
+ final GitVcsSettings vcsSettings = GitVcsSettings.getInstance(project);
Condition preselectActionCondition = new Condition() {
@Override
public boolean value(AnAction action) {
+
if (action instanceof GitBranchPopupActions.LocalBranchActions) {
GitBranchPopupActions.LocalBranchActions branchAction = (GitBranchPopupActions.LocalBranchActions)action;
String branchName = branchAction.getBranchName();
@@ -93,10 +58,10 @@ class GitBranchPopup {
String recentBranch;
List repositories = branchAction.getRepositories();
if (repositories.size() == 1) {
- recentBranch = myVcsSettings.getRecentBranchesByRepository().get(repositories.iterator().next().getRoot().getPath());
+ recentBranch = vcsSettings.getRecentBranchesByRepository().get(repositories.iterator().next().getRoot().getPath());
}
else {
- recentBranch = myVcsSettings.getRecentCommonBranch();
+ recentBranch = vcsSettings.getRecentCommonBranch();
}
if (recentBranch != null && recentBranch.equals(branchName)) {
@@ -106,37 +71,19 @@ class GitBranchPopup {
return false;
}
};
-
- myPopup = new BranchActionGroupPopup(title, project, preselectActionCondition, createActions());
-
- initBranchSyncPolicyIfNotInitialized();
- setCurrentBranchInfo();
- warnThatBranchesDivergedIfNeeded();
+ return new GitBranchPopup(currentRepository, GitUtil.getRepositoryManager(project), vcsSettings, preselectActionCondition);
}
- private void initBranchSyncPolicyIfNotInitialized() {
- if (myRepositoryManager.moreThanOneRoot() && myVcsSettings.getSyncSetting() == GitBranchSyncSetting.NOT_DECIDED) {
- if (!myMultiRootBranchConfig.diverged()) {
- notifyAboutSyncedBranches();
- myVcsSettings.setSyncSetting(GitBranchSyncSetting.SYNC);
- }
- else {
- myVcsSettings.setSyncSetting(GitBranchSyncSetting.DONT);
- }
- }
+ private GitBranchPopup(@NotNull GitRepository currentRepository,
+ @NotNull GitRepositoryManager repositoryManager,
+ @NotNull GitVcsSettings vcsSettings,
+ @NotNull Condition preselectActionCondition) {
+ super(currentRepository, repositoryManager, new GitMultiRootBranchConfig(repositoryManager.getRepositories()), vcsSettings,
+ preselectActionCondition);
}
- @NotNull
- private String createPopupTitle(@NotNull GitRepository currentRepository) {
- String title = "Git Branches";
- if (myRepositoryManager.moreThanOneRoot() &&
- (myMultiRootBranchConfig.diverged() || myVcsSettings.getSyncSetting() == GitBranchSyncSetting.DONT)) {
- title += " in " + DvcsUtil.getShortRepositoryName(currentRepository);
- }
- return title;
- }
-
- private void setCurrentBranchInfo() {
+ @Override
+ protected void setCurrentBranchInfo() {
String currentBranchText = "Current branch";
if (myRepositoryManager.moreThanOneRoot()) {
if (myMultiRootBranchConfig.diverged()) {
@@ -153,55 +100,16 @@ class GitBranchPopup {
myPopup.setAdText(currentBranchText, SwingConstants.CENTER);
}
- private void notifyAboutSyncedBranches() {
- String description = "You have several Git roots in the project and they all are checked out at the same branch. " +
- "We've enabled synchronous branch control for the project.
" +
- "If you wish to control branches in different roots separately, " +
- "you may disable the setting.";
- NotificationListener listener = new NotificationListener() {
- @Override
- public void hyperlinkUpdate(@NotNull Notification notification, @NotNull HyperlinkEvent event) {
- if (event.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
- ShowSettingsUtil.getInstance().showSettingsDialog(myProject, myVcs.getConfigurable().getDisplayName());
- if (myVcsSettings.getSyncSetting() == GitBranchSyncSetting.DONT) {
- notification.expire();
- }
- }
- }
- };
- VcsNotifier.getInstance(myProject).notifyImportantInfo("Synchronous branch control enabled", description, listener);
- }
-
- private ActionGroup createActions() {
- DefaultActionGroup popupGroup = new DefaultActionGroup(null, false);
- GitRepositoryManager repositoryManager = myRepositoryManager;
- if (repositoryManager.moreThanOneRoot()) {
- if (userWantsSyncControl()) {
- fillWithCommonRepositoryActions(popupGroup, repositoryManager);
- }
- else {
- fillPopupWithCurrentRepositoryActions(popupGroup, createRepositoriesActions());
- }
- }
- else {
- fillPopupWithCurrentRepositoryActions(popupGroup, null);
- }
- popupGroup.addSeparator();
- return popupGroup;
- }
-
- private boolean userWantsSyncControl() {
- return (myVcsSettings.getSyncSetting() != GitBranchSyncSetting.DONT);
- }
-
- private void fillWithCommonRepositoryActions(DefaultActionGroup popupGroup, GitRepositoryManager repositoryManager) {
+ @Override
+ protected void fillWithCommonRepositoryActions(@NotNull DefaultActionGroup popupGroup,
+ @NotNull AbstractRepositoryManager repositoryManager) {
List allRepositories = repositoryManager.getRepositories();
popupGroup.add(new GitBranchPopupActions.GitNewBranchAction(myProject, allRepositories));
popupGroup.addAll(createRepositoriesActions());
popupGroup.addSeparator("Common Local Branches");
- for (String branch : myMultiRootBranchConfig.getLocalBranches()) {
+ for (String branch : myMultiRootBranchConfig.getLocalBranchNames()) {
List repositories = filterRepositoriesNotOnThisBranch(branch, allRepositories);
if (!repositories.isEmpty()) {
popupGroup.add(new GitBranchPopupActions.LocalBranchActions(myProject, repositories, branch, myCurrentRepository));
@@ -209,30 +117,14 @@ class GitBranchPopup {
}
popupGroup.addSeparator("Common Remote Branches");
- for (String branch : myMultiRootBranchConfig.getRemoteBranches()) {
+ for (String branch : ((GitMultiRootBranchConfig)myMultiRootBranchConfig).getRemoteBranches()) {
popupGroup.add(new GitBranchPopupActions.RemoteBranchActions(myProject, allRepositories, branch, myCurrentRepository));
}
}
@NotNull
- private static List filterRepositoriesNotOnThisBranch(@NotNull final String branch,
- @NotNull List allRepositories) {
- return ContainerUtil.filter(allRepositories, new Condition() {
- @Override
- public boolean value(GitRepository repository) {
- GitLocalBranch currentBranch = repository.getCurrentBranch();
- return currentBranch == null || !branch.equals(currentBranch.getName());
- }
- });
- }
-
- private void warnThatBranchesDivergedIfNeeded() {
- if (myRepositoryManager.moreThanOneRoot() && myMultiRootBranchConfig.diverged() && userWantsSyncControl()) {
- myPopup.setWarning("Branches have diverged");
- }
- }
-
- private DefaultActionGroup createRepositoriesActions() {
+ @Override
+ protected DefaultActionGroup createRepositoriesActions() {
DefaultActionGroup popupGroup = new DefaultActionGroup(null, false);
popupGroup.addSeparator("Repositories");
for (GitRepository repository : myRepositoryManager.getRepositories()) {
@@ -243,11 +135,8 @@ class GitBranchPopup {
return popupGroup;
}
- private boolean highlightCurrentRepo() {
- return !userWantsSyncControl() || myMultiRootBranchConfig.diverged();
- }
-
- private void fillPopupWithCurrentRepositoryActions(@NotNull DefaultActionGroup popupGroup, @Nullable DefaultActionGroup actions) {
+ @Override
+ protected void fillPopupWithCurrentRepositoryActions(@NotNull DefaultActionGroup popupGroup, @Nullable DefaultActionGroup actions) {
popupGroup.addAll(new GitBranchPopupActions(myCurrentRepository.getProject(), myCurrentRepository).createActions(actions));
}
}
diff --git a/plugins/git4idea/src/git4idea/ui/branch/GitMultiRootBranchConfig.java b/plugins/git4idea/src/git4idea/ui/branch/GitMultiRootBranchConfig.java
index ba4dd2aab369..18076a1b9a61 100644
--- a/plugins/git4idea/src/git4idea/ui/branch/GitMultiRootBranchConfig.java
+++ b/plugins/git4idea/src/git4idea/ui/branch/GitMultiRootBranchConfig.java
@@ -15,8 +15,8 @@
*/
package git4idea.ui.branch;
+import com.intellij.dvcs.branch.DvcsMultiRootBranchConfig;
import com.intellij.util.containers.ContainerUtil;
-import git4idea.GitBranch;
import git4idea.GitLocalBranch;
import git4idea.GitRemoteBranch;
import git4idea.branch.GitBranchUtil;
@@ -32,54 +32,17 @@ import java.util.Collections;
/**
* @author Kirill Likhodedov
*/
-public class GitMultiRootBranchConfig {
-
- private final Collection myRepositories;
+public class GitMultiRootBranchConfig extends DvcsMultiRootBranchConfig {
public GitMultiRootBranchConfig(@NotNull Collection repositories) {
- myRepositories = repositories;
+ super(repositories);
}
- boolean diverged() {
- return getCurrentBranch() == null;
- }
-
- @Nullable
- public String getCurrentBranch() {
- String commonBranch = null;
- for (GitRepository repository : myRepositories) {
- GitBranch branch = repository.getCurrentBranch();
- if (branch == null) {
- return null;
- }
- // NB: if all repositories are in the rebasing state on the same branches, this branch is returned
- if (commonBranch == null) {
- commonBranch = branch.getName();
- } else if (!commonBranch.equals(branch.getName())) {
- return null;
- }
- }
- return commonBranch;
- }
-
- @Nullable
- GitRepository.State getState() {
- GitRepository.State commonState = null;
- for (GitRepository repository : myRepositories) {
- GitRepository.State state = repository.getState();
- if (commonState == null) {
- commonState = state;
- } else if (!commonState.equals(state)) {
- return null;
- }
- }
- return commonState;
- }
-
+ @Override
@NotNull
- Collection getLocalBranches() {
+ public Collection getLocalBranchNames() {
return GitBranchUtil.getCommonBranches(myRepositories, true);
- }
+ }
@NotNull
Collection getRemoteBranches() {
diff --git a/plugins/git4idea/tests/git4idea/log/GitRefManagerTest.java b/plugins/git4idea/tests/git4idea/log/GitRefManagerTest.java
index 2ce560800066..39d5946c90ff 100644
--- a/plugins/git4idea/tests/git4idea/log/GitRefManagerTest.java
+++ b/plugins/git4idea/tests/git4idea/log/GitRefManagerTest.java
@@ -284,6 +284,12 @@ public class GitRefManagerTest extends UsefulTestCase {
throw new UnsupportedOperationException();
}
+ @Nullable
+ @Override
+ public String getCurrentBranchName() {
+ throw new UnsupportedOperationException();
+ }
+
@Nullable
@Override
public AbstractVcs getVcs() {
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryImpl.java b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryImpl.java
index b670fb056c0c..38c9bc328c25 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryImpl.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryImpl.java
@@ -21,6 +21,7 @@ import com.intellij.openapi.Disposable;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.AbstractVcs;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
@@ -97,6 +98,19 @@ public class HgRepositoryImpl extends RepositoryImpl implements HgRepository {
return myInfo.getState();
}
+ @Nullable
+ @Override
+ /**
+ * Return active bookmark name if exist or heavy branch name otherwise
+ */
+ public String getCurrentBranchName() {
+ String branchOrBookMarkName = getCurrentBookmark();
+ if (StringUtil.isEmptyOrSpaces(branchOrBookMarkName)) {
+ branchOrBookMarkName = getCurrentBranch();
+ }
+ return branchOrBookMarkName;
+ }
+
@Nullable
@Override
public AbstractVcs getVcs() {
From 712a256eb68c6fdafb21a07e44105f5cfd4fada3 Mon Sep 17 00:00:00 2001
From: Nadya Zabrodina
Date: Wed, 3 Sep 2014 17:57:47 +0400
Subject: [PATCH 16/60] unnecessary method removed
---
plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUtil.java | 11 +----------
1 file changed, 1 insertion(+), 10 deletions(-)
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUtil.java b/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUtil.java
index d055ca247129..fcf275f70703 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUtil.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUtil.java
@@ -585,16 +585,7 @@ public abstract class HgUtil {
if (state != HgRepository.State.NORMAL) {
branchText += state.toString() + " ";
}
- return branchText + getActiveBranchName(repository);
- }
-
- @NotNull
- public static String getActiveBranchName(@NotNull HgRepository repository) {
- String branchOrBookMarkName = repository.getCurrentBookmark();
- if (StringUtil.isEmptyOrSpaces(branchOrBookMarkName)) {
- branchOrBookMarkName = repository.getCurrentBranch();
- }
- return branchOrBookMarkName;
+ return branchText + repository.getCurrentBranchName();
}
@NotNull
From 360d6f0bf100546d34d97304ad4154ccac1076c4 Mon Sep 17 00:00:00 2001
From: Nadya Zabrodina
Date: Wed, 3 Sep 2014 19:16:45 +0400
Subject: [PATCH 17/60] Tracking hg branches and bookmarks synchronously
implemented
* appropriate setting added to hg project configuration panel;
* branch actions modified and now accept list of sync tracked repositories;
* branch widget updated;
* annotations added;
---
plugins/hg4idea/src/META-INF/plugin.xml | 2 +-
.../org/zmlx/hg4idea/HgProjectSettings.java | 15 +-
.../action/HgAbstractGlobalAction.java | 2 +-
.../zmlx/hg4idea/action/HgBranchPopup.java | 127 ----------------
.../hg4idea/action/HgCommonBranchActions.java | 133 -----------------
.../HgBranchAbstractAction.java | 10 +-
.../zmlx/hg4idea/branch/HgBranchPopup.java | 119 +++++++++++++++
.../HgBranchPopupActions.java | 80 +++++-----
.../org/zmlx/hg4idea/branch/HgBranchUtil.java | 77 ++++++++++
.../{action => branch}/HgBranchesAction.java | 3 +-
.../hg4idea/branch/HgCommonBranchActions.java | 141 ++++++++++++++++++
.../branch/HgMultiRootBranchConfig.java | 50 +++++++
.../org/zmlx/hg4idea/push/HgPushSupport.java | 2 +-
.../hg4idea/status/ui/HgStatusWidget.java | 2 +-
.../ui/HgConfigurationProjectPanel.form | 46 ++++--
.../ui/HgConfigurationProjectPanel.java | 11 ++
16 files changed, 502 insertions(+), 318 deletions(-)
delete mode 100644 plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchPopup.java
delete mode 100644 plugins/hg4idea/src/org/zmlx/hg4idea/action/HgCommonBranchActions.java
rename plugins/hg4idea/src/org/zmlx/hg4idea/{action => branch}/HgBranchAbstractAction.java (83%)
create mode 100644 plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgBranchPopup.java
rename plugins/hg4idea/src/org/zmlx/hg4idea/{action => branch}/HgBranchPopupActions.java (77%)
create mode 100644 plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgBranchUtil.java
rename plugins/hg4idea/src/org/zmlx/hg4idea/{action => branch}/HgBranchesAction.java (92%)
create mode 100644 plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgCommonBranchActions.java
create mode 100644 plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgMultiRootBranchConfig.java
diff --git a/plugins/hg4idea/src/META-INF/plugin.xml b/plugins/hg4idea/src/META-INF/plugin.xml
index 26b69326a703..dc32359a4aec 100644
--- a/plugins/hg4idea/src/META-INF/plugin.xml
+++ b/plugins/hg4idea/src/META-INF/plugin.xml
@@ -75,7 +75,7 @@
-
+
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/HgProjectSettings.java b/plugins/hg4idea/src/org/zmlx/hg4idea/HgProjectSettings.java
index 936587d19755..8abac1bb0b1e 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/HgProjectSettings.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/HgProjectSettings.java
@@ -12,6 +12,8 @@
// limitations under the License.
package org.zmlx.hg4idea;
+import com.intellij.dvcs.branch.DvcsBranchSync;
+import com.intellij.dvcs.branch.DvcsSyncBranchSettings;
import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.openapi.components.State;
import com.intellij.openapi.components.Storage;
@@ -24,7 +26,7 @@ import org.jetbrains.annotations.NotNull;
name = "hg4idea.settings",
storages = @Storage(file = StoragePathMacros.WORKSPACE_FILE)
)
-public class HgProjectSettings implements PersistentStateComponent {
+public class HgProjectSettings implements PersistentStateComponent, DvcsSyncBranchSettings {
@NotNull private final HgGlobalSettings myAppSettings;
@NotNull private final Project myProject;
@@ -37,10 +39,12 @@ public class HgProjectSettings implements PersistentStateComponent
- * The popup which allows to quickly switch and control Hg branches.
- *
- *
- * Use {@link #asListPopup()} to achieve the {@link com.intellij.openapi.ui.popup.ListPopup} itself.
- *
- *
- * @author NadyaZabrodina
- */
-public class HgBranchPopup {
-
- private final Project myProject;
-
- private final HgRepository myCurrentRepository;
- private final ListPopupImpl myPopup;
-
- public ListPopup asListPopup() {
- return myPopup;
- }
-
- /**
- * @param currentRepository Current repository, which means the repository of the currently open or selected file.
- */
- public static HgBranchPopup getInstance(@NotNull Project project, @NotNull HgRepository currentRepository) {
- return new HgBranchPopup(project, currentRepository);
- }
-
- private HgBranchPopup(@NotNull Project project, @NotNull HgRepository currentRepository) {
- myProject = project;
- myCurrentRepository = currentRepository;
- String title = createPopupTitle(currentRepository);
-
- Condition preselectActionCondition = new Condition() {
- @Override
- public boolean value(AnAction action) {
- return false;
- }
- };
- myPopup = new BranchActionGroupPopup(title, project, preselectActionCondition, createActions());
- setCurrentBranchInfo();
- }
-
-
- @NotNull
- private static String createPopupTitle(@NotNull HgRepository currentRepository) {
- String title = "Hg Branches";
- title += " in " + DvcsUtil.getShortRepositoryName(currentRepository);
- return title;
- }
-
- private void setCurrentBranchInfo() {
- String branchText = "Current branch : ";
- //always display heavy branch name for additional info //
- myPopup.setAdText(branchText + myCurrentRepository.getCurrentBranch(), SwingConstants.CENTER);
- }
-
-
- private ActionGroup createActions() {
- DefaultActionGroup popupGroup = new DefaultActionGroup(null, false);
- fillPopupWithCurrentRepositoryActions(popupGroup, createRepositoriesActions());
- popupGroup.addSeparator();
- return popupGroup;
- }
-
-
- @Nullable
- private DefaultActionGroup createRepositoriesActions() {
- List repositories = HgUtil.getHgRepositories(myProject);
- if (repositories.size() == 1) {
- return null; // if project has only one repository all branches, bookmarks and actions should be inline and no repository group needed
- }
- DefaultActionGroup popupGroup = new DefaultActionGroup(null, false);
- popupGroup.addSeparator("Repositories");
- boolean isMultiRepoConfig = repositories.size() > 1;
- for (VirtualFile repository : repositories) {
- HgRepository repo = HgUtil.getRepositoryManager(myProject).getRepositoryForRoot(repository);
- if (repo != null) {
- popupGroup.add(new RootAction(repo, isMultiRepoConfig ? myCurrentRepository : null,
- new HgBranchPopupActions(repo.getProject(), repo).createActions(null),
- HgUtil.getDisplayableBranchOrBookmarkText(repo)));
- }
- }
- return popupGroup;
- }
-
- protected void fillPopupWithCurrentRepositoryActions(@NotNull DefaultActionGroup popupGroup, @Nullable DefaultActionGroup actions) {
- popupGroup.addAll(new HgBranchPopupActions(myProject, myCurrentRepository).createActions(actions));
- }
-}
-
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgCommonBranchActions.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgCommonBranchActions.java
deleted file mode 100644
index c79ae1ca0b7c..000000000000
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgCommonBranchActions.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright 2000-2014 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.zmlx.hg4idea.action;
-
-import com.intellij.openapi.actionSystem.ActionGroup;
-import com.intellij.openapi.actionSystem.AnAction;
-import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.openapi.fileEditor.FileDocumentManager;
-import com.intellij.openapi.progress.ProgressIndicator;
-import com.intellij.openapi.progress.Task;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.vcs.VcsException;
-import com.intellij.openapi.vcs.VcsNotifier;
-import com.intellij.openapi.vcs.update.UpdatedFiles;
-import com.intellij.openapi.vfs.VirtualFile;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.zmlx.hg4idea.HgVcs;
-import org.zmlx.hg4idea.HgVcsMessages;
-import org.zmlx.hg4idea.command.HgMergeCommand;
-import org.zmlx.hg4idea.command.HgUpdateCommand;
-import org.zmlx.hg4idea.execution.HgCommandResult;
-import org.zmlx.hg4idea.provider.update.HgConflictResolver;
-import org.zmlx.hg4idea.provider.update.HgHeadMerger;
-import org.zmlx.hg4idea.repo.HgRepository;
-import org.zmlx.hg4idea.util.HgErrorUtil;
-
-public class HgCommonBranchActions extends ActionGroup {
-
- @NotNull protected final Project myProject;
- @NotNull protected String myBranchName;
- @NotNull protected final HgRepository mySelectedRepository;
-
- HgCommonBranchActions(@NotNull Project project, @NotNull HgRepository selectedRepository, @NotNull String branchName) {
- super("", true);
- myProject = project;
- myBranchName = branchName;
- mySelectedRepository = selectedRepository;
- getTemplatePresentation().setText(myBranchName, false); // no mnemonics
- }
-
- @NotNull
- @Override
- public AnAction[] getChildren(@Nullable AnActionEvent e) {
- return new AnAction[]{
- new UpdateAction(myProject, mySelectedRepository, myBranchName),
- new MergeAction(myProject, mySelectedRepository, myBranchName)
- };
- }
-
- private static class MergeAction extends HgBranchAbstractAction {
-
- public MergeAction(@NotNull Project project,
- @NotNull HgRepository selectedRepository,
- @NotNull String branchName) {
- super(project, "Merge", selectedRepository, branchName);
- }
-
- @Override
- public void actionPerformed(AnActionEvent e) {
- FileDocumentManager.getInstance().saveAllDocuments();
- final UpdatedFiles updatedFiles = UpdatedFiles.create();
- final HgMergeCommand hgMergeCommand = new HgMergeCommand(myProject, mySelectedRepository.getRoot());
- hgMergeCommand.setRevision(myBranchName);//there is no difference between branch or revision or bookmark as parameter to merge,
- // we need just a string
- new Task.Backgroundable(myProject, "Merging changes...") {
- @Override
- public void run(@NotNull ProgressIndicator indicator) {
- try {
- new HgHeadMerger(myProject, hgMergeCommand)
- .merge(mySelectedRepository.getRoot());
- new HgConflictResolver(myProject, updatedFiles).resolve(mySelectedRepository.getRoot());
- }
-
- catch (VcsException exception) {
- assert myProject != null; // myProject couldn't be null, see annotation for Merge action
- if (exception.isWarning()) {
- VcsNotifier.getInstance(myProject).notifyWarning("Warning during merge", exception.getMessage());
- }
- else {
- VcsNotifier.getInstance(myProject).notifyError("Exception during merge", exception.getMessage());
- }
- }
- catch (Exception e1) {
- HgAbstractGlobalAction.handleException(myProject, e1);
- }
- }
- }.queue();
- }
- }
-
- private static class UpdateAction extends HgBranchAbstractAction {
-
- public UpdateAction(@NotNull Project project,
- @NotNull HgRepository selectedRepository,
- @NotNull String branchName) {
- super(project, "Update", selectedRepository, branchName);
- }
-
- @Override
- public void actionPerformed(AnActionEvent e) {
- final VirtualFile repository = mySelectedRepository.getRoot();
- FileDocumentManager.getInstance().saveAllDocuments();
- final HgUpdateCommand hgUpdateCommand = new HgUpdateCommand(myProject, repository);
- hgUpdateCommand.setBranch(myBranchName);
- new Task.Backgroundable(myProject, HgVcsMessages.message("action.hg4idea.updateTo.description", myBranchName)) {
- @Override
- public void run(@NotNull ProgressIndicator indicator) {
- HgCommandResult result = hgUpdateCommand.execute();
- assert myProject != null; // myProject couldn't be null, see annotation for updateTo action
- if (HgErrorUtil.hasErrorsInCommandExecution(result)) {
- new HgCommandResultNotifier(myProject).notifyError(result, "", "Update failed");
- new HgConflictResolver(myProject).resolve(repository);
- }
- myProject.getMessageBus().syncPublisher(HgVcs.BRANCH_TOPIC).update(myProject, null);
- }
- }.queue();
- }
- }
-}
\ No newline at end of file
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchAbstractAction.java b/plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgBranchAbstractAction.java
similarity index 83%
rename from plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchAbstractAction.java
rename to plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgBranchAbstractAction.java
index 78b67013ed54..3998dedd0cc5 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchAbstractAction.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgBranchAbstractAction.java
@@ -13,24 +13,26 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.zmlx.hg4idea.action;
+package org.zmlx.hg4idea.branch;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.zmlx.hg4idea.repo.HgRepository;
+import java.util.List;
+
public abstract class HgBranchAbstractAction extends DumbAwareAction {
@NotNull protected final Project myProject;
- @NotNull protected final HgRepository mySelectedRepository;
+ @NotNull protected final List myRepositories;
@NotNull protected final String myBranchName;
public HgBranchAbstractAction(@NotNull Project project, @NotNull String title,
- @NotNull HgRepository selectedRepository,
+ @NotNull List repositories,
@NotNull String branchName) {
super(title);
myProject = project;
- mySelectedRepository = selectedRepository;
+ myRepositories = repositories;
myBranchName = branchName;
}
}
\ No newline at end of file
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgBranchPopup.java b/plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgBranchPopup.java
new file mode 100644
index 000000000000..c0d6f58d5e0e
--- /dev/null
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgBranchPopup.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2000-2013 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.zmlx.hg4idea.branch;
+
+import com.intellij.dvcs.branch.DvcsBranchPopup;
+import com.intellij.dvcs.repo.AbstractRepositoryManager;
+import com.intellij.dvcs.ui.RootAction;
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.DefaultActionGroup;
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Condition;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.zmlx.hg4idea.HgProjectSettings;
+import org.zmlx.hg4idea.repo.HgRepository;
+import org.zmlx.hg4idea.repo.HgRepositoryManager;
+import org.zmlx.hg4idea.util.HgUtil;
+
+import javax.swing.*;
+import java.util.List;
+
+/**
+ *
+ * The popup which allows to quickly switch and control Hg branches.
+ *
+ *
+ * Use {@link #asListPopup()} to achieve the {@link com.intellij.openapi.ui.popup.ListPopup} itself.
+ *
+ */
+public class HgBranchPopup extends DvcsBranchPopup {
+
+ /**
+ * @param currentRepository Current repository, which means the repository of the currently open or selected file.
+ */
+ public static HgBranchPopup getInstance(@NotNull Project project, @NotNull HgRepository currentRepository) {
+
+ HgRepositoryManager manager = HgUtil.getRepositoryManager(project);
+ HgProjectSettings hgProjectSettings = ServiceManager.getService(project, HgProjectSettings.class);
+ HgMultiRootBranchConfig hgMultiRootBranchConfig = new HgMultiRootBranchConfig(manager.getRepositories());
+
+ Condition preselectActionCondition = new Condition() {
+ @Override
+ public boolean value(AnAction action) {
+ return false;
+ }
+ };
+ return new HgBranchPopup(currentRepository, manager, hgMultiRootBranchConfig, hgProjectSettings,
+ preselectActionCondition);
+ }
+
+ private HgBranchPopup(@NotNull HgRepository currentRepository,
+ @NotNull HgRepositoryManager repositoryManager,
+ @NotNull HgMultiRootBranchConfig hgMultiRootBranchConfig, @NotNull HgProjectSettings vcsSettings,
+ @NotNull Condition preselectActionCondition) {
+ super(currentRepository, repositoryManager, hgMultiRootBranchConfig, vcsSettings, preselectActionCondition);
+ }
+
+ protected void setCurrentBranchInfo() {
+ String branchText = "Current branch : ";
+ //always display heavy branch name for additional info //
+ myPopup.setAdText(branchText + myCurrentRepository.getCurrentBranch(), SwingConstants.CENTER);
+ }
+
+ @Override
+ protected void fillWithCommonRepositoryActions(@NotNull DefaultActionGroup popupGroup,
+ @NotNull AbstractRepositoryManager repositoryManager) {
+ List allRepositories = repositoryManager.getRepositories();
+ popupGroup.add(new HgBranchPopupActions.HgNewBranchAction(myProject, allRepositories, myCurrentRepository));
+ popupGroup.addAction(new HgBranchPopupActions.HgNewBookmarkAction(myProject, allRepositories, myCurrentRepository));
+ popupGroup.addAction(new HgBranchPopupActions.HgShowUnnamedHeadsForCurrentBranchAction(myProject, myCurrentRepository));
+ popupGroup.addAll(createRepositoriesActions());
+
+ popupGroup.addSeparator("Common Branches");
+ for (String branch : myMultiRootBranchConfig.getLocalBranchNames()) {
+ List repositories = filterRepositoriesNotOnThisBranch(branch, allRepositories);
+ if (!repositories.isEmpty()) {
+ popupGroup.add(new HgCommonBranchActions(myProject, repositories, branch));
+ }
+ }
+ popupGroup.addSeparator("Common Bookmarks");
+ for (String branch : ((HgMultiRootBranchConfig)myMultiRootBranchConfig).getBookmarkNames()) {
+ List repositories = filterRepositoriesNotOnThisBranch(branch, allRepositories);
+ if (!repositories.isEmpty()) {
+ popupGroup.add(new HgBranchPopupActions.BookmarkActions(myProject, repositories, branch));
+ }
+ }
+ }
+
+ @NotNull
+ protected DefaultActionGroup createRepositoriesActions() {
+ DefaultActionGroup popupGroup = new DefaultActionGroup(null, false);
+ popupGroup.addSeparator("Repositories");
+ for (HgRepository repository : myRepositoryManager.getRepositories()) {
+ popupGroup.add(new RootAction(repository, highlightCurrentRepo() ? myCurrentRepository : null,
+ new HgBranchPopupActions(repository.getProject(), repository).createActions(null),
+ HgUtil.getDisplayableBranchOrBookmarkText(repository)));
+ }
+ return popupGroup;
+ }
+
+ protected void fillPopupWithCurrentRepositoryActions(@NotNull DefaultActionGroup popupGroup, @Nullable DefaultActionGroup actions) {
+ popupGroup.addAll(new HgBranchPopupActions(myProject, myCurrentRepository).createActions(actions));
+ }
+}
+
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchPopupActions.java b/plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgBranchPopupActions.java
similarity index 77%
rename from plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchPopupActions.java
rename to plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgBranchPopupActions.java
index 45dd12bd9c81..10b97235f559 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchPopupActions.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgBranchPopupActions.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.zmlx.hg4idea.action;
+package org.zmlx.hg4idea.branch;
import com.intellij.dvcs.DvcsUtil;
import com.intellij.dvcs.repo.Repository;
@@ -35,6 +35,8 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.HgNameWithHashInfo;
import org.zmlx.hg4idea.HgRevisionNumber;
+import org.zmlx.hg4idea.action.HgAbstractGlobalAction;
+import org.zmlx.hg4idea.action.HgCommandResultNotifier;
import org.zmlx.hg4idea.command.HgBookmarkCommand;
import org.zmlx.hg4idea.command.HgBranchCreateCommand;
import org.zmlx.hg4idea.command.HgWorkingCopyRevisionsCommand;
@@ -73,7 +75,7 @@ public class HgBranchPopupActions {
List bookmarkNames = getNamesWithoutHashes(myRepository.getBookmarks());
String currentBookmark = myRepository.getCurrentBookmark();
for (String bookmark : bookmarkNames) {
- AnAction bookmarkAction = new BookmarkActions(myProject, myRepository, bookmark);
+ AnAction bookmarkAction = new BookmarkActions(myProject, Collections.singletonList(myRepository), bookmark);
if (bookmark.equals(currentBookmark)) {
bookmarkAction.getTemplatePresentation().setIcon(PlatformIcons.CHECK_ICON);
}
@@ -85,13 +87,13 @@ public class HgBranchPopupActions {
Collections.sort(branchNamesList);
for (String branch : branchNamesList) {
if (!branch.equals(myRepository.getCurrentBranch())) { // don't show current branch in the list
- popupGroup.add(new HgCommonBranchActions(myProject, myRepository, branch));
+ popupGroup.add(new HgCommonBranchActions(myProject, Collections.singletonList(myRepository), branch));
}
}
return popupGroup;
}
- private static class HgNewBranchAction extends NewBranchAction {
+ public static class HgNewBranchAction extends NewBranchAction {
@NotNull final HgRepository myPreselectedRepo;
HgNewBranchAction(@NotNull Project project, @NotNull List repositories, @NotNull HgRepository preselectedRepo) {
@@ -105,25 +107,27 @@ public class HgBranchPopupActions {
if (name == null) {
return;
}
- try {
- new HgBranchCreateCommand(myProject, myPreselectedRepo.getRoot(), name).execute(new HgCommandResultHandler() {
- @Override
- public void process(@Nullable HgCommandResult result) {
- myPreselectedRepo.update();
- if (HgErrorUtil.hasErrorsInCommandExecution(result)) {
- new HgCommandResultNotifier(myProject)
- .notifyError(result, "Creation failed", "Branch creation [" + name + "] failed");
+ for (final HgRepository repository : myRepositories) {
+ try {
+ new HgBranchCreateCommand(myProject, repository.getRoot(), name).execute(new HgCommandResultHandler() {
+ @Override
+ public void process(@Nullable HgCommandResult result) {
+ repository.update();
+ if (HgErrorUtil.hasErrorsInCommandExecution(result)) {
+ new HgCommandResultNotifier(myProject)
+ .notifyError(result, "Creation failed", "Branch creation [" + name + "] failed");
+ }
}
- }
- });
- }
- catch (HgCommandException exception) {
- HgAbstractGlobalAction.handleException(myProject, "Can't create new branch: ", exception);
+ });
+ }
+ catch (HgCommandException exception) {
+ HgAbstractGlobalAction.handleException(myProject, "Can't create new branch: ", exception);
+ }
}
}
}
- private static class HgNewBookmarkAction extends DumbAwareAction {
+ public static class HgNewBookmarkAction extends DumbAwareAction {
@NotNull protected final List myRepositories;
@NotNull protected Project myProject;
@NotNull final HgRepository myPreselectedRepo;
@@ -149,18 +153,20 @@ public class HgBranchPopupActions {
final HgBookmarkDialog bookmarkDialog = new HgBookmarkDialog(myPreselectedRepo);
bookmarkDialog.show();
if (bookmarkDialog.isOK()) {
- try {
- final String name = bookmarkDialog.getName();
- new HgBookmarkCommand(myProject, myPreselectedRepo.getRoot(), name).createBookmark(bookmarkDialog.isActive());
- }
- catch (HgCommandException exception) {
- HgAbstractGlobalAction.handleException(myProject, exception);
+ final String name = bookmarkDialog.getName();
+ for (HgRepository repository : myRepositories) {
+ try {
+ new HgBookmarkCommand(myProject, repository.getRoot(), name).createBookmark(bookmarkDialog.isActive());
+ }
+ catch (HgCommandException exception) {
+ HgAbstractGlobalAction.handleException(myProject, exception);
+ }
}
}
}
}
- static private class HgShowUnnamedHeadsForCurrentBranchAction extends ActionGroup {
+ public static class HgShowUnnamedHeadsForCurrentBranchAction extends ActionGroup {
@NotNull final Project myProject;
@NotNull final HgRepository myRepository;
@NotNull final String myCurrentBranchName;
@@ -210,7 +216,7 @@ public class HgBranchPopupActions {
public AnAction[] getChildren(@Nullable AnActionEvent e) {
List branchHeadActions = new ArrayList();
for (Hash hash : myHeads) {
- branchHeadActions.add(new HgCommonBranchActions(myProject, myRepository, hash.toShortString()));
+ branchHeadActions.add(new HgCommonBranchActions(myProject, Collections.singletonList(myRepository), hash.toShortString()));
}
return ContainerUtil.toArray(branchHeadActions, new AnAction[branchHeadActions.size()]);
}
@@ -232,29 +238,31 @@ public class HgBranchPopupActions {
*/
static class BookmarkActions extends HgCommonBranchActions {
- BookmarkActions(@NotNull Project project, @NotNull HgRepository selectedRepository, @NotNull String branchName) {
- super(project, selectedRepository, branchName);
+ BookmarkActions(@NotNull Project project, @NotNull List repositories, @NotNull String branchName) {
+ super(project, repositories, branchName);
}
@NotNull
@Override
public AnAction[] getChildren(@Nullable AnActionEvent e) {
- return ArrayUtil.append(super.getChildren(e), new DeleteBookmarkAction(myProject, mySelectedRepository, myBranchName));
+ return ArrayUtil.append(super.getChildren(e), new DeleteBookmarkAction(myProject, myRepositories, myBranchName));
}
private static class DeleteBookmarkAction extends HgBranchAbstractAction {
- DeleteBookmarkAction(@NotNull Project project, @NotNull HgRepository selectedRepository, @NotNull String branchName) {
- super(project, "Delete", selectedRepository, branchName);
+ DeleteBookmarkAction(@NotNull Project project, @NotNull List repositories, @NotNull String branchName) {
+ super(project, "Delete", repositories, branchName);
}
@Override
public void actionPerformed(AnActionEvent e) {
- try {
- new HgBookmarkCommand(myProject, mySelectedRepository.getRoot(), myBranchName).deleteBookmark();
- }
- catch (HgCommandException exception) {
- HgAbstractGlobalAction.handleException(myProject, exception);
+ for (HgRepository repository : myRepositories) {
+ try {
+ new HgBookmarkCommand(myProject, repository.getRoot(), myBranchName).deleteBookmark();
+ }
+ catch (HgCommandException exception) {
+ HgAbstractGlobalAction.handleException(myProject, exception);
+ }
}
}
}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgBranchUtil.java b/plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgBranchUtil.java
new file mode 100644
index 000000000000..9dbdd3ea7f65
--- /dev/null
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgBranchUtil.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2000-2014 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.zmlx.hg4idea.branch;
+
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.vcs.log.Hash;
+import org.jetbrains.annotations.NotNull;
+import org.zmlx.hg4idea.HgNameWithHashInfo;
+import org.zmlx.hg4idea.repo.HgRepository;
+import org.zmlx.hg4idea.util.HgUtil;
+
+import java.util.*;
+
+public class HgBranchUtil {
+
+ /**
+ * Only common hg heavy branches
+ */
+ @NotNull
+ public static Collection getCommonBranches(@NotNull Collection repositories) {
+ Collection commonBranches = null;
+ for (HgRepository repository : repositories) {
+ Map> branchesWithHashes = repository.getBranches();
+ Collection names = branchesWithHashes.keySet();
+ if (commonBranches == null) {
+ commonBranches = names;
+ }
+ else {
+ commonBranches = ContainerUtil.intersection(commonBranches, names);
+ }
+ }
+ if (commonBranches != null) {
+ ArrayList common = new ArrayList(commonBranches);
+ Collections.sort(common);
+ return common;
+ }
+ else {
+ return Collections.emptyList();
+ }
+ }
+
+ @NotNull
+ public static Collection getCommonBookmarks(@NotNull Collection repositories) {
+ Collection commonBookmarkNames = null;
+ for (HgRepository repository : repositories) {
+ Collection bookmarksInfo = repository.getBookmarks();
+ Collection names = HgUtil.getNamesWithoutHashes(bookmarksInfo);
+ if (commonBookmarkNames == null) {
+ commonBookmarkNames = names;
+ }
+ else {
+ commonBookmarkNames = ContainerUtil.intersection(commonBookmarkNames, names);
+ }
+ }
+ if (commonBookmarkNames != null) {
+ ArrayList common = new ArrayList(commonBookmarkNames);
+ Collections.sort(common);
+ return common;
+ }
+ else {
+ return Collections.emptyList();
+ }
+ }
+}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchesAction.java b/plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgBranchesAction.java
similarity index 92%
rename from plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchesAction.java
rename to plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgBranchesAction.java
index d799cde1705c..b078da12548f 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchesAction.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgBranchesAction.java
@@ -13,11 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.zmlx.hg4idea.action;
+package org.zmlx.hg4idea.branch;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.zmlx.hg4idea.action.HgAbstractGlobalSingleRepoAction;
import org.zmlx.hg4idea.repo.HgRepository;
import java.util.Collection;
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgCommonBranchActions.java b/plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgCommonBranchActions.java
new file mode 100644
index 000000000000..ecba99f7b532
--- /dev/null
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgCommonBranchActions.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2000-2014 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.zmlx.hg4idea.branch;
+
+import com.intellij.openapi.actionSystem.ActionGroup;
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.fileEditor.FileDocumentManager;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.progress.Task;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vcs.VcsException;
+import com.intellij.openapi.vcs.VcsNotifier;
+import com.intellij.openapi.vcs.update.UpdatedFiles;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.zmlx.hg4idea.HgVcs;
+import org.zmlx.hg4idea.HgVcsMessages;
+import org.zmlx.hg4idea.action.HgAbstractGlobalAction;
+import org.zmlx.hg4idea.action.HgCommandResultNotifier;
+import org.zmlx.hg4idea.command.HgMergeCommand;
+import org.zmlx.hg4idea.command.HgUpdateCommand;
+import org.zmlx.hg4idea.execution.HgCommandResult;
+import org.zmlx.hg4idea.provider.update.HgConflictResolver;
+import org.zmlx.hg4idea.provider.update.HgHeadMerger;
+import org.zmlx.hg4idea.repo.HgRepository;
+import org.zmlx.hg4idea.util.HgErrorUtil;
+
+import java.util.List;
+
+public class HgCommonBranchActions extends ActionGroup {
+
+ @NotNull protected final Project myProject;
+ @NotNull protected String myBranchName;
+ @NotNull List myRepositories;
+
+ HgCommonBranchActions(@NotNull Project project, @NotNull List repositories, @NotNull String branchName) {
+ super("", true);
+ myProject = project;
+ myBranchName = branchName;
+ myRepositories = repositories;
+ getTemplatePresentation().setText(myBranchName, false); // no mnemonics
+ }
+
+ @NotNull
+ @Override
+ public AnAction[] getChildren(@Nullable AnActionEvent e) {
+ return new AnAction[]{
+ new UpdateAction(myProject, myRepositories, myBranchName),
+ new MergeAction(myProject, myRepositories, myBranchName)
+ };
+ }
+
+ private static class MergeAction extends HgBranchAbstractAction {
+
+ public MergeAction(@NotNull Project project,
+ @NotNull List repositories,
+ @NotNull String branchName) {
+ super(project, "Merge", repositories, branchName);
+ }
+
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ FileDocumentManager.getInstance().saveAllDocuments();
+ final UpdatedFiles updatedFiles = UpdatedFiles.create();
+ for (final HgRepository repository : myRepositories) {
+ final HgMergeCommand hgMergeCommand = new HgMergeCommand(myProject, repository.getRoot());
+ hgMergeCommand.setRevision(myBranchName);//there is no difference between branch or revision or bookmark as parameter to merge,
+ // we need just a string
+ new Task.Backgroundable(myProject, "Merging changes...") {
+ @Override
+ public void run(@NotNull ProgressIndicator indicator) {
+ try {
+ new HgHeadMerger(myProject, hgMergeCommand)
+ .merge(repository.getRoot());
+ new HgConflictResolver(myProject, updatedFiles).resolve(repository.getRoot());
+ }
+
+ catch (VcsException exception) {
+ assert myProject != null; // myProject couldn't be null, see annotation for Merge action
+ if (exception.isWarning()) {
+ VcsNotifier.getInstance(myProject).notifyWarning("Warning during merge", exception.getMessage());
+ }
+ else {
+ VcsNotifier.getInstance(myProject).notifyError("Exception during merge", exception.getMessage());
+ }
+ }
+ catch (Exception e1) {
+ HgAbstractGlobalAction.handleException(myProject, e1);
+ }
+ }
+ }.queue();
+ }
+ }
+ }
+
+ private static class UpdateAction extends HgBranchAbstractAction {
+
+ public UpdateAction(@NotNull Project project,
+ @NotNull List repositories,
+ @NotNull String branchName) {
+ super(project, "Update", repositories, branchName);
+ }
+
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ FileDocumentManager.getInstance().saveAllDocuments();
+ for (HgRepository repo : myRepositories) {
+ final VirtualFile repository = repo.getRoot();
+ final HgUpdateCommand hgUpdateCommand = new HgUpdateCommand(myProject, repository);
+ hgUpdateCommand.setBranch(myBranchName);
+ new Task.Backgroundable(myProject, HgVcsMessages.message("action.hg4idea.updateTo.description", myBranchName)) {
+ @Override
+ public void run(@NotNull ProgressIndicator indicator) {
+ HgCommandResult result = hgUpdateCommand.execute();
+ assert myProject != null; // myProject couldn't be null, see annotation for updateTo action
+ if (HgErrorUtil.hasErrorsInCommandExecution(result)) {
+ new HgCommandResultNotifier(myProject).notifyError(result, "", "Update failed");
+ new HgConflictResolver(myProject).resolve(repository);
+ }
+ myProject.getMessageBus().syncPublisher(HgVcs.BRANCH_TOPIC).update(myProject, repository);
+ }
+ }.queue();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgMultiRootBranchConfig.java b/plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgMultiRootBranchConfig.java
new file mode 100644
index 000000000000..e762fb8992ab
--- /dev/null
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgMultiRootBranchConfig.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2000-2014 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.zmlx.hg4idea.branch;
+
+import com.intellij.dvcs.branch.DvcsMultiRootBranchConfig;
+import org.jetbrains.annotations.NotNull;
+import org.zmlx.hg4idea.repo.HgRepository;
+
+import java.util.Collection;
+
+public class HgMultiRootBranchConfig extends DvcsMultiRootBranchConfig {
+
+ public HgMultiRootBranchConfig(@NotNull Collection repositories) {
+ super(repositories);
+ }
+
+ @NotNull
+ @Override
+ public Collection getLocalBranchNames() {
+ return HgBranchUtil.getCommonBranches(myRepositories);
+ }
+
+ @NotNull
+ Collection getBookmarkNames() {
+ return HgBranchUtil.getCommonBookmarks(myRepositories);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ for (HgRepository repository : myRepositories) {
+ sb.append(repository.getPresentableUrl()).append(":").append(repository.getCurrentBranchName()).append(":")
+ .append(repository.getState());
+ }
+ return sb.toString();
+ }
+}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgPushSupport.java b/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgPushSupport.java
index bb865468e233..b28703930b6f 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgPushSupport.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgPushSupport.java
@@ -64,7 +64,7 @@ public class HgPushSupport extends PushSupport