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 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
- + - + @@ -11,7 +11,7 @@ - + @@ -39,16 +39,43 @@ - + + + + + + - + - + + + + + + + + + + + + + + + + + + + + + + + @@ -65,7 +92,7 @@ - + @@ -80,11 +107,6 @@ - - - - - diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgConfigurationProjectPanel.java b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgConfigurationProjectPanel.java index 2aff9073d266..619536de0f88 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgConfigurationProjectPanel.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgConfigurationProjectPanel.java @@ -12,14 +12,18 @@ // limitations under the License. package org.zmlx.hg4idea.ui; +import com.intellij.dvcs.branch.DvcsBranchSync; +import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.ui.TextFieldWithBrowseButton; +import com.intellij.ui.components.JBCheckBox; import org.jetbrains.annotations.NotNull; import org.zmlx.hg4idea.HgProjectSettings; import org.zmlx.hg4idea.HgVcs; import org.zmlx.hg4idea.HgVcsMessages; +import org.zmlx.hg4idea.repo.HgRepositoryManager; import org.zmlx.hg4idea.util.HgUtil; import org.zmlx.hg4idea.util.HgVersion; @@ -36,6 +40,8 @@ public class HgConfigurationProjectPanel { private JCheckBox myIgnoredWhitespacesInAnnotationsCbx; private TextFieldWithBrowseButton myPathSelector; private JButton myTestButton; + private JBCheckBox mySyncBranchControl; + private JPanel myRepositorySettingsPanel; private final HgVcs myVcs; public HgConfigurationProjectPanel(@NotNull HgProjectSettings projectSettings, @NotNull Project project) { @@ -58,12 +64,15 @@ public class HgConfigurationProjectPanel { ); } }); + final HgRepositoryManager repositoryManager = ServiceManager.getService(project, HgRepositoryManager.class); + myRepositorySettingsPanel.setVisible(repositoryManager != null && repositoryManager.moreThanOneRoot()); } public boolean isModified() { boolean executableModified = !getCurrentPath().equals(myProjectSettings.getHgExecutable()); return executableModified || myCheckIncomingOutgoingCbx.isSelected() != myProjectSettings.isCheckIncomingOutgoing() || + ((myProjectSettings.getSyncSetting() == DvcsBranchSync.SYNC) != mySyncBranchControl.isSelected()) || myIgnoredWhitespacesInAnnotationsCbx.isSelected() != myProjectSettings.isWhitespacesIgnoredInAnnotations(); } @@ -71,6 +80,7 @@ public class HgConfigurationProjectPanel { myProjectSettings.setCheckIncomingOutgoing(myCheckIncomingOutgoingCbx.isSelected()); myProjectSettings.setIgnoreWhitespacesInAnnotations(myIgnoredWhitespacesInAnnotationsCbx.isSelected()); myProjectSettings.setHgExecutable(getCurrentPath()); + myProjectSettings.setSyncSetting(mySyncBranchControl.isSelected() ? DvcsBranchSync.SYNC : DvcsBranchSync.DONT); myVcs.checkVersion(); } @@ -82,6 +92,7 @@ public class HgConfigurationProjectPanel { myCheckIncomingOutgoingCbx.setSelected(myProjectSettings.isCheckIncomingOutgoing()); myIgnoredWhitespacesInAnnotationsCbx.setSelected(myProjectSettings.isWhitespacesIgnoredInAnnotations()); myPathSelector.setText(myProjectSettings.getGlobalSettings().getHgExecutable()); + mySyncBranchControl.setSelected(myProjectSettings.getSyncSetting() == DvcsBranchSync.SYNC); } public JPanel getPanel() { From 872bbf5380adef93b13245892db79cef8971428c Mon Sep 17 00:00:00 2001 From: Vyacheslav Karpukhin Date: Wed, 3 Sep 2014 19:32:39 +0400 Subject: [PATCH 18/60] Added escaped quotes support to CommandLineTokenizer --- .../configurations/CommandLineTokenizer.java | 10 ++-- .../CommandLineTokenizerTest.java | 54 +++++++++++++++++++ 2 files changed, 60 insertions(+), 4 deletions(-) create mode 100644 platform/util/testSrc/com/intellij/execution/configurations/CommandLineTokenizerTest.java diff --git a/platform/util/src/com/intellij/execution/configurations/CommandLineTokenizer.java b/platform/util/src/com/intellij/execution/configurations/CommandLineTokenizer.java index a62af9aa62dc..3f351b9a573e 100644 --- a/platform/util/src/com/intellij/execution/configurations/CommandLineTokenizer.java +++ b/platform/util/src/com/intellij/execution/configurations/CommandLineTokenizer.java @@ -20,9 +20,9 @@ import java.util.List; import java.util.StringTokenizer; /** - * Splits input String to tokens being aware of quoted tokens ("foo bar") and escaped spaces (foo\ bar), + * Splits input String to tokens being aware of quoted tokens ("foo bar") and escaped spaces & quotes (\"foo\ bar\"), * usually used for splitting command line to separate arguments that may contain space symbols. - * Escaped symbols are not handled so there's no way to get token that itself contains quotation mark. + * Space and quote are the only symbols that can be escaped */ public class CommandLineTokenizer extends StringTokenizer { @@ -103,8 +103,10 @@ public class CommandLineTokenizer extends StringTokenizer { do { while ((i = nextToken.indexOf('"')) >= 0) { - quotationMarks++; - buffer.append(nextToken.substring(0, i)); + boolean isEscapedQuote = i > 0 && nextToken.charAt(i - 1) == '\\'; + if (!isEscapedQuote) quotationMarks++; + buffer.append(nextToken.substring(0, isEscapedQuote ? i - 1 : i)); + if (isEscapedQuote) buffer.append('"'); nextToken = nextToken.substring(i + 1); } diff --git a/platform/util/testSrc/com/intellij/execution/configurations/CommandLineTokenizerTest.java b/platform/util/testSrc/com/intellij/execution/configurations/CommandLineTokenizerTest.java new file mode 100644 index 000000000000..27235e4a132c --- /dev/null +++ b/platform/util/testSrc/com/intellij/execution/configurations/CommandLineTokenizerTest.java @@ -0,0 +1,54 @@ +/* + * 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.execution.configurations; + +import junit.framework.TestCase; + +public class CommandLineTokenizerTest extends TestCase { + public void testBasic() throws Exception { + assertTokens("a b", "a", "b"); + assertTokens("\"a b\"", "a b"); + assertTokens("a\" b\"", "a b"); + assertTokens("\"a b", "a b"); + assertTokens("a b\"", "a", "b"); + assertTokens("a b\" c", "a", "b c"); + assertTokens("\"a b\" c \"d e\"", "a b", "c", "d e"); + } + + public void testEscape() throws Exception { + assertTokens("a\\ b", true, "a b"); + assertTokens("\"a\\ b\"", true, "a\\ b"); + assertTokens("a\\ ", true, "a "); + + assertTokens("\\\"", "\""); + assertTokens("\"\\\" a \\\"\"", "\" a \""); + assertTokens("\\\"a b\\\"", "\"a", "b\""); + assertTokens("\\\"a\\ b\\\"", true, "\"a b\""); + } + + private static void assertTokens(String cmd, String... tokens) { + assertTokens(cmd, false, tokens); + } + + private static void assertTokens(String cmd, boolean handleEscapedWhitespaces, String... tokens) { + CommandLineTokenizer tokenizer = new CommandLineTokenizer(cmd, handleEscapedWhitespaces); + + assertEquals(tokens.length, tokenizer.countTokens()); + for (String token : tokens) { + assertEquals(token, tokenizer.nextToken()); + } + } +} From 117c7a3aa691f6fa58c13e10c4be5f7d20271042 Mon Sep 17 00:00:00 2001 From: Max Medvedev Date: Wed, 3 Sep 2014 20:01:26 +0400 Subject: [PATCH 19/60] ContainerUtil.newHashMap(initialCapacity) --- .../src/com/intellij/util/containers/ContainerUtilRt.java | 6 ++++++ .../src/com/intellij/util/containers/ContainerUtil.java | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/platform/util-rt/src/com/intellij/util/containers/ContainerUtilRt.java b/platform/util-rt/src/com/intellij/util/containers/ContainerUtilRt.java index e4d4899b5fb3..a77ff2e315f4 100644 --- a/platform/util-rt/src/com/intellij/util/containers/ContainerUtilRt.java +++ b/platform/util-rt/src/com/intellij/util/containers/ContainerUtilRt.java @@ -77,6 +77,12 @@ public class ContainerUtilRt { return map; } + @NotNull + @Contract(pure=true) + public static Map newHashMap(int initialCapacity) { + return new com.intellij.util.containers.HashMap(initialCapacity); + } + @NotNull @Contract(pure=true) public static TreeMap newTreeMap() { diff --git a/platform/util/src/com/intellij/util/containers/ContainerUtil.java b/platform/util/src/com/intellij/util/containers/ContainerUtil.java index ab8ab2a33aa4..053bab6c86f2 100644 --- a/platform/util/src/com/intellij/util/containers/ContainerUtil.java +++ b/platform/util/src/com/intellij/util/containers/ContainerUtil.java @@ -68,6 +68,12 @@ public class ContainerUtil extends ContainerUtilRt { return ContainerUtilRt.newHashMap(keys, values); } + @NotNull + @Contract(pure=true) + public static Map newHashMap(int initialCapacity) { + return ContainerUtilRt.newHashMap(initialCapacity); + } + @NotNull @Contract(pure=true) public static TreeMap newTreeMap() { From 6609fea0f8e280fec801a3782623a18268022cd7 Mon Sep 17 00:00:00 2001 From: Max Medvedev Date: Wed, 3 Sep 2014 20:02:12 +0400 Subject: [PATCH 20/60] HashMap: descriptive parameter names --- .../util-rt/src/com/intellij/util/containers/HashMap.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/platform/util-rt/src/com/intellij/util/containers/HashMap.java b/platform/util-rt/src/com/intellij/util/containers/HashMap.java index af41488814d0..fa8608f50bf8 100644 --- a/platform/util-rt/src/com/intellij/util/containers/HashMap.java +++ b/platform/util-rt/src/com/intellij/util/containers/HashMap.java @@ -21,12 +21,12 @@ import java.util.Map; public class HashMap extends java.util.HashMap { public HashMap() { } - public HashMap(int i, float v) { - super(i, v); + public HashMap(int initialCapacity, float loadFactor) { + super(initialCapacity, loadFactor); } - public HashMap(int i) { - super(i); + public HashMap(int initialCapacity) { + super(initialCapacity); } public HashMap(Map map) { From d0da022592118d2768be79c3f9ec7a1cee30c65c Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Wed, 3 Sep 2014 21:23:13 +0400 Subject: [PATCH 21/60] no static text attributes (problems after switching from/to Darcula) --- .../execution/filters/ExceptionWorker.java | 23 ++++++------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/java/openapi/src/com/intellij/execution/filters/ExceptionWorker.java b/java/openapi/src/com/intellij/execution/filters/ExceptionWorker.java index 680ae8f744ce..c912e57999dd 100644 --- a/java/openapi/src/com/intellij/execution/filters/ExceptionWorker.java +++ b/java/openapi/src/com/intellij/execution/filters/ExceptionWorker.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. @@ -48,18 +48,6 @@ public class ExceptionWorker { private static final String AT_PREFIX = AT + " "; private static final String STANDALONE_AT = " " + AT + " "; - private static final TextAttributes HYPERLINK_ATTRIBUTES; - private static final TextAttributes LIBRARY_HYPERLINK_ATTRIBUTES; - - static { - HYPERLINK_ATTRIBUTES = EditorColorsManager.getInstance().getGlobalScheme().getAttributes(CodeInsightColors.HYPERLINK_ATTRIBUTES); - - LIBRARY_HYPERLINK_ATTRIBUTES = HYPERLINK_ATTRIBUTES.clone(); - Color libTextColor = UIUtil.getInactiveTextColor(); - LIBRARY_HYPERLINK_ATTRIBUTES.setForegroundColor(libTextColor); - LIBRARY_HYPERLINK_ATTRIBUTES.setEffectColor(libTextColor); - } - private final Project myProject; private Filter.Result myResult; private PsiClass[] myClasses = PsiClass.EMPTY_ARRAY; @@ -129,13 +117,16 @@ public class ExceptionWorker { } List virtualFiles; - TextAttributes attributes; + TextAttributes attributes = EditorColorsManager.getInstance().getGlobalScheme().getAttributes(CodeInsightColors.HYPERLINK_ATTRIBUTES); if (virtualFilesInContent.isEmpty()) { - attributes = LIBRARY_HYPERLINK_ATTRIBUTES; + Color libTextColor = UIUtil.getInactiveTextColor(); + attributes = attributes.clone(); + attributes.setForegroundColor(libTextColor); + attributes.setEffectColor(libTextColor); + virtualFiles = virtualFilesInLibraries; } else { - attributes = HYPERLINK_ATTRIBUTES; virtualFiles = virtualFilesInContent; } HyperlinkInfo linkInfo = HyperlinkInfoFactory.getInstance().createMultipleFilesHyperlinkInfo(virtualFiles, lineNumber - 1, myProject); From abe4d624b46c61e071cba5384bc8158063c93018 Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Wed, 3 Sep 2014 21:55:56 +0400 Subject: [PATCH 22/60] Better way to ignore invisible configurables --- .../roots/ui/configuration/ModuleEditor.java | 4 +- .../openapi/options/ConfigurableEP.java | 18 +++++++- .../openapi/options/ConfigurableProvider.java | 11 +++++ .../options/SearchableConfigurable.java | 6 +++ .../ex/ConfigurableExtensionPointUtil.java | 2 +- .../options/ex/ConfigurableWrapper.java | 41 ++----------------- .../options/ex/MixedConfigurableGroup.java | 6 --- .../src/META-INF/VcsExtensions.xml | 3 +- .../src/META-INF/xdebugger.xml | 3 +- .../VcsManagerConfigurableProvider.java | 41 +++++++++++++++++++ .../DebuggerConfigurableProvider.java | 34 +++++++++++++++ 11 files changed, 121 insertions(+), 48 deletions(-) create mode 100644 platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsManagerConfigurableProvider.java create mode 100644 platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DebuggerConfigurableProvider.java diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModuleEditor.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModuleEditor.java index 10df2939f6e7..b3de63ee0f7b 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModuleEditor.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModuleEditor.java @@ -206,7 +206,9 @@ public abstract class ModuleEditor implements Place.Navigator, Disposable { myEditors.add(new ModuleConfigurableWrapper(moduleConfigurable)); } for(ModuleConfigurableEP extension : myModule.getExtensions(MODULE_CONFIGURABLES)) { - myEditors.add(new ModuleConfigurableWrapper(extension.createConfigurable())); + if (extension.isConfigurableProvided()) { + myEditors.add(new ModuleConfigurableWrapper(extension.createConfigurable())); + } } } diff --git a/platform/platform-api/src/com/intellij/openapi/options/ConfigurableEP.java b/platform/platform-api/src/com/intellij/openapi/options/ConfigurableEP.java index 78a4c1ece130..3f9bc9d241f2 100644 --- a/platform/platform-api/src/com/intellij/openapi/options/ConfigurableEP.java +++ b/platform/platform-api/src/com/intellij/openapi/options/ConfigurableEP.java @@ -175,9 +175,25 @@ public class ConfigurableEP extends AbstractExten return getDisplayName(); } + public boolean isConfigurableProvided() { + if (providerClass == null) { + return implementationClass != null || instanceClass != null; + } + try { + ConfigurableProvider provider = instantiate(providerClass, myPicoContainer); + return provider.isConfigurableProvided(); // do not load heavy configurables + } + catch (Exception ignored) { + return true; // see InstanceFromProviderFactory#compute + } + } + private class InstanceFromProviderFactory extends AtomicNotNullLazyValue implements NullableFactory { public T create() { - return (T)getValue().createConfigurable(); + ConfigurableProvider provider = getValue(); + return provider.isConfigurableProvided() + ? (T)provider.createConfigurable() + : null; } @NotNull diff --git a/platform/platform-api/src/com/intellij/openapi/options/ConfigurableProvider.java b/platform/platform-api/src/com/intellij/openapi/options/ConfigurableProvider.java index 5a71ffa73050..f0389cf83649 100644 --- a/platform/platform-api/src/com/intellij/openapi/options/ConfigurableProvider.java +++ b/platform/platform-api/src/com/intellij/openapi/options/ConfigurableProvider.java @@ -29,4 +29,15 @@ public abstract class ConfigurableProvider { @Nullable public abstract Configurable createConfigurable(); + /** + * Defines whether this provider creates a configurable or not. + * Note that the {@code createConfigurable} method will be called + * if this method returns {@code true}. + * + * @return {@code true} if this provider creates configurable, + * {@code false} otherwise + */ + public boolean isConfigurableProvided() { + return true; + } } diff --git a/platform/platform-api/src/com/intellij/openapi/options/SearchableConfigurable.java b/platform/platform-api/src/com/intellij/openapi/options/SearchableConfigurable.java index e98bb05aba99..4f1d0dd4eaf9 100644 --- a/platform/platform-api/src/com/intellij/openapi/options/SearchableConfigurable.java +++ b/platform/platform-api/src/com/intellij/openapi/options/SearchableConfigurable.java @@ -34,6 +34,12 @@ public interface SearchableConfigurable extends Configurable { interface Parent extends SearchableConfigurable, Composite { boolean hasOwnContent(); + + /** + * @deprecated use {@link ConfigurableProvider#isConfigurableProvided()} instead + * to specify configurables which should not be visible + */ + @Deprecated boolean isVisible(); abstract class Abstract implements Parent { diff --git a/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableExtensionPointUtil.java b/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableExtensionPointUtil.java index 429a55b2b809..2b5428411e47 100644 --- a/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableExtensionPointUtil.java +++ b/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableExtensionPointUtil.java @@ -164,7 +164,7 @@ public class ConfigurableExtensionPointUtil { @NotNull private static T findConfigurable(ConfigurableEP[] extensions, Class configurableClass) { for (ConfigurableEP extension : extensions) { - if (extension.providerClass != null || extension.instanceClass != null || extension.implementationClass != null) { + if (extension.isConfigurableProvided()) { final Configurable configurable = extension.createConfigurable(); if (configurableClass.isInstance(configurable)) { return configurableClass.cast(configurable); diff --git a/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableWrapper.java b/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableWrapper.java index b5a62f8ae395..cca07555054b 100644 --- a/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableWrapper.java +++ b/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableWrapper.java @@ -47,6 +47,9 @@ public class ConfigurableWrapper implements SearchableConfigurable { @Nullable public static T wrapConfigurable(ConfigurableEP ep) { + if (!ep.isConfigurableProvided()) { + return null; + } if (ep.displayName != null || ep.key != null || ep.groupId != null) { T configurable = null; if (ep.providerClass != null) { @@ -196,7 +199,7 @@ public class ConfigurableWrapper implements SearchableConfigurable { return configurable instanceof SearchableConfigurable ? ((SearchableConfigurable)configurable).enableSearch(option) : null; } - private static class CompositeWrapper extends ConfigurableWrapper implements SearchableConfigurable.Parent { + private static class CompositeWrapper extends ConfigurableWrapper implements Configurable.Composite { private Configurable[] myKids; @@ -241,42 +244,6 @@ public class ConfigurableWrapper implements SearchableConfigurable { myKids = ArrayUtil.append(myKids, configurable); return this; } - - @Override - public boolean hasOwnContent() { - UnnamedConfigurable configurable = getConfigurable(); - if (configurable instanceof SearchableConfigurable.Parent) { - SearchableConfigurable.Parent parent = (SearchableConfigurable.Parent)configurable; - return parent.hasOwnContent(); - } - return false; - } - - @Override - public boolean isVisible() { - if (super.myConfigurable == null) { - String name = super.myEp.instanceClass; - if (name == null) { - name = super.myEp.implementationClass; - } - if (name != null) { - try { - if (!SearchableConfigurable.Parent.class.isAssignableFrom(super.myEp.findClass(name))) { - return true; // do not instantiate wrapped configurable if not needed - } - } - catch (ClassNotFoundException exception) { - return true; // ignore unexpected exception from findClass - } - } - } - UnnamedConfigurable configurable = getConfigurable(); - if (configurable instanceof SearchableConfigurable.Parent) { - SearchableConfigurable.Parent parent = (SearchableConfigurable.Parent)configurable; - return parent.isVisible(); - } - return true; - } } private static final class GroupWrapper extends CompositeWrapper implements ConfigurableGroup { diff --git a/platform/platform-impl/src/com/intellij/openapi/options/ex/MixedConfigurableGroup.java b/platform/platform-impl/src/com/intellij/openapi/options/ex/MixedConfigurableGroup.java index ee12807ed9e1..bf81c7b17cbe 100644 --- a/platform/platform-impl/src/com/intellij/openapi/options/ex/MixedConfigurableGroup.java +++ b/platform/platform-impl/src/com/intellij/openapi/options/ex/MixedConfigurableGroup.java @@ -97,12 +97,6 @@ public final class MixedConfigurableGroup implements SearchableConfigurable, Con ArrayList groups = new ArrayList(); HashMap> map = new HashMap>(); for (Configurable configurable : configurables) { - if (configurable instanceof SearchableConfigurable.Parent) { - SearchableConfigurable.Parent parent = (SearchableConfigurable.Parent)configurable; - if (!parent.isVisible()) { - continue; - } - } if (configurable instanceof ConfigurableGroup) { groups.add((ConfigurableGroup)configurable); } diff --git a/platform/platform-resources/src/META-INF/VcsExtensions.xml b/platform/platform-resources/src/META-INF/VcsExtensions.xml index 9aa86cfb9a01..8c416e6df410 100644 --- a/platform/platform-resources/src/META-INF/VcsExtensions.xml +++ b/platform/platform-resources/src/META-INF/VcsExtensions.xml @@ -25,7 +25,8 @@ - + diff --git a/platform/platform-resources/src/META-INF/xdebugger.xml b/platform/platform-resources/src/META-INF/xdebugger.xml index d28921d17ba6..821cb528b6a9 100644 --- a/platform/platform-resources/src/META-INF/xdebugger.xml +++ b/platform/platform-resources/src/META-INF/xdebugger.xml @@ -30,7 +30,8 @@ - + diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsManagerConfigurableProvider.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsManagerConfigurableProvider.java new file mode 100644 index 000000000000..3536139be64d --- /dev/null +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsManagerConfigurableProvider.java @@ -0,0 +1,41 @@ +/* + * 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.openapi.vcs.configurable; + +import com.intellij.openapi.options.Configurable; +import com.intellij.openapi.options.ConfigurableProvider; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vcs.ProjectLevelVcsManager; +import org.jetbrains.annotations.NotNull; + +public final class VcsManagerConfigurableProvider extends ConfigurableProvider { + private final Project myProject; + + public VcsManagerConfigurableProvider(Project project) { + myProject = project; + } + + @NotNull + @Override + public Configurable createConfigurable() { + return new VcsManagerConfigurable(myProject); + } + + @Override + public boolean isConfigurableProvided() { + return ProjectLevelVcsManager.getInstance(myProject).getAllVcss().length > 0; + } +} diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DebuggerConfigurableProvider.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DebuggerConfigurableProvider.java new file mode 100644 index 000000000000..cd0f0dccb1af --- /dev/null +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DebuggerConfigurableProvider.java @@ -0,0 +1,34 @@ +/* + * 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.xdebugger.impl.settings; + +import com.intellij.openapi.options.Configurable; +import com.intellij.openapi.options.ConfigurableProvider; +import com.intellij.xdebugger.breakpoints.XBreakpointType; +import org.jetbrains.annotations.NotNull; + +public final class DebuggerConfigurableProvider extends ConfigurableProvider { + @NotNull + @Override + public Configurable createConfigurable() { + return new DebuggerConfigurable(); + } + + @Override + public boolean isConfigurableProvided() { + return XBreakpointType.EXTENSION_POINT_NAME.getExtensions().length != 0; + } +} From c5349c1318d23b1f7deb3972b4daf4ea4eded8cd Mon Sep 17 00:00:00 2001 From: "Ilya.Kazakevich" Date: Wed, 3 Sep 2014 21:59:56 +0400 Subject: [PATCH 23/60] PY-13758 BDD: allow to run several feature files in one run configuration --- .../openapi/util/JDOMExternalizer.java | 27 ++++++++++++++++-- python/helpers/pycharm/_bdd_utils.py | 28 ++++++++++++------- python/helpers/pycharm/behave_runner.py | 19 +++++++------ python/helpers/pycharm/lettuce_runner.py | 9 ++++-- 4 files changed, 60 insertions(+), 23 deletions(-) diff --git a/platform/util/src/com/intellij/openapi/util/JDOMExternalizer.java b/platform/util/src/com/intellij/openapi/util/JDOMExternalizer.java index 909c44db199b..cd5e8630a087 100644 --- a/platform/util/src/com/intellij/openapi/util/JDOMExternalizer.java +++ b/platform/util/src/com/intellij/openapi/util/JDOMExternalizer.java @@ -22,7 +22,10 @@ import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.*; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; public class JDOMExternalizer { private JDOMExternalizer() { @@ -66,7 +69,7 @@ public class JDOMExternalizer { return null; } - public static void writeMap(Element root, Mapmap, @NonNls @Nullable String rootName, @NonNls String entryName) { + public static void writeMap(Element root, Map map, @NonNls @Nullable String rootName, @NonNls String entryName) { Element mapRoot; if (StringUtil.isNotEmpty(rootName)) { mapRoot = new Element(rootName); @@ -106,6 +109,26 @@ public class JDOMExternalizer { } } + /** + * Saves a pack of strings to some attribte. I.e: [tag attr="value"] + * @param parent parent element (where to add newly created tags) + * @param nodeName node name (tag, in our example) + * @param attrName attribute name (attr, in our example) + * @param values a pack of values to add + * @see #loadStringsList(org.jdom.Element, String, String) + */ + public static void saveStringsList(@NotNull final Element parent, + @NotNull final String nodeName, + @NotNull final String attrName, + @NotNull final String... values) { + for (final String value : values) { + final Element node = new Element(nodeName); + node.setAttribute(attrName, value); + parent.addContent(node); + } + } + + @NotNull public static List loadStringsList(Element element, String rootName, String attrName) { final List paths = new LinkedList(); if (element != null) { diff --git a/python/helpers/pycharm/_bdd_utils.py b/python/helpers/pycharm/_bdd_utils.py index eea1bebf1654..9eb90681e127 100644 --- a/python/helpers/pycharm/_bdd_utils.py +++ b/python/helpers/pycharm/_bdd_utils.py @@ -29,19 +29,27 @@ def fix_win_drive(feature_path): os.chdir(feature_disk) -def get_path_by_args(arguments): +def get_path_by_env(environment): """ - :type arguments list - :param arguments: arguments (sys.argv) - :return: tuple (base_dir, what_to_run) where dir is current or first argument from argv, checking it exists - :rtype tuple of str + :type environment dict + :param environment: os.environment (files and folders should be separated with | and passed to PY_STUFF_TO_RUN) + :return: tuple (base_dir, what_to_run(list of feature files or folders))) where dir is current or first argument from env, checking it exists + :rtype tuple of (str, iterable) """ - what_to_run = arguments[1] if len(arguments) > 1 else "." - base_dir = what_to_run - assert os.path.exists(what_to_run), "{} does not exist".format(what_to_run) + if "PY_STUFF_TO_RUN" not in environment: + what_to_run = ["."] + else: + what_to_run = str(environment["PY_STUFF_TO_RUN"]).split("|") - if os.path.isfile(what_to_run): - base_dir = os.path.dirname(what_to_run) # User may point to the file directly + if not what_to_run: + what_to_run = ["."] + + for path in what_to_run: + assert os.path.exists(path), "{} does not exist".format(path) + + base_dir = what_to_run[0] + if os.path.isfile(what_to_run[0]): + base_dir = os.path.dirname(what_to_run[0]) # User may point to the file directly return base_dir, what_to_run diff --git a/python/helpers/pycharm/behave_runner.py b/python/helpers/pycharm/behave_runner.py index 2ec649ea7c1d..51171530ddb4 100644 --- a/python/helpers/pycharm/behave_runner.py +++ b/python/helpers/pycharm/behave_runner.py @@ -1,13 +1,14 @@ # coding=utf-8 """ Behave BDD runner. -*FIRST* param now: folder to search "features" for. -Each "features" folder should have features and "steps" subdir. +See _bdd_utils#get_path_by_env for information how to pass list of features here. +Each feature could be file, folder with feature files or folder with "features" subfolder Other args are tag expressionsin format (--tags=.. --tags=..). See https://pythonhosted.org/behave/behave.html#tag-expression """ import functools +import glob import sys import os import traceback @@ -236,12 +237,14 @@ if __name__ == "__main__": my_config.reporters = [] # To prevent summary to stdout my_config.stdout_capture = False # For test output my_config.stderr_capture = False # For test output - (base_dir, what_to_run) = _bdd_utils.get_path_by_args(sys.argv) - if not my_config.paths: # No path provided, trying to load dit manually - if os.path.isfile(what_to_run): # File is provided, load it - my_config.paths = [what_to_run] - else: # Dir is provided, find subdirs ro run - my_config.paths = _get_dirs_to_run(base_dir) + (base_dir, what_to_run) = _bdd_utils.get_path_by_env(os.environ) + features = set() + for feature in what_to_run: + if os.path.isfile(feature) or glob.glob(os.path.join(feature, "*.feature")): # File of folder with "features" provided, load it + features.add(feature) + elif os.path.isdir(feature): + features |= set(_get_dirs_to_run(feature)) # Find "features" subfolder + my_config.paths = list(features) _BehaveRunner(my_config, base_dir).run() diff --git a/python/helpers/pycharm/lettuce_runner.py b/python/helpers/pycharm/lettuce_runner.py index f0a4b5dbb873..6c4dbb7028a6 100644 --- a/python/helpers/pycharm/lettuce_runner.py +++ b/python/helpers/pycharm/lettuce_runner.py @@ -4,6 +4,7 @@ BDD lettuce framework runner TODO: Support other params (like tags) as well. Supports only 1 param now: folder to search "features" for. """ +import os import _bdd_utils __author__ = 'Ilya.Kazakevich' @@ -108,6 +109,8 @@ class _LettuceRunner(_bdd_utils.BddRunner): if __name__ == "__main__": - (base_dir, what_to_run) = _bdd_utils.get_path_by_args(sys.argv) - _bdd_utils.fix_win_drive(what_to_run) - _LettuceRunner(base_dir, what_to_run).run() \ No newline at end of file + (base_dir, what_to_run) = _bdd_utils.get_path_by_env(os.environ) + if len(what_to_run) > 1: + raise Exception("Lettuce can't run more than one file now") + _bdd_utils.fix_win_drive(what_to_run[0]) + _LettuceRunner(base_dir, what_to_run[0]).run() \ No newline at end of file From a53fd51217ffadf22c1f28d08f50fff440d5c1a3 Mon Sep 17 00:00:00 2001 From: "Ilya.Kazakevich" Date: Wed, 3 Sep 2014 22:23:55 +0400 Subject: [PATCH 24/60] FileChooserDialog now supports several files (after review) --- .../src/com/intellij/ide/actions/ImportModuleAction.java | 2 +- .../options/codeStyle/ManageCodeStyleSchemesDialog.java | 2 +- .../src/com/intellij/openapi/fileChooser/FileChooser.java | 2 +- .../intellij/openapi/fileChooser/ex/FileChooserDialogImpl.java | 3 +++ 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/java/idea-ui/src/com/intellij/ide/actions/ImportModuleAction.java b/java/idea-ui/src/com/intellij/ide/actions/ImportModuleAction.java index 3d497b829d50..3f087a998304 100644 --- a/java/idea-ui/src/com/intellij/ide/actions/ImportModuleAction.java +++ b/java/idea-ui/src/com/intellij/ide/actions/ImportModuleAction.java @@ -116,7 +116,7 @@ public class ImportModuleAction extends AnAction { if (lastLocation != null) { toSelect = LocalFileSystem.getInstance().refreshAndFindFileByPath(lastLocation); } - VirtualFile[] files = chooser.choose(toSelect, project); + VirtualFile[] files = chooser.choose(project, toSelect); if (files.length == 0) { return null; } diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/ManageCodeStyleSchemesDialog.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/ManageCodeStyleSchemesDialog.java index 653f6b51e8bd..282f44d04a60 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/ManageCodeStyleSchemesDialog.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/ManageCodeStyleSchemesDialog.java @@ -214,7 +214,7 @@ public class ManageCodeStyleSchemesDialog extends DialogWrapper { return !file.isDirectory() && importer.getSourceExtension().equals(file.getExtension()); } }, null, myContentPane); - VirtualFile[] selection = fileChooser.choose(CodeStyleSchemesUIConfiguration.Util.getRecentImportFile(), null); + VirtualFile[] selection = fileChooser.choose(null, CodeStyleSchemesUIConfiguration.Util.getRecentImportFile()); if (selection.length == 1) { VirtualFile selectedFile = selection[0]; selectedFile.refresh(false, false); diff --git a/platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooser.java b/platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooser.java index 9e0bf738a7cf..fee268813d14 100644 --- a/platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooser.java +++ b/platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooser.java @@ -52,7 +52,7 @@ public class FileChooser { @Nullable final Project project, @Nullable final VirtualFile toSelect) { final FileChooserDialog chooser = FileChooserFactory.getInstance().createFileChooser(descriptor, project, parent); - return chooser.choose(toSelect, project); + return chooser.choose(project, toSelect); } @Nullable diff --git a/platform/platform-impl/src/com/intellij/openapi/fileChooser/ex/FileChooserDialogImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileChooser/ex/FileChooserDialogImpl.java index d2ea19bc403d..2938f419909c 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileChooser/ex/FileChooserDialogImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileChooser/ex/FileChooserDialogImpl.java @@ -122,6 +122,9 @@ public class FileChooserDialogImpl extends DialogWrapper implements FileChooserD if (toSelect.length == 1) { restoreSelection(toSelect[0]); } + else if (toSelect.length == 0) { + restoreSelection(null); // select last opened file + } else { selectInTree(toSelect, true); } From 64422b696d771ae4763dc8f040c614c8329567b4 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Wed, 3 Sep 2014 22:34:03 +0400 Subject: [PATCH 25/60] extract method object to emulate debugging for anonymous classes, lambdas, etc --- .../extractMethod/AbstractExtractDialog.java | 23 +-- .../extractMethod/ExtractMethodDialog.java | 5 +- .../extractMethod/ExtractMethodProcessor.java | 40 ++++- .../ExtractLightMethodObjectHandler.java | 144 ++++++++++++++++++ .../ExtractMethodObjectDialog.java | 5 +- .../ExtractMethodObjectHandler.java | 19 ++- .../ExtractMethodObjectProcessor.java | 43 ++++-- .../SimpleGeneration.java | 7 + .../ExtractMethodObject4DebuggerTest.java | 84 ++++++++++ 9 files changed, 327 insertions(+), 43 deletions(-) create mode 100644 java/java-impl/src/com/intellij/refactoring/extractMethodObject/ExtractLightMethodObjectHandler.java create mode 100644 java/java-tests/testData/refactoring/extractMethodObject4Debugger/SimpleGeneration.java create mode 100644 java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodObject4DebuggerTest.java diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethod/AbstractExtractDialog.java b/java/java-impl/src/com/intellij/refactoring/extractMethod/AbstractExtractDialog.java index 7e49181472b0..9f83b6ed080b 100644 --- a/java/java-impl/src/com/intellij/refactoring/extractMethod/AbstractExtractDialog.java +++ b/java/java-impl/src/com/intellij/refactoring/extractMethod/AbstractExtractDialog.java @@ -20,25 +20,18 @@ */ package com.intellij.refactoring.extractMethod; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.ui.DialogWrapper; import com.intellij.psi.PsiModifier; import com.intellij.refactoring.util.VariableData; -public abstract class AbstractExtractDialog extends DialogWrapper { - protected AbstractExtractDialog(Project project) { - super(project, true); - } - - - public abstract String getChosenMethodName(); - - public abstract VariableData[] getChosenParameters(); +public interface AbstractExtractDialog { + String getChosenMethodName(); + VariableData[] getChosenParameters(); @PsiModifier.ModifierConstant - public abstract String getVisibility(); + String getVisibility(); + boolean isMakeStatic(); + boolean isChainedConstructor(); - public abstract boolean isMakeStatic(); - - public abstract boolean isChainedConstructor(); + void show(); + boolean isOK(); } \ No newline at end of file diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodDialog.java b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodDialog.java index f4cfccb496ad..fc933de2b80e 100644 --- a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodDialog.java +++ b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodDialog.java @@ -21,6 +21,7 @@ import com.intellij.openapi.editor.event.DocumentAdapter; import com.intellij.openapi.editor.event.DocumentEvent; import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.Splitter; import com.intellij.openapi.ui.VerticalFlowLayout; import com.intellij.openapi.util.text.StringUtil; @@ -59,7 +60,7 @@ import java.awt.event.*; * @author Konstantin Bulenkov */ @SuppressWarnings("MethodMayBeStatic") -public class ExtractMethodDialog extends AbstractExtractDialog { +public class ExtractMethodDialog extends DialogWrapper implements AbstractExtractDialog { public static final String EXTRACT_METHOD_DEFAULT_VISIBILITY = "extract.method.default.visibility"; private final Project myProject; private final PsiType myReturnType; @@ -96,7 +97,7 @@ public class ExtractMethodDialog extends AbstractExtractDialog { String title, String helpId, final PsiElement[] elementsToExtract) { - super(project); + super(project, true); myProject = project; myTargetClass = targetClass; myReturnType = returnType; diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java index c61c29c58ff9..e63b3751e425 100644 --- a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java @@ -463,14 +463,14 @@ public class ExtractMethodProcessor implements MatchProvider { protected void apply(final AbstractExtractDialog dialog) { myMethodName = dialog.getChosenMethodName(); myVariableDatum = dialog.getChosenParameters(); - myStatic |= dialog.isMakeStatic(); + myStatic = isStatic() | dialog.isMakeStatic(); myIsChainedConstructor = dialog.isChainedConstructor(); myMethodVisibility = dialog.getVisibility(); } protected AbstractExtractDialog createExtractMethodDialog(final boolean direct) { - return new ExtractMethodDialog(myProject, myTargetClass, myInputVariables, myReturnType, myTypeParameterList, - myThrownExceptions, myStatic, myCanBeStatic, myCanBeChainedConstructor, + return new ExtractMethodDialog(myProject, myTargetClass, myInputVariables, myReturnType, getTypeParameterList(), + getThrownExceptions(), isStatic(), isCanBeStatic(), myCanBeChainedConstructor, suggestInitialMethodName(), myRefactoringName, myHelpId, myElements) { protected boolean areTypesDirected() { @@ -620,7 +620,7 @@ public class ExtractMethodProcessor implements MatchProvider { private void doExtract() throws IncorrectOperationException { - PsiMethod newMethod = generateEmptyMethod(myThrownExceptions, myStatic); + PsiMethod newMethod = generateEmptyMethod(getThrownExceptions(), isStatic()); myExpression = myInputVariables.replaceWrappedReferences(myElements, myExpression); renameInputVariables(); @@ -991,6 +991,10 @@ public class ExtractMethodProcessor implements MatchProvider { return myTargetClass; } + public PsiType getReturnType() { + return myReturnType; + } + private PsiMethod generateEmptyMethod(PsiClassType[] exceptions, boolean isStatic) throws IncorrectOperationException { PsiMethod newMethod; if (myIsChainedConstructor) { @@ -1001,8 +1005,8 @@ public class ExtractMethodProcessor implements MatchProvider { PsiUtil.setModifierProperty(newMethod, PsiModifier.STATIC, isStatic); } PsiUtil.setModifierProperty(newMethod, myMethodVisibility, true); - if (myTypeParameterList != null) { - newMethod.getTypeParameterList().replace(myTypeParameterList); + if (getTypeParameterList() != null) { + newMethod.getTypeParameterList().replace(getTypeParameterList()); } PsiCodeBlock body = newMethod.getBody(); LOG.assertTrue(body != null); @@ -1400,4 +1404,28 @@ public class ExtractMethodProcessor implements MatchProvider { public InputVariables getInputVariables() { return myInputVariables; } + + public PsiTypeParameterList getTypeParameterList() { + return myTypeParameterList; + } + + public PsiClassType[] getThrownExceptions() { + return myThrownExceptions; + } + + public boolean isStatic() { + return myStatic; + } + + public boolean isCanBeStatic() { + return myCanBeStatic; + } + + public PsiElement[] getElements() { + return myElements; + } + + public PsiVariable[] getOutputVariables() { + return myOutputVariables; + } } diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethodObject/ExtractLightMethodObjectHandler.java b/java/java-impl/src/com/intellij/refactoring/extractMethodObject/ExtractLightMethodObjectHandler.java new file mode 100644 index 000000000000..c5ee560434a5 --- /dev/null +++ b/java/java-impl/src/com/intellij/refactoring/extractMethodObject/ExtractLightMethodObjectHandler.java @@ -0,0 +1,144 @@ +/* + * 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.refactoring.extractMethodObject; + +import com.intellij.codeInsight.CodeInsightUtil; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.RangeMarker; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; +import com.intellij.refactoring.extractMethod.AbstractExtractDialog; +import com.intellij.refactoring.extractMethod.InputVariables; +import com.intellij.refactoring.util.VariableData; +import org.jetbrains.annotations.Nullable; + +public class ExtractLightMethodObjectHandler { + private static final Logger LOG = Logger.getInstance("#" + ExtractLightMethodObjectHandler.class.getName()); + + public static class ExtractedData { + private String myGeneratedCallText; + private PsiClass myGeneratedInnerClass; + + public ExtractedData(String generatedCallText, PsiClass generatedInnerClass) { + myGeneratedCallText = generatedCallText; + myGeneratedInnerClass = generatedInnerClass; + } + + public String getGeneratedCallText() { + return myGeneratedCallText; + } + + public PsiClass getGeneratedInnerClass() { + return myGeneratedInnerClass; + } + } + + @Nullable + public static ExtractedData extractLightMethodObject(final Project project, + final Editor editor, + final PsiFile file, + final PsiElement[] elements, + final String methodName) { + if (elements == null || elements.length == 0) { + return null; + } + + final PsiFile copy = PsiFileFactory.getInstance(project) + .createFileFromText(file.getName(), file.getFileType(), file.getText(), file.getModificationStamp(), true); + + final PsiElement[] elementsCopy = new PsiElement[elements.length]; + for (int i = 0; i < elements.length; i++) { + PsiElement element = elements[i]; + final TextRange textRange = element.getTextRange(); + elementsCopy[i] = CodeInsightUtil.findElementInRange(copy, textRange.getStartOffset(), textRange.getEndOffset(), element.getClass()); + } + + final Document document = PsiDocumentManager.getInstance(project).getDocument(copy); + LOG.assertTrue(document != null); + + final int startOffset = elements[0].getTextRange().getStartOffset(); + final int endOffset = elements[elements.length - 1].getTextRange().getEndOffset(); + + final RangeMarker callSiteMarker = document.createRangeMarker(startOffset, endOffset); + callSiteMarker.setGreedyToLeft(true); + callSiteMarker.setGreedyToRight(true); + + try { + final ExtractMethodObjectProcessor extractMethodObjectProcessor = new ExtractMethodObjectProcessor(project, editor, elementsCopy, "") { + @Override + protected AbstractExtractDialog createExtractMethodObjectDialog(MyExtractMethodProcessor processor) { + return new LightExtractMethodObjectDialog(this, methodName); + } + }; + extractMethodObjectProcessor.getExtractProcessor().setShowErrorDialogs(false); + + ExtractMethodObjectHandler.extractMethodObject(project, editor, file, extractMethodObjectProcessor); + + final String generatedCall = document.getText(new TextRange(callSiteMarker.getStartOffset(), callSiteMarker.getEndOffset())); + return new ExtractedData(generatedCall, extractMethodObjectProcessor.getInnerClass()); + } + finally { + callSiteMarker.dispose(); + } + } + + private static class LightExtractMethodObjectDialog implements AbstractExtractDialog { + private final ExtractMethodObjectProcessor myProcessor; + private final String myMethodName; + + public LightExtractMethodObjectDialog(ExtractMethodObjectProcessor processor, String methodName) { + myProcessor = processor; + myMethodName = methodName; + } + + @Override + public String getChosenMethodName() { + return myMethodName; + } + + @Override + public VariableData[] getChosenParameters() { + final InputVariables inputVariables = myProcessor.getExtractProcessor().getInputVariables(); + return inputVariables.getInputVariables().toArray(new VariableData[inputVariables.getInputVariables().size()]); + } + + @Override + public String getVisibility() { + return PsiModifier.PUBLIC; + } + + @Override + public boolean isMakeStatic() { + return false; + } + + @Override + public boolean isChainedConstructor() { + return false; + } + + @Override + public void show() {} + + @Override + public boolean isOK() { + return true; + } + } +} diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethodObject/ExtractMethodObjectDialog.java b/java/java-impl/src/com/intellij/refactoring/extractMethodObject/ExtractMethodObjectDialog.java index fddd19bb4630..f79280fd1365 100644 --- a/java/java-impl/src/com/intellij/refactoring/extractMethodObject/ExtractMethodObjectDialog.java +++ b/java/java-impl/src/com/intellij/refactoring/extractMethodObject/ExtractMethodObjectDialog.java @@ -19,6 +19,7 @@ import com.intellij.openapi.editor.event.DocumentAdapter; import com.intellij.openapi.editor.event.DocumentEvent; import com.intellij.openapi.help.HelpManager; import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.psi.*; @@ -44,7 +45,7 @@ import java.awt.event.ActionListener; import java.util.Enumeration; -public class ExtractMethodObjectDialog extends AbstractExtractDialog { +public class ExtractMethodObjectDialog extends DialogWrapper implements AbstractExtractDialog { private final Project myProject; private final PsiType myReturnType; private final PsiTypeParameterList myTypeParameterList; @@ -86,7 +87,7 @@ public class ExtractMethodObjectDialog extends AbstractExtractDialog { public ExtractMethodObjectDialog(Project project, PsiClass targetClass, final InputVariables inputVariables, PsiType returnType, PsiTypeParameterList typeParameterList, PsiType[] exceptions, boolean isStatic, boolean canBeStatic, final PsiElement[] elementsToExtract, final boolean multipleExitPoints) { - super(project); + super(project, true); myProject = project; myTargetClass = targetClass; myReturnType = returnType; diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethodObject/ExtractMethodObjectHandler.java b/java/java-impl/src/com/intellij/refactoring/extractMethodObject/ExtractMethodObjectHandler.java index d8fb3fd6ef87..b09a02cfd561 100644 --- a/java/java-impl/src/com/intellij/refactoring/extractMethodObject/ExtractMethodObjectHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/extractMethodObject/ExtractMethodObjectHandler.java @@ -20,26 +20,29 @@ */ package com.intellij.refactoring.extractMethodObject; +import com.intellij.codeInsight.CodeInsightUtil; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.RangeMarker; import com.intellij.openapi.editor.ScrollType; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Pass; import com.intellij.openapi.util.TextRange; -import com.intellij.psi.PsiDocumentManager; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; +import com.intellij.psi.*; import com.intellij.psi.impl.source.PostprocessReformattingAspect; import com.intellij.refactoring.HelpID; import com.intellij.refactoring.RefactoringActionHandler; import com.intellij.refactoring.RefactoringBundle; +import com.intellij.refactoring.extractMethod.AbstractExtractDialog; import com.intellij.refactoring.extractMethod.ExtractMethodHandler; +import com.intellij.refactoring.extractMethod.InputVariables; import com.intellij.refactoring.extractMethod.PrepareFailedException; import com.intellij.refactoring.util.CommonRefactoringUtil; +import com.intellij.refactoring.util.VariableData; import com.intellij.refactoring.util.duplicates.DuplicatesImpl; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; @@ -55,7 +58,10 @@ public class ExtractMethodObjectHandler implements RefactoringActionHandler { }); } - private void invokeOnElements(@NotNull final Project project, @NotNull final Editor editor, @NotNull PsiFile file, @NotNull PsiElement[] elements) { + private static void invokeOnElements(@NotNull final Project project, + @NotNull final Editor editor, + @NotNull PsiFile file, + @NotNull PsiElement[] elements) { if (elements.length == 0) { String message = RefactoringBundle .getCannotRefactorMessage(RefactoringBundle.message("selected.block.should.represent.a.set.of.statements.or.an.expression")); @@ -63,7 +69,10 @@ public class ExtractMethodObjectHandler implements RefactoringActionHandler { return; } - final ExtractMethodObjectProcessor processor = new ExtractMethodObjectProcessor(project, editor, elements, ""); + extractMethodObject(project, editor, file, new ExtractMethodObjectProcessor(project, editor, elements, "")); + } + + static void extractMethodObject(Project project, Editor editor, PsiFile file, ExtractMethodObjectProcessor processor) { final ExtractMethodObjectProcessor.MyExtractMethodProcessor extractProcessor = processor.getExtractProcessor(); try { if (!extractProcessor.prepare()) return; diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethodObject/ExtractMethodObjectProcessor.java b/java/java-impl/src/com/intellij/refactoring/extractMethodObject/ExtractMethodObjectProcessor.java index 7f95c49c65b3..20c536bb5a1d 100644 --- a/java/java-impl/src/com/intellij/refactoring/extractMethodObject/ExtractMethodObjectProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/extractMethodObject/ExtractMethodObjectProcessor.java @@ -37,10 +37,13 @@ import com.intellij.psi.codeStyle.VariableKind; import com.intellij.psi.controlFlow.ControlFlowUtil; import com.intellij.psi.impl.source.PsiImmediateClassType; import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.LocalSearchScope; +import com.intellij.psi.search.SearchScope; import com.intellij.psi.search.searches.ReferencesSearch; import com.intellij.psi.util.PropertyUtil; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; +import com.intellij.psi.util.PsiUtilCore; import com.intellij.refactoring.BaseRefactoringProcessor; import com.intellij.refactoring.HelpID; import com.intellij.refactoring.changeSignature.ChangeSignatureProcessor; @@ -52,6 +55,7 @@ import com.intellij.refactoring.ui.MemberSelectionPanel; import com.intellij.refactoring.util.RefactoringUtil; import com.intellij.refactoring.util.classMembers.MemberInfo; import com.intellij.refactoring.util.duplicates.Match; +import com.intellij.testFramework.LightVirtualFile; import com.intellij.usageView.UsageInfo; import com.intellij.usageView.UsageViewDescriptor; import com.intellij.usageView.UsageViewUtil; @@ -100,8 +104,12 @@ public class ExtractMethodObjectProcessor extends BaseRefactoringProcessor { @NotNull protected UsageInfo[] findUsages() { final ArrayList result = new ArrayList(); + final PsiClass containingClass = getMethod().getContainingClass(); + final SearchScope scope = PsiUtilCore.getVirtualFile(containingClass) instanceof LightVirtualFile + ? new LocalSearchScope(containingClass) + : GlobalSearchScope.projectScope(myProject); PsiReference[] refs = - ReferencesSearch.search(getMethod(), GlobalSearchScope.projectScope(myProject), false).toArray(PsiReference.EMPTY_ARRAY); + ReferencesSearch.search(getMethod(), scope, false).toArray(PsiReference.EMPTY_ARRAY); for (PsiReference ref : refs) { final PsiElement element = ref.getElement(); if (element != null && element.isValid()) { @@ -320,7 +328,7 @@ public class ExtractMethodObjectProcessor extends BaseRefactoringProcessor { for (PsiElement declaredElement : declaredElements) { if (declaredElement instanceof PsiVariable) { for (PsiVariable variable : outputVariables) { - PsiLocalVariable var = (PsiLocalVariable)declaredElement; + PsiVariable var = (PsiVariable)declaredElement; if (Comparing.strEqual(var.getName(), variable.getName())) { final PsiExpression initializer = var.getInitializer(); if (initializer == null) { @@ -400,8 +408,7 @@ public class ExtractMethodObjectProcessor extends BaseRefactoringProcessor { private String getPureName(PsiVariable var) { final JavaCodeStyleManager styleManager = JavaCodeStyleManager.getInstance(myProject); - final VariableKind kind = var instanceof PsiLocalVariable ? VariableKind.LOCAL_VARIABLE : VariableKind.PARAMETER; - return styleManager.variableNameToPropertyName(var.getName(), kind); + return styleManager.variableNameToPropertyName(var.getName(), styleManager.getVariableKind(var)); } public PsiExpression processMethodDeclaration( PsiExpressionList expressionList) throws IncorrectOperationException { @@ -517,7 +524,7 @@ public class ExtractMethodObjectProcessor extends BaseRefactoringProcessor { LOG.assertTrue(methodBody != null); replacedMethodBody.replace(methodBody); PsiUtil.setModifierProperty(newMethod, PsiModifier.STATIC, myInnerClass.hasModifierProperty(PsiModifier.STATIC) && notHasGeneratedFields()); - myInnerMethod = (PsiMethod)myInnerClass.add(newMethod); + myInnerMethod = (PsiMethod)JavaCodeStyleManager.getInstance(myProject).shortenClassReferences(myInnerClass.add(newMethod)); } private boolean notHasGeneratedFields() { @@ -624,6 +631,22 @@ public class ExtractMethodObjectProcessor extends BaseRefactoringProcessor { return myExtractProcessor; } + protected AbstractExtractDialog createExtractMethodObjectDialog(final MyExtractMethodProcessor processor) { + return new ExtractMethodObjectDialog(myProject, processor.getTargetClass(), processor.getInputVariables(), processor.getReturnType(), + processor.getTypeParameterList(), + processor.getThrownExceptions(), processor.isStatic(), processor.isCanBeStatic(), + processor.getElements(), myMultipleExitPoints){ + @Override + protected boolean isUsedAfter(PsiVariable variable) { + return ArrayUtil.find(processor.getOutputVariables(), variable) != -1; + } + }; + } + + public PsiClass getInnerClass() { + return myInnerClass; + } + public class MyExtractMethodProcessor extends ExtractMethodProcessor { public MyExtractMethodProcessor(Project project, @@ -640,19 +663,13 @@ public class ExtractMethodObjectProcessor extends BaseRefactoringProcessor { @Override protected void apply(final AbstractExtractDialog dialog) { super.apply(dialog); - myCreateInnerClass = ((ExtractMethodObjectDialog)dialog).createInnerClass(); + myCreateInnerClass = !(dialog instanceof ExtractMethodObjectDialog) || ((ExtractMethodObjectDialog)dialog).createInnerClass(); myInnerClassName = myCreateInnerClass ? StringUtil.capitalize(dialog.getChosenMethodName()) : dialog.getChosenMethodName(); } @Override protected AbstractExtractDialog createExtractMethodDialog(final boolean direct) { - return new ExtractMethodObjectDialog(myProject, myTargetClass, myInputVariables, myReturnType, myTypeParameterList, - myThrownExceptions, myStatic, myCanBeStatic, myElements, myMultipleExitPoints){ - @Override - protected boolean isUsedAfter(PsiVariable variable) { - return ArrayUtil.find(myOutputVariables, variable) != -1; - } - }; + return createExtractMethodObjectDialog(this); } @Override diff --git a/java/java-tests/testData/refactoring/extractMethodObject4Debugger/SimpleGeneration.java b/java/java-tests/testData/refactoring/extractMethodObject4Debugger/SimpleGeneration.java new file mode 100644 index 000000000000..178a4844ef5f --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethodObject4Debugger/SimpleGeneration.java @@ -0,0 +1,7 @@ +class Sample { + void foo() { + int i = 0; + int j = 0; + System.out.println(i + j); + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodObject4DebuggerTest.java b/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodObject4DebuggerTest.java new file mode 100644 index 000000000000..64e355126e2f --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodObject4DebuggerTest.java @@ -0,0 +1,84 @@ +/* + * 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. + */ + +/* + * User: anna + * Date: 06-May-2008 + */ +package com.intellij.refactoring; + +import com.intellij.JavaTestUtil; +import com.intellij.codeInsight.CodeInsightUtil; +import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.refactoring.extractMethodObject.ExtractLightMethodObjectHandler; +import com.intellij.testFramework.IdeaTestUtil; +import org.jetbrains.annotations.NotNull; + +public class ExtractMethodObject4DebuggerTest extends LightRefactoringTestCase { + @NotNull + @Override + protected String getTestDataPath() { + return JavaTestUtil.getJavaTestDataPath(); + } + + private void doTest(String expectedCallSite, String expectedClass) throws Exception { + final String testName = getTestName(false); + configureByFile("/refactoring/extractMethodObject4Debugger/" + testName + ".java"); + int startOffset = getEditor().getSelectionModel().getSelectionStart(); + int endOffset = getEditor().getSelectionModel().getSelectionEnd(); + PsiElement[] elements = CodeInsightUtil.findStatementsInRange(getFile(), startOffset, endOffset); + assertTrue(elements.length > 0); + + final ExtractLightMethodObjectHandler.ExtractedData extractedData = + ExtractLightMethodObjectHandler.extractLightMethodObject(getProject(), getEditor(), getFile(), elements, "test"); + assertNotNull(extractedData); + assertEquals(expectedCallSite, extractedData.getGeneratedCallText()); + final PsiClass innerClass = extractedData.getGeneratedInnerClass(); + assertEquals(expectedClass, innerClass.getText()); + } + + public void testSimpleGeneration() throws Exception { + doTest(" Test test = new Test().invoke();\n" + + " int i = test.getI();\n" + + " int j = test.getJ();", + + "public class Test {\n" + + " private int i;\n" + + " private int j;\n" + + "\n" + + " public int getI() {\n" + + " return i;\n" + + " }\n" + + "\n" + + " public int getJ() {\n" + + " return j;\n" + + " }\n" + + "\n" + + " public Test invoke() {\n" + + " i = 0;\n" + + " j = 0;\n" + + " return this;\n" + + " }\n" + + " }"); + } + + @Override + protected Sdk getProjectJDK() { + return IdeaTestUtil.getMockJdk18(); + } +} From 06b35cb29f1a354c722587f8717df2cba827be7c Mon Sep 17 00:00:00 2001 From: "Vassiliy.Kudryashov" Date: Wed, 3 Sep 2014 23:31:50 +0400 Subject: [PATCH 26/60] IDEA-127739 Navigation Tab Stage 4 mock gear actions --- .../openapi/actionSystem/Separator.java | 5 + .../openapi/actionSystem/impl/Utils.java | 26 +++- .../openapi/fileEditor/impl/EditorWindow.java | 4 + .../fileEditor/impl/EditorsSplitters.java | 8 +- .../impl/FileEditorManagerImpl.java | 36 +----- .../openapi/fileEditor/impl/PreviewPanel.java | 119 +++++++++++++++--- .../openapi/wm/impl/InternalDecorator.java | 5 + 7 files changed, 152 insertions(+), 51 deletions(-) diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/Separator.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/Separator.java index 2dd2ee50d120..191c8c01ce32 100644 --- a/platform/platform-api/src/com/intellij/openapi/actionSystem/Separator.java +++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/Separator.java @@ -41,6 +41,11 @@ public final class Separator extends AnAction implements DumbAware { return ourInstance; } + @Override + public String toString() { + return "Separator (" + myText + ")"; + } + @Override public void actionPerformed(AnActionEvent e){ throw new UnsupportedOperationException(); diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/Utils.java b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/Utils.java index 85c0555f9bc6..9af1d30c28bf 100644 --- a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/Utils.java +++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/Utils.java @@ -26,6 +26,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.ActionCallback; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.registry.Registry; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NonNls; @@ -164,7 +165,7 @@ public class Utils{ } } else if (child instanceof Separator) { - if (!list.isEmpty() && !(list.get(list.size() - 1) instanceof Separator)) { + if (!StringUtil.isEmpty(((Separator)child).getText()) || (!list.isEmpty() && !(list.get(list.size() - 1) instanceof Separator))) { list.add(child); } } @@ -284,8 +285,10 @@ public class Utils{ for (int i = 0, size = list.size(); i < size; i++) { final AnAction action = list.get(i); if (action instanceof Separator) { - if (i > 0 && i < size - 1) { + final String text = ((Separator)action).getText(); + if (!StringUtil.isEmpty(text) || (i > 0 && i < size - 1)) { component.add(new JPopupMenu.Separator() { + private final JMenuItem myMenu = !StringUtil.isEmpty(text) ? new JMenuItem(text) : null; @Override public Insets getInsets() { final Insets insets = super.getInsets(); @@ -295,13 +298,30 @@ public class Utils{ return fix ? new Insets(2, insets.left, 3, insets.right) : insets; // workaround for Sun bug #6636964 } + @Override + public void doLayout() { + super.doLayout(); + if (myMenu != null) { + myMenu.setBounds(getBounds()); + } + } + @Override protected void paintComponent(Graphics g) { if (UIUtil.isUnderWindowsClassicLookAndFeel() || UIUtil.isUnderDarcula() || UIUtil.isUnderWindowsLookAndFeel()) { g.setColor(component.getBackground()); g.fillRect(0, 0, getWidth(), getHeight()); } - super.paintComponent(g); + if (myMenu != null) { + myMenu.paint(g); + } else { + super.paintComponent(g); + } + } + + @Override + public Dimension getPreferredSize() { + return myMenu != null ? myMenu.getPreferredSize() : super.getPreferredSize(); } }); } diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWindow.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWindow.java index 06a3966ade1d..c1515a817b26 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWindow.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWindow.java @@ -701,6 +701,7 @@ public class EditorWindow { public void setEditor(@Nullable final EditorWithProviderComposite editor, final boolean selectEditor, final boolean focusEditor) { if (editor != null) { + onBeforeSetEditor(editor.getFile()); if (myTabbedPane == null) { myPanel.removeAll (); myPanel.add (new TCompForTablessMode(this, editor), BorderLayout.CENTER); @@ -741,6 +742,9 @@ public class EditorWindow { myOwner.validate(); } + protected void onBeforeSetEditor(VirtualFile file) { + } + private boolean splitAvailable() { return getTabCount() >= 1; } diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java index fa0a4dbd6fe4..b0f274e9e5a4 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java @@ -614,10 +614,14 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener public void createCurrentWindow() { LOG.assertTrue(myCurrentWindow == null); - setCurrentWindow(new EditorWindow(this)); + setCurrentWindow(createEditorWindow()); add(myCurrentWindow.myPanel, BorderLayout.CENTER); } + protected EditorWindow createEditorWindow() { + return new EditorWindow(this); + } + /** * sets the window passed as a current ('focused') window among all splitters. All file openings will be done inside this * current window @@ -832,7 +836,7 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener UIUtil.invokeAndWaitIfNeeded(new Runnable() { @Override public void run() { - windowRef.set(context == null ? new EditorWindow(EditorsSplitters.this) : findWindowWith(context)); + windowRef.set(context == null ? createEditorWindow() : findWindowWith(context)); } }); final EditorWindow window = windowRef.get(); diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java index 1cedbd8c3c00..c0135f98dfea 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java @@ -58,7 +58,6 @@ import com.intellij.openapi.vcs.FileStatusListener; import com.intellij.openapi.vcs.FileStatusManager; import com.intellij.openapi.vfs.*; import com.intellij.openapi.wm.IdeFocusManager; -import com.intellij.openapi.wm.ToolWindowId; import com.intellij.openapi.wm.ToolWindowManager; import com.intellij.openapi.wm.WindowManager; import com.intellij.openapi.wm.ex.StatusBarEx; @@ -91,7 +90,6 @@ import java.beans.PropertyChangeListener; import java.lang.ref.WeakReference; import java.util.*; import java.util.List; -import java.util.concurrent.atomic.AtomicBoolean; /** * @author Anton Katilin @@ -113,7 +111,6 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec private final Project myProject; private final List> mySelectionHistory = new ArrayList>(); private WeakReference myLastSelectedComposite = new WeakReference(null); - private final AtomicBoolean myPreviewBlocker = new AtomicBoolean(false); private final MergingUpdateQueue myQueue = new MergingUpdateQueue("FileEditorManagerUpdateQueue", 50, true, null); @@ -181,8 +178,9 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec HashSet all = new LinkedHashSet(); if (PreviewPanel.isAvailable()) { initUI(); - if (!myProject.isDisposed()) { - all.add(myPreviewPanel.getWindow().getOwner()); + EditorWindow window = myPreviewPanel.getWindow(); + if (window != null) { + all.add(window.getOwner()); } } all.add(getMainSplitters()); @@ -644,7 +642,8 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec } if (wndToOpenIn == null || !wndToOpenIn.isFileOpen(file)) { - EditorWindow previewWindow = getPreviewWindow(file, focusEditor, searchForSplitter); + initUI(); + EditorWindow previewWindow = myPreviewPanel.getWindow(); if (previewWindow != null) { wndToOpenIn = previewWindow; } @@ -660,31 +659,6 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec return openFileImpl2(wndToOpenIn, file, focusEditor); } - @Nullable - private EditorWindow getPreviewWindow(@NotNull VirtualFile virtualFile, final boolean focusEditor, final boolean searchForSplitter) { - EditorWindow wndToOpenIn = null; - if (PreviewPanel.isAvailable() && !myPreviewBlocker.get()) { - wndToOpenIn = myPreviewPanel.getWindow(); - if (myPreviewPanel.hasCurrentFile(virtualFile)) return wndToOpenIn; - final VirtualFile modifiedFile = myPreviewPanel.getCurrentModifiedFile(); - ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.PREVIEW).activate(null, false); - if (modifiedFile != null) { - CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { - @Override - public void run() { - myPreviewBlocker.set(true); - try { - openFileWithProviders(modifiedFile, focusEditor, searchForSplitter); - } finally { - myPreviewBlocker.set(false); - } - } - }, "", null); - } - } - return wndToOpenIn; - } - public Pair openFileInNewWindow(@NotNull VirtualFile file) { return ((DockManagerImpl)DockManager.getInstance(getProject())).createNewDockContainerFor(file, this); } diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/PreviewPanel.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/PreviewPanel.java index ade7001fc279..1c9af86cd12a 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/PreviewPanel.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/PreviewPanel.java @@ -17,8 +17,11 @@ package com.intellij.openapi.fileEditor.impl; import com.intellij.icons.AllIcons; import com.intellij.ide.ui.UISettings; +import com.intellij.ide.ui.UISettingsListener; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DefaultActionGroup; +import com.intellij.openapi.actionSystem.ToggleAction; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.fileEditor.FileEditorManagerListener; @@ -41,8 +44,11 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; import java.util.ArrayList; +import java.util.EnumSet; class PreviewPanel extends JPanel { + enum ContentType {Files, Usages, Diagrams, Documentation} + private static final Key FILE_KEY = Key.create("v_file"); private static final int HISTORY_LIMIT = 10; @@ -57,6 +63,9 @@ class PreviewPanel extends JPanel { private VirtualFile myAwaitingForOpen = null; private ContentManager myContentManager; private Content myStubContent; + private boolean myBlocked = false; + + private EnumSet myTypes = EnumSet.noneOf(ContentType.class); static boolean isAvailable() { return UISettings.getInstance().NAVIGATE_TO_PREVIEW; @@ -68,28 +77,37 @@ class PreviewPanel extends JPanel { myDockManager = dockManager; } - // package-private API - + /* + * @return null if preview is not avalable + */ + @Nullable EditorWindow getWindow() { + if (!isAvailable() || isBlocked() || myProject.isDisposed()) return null; initToolWindowIfNeed(); return myWindow; } - boolean hasCurrentFile(@NotNull VirtualFile file) { - return file.equals(getCurrentFile()); - } - - @Nullable - VirtualFile getCurrentModifiedFile() { - VirtualFile file = getCurrentFile(); - return file != null && file.equals(myModifiedFile) ? file : null; + boolean isBlocked() { + return myBlocked; } private void initToolWindowIfNeed() { - if (ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.PREVIEW) != null) return; + if (!isAvailable() || ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.PREVIEW) != null) return; myToolWindow = (ToolWindowImpl)ToolWindowManager.getInstance(myProject) .registerToolWindow(ToolWindowId.PREVIEW, this, ToolWindowAnchor.RIGHT, myProject, false); + UISettings.getInstance().addUISettingsListener(new UISettingsListener() { + @Override + public void uiSettingsChanged(UISettings source) { + if (!isAvailable()) { + VirtualFile[] files = myWindow.getFiles(); + for (VirtualFile file : files) { + close(file); + } + ToolWindowManager.getInstance(myProject).unregisterToolWindow(ToolWindowId.PREVIEW); + } + } + }, myProject); myToolWindow.setIcon(AllIcons.Actions.PreviewDetails); myToolWindow.setContentUiType(ToolWindowContentUiType.COMBO, null); myContentManager = myToolWindow.getContentManager(); @@ -147,6 +165,11 @@ class PreviewPanel extends JPanel { setLayout(new GridLayout(1, 1)); add(myEditorsSplitters); myToolWindow.setTitleActions(new MoveToEditorTabsAction(), new CloseFileAction()); + ArrayList myGearActions = new ArrayList(); + for (ContentType contentType : ContentType.values()) { + myGearActions.add(new ContentTypeToggleAction(contentType)); + } + myToolWindow.setAdditionalGearActions(new DefaultActionGroup("Preview", myGearActions)); myToolWindow.hide(null); } @@ -204,7 +227,7 @@ class PreviewPanel extends JPanel { @Override public void run() { if (myContentManager.getIndexOfContent(myStubContent) != -1) { - ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.PREVIEW).hide(null); + toggleToolWindow(false); } } }); @@ -224,6 +247,13 @@ class PreviewPanel extends JPanel { myAwaitingForOpen = null; } if (file.equals(myModifiedFile)) { + myBlocked = true; + try { + myManager.openFileWithProviders(myModifiedFile, false, true); + } + finally { + myBlocked = false; + } myModifiedFile = null; } Content content = getContent(file); @@ -233,9 +263,22 @@ class PreviewPanel extends JPanel { } } + private void toggleToolWindow(boolean activate) { + ToolWindow toolWindow = ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.PREVIEW); + if (toolWindow != null) { + if (activate) { + toolWindow.activate(null, false); + } + else { + toolWindow.hide(null); + } + } + } + private class MoveToEditorTabsAction extends AnAction { + public MoveToEditorTabsAction() { - super(null, "Move to main tabs", AllIcons.Duplicates.SendToTheLeftGrayed); + super("Move to main tabs", "Move to main tabs", AllIcons.Duplicates.SendToTheLeftGrayed); } @Override @@ -252,14 +295,14 @@ class PreviewPanel extends JPanel { } myManager.openFileWithProviders(virtualFile, true, window); close(virtualFile); - ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.PREVIEW).hide(null); + toggleToolWindow(false); } } private class CloseFileAction extends AnAction { public CloseFileAction() { - super(null, "Close", AllIcons.Actions.Close); + super("Close", "Close", AllIcons.Actions.Close); } @Override @@ -267,6 +310,30 @@ class PreviewPanel extends JPanel { for (VirtualFile file : myHistory.toArray(new VirtualFile[myHistory.size()])) { close(file); } + toggleToolWindow(false); + } + } + + private class ContentTypeToggleAction extends ToggleAction { + private final ContentType myContentType; + + ContentTypeToggleAction(ContentType contentType) { + super(contentType.toString()); + myContentType = contentType; + } + + @Override + public boolean isSelected(AnActionEvent e) { + return myTypes.contains(myContentType); + } + + @Override + public void setSelected(AnActionEvent e, boolean state) { + if (state) { + myTypes.add(myContentType); + } else { + myTypes.remove(myContentType); + } } } @@ -296,6 +363,28 @@ class PreviewPanel extends JPanel { } } + @Override + protected EditorWindow createEditorWindow() { + return new EditorWindow(this) { + @Override + protected void onBeforeSetEditor(VirtualFile file) { + VirtualFile currentFile = getCurrentFile(); + if (currentFile != null && currentFile.equals(myModifiedFile)) { + myBlocked = true; + try { + myManager.openFileWithProviders(myModifiedFile, false, true); + } + finally { + myBlocked = false; + } + } + else { + toggleToolWindow(true); + } + } + }; + } + @Override public void setTabsPlacement(int tabPlacement) { super.setTabsPlacement(UISettings.TABS_NONE); diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/InternalDecorator.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/InternalDecorator.java index e6c84f5e7768..17acd7d1ee66 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/InternalDecorator.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/InternalDecorator.java @@ -28,6 +28,7 @@ import com.intellij.openapi.ui.Splitter; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.wm.*; import com.intellij.ui.Gray; import com.intellij.ui.JBColor; @@ -447,6 +448,10 @@ public final class InternalDecorator extends JPanel implements Queryable, TypeSa } } } + String separatorText = group.getTemplatePresentation().getText(); + if (children.length > 0 && !StringUtil.isEmpty(separatorText)) { + main.addAction(new Separator(separatorText), Constraints.FIRST); + } } /** From fbbef502edf39125371eb3c115a147873241431f Mon Sep 17 00:00:00 2001 From: Sergey Simonchik Date: Thu, 4 Sep 2014 01:33:00 +0400 Subject: [PATCH 27/60] order children inside "Settings | JavaScript": Libraries, Code Quality Tools, Templates, Bower, PhoneGap, Meteor --- .../openapi/options/ex/ConfigurableExtensionPointUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableExtensionPointUtil.java b/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableExtensionPointUtil.java index 2b5428411e47..2aebbbbbeab1 100644 --- a/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableExtensionPointUtil.java +++ b/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableExtensionPointUtil.java @@ -48,7 +48,7 @@ public class ConfigurableExtensionPointUtil { } } - final Map idToConfigurable = new HashMap(); + final Map idToConfigurable = new LinkedHashMap(); for (ConfigurableEP ep : extensions) { final Configurable configurable = ConfigurableWrapper.wrapConfigurable(ep); if (isSuppressed(configurable, filter)) continue; From d14cfcea2684d015d4c1dd3c95605e12b68e9a18 Mon Sep 17 00:00:00 2001 From: Anton Makeev Date: Fri, 29 Aug 2014 23:59:03 +0200 Subject: [PATCH 28/60] Windows 64-bit launcher looks for bundled jre in both jre and jre64 folders (cherry picked from commit 758810a) --- bin/WinLauncher/WinLauncher.exe | Bin 822784 -> 822784 bytes bin/WinLauncher/WinLauncher64.exe | Bin 839168 -> 839168 bytes .../WinLauncher/WinLauncher/WinLauncher.cpp | 15 ++++++++++----- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/bin/WinLauncher/WinLauncher.exe b/bin/WinLauncher/WinLauncher.exe index 66b04fa1bfd83af8f9108dbc0a2e188ec69926dd..afe000ae7459ee95addaf83d26994d29d25526e3 100644 GIT binary patch delta 31542 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 delta 32348 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 K*|;UPr|dt`GKs$c diff --git a/bin/WinLauncher/WinLauncher64.exe b/bin/WinLauncher/WinLauncher64.exe index 12a18522deedde6e20f9184373a97edb2e210e2a..7dc6ef8deb5e3d3213ef5ddc4b0898006b65d595 100644 GIT binary patch delta 39124 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 delta 38335 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 diff --git a/native/WinLauncher/WinLauncher/WinLauncher.cpp b/native/WinLauncher/WinLauncher/WinLauncher.cpp index 3249a9a1f0de..681cb46ae6aa 100644 --- a/native/WinLauncher/WinLauncher/WinLauncher.cpp +++ b/native/WinLauncher/WinLauncher/WinLauncher.cpp @@ -194,11 +194,16 @@ bool LocateJVM() return result; } - std::string jreDir = GetAdjacentDir(need64BitJRE ? "jre64":"jre"); - if (FindValidJVM(jreDir.c_str()) && Is64BitJRE(jvmPath) == need64BitJRE) - { - return true; - } + + std::vector jrePaths; + if(need64BitJRE) jrePaths.push_back(GetAdjacentDir("jre64")); + jrePaths.push_back(GetAdjacentDir("jre")); + for(std::vector::iterator it = jrePaths.begin(); it != jrePaths.end(); ++it) { + if (FindValidJVM((*it).c_str()) && Is64BitJRE(jvmPath) == need64BitJRE) + { + return true; + } + } if (FindJVMInRegistry()) { From ae5c1967c21f273d8b322386339222063346fad5 Mon Sep 17 00:00:00 2001 From: Sergey Ignatov Date: Thu, 4 Sep 2014 11:54:45 +0400 Subject: [PATCH 29/60] NPE fix and cleanup --- .../fileEditor/impl/FileEditorManagerImpl.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java index c0135f98dfea..f0d5c8df807c 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java @@ -264,7 +264,7 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec private static class MyBorder implements Border { @Override - public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { + public void paintBorder(@NotNull Component c, @NotNull Graphics g, int x, int y, int width, int height) { if (UIUtil.isUnderAquaLookAndFeel()) { g.setColor(JBTabsImpl.MAC_AQUA_BG_COLOR); final Insets insets = getBorderInsets(c); @@ -274,6 +274,7 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec } } + @NotNull @Override public Insets getBorderInsets(Component c) { return JBInsets.NONE; @@ -643,7 +644,7 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec if (wndToOpenIn == null || !wndToOpenIn.isFileOpen(file)) { initUI(); - EditorWindow previewWindow = myPreviewPanel.getWindow(); + EditorWindow previewWindow = PreviewPanel.isAvailable() && myPreviewPanel != null ? myPreviewPanel.getWindow() : null; if (previewWindow != null) { wndToOpenIn = previewWindow; } @@ -781,7 +782,7 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec final FileEditorProvider provider = newProviders[i]; LOG.assertTrue(provider != null, "Provider for file "+file+" is null. All providers: "+Arrays.asList(newProviders)); LOG.assertTrue(provider.accept(myProject, file), "Provider " + provider + " doesn't accept file " + file); - if ((provider instanceof AsyncFileEditorProvider)) { + if (provider instanceof AsyncFileEditorProvider) { builders[i] = ((AsyncFileEditorProvider)provider).createEditorAsync(myProject, file); } } @@ -920,7 +921,7 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec return Pair.create(compositeRef.get().getEditors(), compositeRef.get().getProviders()); } - private void clearWindowIfNeeded(EditorWindow window) { + private static void clearWindowIfNeeded(EditorWindow window) { if (UISettings.getInstance().EDITOR_TAB_PLACEMENT == UISettings.TABS_NONE || UISettings.getInstance().PRESENTATION_MODE) { for (EditorWithProviderComposite composite : window.getEditors()) { Disposer.dispose(composite); @@ -1736,7 +1737,7 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec private final class MyEditorPropertyChangeListener implements PropertyChangeListener { @Override - public void propertyChange(final PropertyChangeEvent e) { + public void propertyChange(@NotNull final PropertyChangeEvent e) { assertDispatchThread(); final String propertyName = e.getPropertyName(); @@ -1975,6 +1976,7 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec mySelectionHistory.remove(Pair.create(file, window)); } + @NotNull @Override public ActionCallback getReady(@NotNull Object requestor) { return myBusyObject.getReady(requestor); From e3f5d929951a6c0a83746119eba1ccfa7b6e8870 Mon Sep 17 00:00:00 2001 From: Sergey Ignatov Date: Thu, 4 Sep 2014 12:07:25 +0400 Subject: [PATCH 30/60] notnull --- .../src/com/intellij/ide/actions/GotoActionBase.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/actions/GotoActionBase.java b/platform/lang-impl/src/com/intellij/ide/actions/GotoActionBase.java index c109de7a00a9..5da112b375b9 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/GotoActionBase.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/GotoActionBase.java @@ -62,7 +62,7 @@ public abstract class GotoActionBase extends AnAction { private int myHistoryIndex = 0; @Override - public void actionPerformed(AnActionEvent e) { + public void actionPerformed(@NotNull AnActionEvent e) { LOG.assertTrue(!getClass().equals(myInAction)); try { myInAction = getClass(); @@ -79,7 +79,7 @@ public abstract class GotoActionBase extends AnAction { protected abstract void gotoActionPerformed(AnActionEvent e); @Override - public void update(final AnActionEvent event) { + public void update(@NotNull final AnActionEvent event) { final Presentation presentation = event.getPresentation(); final DataContext dataContext = event.getDataContext(); final Project project = CommonDataKeys.PROJECT.getData(dataContext); @@ -260,7 +260,7 @@ public abstract class GotoActionBase extends AnAction { abstract class HistoryAction extends DumbAwareAction { @Override - public void update(AnActionEvent e) { + public void update(@NotNull AnActionEvent e) { e.getPresentation().setEnabled(historyEnabled()); } @@ -277,7 +277,7 @@ public abstract class GotoActionBase extends AnAction { new HistoryAction() { @Override - public void actionPerformed(AnActionEvent e) { + public void actionPerformed(@NotNull AnActionEvent e) { List strings = ourHistory.get(myInAction); setText(strings); myHistoryIndex = myHistoryIndex >= strings.size() - 1 ? 0 : myHistoryIndex + 1; @@ -287,7 +287,7 @@ public abstract class GotoActionBase extends AnAction { new HistoryAction() { @Override - public void actionPerformed(AnActionEvent e) { + public void actionPerformed(@NotNull AnActionEvent e) { List strings = ourHistory.get(myInAction); setText(strings); myHistoryIndex = myHistoryIndex <= 0 ? strings.size() - 1 : myHistoryIndex - 1; From 623445751282bd6ec396273b855cbcba0ee92d7e Mon Sep 17 00:00:00 2001 From: Sergey Ignatov Date: Thu, 4 Sep 2014 12:58:18 +0400 Subject: [PATCH 31/60] recent files: open file in new window when shift is pressed --- .../com/intellij/ide/actions/Switcher.java | 35 +++++++++++-------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/actions/Switcher.java b/platform/platform-impl/src/com/intellij/ide/actions/Switcher.java index cb35b5a504f9..b6ae7a573fac 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/Switcher.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/Switcher.java @@ -94,7 +94,7 @@ public class Switcher extends AnAction implements DumbAware { public void run() { synchronized (Switcher.class) { if (SWITCHER != null) { - SWITCHER.navigate(); + SWITCHER.navigate(false); } } } @@ -200,7 +200,7 @@ public class Switcher extends AnAction implements DumbAware { jList.setSelectedIndex(jList.getAnchorSelectionIndex()); } if (jList.getSelectedIndex() != -1) { - navigate(); + navigate(false); } } return true; @@ -590,17 +590,17 @@ public class Switcher extends AnAction implements DumbAware { return ((KeyboardShortcut)shortcutSet.getShortcuts()[0]).getFirstKeyStroke().getModifiers(); } - public void keyTyped(KeyEvent e) { + public void keyTyped(@NotNull KeyEvent e) { } public void keyReleased(KeyEvent e) { - if ((e.getKeyCode() == CTRL_KEY && isAutoHide()) - || e.getKeyCode() == VK_ENTER) { - navigate(); - } else - if (e.getKeyCode() == VK_LEFT) { + if (e.getKeyCode() == CTRL_KEY && isAutoHide() || e.getKeyCode() == VK_ENTER) { + navigate(e.isShiftDown()); + } + else if (e.getKeyCode() == VK_LEFT) { goLeft(); - } else if (e.getKeyCode() == VK_RIGHT) { + } + else if (e.getKeyCode() == VK_RIGHT) { goRight(); } } @@ -836,7 +836,7 @@ public class Switcher extends AnAction implements DumbAware { } } - void navigate() { + void navigate(final boolean openInNewWindow) { final Object[] values = getSelectedList().getSelectedValues(); myPopup.closeOk(null); if (values.length > 0 && values[0] instanceof ToolWindow) { @@ -850,14 +850,19 @@ public class Switcher extends AnAction implements DumbAware { if (value instanceof FileInfo) { final FileInfo info = (FileInfo)value; - if (info.second != null) { + VirtualFile file = info.first; + if (openInNewWindow) { + manager.openFileInNewWindow(file); + } + else if (info.second != null) { EditorWindow wnd = findAppropriateWindow(info); if (wnd != null) { - manager.openFileImpl2(wnd, info.first, true); - manager.addSelectionRecord(info.first, wnd); + manager.openFileImpl2(wnd, file, true); + manager.addSelectionRecord(file, wnd); } - } else { - manager.openFile(info.first, true, true); + } + else { + manager.openFile(file, true, true); } } } From 8c15c69f2f7b602fbb61d82aaa50e502564caf53 Mon Sep 17 00:00:00 2001 From: Sergey Ignatov Date: Thu, 4 Sep 2014 12:59:08 +0400 Subject: [PATCH 32/60] notnull and cleanup --- .../com/intellij/ide/actions/Switcher.java | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/actions/Switcher.java b/platform/platform-impl/src/com/intellij/ide/actions/Switcher.java index b6ae7a573fac..cecf0f60a803 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/Switcher.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/Switcher.java @@ -135,7 +135,7 @@ public class Switcher extends AnAction implements DumbAware { @NonNls private static final String SWITCHER_TITLE = "Switcher"; - public void actionPerformed(AnActionEvent e) { + public void actionPerformed(@NotNull AnActionEvent e) { final Project project = CommonDataKeys.PROJECT.getData(e.getDataContext()); if (project == null) return; @@ -226,7 +226,7 @@ public class Switcher extends AnAction implements DumbAware { descriptions = new JPanel(new BorderLayout()) { @Override - protected void paintComponent(Graphics g) { + protected void paintComponent(@NotNull Graphics g) { super.paintComponent(g); g.setColor(UIUtil.isUnderDarcula() ? SEPARATOR_COLOR : BORDER_COLOR); g.drawLine(0, 0, getWidth(), 0); @@ -249,7 +249,7 @@ public class Switcher extends AnAction implements DumbAware { final Map map = ContainerUtil.reverseMap(twShortcuts); Collections.sort(windows, new Comparator() { @Override - public int compare(ToolWindow o1, ToolWindow o2) { + public int compare(@NotNull ToolWindow o1, @NotNull ToolWindow o2) { return StringUtil.compare(map.get(o1), map.get(o2), false); } }); @@ -297,7 +297,7 @@ public class Switcher extends AnAction implements DumbAware { toolWindows.addMouseMotionListener(this); myClickListener.installOn(toolWindows); toolWindows.getSelectionModel().addListSelectionListener(new ListSelectionListener() { - public void valueChanged(ListSelectionEvent e) { + public void valueChanged(@NotNull ListSelectionEvent e) { if (!toolWindows.isSelectionEmpty() && !files.isSelectionEmpty()) { files.clearSelection(); } @@ -306,7 +306,7 @@ public class Switcher extends AnAction implements DumbAware { separator = new JPanel() { @Override - protected void paintComponent(Graphics g) { + protected void paintComponent(@NotNull Graphics g) { super.paintComponent(g); g.setColor(SEPARATOR_COLOR); g.drawLine(0, 0, 0, getHeight()); @@ -374,7 +374,7 @@ public class Switcher extends AnAction implements DumbAware { JPanel myPanel = new JPanel(new BorderLayout()); JLabel myLabel = new JLabel() { @Override - protected void paintComponent(Graphics g) { + protected void paintComponent(@NotNull Graphics g) { GraphicsConfig config = new GraphicsConfig(g); ((Graphics2D)g).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.3f)); super.paintComponent(g); @@ -425,7 +425,7 @@ public class Switcher extends AnAction implements DumbAware { return fullText; } - public void valueChanged(final ListSelectionEvent e) { + public void valueChanged(@NotNull final ListSelectionEvent e) { ApplicationManager.getApplication().invokeLater(new Runnable() { public void run() { updatePathLabel(); @@ -466,7 +466,7 @@ public class Switcher extends AnAction implements DumbAware { files.setSelectionMode(pinned ? ListSelectionModel.MULTIPLE_INTERVAL_SELECTION : ListSelectionModel.SINGLE_SELECTION); files.getSelectionModel().addListSelectionListener(new ListSelectionListener() { - public void valueChanged(ListSelectionEvent e) { + public void valueChanged(@NotNull ListSelectionEvent e) { if (!files.isSelectionEmpty() && !toolWindows.isSelectionEmpty()) { toolWindows.getSelectionModel().clearSelection(); } @@ -526,21 +526,21 @@ public class Switcher extends AnAction implements DumbAware { if (isPinnedMode()) { new AnAction(null ,null ,null) { @Override - public void actionPerformed(AnActionEvent e) { + public void actionPerformed(@NotNull AnActionEvent e) { changeSelection(); } }.registerCustomShortcutSet(CustomShortcutSet.fromString("TAB"), this, myPopup); new AnAction(null, null, null) { @Override - public void actionPerformed(AnActionEvent e) { + public void actionPerformed(@NotNull AnActionEvent e) { //suppress all actions to activate a toolwindow : IDEA-71277 } }.registerCustomShortcutSet(TW_SHORTCUT, this, myPopup); new AnAction(null, null, null) { @Override - public void actionPerformed(AnActionEvent e) { + public void actionPerformed(@NotNull AnActionEvent e) { if (mySpeedSearch != null && mySpeedSearch.isPopupActive()) { mySpeedSearch.hidePopup(); } else { @@ -606,8 +606,8 @@ public class Switcher extends AnAction implements DumbAware { } KeyEvent lastEvent; - public void keyPressed(KeyEvent e) { - if ((mySpeedSearch != null && mySpeedSearch.isPopupActive()) || lastEvent == e) return; + public void keyPressed(@NotNull KeyEvent e) { + if (mySpeedSearch != null && mySpeedSearch.isPopupActive() || lastEvent == e) return; lastEvent = e; switch (e.getKeyCode()) { case VK_UP: @@ -668,7 +668,7 @@ public class Switcher extends AnAction implements DumbAware { if (value instanceof FileInfo) { final FileInfo info = (FileInfo)value; final VirtualFile virtualFile = info.first; - final FileEditorManagerImpl editorManager = ((FileEditorManagerImpl)FileEditorManager.getInstance(project)); + final FileEditorManagerImpl editorManager = (FileEditorManagerImpl)FileEditorManager.getInstance(project); final JList jList = getSelectedList(); final EditorWindow wnd = findAppropriateWindow(info); if (wnd == null) { @@ -878,13 +878,13 @@ public class Switcher extends AnAction implements DumbAware { return ArrayUtil.contains(info.second, windows) ? info.second : windows.length > 0 ? windows[0] : null; } - public void mouseClicked(MouseEvent e) { + public void mouseClicked(@NotNull MouseEvent e) { } private boolean mouseMovedFirstTime = true; private JList mouseMoveSrc = null; private int mouseMoveListIndex = -1; - public void mouseMoved(MouseEvent e) { + public void mouseMoved(@NotNull MouseEvent e) { if (mouseMovedFirstTime) { mouseMovedFirstTime = false; return; @@ -912,15 +912,15 @@ public class Switcher extends AnAction implements DumbAware { files.repaint(); } - public void mousePressed(MouseEvent e) {} - public void mouseReleased(MouseEvent e) {} - public void mouseEntered(MouseEvent e) {} - public void mouseExited(MouseEvent e) { + public void mousePressed(@NotNull MouseEvent e) {} + public void mouseReleased(@NotNull MouseEvent e) {} + public void mouseEntered(@NotNull MouseEvent e) {} + public void mouseExited(@NotNull MouseEvent e) { mouseMoveSrc = null; mouseMoveListIndex = -1; repaintLists(); } - public void mouseDragged(MouseEvent e) {} + public void mouseDragged(@NotNull MouseEvent e) {} private class SwitcherSpeedSearch extends SpeedSearchBase implements PropertyChangeListener { private Object[] myElements; @@ -1036,7 +1036,7 @@ public class Switcher extends AnAction implements DumbAware { } @Override - public void propertyChange(PropertyChangeEvent evt) { + public void propertyChange(@NotNull PropertyChangeEvent evt) { final MyList list = getSelectedList(); final Object value = list.getSelectedValue(); if (project.isDisposed()) { @@ -1073,7 +1073,7 @@ public class Switcher extends AnAction implements DumbAware { private Rectangle dBounds; @Override - public void layoutContainer(Container target) { + public void layoutContainer(@NotNull Container target) { final JScrollPane scrollPane = UIUtil.getParentOfType(JScrollPane.class, files); JComponent filesPane = scrollPane != null ? scrollPane : files; if (sBounds == null || !target.isShowing()) { @@ -1147,7 +1147,7 @@ public class Switcher extends AnAction implements DumbAware { } @Override - public void processKeyEvent(KeyEvent e) { + public void processKeyEvent(@NotNull KeyEvent e) { super.processKeyEvent(e); } } From d4d8e4314a025d8c6e882ab57ffd30a1ab1185f1 Mon Sep 17 00:00:00 2001 From: Sergey Ignatov Date: Thu, 4 Sep 2014 12:59:44 +0400 Subject: [PATCH 33/60] notnull --- .../src/com/intellij/ide/actions/ShowRecentFilesAction.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/actions/ShowRecentFilesAction.java b/platform/platform-impl/src/com/intellij/ide/actions/ShowRecentFilesAction.java index 59ac567af38a..abd875af728f 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/ShowRecentFilesAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/ShowRecentFilesAction.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. @@ -25,13 +25,14 @@ import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; +import org.jetbrains.annotations.NotNull; /** * @author Konstantin Bulenkov */ public class ShowRecentFilesAction extends DumbAwareAction { @Override - public void actionPerformed(AnActionEvent e) { + public void actionPerformed(@NotNull AnActionEvent e) { final Project project = e.getData(CommonDataKeys.PROJECT); if (project != null) { FeatureUsageTracker.getInstance().triggerFeatureUsed("navigation.recent.files"); From 12952365ff58aae7dac4939367a9044fe41f9540 Mon Sep 17 00:00:00 2001 From: Sergey Ignatov Date: Thu, 4 Sep 2014 13:03:35 +0400 Subject: [PATCH 34/60] notnull --- .../ide/actions/BaseShowRecentFilesAction.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/actions/BaseShowRecentFilesAction.java b/platform/platform-impl/src/com/intellij/ide/actions/BaseShowRecentFilesAction.java index 442d09b8b3bd..505d0f5eef3d 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/BaseShowRecentFilesAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/BaseShowRecentFilesAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 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. @@ -39,6 +39,7 @@ import com.intellij.ui.components.JBList; import com.intellij.util.ArrayUtil; import com.intellij.util.Function; import com.intellij.util.IconUtil; +import org.jetbrains.annotations.NotNull; import javax.swing.*; import javax.swing.event.ListSelectionEvent; @@ -53,11 +54,11 @@ import java.io.File; public abstract class BaseShowRecentFilesAction extends AnAction implements DumbAware { private static final Color BORDER_COLOR = Gray._135; - public void actionPerformed(AnActionEvent e) { + public void actionPerformed(@NotNull AnActionEvent e) { show(CommonDataKeys.PROJECT.getData(e.getDataContext())); } - public void update(AnActionEvent event){ + public void update(@NotNull AnActionEvent event){ Presentation presentation = event.getPresentation(); Project project = CommonDataKeys.PROJECT.getData(event.getDataContext()); presentation.setEnabled(project != null); @@ -93,7 +94,7 @@ public abstract class BaseShowRecentFilesAction extends AnAction implements Dumb final JList list = new JBList(model); list.addKeyListener( new KeyAdapter() { - public void keyPressed(KeyEvent e) { + public void keyPressed(@NotNull KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_DELETE) { int index = list.getSelectedIndex(); if (index == -1 || index >= list.getModel().getSize()){ @@ -150,7 +151,7 @@ public abstract class BaseShowRecentFilesAction extends AnAction implements Dumb JPanel footerPanel = new JPanel(new BorderLayout()) { @Override - protected void paintComponent(Graphics g) { + protected void paintComponent(@NotNull Graphics g) { super.paintComponent(g); g.setColor(BORDER_COLOR); g.drawLine(0, 0, getWidth(), 0); @@ -237,7 +238,7 @@ public abstract class BaseShowRecentFilesAction extends AnAction implements Dumb } @Override - public void actionPerformed(ActionEvent e) { + public void actionPerformed(@NotNull ActionEvent e) { if (myPopup != null) { myPopup.cancel(); } @@ -272,7 +273,7 @@ public abstract class BaseShowRecentFilesAction extends AnAction implements Dumb return fullText; } - public void valueChanged(final ListSelectionEvent e) { + public void valueChanged(@NotNull final ListSelectionEvent e) { //noinspection SSBasedInspection SwingUtilities.invokeLater(new Runnable() { public void run() { From d1e4e88bca9d507faad9438f5cd4c07971d249a3 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Thu, 4 Sep 2014 13:29:49 +0400 Subject: [PATCH 35/60] fix AIOOB while editing colors --- .../src/com/intellij/openapi/util/registry/RegistryUi.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/openapi/util/registry/RegistryUi.java b/platform/lang-impl/src/com/intellij/openapi/util/registry/RegistryUi.java index 65f2d758fcfd..59f7e37f365f 100644 --- a/platform/lang-impl/src/com/intellij/openapi/util/registry/RegistryUi.java +++ b/platform/lang-impl/src/com/intellij/openapi/util/registry/RegistryUi.java @@ -471,7 +471,7 @@ public class RegistryUi implements Disposable { public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { myValue = ((MyTableModel)table.getModel()).getRegistryValue(row); if (myValue.asColor(null) != null) { - final Color color = ColorChooser.chooseColor(table, "Choose color", ((RegistryValue)value).asColor(Color.WHITE)); + final Color color = ColorChooser.chooseColor(table, "Choose color", myValue.asColor(Color.WHITE)); if (color != null) { myValue.setValue(color.getRed() + "," + color.getGreen() + "," + color.getBlue()); } From 1eb1b9d9d6740c16a297ac9f6337232ecacddc27 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Thu, 4 Sep 2014 13:31:19 +0400 Subject: [PATCH 36/60] move inline debugger colors to registry --- platform/util/resources/misc/registry.properties | 9 +++++++++ .../impl/evaluate/XDebuggerEditorLinePainter.java | 6 ++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/platform/util/resources/misc/registry.properties b/platform/util/resources/misc/registry.properties index 6599ec8bd8d7..9ce61924bc19 100644 --- a/platform/util/resources/misc/registry.properties +++ b/platform/util/resources/misc/registry.properties @@ -45,6 +45,15 @@ ide.firstStartup=true ide.debugMode=false ide.debugger.inline=false ide.debugger.inline.description=Enables variables view in editor +ide.debugger.inline.fg.color=61,128,101 +ide.debugger.inline.fg.color.description=Inline values foreground +ide.debugger.inline.dark.fg.color=61,128,101 +ide.debugger.inline.dark.fg.color.description=Inline values foreground for dark editor scheme +ide.debugger.inline.fg.modified.color=202,128,33 +ide.debugger.inline.fg.modified.color.description=Inline modified values foreground +ide.debugger.inline.dark.fg.modified.color=161,131,10 +ide.debugger.inline.dark.fg.modified.color.description=Inline modified values foreground for dark editor scheme + ide.debugMode.description=Record additional information to make bug reports more informative. ide.debug.minProgressTime=0 ide.forcedShowTooltip=alt diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEditorLinePainter.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEditorLinePainter.java index e73564095b21..d70dfa9c1681 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEditorLinePainter.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEditorLinePainter.java @@ -143,11 +143,13 @@ public class XDebuggerEditorLinePainter extends EditorLinePainter { } public static JBColor getForeground() { - return new JBColor(new Color(61, 128, 101), new Color(61, 128, 101)); + return new JBColor(Registry.getColor("ide.debugger.inline.fg.color", new Color(0x3d8065)), + Registry.getColor("ide.debugger.inline.dark.fg.color", new Color(0x3d8065))); } public static JBColor getChangedForeground() { - return new JBColor(new Color(202, 128, 33), new Color(161, 131, 10)); + return new JBColor(Registry.getColor("ide.debugger.inline.fg.modified.color", new Color(0xca8021)), + Registry.getColor("ide.debugger.inline.dark.fg.modified.color", new Color(0xa1830a))); } static class Variable { From 33f7cb51f22b336d497c0a7652804af9e1b49915 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Thu, 4 Sep 2014 12:51:50 +0400 Subject: [PATCH 37/60] new inference: most specific check according to spec, fixed testdata after JDK-8043734 --- .../source/resolve/graphInference/InferenceSession.java | 7 ------- .../daemonCodeAnalyzer/lambda/highlighting/Ambiguity1.java | 2 +- .../lambda/highlighting/AmbiguityRawGenerics.java | 2 +- .../NoReturnTypeResolutionForThrownException.java | 2 +- 4 files changed, 3 insertions(+), 10 deletions(-) diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java index e3c6d2341dc8..d93b7565c988 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java @@ -1205,9 +1205,6 @@ public class InferenceSession { } final List returnExpressions = LambdaUtil.getReturnExpressions((PsiLambdaExpression)arg); - if (sReturnType == PsiType.VOID) { - return returnExpressions.isEmpty() && session == null; - } if (LambdaUtil.isFunctionalType(sReturnType) && LambdaUtil.isFunctionalType(tReturnType) && !TypeConversionUtil.isAssignable(TypeConversionUtil.erasure(sReturnType), TypeConversionUtil.erasure(tReturnType)) && @@ -1263,10 +1260,6 @@ public class InferenceSession { return true; } - if (sReturnType == PsiType.VOID && session != null) { - return false; - } - final boolean sPrimitive = sReturnType instanceof PsiPrimitiveType && sReturnType != PsiType.VOID; final boolean tPrimitive = tReturnType instanceof PsiPrimitiveType && tReturnType != PsiType.VOID; diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/Ambiguity1.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/Ambiguity1.java index e66630146e6f..02bbebd074b0 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/Ambiguity1.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/Ambiguity1.java @@ -12,7 +12,7 @@ class Ambiguity1 { static void m(I2 i2) {} { - m(()->{throw new AssertionError();}); + m(()->{throw new AssertionError();}); m(() -> {}); m(() -> { if (false) return; diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/AmbiguityRawGenerics.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/AmbiguityRawGenerics.java index 595787704437..6c664dd9e65a 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/AmbiguityRawGenerics.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/AmbiguityRawGenerics.java @@ -22,6 +22,6 @@ class AmbiguityRawGenerics { void foo(I3 s) { } void bar() { - foo(()-> { throw new RuntimeException(); }); + foo(()-> { throw new RuntimeException(); }); } } \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/mostSpecific/NoReturnTypeResolutionForThrownException.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/mostSpecific/NoReturnTypeResolutionForThrownException.java index 81429131d099..1fe14f680abe 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/mostSpecific/NoReturnTypeResolutionForThrownException.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/mostSpecific/NoReturnTypeResolutionForThrownException.java @@ -7,7 +7,7 @@ class Test { void call(I2 p) { } void test() { - call(() -> { throw new RuntimeException(); }); + call(() -> { throw new RuntimeException(); }); call(() -> { if (true) return ""; throw new RuntimeException(); }); call(() -> { if (true) return; throw new RuntimeException(); }); } From 041f4d6e348647d6b04735d90c61298deb269ce4 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Thu, 4 Sep 2014 13:42:45 +0400 Subject: [PATCH 38/60] EA-60119 - IAE: PsiCapturedWildcardType.create --- java/java-psi-api/src/com/intellij/psi/GenericsUtil.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java b/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java index c835a4171f74..4646aea635b3 100644 --- a/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java @@ -262,7 +262,9 @@ public class GenericsUtil { for (PsiTypeParameter typeParameter : typeParams) { PsiType substituted = substitutor.substitute(typeParameter); if (substituted == null) return null; - substituted = PsiUtil.captureToplevelWildcards(substituted, context); + if (context != null) { + substituted = PsiUtil.captureToplevelWildcards(substituted, context); + } PsiClassType[] extendsTypes = typeParameter.getExtendsListTypes(); for (PsiClassType type : extendsTypes) { From 9c4505b7898ae9088f3a60398a7978918a115619 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Thu, 4 Sep 2014 14:03:25 +0400 Subject: [PATCH 39/60] save changed colors in recent changed keys --- .../src/com/intellij/openapi/util/registry/RegistryUi.java | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/lang-impl/src/com/intellij/openapi/util/registry/RegistryUi.java b/platform/lang-impl/src/com/intellij/openapi/util/registry/RegistryUi.java index 59f7e37f365f..a30ccd677682 100644 --- a/platform/lang-impl/src/com/intellij/openapi/util/registry/RegistryUi.java +++ b/platform/lang-impl/src/com/intellij/openapi/util/registry/RegistryUi.java @@ -474,6 +474,7 @@ public class RegistryUi implements Disposable { final Color color = ColorChooser.chooseColor(table, "Choose color", myValue.asColor(Color.WHITE)); if (color != null) { myValue.setValue(color.getRed() + "," + color.getGreen() + "," + color.getBlue()); + keyChanged(myValue.getKey()); } return null; } else if (myValue.isBoolean()) { From 2f8d7dd65295a45debed5df3a48a22a53fe57d05 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Thu, 4 Sep 2014 14:04:11 +0400 Subject: [PATCH 40/60] use darcula-aware fg --- .../evaluate/XDebuggerEditorLinePainter.java | 34 ++++++++++++++----- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEditorLinePainter.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEditorLinePainter.java index d70dfa9c1681..b9a58844585a 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEditorLinePainter.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEditorLinePainter.java @@ -18,6 +18,7 @@ package com.intellij.xdebugger.impl.evaluate; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.EditorLinePainter; import com.intellij.openapi.editor.LineExtensionInfo; +import com.intellij.openapi.editor.colors.EditorColorsManager; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Key; @@ -25,10 +26,8 @@ import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.ui.Gray; -import com.intellij.ui.JBColor; -import com.intellij.ui.SimpleColoredText; -import com.intellij.ui.SimpleTextAttributes; +import com.intellij.ui.*; +import com.intellij.util.NotNullProducer; import com.intellij.xdebugger.XDebugSession; import com.intellij.xdebugger.XSourcePosition; import com.intellij.xdebugger.frame.presentation.XValuePresentation; @@ -142,14 +141,33 @@ public class XDebuggerEditorLinePainter extends EditorLinePainter { return -1; } + private static boolean isDarkEditor() { + Color bg = EditorColorsManager.getInstance().getGlobalScheme().getDefaultBackground(); + return ColorUtil.isDark(bg); + } + public static JBColor getForeground() { - return new JBColor(Registry.getColor("ide.debugger.inline.fg.color", new Color(0x3d8065)), - Registry.getColor("ide.debugger.inline.dark.fg.color", new Color(0x3d8065))); + return new JBColor(new NotNullProducer() { + @SuppressWarnings("UseJBColor") + @NotNull + @Override + public Color produce() { + return isDarkEditor() ? Registry.getColor("ide.debugger.inline.dark.fg.color", new Color(0x3d8065)) + : Registry.getColor("ide.debugger.inline.fg.color", new Color(0x3d8065)); + } + }); } public static JBColor getChangedForeground() { - return new JBColor(Registry.getColor("ide.debugger.inline.fg.modified.color", new Color(0xca8021)), - Registry.getColor("ide.debugger.inline.dark.fg.modified.color", new Color(0xa1830a))); + return new JBColor(new NotNullProducer() { + @SuppressWarnings("UseJBColor") + @NotNull + @Override + public Color produce() { + return isDarkEditor() ? Registry.getColor("ide.debugger.inline.dark.fg.modified.color", new Color(0xa1830a)) + : Registry.getColor("ide.debugger.inline.fg.modified.color", new Color(0xca8021)); + } + }); } static class Variable { From e4d73d688b7f9f2c13bb7a8906bd0b54ab503a3b Mon Sep 17 00:00:00 2001 From: Dennis Ushakov Date: Thu, 4 Sep 2014 11:59:34 +0400 Subject: [PATCH 41/60] full SVG support: symbol element fixed, attributes search improved #WEB-12667 fixed --- .../html/RelaxedHtmlFromRngElementDescriptor.java | 4 +++- .../src/resources/html5-schema/html5-svg-mathml.rnc | 2 +- .../src/resources/html5-schema/xhtml5-svg-mathml.rnc | 2 +- .../src/resources/patches/0007_html5_svg_tiny.patch | 11 ----------- .../src/resources/patches/0008_xhtml5_svg_tiny.patch | 11 ----------- 5 files changed, 5 insertions(+), 25 deletions(-) delete mode 100644 xml/relaxng/src/resources/patches/0007_html5_svg_tiny.patch delete mode 100644 xml/relaxng/src/resources/patches/0008_xhtml5_svg_tiny.patch diff --git a/xml/relaxng/src/org/intellij/html/RelaxedHtmlFromRngElementDescriptor.java b/xml/relaxng/src/org/intellij/html/RelaxedHtmlFromRngElementDescriptor.java index 08ada22129d9..e21db4785f8c 100644 --- a/xml/relaxng/src/org/intellij/html/RelaxedHtmlFromRngElementDescriptor.java +++ b/xml/relaxng/src/org/intellij/html/RelaxedHtmlFromRngElementDescriptor.java @@ -94,7 +94,9 @@ public class RelaxedHtmlFromRngElementDescriptor implements XmlElementDescriptor @Override public XmlAttributeDescriptor getAttributeDescriptor(String attributeName, final XmlTag context) { - final XmlAttributeDescriptor descriptor = myDelegate.getAttributeDescriptor(attributeName.toLowerCase(), context); + XmlAttributeDescriptor descriptor = myDelegate.getAttributeDescriptor(attributeName.toLowerCase(), context); + // some elements in HTML5 schema (e.g. SVG) are case sensitive + descriptor = descriptor == null ? myDelegate.getAttributeDescriptor(attributeName, context) : descriptor; if (descriptor != null) return descriptor; return RelaxedHtmlFromSchemaElementDescriptor.getAttributeDescriptorFromFacelets(attributeName, context); diff --git a/xml/relaxng/src/resources/html5-schema/html5-svg-mathml.rnc b/xml/relaxng/src/resources/html5-schema/html5-svg-mathml.rnc index fe154b8f57bf..095868dee70a 100644 --- a/xml/relaxng/src/resources/html5-schema/html5-svg-mathml.rnc +++ b/xml/relaxng/src/resources/html5-schema/html5-svg-mathml.rnc @@ -1,7 +1,7 @@ namespace svg = "http://www.w3.org/2000/svg" namespace math = "http://www.w3.org/1998/Math/MathML" -include "svg11/svg11-tiny-inc.rnc" +include "svg11/svg11-inc.rnc" include "mml3/mathml3-inc.rnc" common.elem.phrasing |= svg diff --git a/xml/relaxng/src/resources/html5-schema/xhtml5-svg-mathml.rnc b/xml/relaxng/src/resources/html5-schema/xhtml5-svg-mathml.rnc index 74f188644741..98d6fbd597e4 100644 --- a/xml/relaxng/src/resources/html5-schema/xhtml5-svg-mathml.rnc +++ b/xml/relaxng/src/resources/html5-schema/xhtml5-svg-mathml.rnc @@ -2,7 +2,7 @@ namespace svg = "http://www.w3.org/2000/svg" namespace math = "http://www.w3.org/1998/Math/MathML" namespace rdf = "http://www.w3.org/1999/02/22-rdf-syntax-ns#" -include "svg11/svg11-tiny-inc.rnc" +include "svg11/svg11-inc.rnc" include "inkscape/inkscape.rnc" include "mml3/mathml3-inc.rnc" include "rdf/rdf.rnc" diff --git a/xml/relaxng/src/resources/patches/0007_html5_svg_tiny.patch b/xml/relaxng/src/resources/patches/0007_html5_svg_tiny.patch deleted file mode 100644 index 6a3cc10cc8e2..000000000000 --- a/xml/relaxng/src/resources/patches/0007_html5_svg_tiny.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- /Users/denofevil/Code/sandbox/checker/validator/schema/html5-svg-mathml.rnc 2014-01-24 12:18:54.000000000 +0400 -+++ html5-svg-mathml.rnc 2014-01-25 15:32:10.000000000 +0400 -@@ -1,7 +1,7 @@ - namespace svg = "http://www.w3.org/2000/svg" - namespace math = "http://www.w3.org/1998/Math/MathML" - --include "svg11/svg11-inc.rnc" -+include "svg11/svg11-tiny-inc.rnc" - include "mml3/mathml3-inc.rnc" - - common.elem.phrasing |= svg diff --git a/xml/relaxng/src/resources/patches/0008_xhtml5_svg_tiny.patch b/xml/relaxng/src/resources/patches/0008_xhtml5_svg_tiny.patch deleted file mode 100644 index 773c8969c177..000000000000 --- a/xml/relaxng/src/resources/patches/0008_xhtml5_svg_tiny.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- /Users/denofevil/Code/sandbox/checker/validator/schema/xhtml5-svg-mathml.rnc 2014-01-24 12:18:54.000000000 +0400 -+++ xhtml5-svg-mathml.rnc 2014-01-25 15:50:41.000000000 +0400 -@@ -2,7 +2,7 @@ - namespace math = "http://www.w3.org/1998/Math/MathML" - namespace rdf = "http://www.w3.org/1999/02/22-rdf-syntax-ns#" - --include "svg11/svg11-inc.rnc" -+include "svg11/svg11-tiny-inc.rnc" - include "inkscape/inkscape.rnc" - include "mml3/mathml3-inc.rnc" - include "rdf/rdf.rnc" From 998397403a7e6b92535faf7ebd5f45952430b519 Mon Sep 17 00:00:00 2001 From: Dennis Ushakov Date: Thu, 4 Sep 2014 12:49:53 +0400 Subject: [PATCH 42/60] full SVG support: xlink schema provided --- .../RelaxedHtmlFromRngElementDescriptor.java | 7 +- .../resources/standardSchemas/xlink.dtd | 66 +++++++++++++++++++ .../javaee/InternalResourceProvider.java | 1 + .../com/intellij/xml/HtmlXmlExtension.java | 13 +++- 4 files changed, 83 insertions(+), 4 deletions(-) create mode 100644 xml/xml-psi-impl/resources/standardSchemas/xlink.dtd diff --git a/xml/relaxng/src/org/intellij/html/RelaxedHtmlFromRngElementDescriptor.java b/xml/relaxng/src/org/intellij/html/RelaxedHtmlFromRngElementDescriptor.java index e21db4785f8c..b287e6b50777 100644 --- a/xml/relaxng/src/org/intellij/html/RelaxedHtmlFromRngElementDescriptor.java +++ b/xml/relaxng/src/org/intellij/html/RelaxedHtmlFromRngElementDescriptor.java @@ -69,6 +69,9 @@ public class RelaxedHtmlFromRngElementDescriptor implements XmlElementDescriptor @Override public XmlAttributeDescriptor getAttributeDescriptor(XmlAttribute attribute) { + XmlAttributeDescriptor descriptor = myDelegate.getAttributeDescriptor(attribute); + if (descriptor != null) return descriptor; + return getAttributeDescriptor(attribute.getName(), attribute.getParent()); } @@ -94,9 +97,7 @@ public class RelaxedHtmlFromRngElementDescriptor implements XmlElementDescriptor @Override public XmlAttributeDescriptor getAttributeDescriptor(String attributeName, final XmlTag context) { - XmlAttributeDescriptor descriptor = myDelegate.getAttributeDescriptor(attributeName.toLowerCase(), context); - // some elements in HTML5 schema (e.g. SVG) are case sensitive - descriptor = descriptor == null ? myDelegate.getAttributeDescriptor(attributeName, context) : descriptor; + final XmlAttributeDescriptor descriptor = myDelegate.getAttributeDescriptor(attributeName.toLowerCase(), context); if (descriptor != null) return descriptor; return RelaxedHtmlFromSchemaElementDescriptor.getAttributeDescriptorFromFacelets(attributeName, context); diff --git a/xml/xml-psi-impl/resources/standardSchemas/xlink.dtd b/xml/xml-psi-impl/resources/standardSchemas/xlink.dtd new file mode 100644 index 000000000000..1a8f153e55db --- /dev/null +++ b/xml/xml-psi-impl/resources/standardSchemas/xlink.dtd @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/xml/xml-psi-impl/src/com/intellij/javaee/InternalResourceProvider.java b/xml/xml-psi-impl/src/com/intellij/javaee/InternalResourceProvider.java index 673540ef38e8..38777922ee35 100644 --- a/xml/xml-psi-impl/src/com/intellij/javaee/InternalResourceProvider.java +++ b/xml/xml-psi-impl/src/com/intellij/javaee/InternalResourceProvider.java @@ -63,5 +63,6 @@ public class InternalResourceProvider implements StandardResourceProvider{ // svg and mathML impl.addIgnoredResource(HtmlUtil.MATH_ML_NAMESPACE); impl.addIgnoredResource(HtmlUtil.SVG_NAMESPACE); + impl.addInternalResource("http://www.w3.org/1999/xlink", "xlink.dtd"); } } diff --git a/xml/xml-psi-impl/src/com/intellij/xml/HtmlXmlExtension.java b/xml/xml-psi-impl/src/com/intellij/xml/HtmlXmlExtension.java index 4ece939ffac0..e54a93394242 100644 --- a/xml/xml-psi-impl/src/com/intellij/xml/HtmlXmlExtension.java +++ b/xml/xml-psi-impl/src/com/intellij/xml/HtmlXmlExtension.java @@ -3,6 +3,7 @@ package com.intellij.xml; import com.intellij.ide.highlighter.HtmlFileType; import com.intellij.psi.PsiFile; import com.intellij.psi.xml.XmlDocument; +import com.intellij.xml.util.HtmlUtil; import org.jetbrains.annotations.Nullable; /** @@ -19,6 +20,16 @@ public class HtmlXmlExtension extends DefaultXmlExtension { @Nullable @Override public String[][] getNamespacesFromDocument(XmlDocument parent, boolean declarationsExist) { - return super.getNamespacesFromDocument(parent, false); + String[][] namespaces = super.getNamespacesFromDocument(parent, false); + if (namespaces == null || !HtmlUtil.isHtml5Document(parent)) return namespaces; + + for (String[] namespace : namespaces) { + if ("xlink".equals(namespace[0])) return namespaces; + } + + String[][] newNamespaces = new String[namespaces.length + 1][2]; + System.arraycopy(namespaces, 0, newNamespaces, 0, namespaces.length); + newNamespaces[namespaces.length] = new String[] {"xlink", "http://www.w3.org/1999/xlink"}; + return newNamespaces; } } From d10bb6985397d4388439f9cfd8763d45a871d002 Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Thu, 4 Sep 2014 14:18:06 +0400 Subject: [PATCH 43/60] Rename isConfigurableProvided to canCreateConfigurable and remove duplicated code in several createConfigurable methods --- .../openapi/roots/ui/configuration/ModuleEditor.java | 2 +- .../src/com/intellij/openapi/options/ConfigurableEP.java | 6 +++--- .../com/intellij/openapi/options/ConfigurableProvider.java | 2 +- .../intellij/openapi/options/SearchableConfigurable.java | 2 +- .../openapi/options/ex/ConfigurableExtensionPointUtil.java | 2 +- .../intellij/openapi/options/ex/ConfigurableWrapper.java | 2 +- .../vcs/configurable/VcsManagerConfigurableProvider.java | 2 +- .../impl/settings/DebuggerConfigurableProvider.java | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModuleEditor.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModuleEditor.java index b3de63ee0f7b..a10265607029 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModuleEditor.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModuleEditor.java @@ -206,7 +206,7 @@ public abstract class ModuleEditor implements Place.Navigator, Disposable { myEditors.add(new ModuleConfigurableWrapper(moduleConfigurable)); } for(ModuleConfigurableEP extension : myModule.getExtensions(MODULE_CONFIGURABLES)) { - if (extension.isConfigurableProvided()) { + if (extension.canCreateConfigurable()) { myEditors.add(new ModuleConfigurableWrapper(extension.createConfigurable())); } } diff --git a/platform/platform-api/src/com/intellij/openapi/options/ConfigurableEP.java b/platform/platform-api/src/com/intellij/openapi/options/ConfigurableEP.java index 3f9bc9d241f2..828907c13cfb 100644 --- a/platform/platform-api/src/com/intellij/openapi/options/ConfigurableEP.java +++ b/platform/platform-api/src/com/intellij/openapi/options/ConfigurableEP.java @@ -175,13 +175,13 @@ public class ConfigurableEP extends AbstractExten return getDisplayName(); } - public boolean isConfigurableProvided() { + public boolean canCreateConfigurable() { if (providerClass == null) { return implementationClass != null || instanceClass != null; } try { ConfigurableProvider provider = instantiate(providerClass, myPicoContainer); - return provider.isConfigurableProvided(); // do not load heavy configurables + return provider.canCreateConfigurable(); // do not load heavy configurables } catch (Exception ignored) { return true; // see InstanceFromProviderFactory#compute @@ -191,7 +191,7 @@ public class ConfigurableEP extends AbstractExten private class InstanceFromProviderFactory extends AtomicNotNullLazyValue implements NullableFactory { public T create() { ConfigurableProvider provider = getValue(); - return provider.isConfigurableProvided() + return provider.canCreateConfigurable() ? (T)provider.createConfigurable() : null; } diff --git a/platform/platform-api/src/com/intellij/openapi/options/ConfigurableProvider.java b/platform/platform-api/src/com/intellij/openapi/options/ConfigurableProvider.java index f0389cf83649..cf2bc0390c5a 100644 --- a/platform/platform-api/src/com/intellij/openapi/options/ConfigurableProvider.java +++ b/platform/platform-api/src/com/intellij/openapi/options/ConfigurableProvider.java @@ -37,7 +37,7 @@ public abstract class ConfigurableProvider { * @return {@code true} if this provider creates configurable, * {@code false} otherwise */ - public boolean isConfigurableProvided() { + public boolean canCreateConfigurable() { return true; } } diff --git a/platform/platform-api/src/com/intellij/openapi/options/SearchableConfigurable.java b/platform/platform-api/src/com/intellij/openapi/options/SearchableConfigurable.java index 4f1d0dd4eaf9..b426e35d77a8 100644 --- a/platform/platform-api/src/com/intellij/openapi/options/SearchableConfigurable.java +++ b/platform/platform-api/src/com/intellij/openapi/options/SearchableConfigurable.java @@ -36,7 +36,7 @@ public interface SearchableConfigurable extends Configurable { boolean hasOwnContent(); /** - * @deprecated use {@link ConfigurableProvider#isConfigurableProvided()} instead + * @deprecated use {@link ConfigurableProvider#canCreateConfigurable()} instead * to specify configurables which should not be visible */ @Deprecated diff --git a/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableExtensionPointUtil.java b/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableExtensionPointUtil.java index 2aebbbbbeab1..2ead77c297e5 100644 --- a/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableExtensionPointUtil.java +++ b/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableExtensionPointUtil.java @@ -164,7 +164,7 @@ public class ConfigurableExtensionPointUtil { @NotNull private static T findConfigurable(ConfigurableEP[] extensions, Class configurableClass) { for (ConfigurableEP extension : extensions) { - if (extension.isConfigurableProvided()) { + if (extension.canCreateConfigurable()) { final Configurable configurable = extension.createConfigurable(); if (configurableClass.isInstance(configurable)) { return configurableClass.cast(configurable); diff --git a/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableWrapper.java b/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableWrapper.java index cca07555054b..83960e742ed1 100644 --- a/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableWrapper.java +++ b/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableWrapper.java @@ -47,7 +47,7 @@ public class ConfigurableWrapper implements SearchableConfigurable { @Nullable public static T wrapConfigurable(ConfigurableEP ep) { - if (!ep.isConfigurableProvided()) { + if (!ep.canCreateConfigurable()) { return null; } if (ep.displayName != null || ep.key != null || ep.groupId != null) { diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsManagerConfigurableProvider.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsManagerConfigurableProvider.java index 3536139be64d..0ff9ef6c96d6 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsManagerConfigurableProvider.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsManagerConfigurableProvider.java @@ -35,7 +35,7 @@ public final class VcsManagerConfigurableProvider extends ConfigurableProvider { } @Override - public boolean isConfigurableProvided() { + public boolean canCreateConfigurable() { return ProjectLevelVcsManager.getInstance(myProject).getAllVcss().length > 0; } } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DebuggerConfigurableProvider.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DebuggerConfigurableProvider.java index cd0f0dccb1af..bb747f92eab7 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DebuggerConfigurableProvider.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DebuggerConfigurableProvider.java @@ -28,7 +28,7 @@ public final class DebuggerConfigurableProvider extends ConfigurableProvider { } @Override - public boolean isConfigurableProvided() { + public boolean canCreateConfigurable() { return XBreakpointType.EXTENSION_POINT_NAME.getExtensions().length != 0; } } From 2b7fcf80acf11de1ac261262637ead514d4463b9 Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Thu, 4 Sep 2014 14:36:11 +0400 Subject: [PATCH 44/60] IDEA-129381 Settings dialog: not the whole area of hyperlinks is clickable --- .../src/com/intellij/ui/components/labels/LinkLabel.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/platform/platform-api/src/com/intellij/ui/components/labels/LinkLabel.java b/platform/platform-api/src/com/intellij/ui/components/labels/LinkLabel.java index 129217ec7e4a..0416008d1d57 100644 --- a/platform/platform-api/src/com/intellij/ui/components/labels/LinkLabel.java +++ b/platform/platform-api/src/com/intellij/ui/components/labels/LinkLabel.java @@ -204,6 +204,8 @@ public class LinkLabel extends JLabel { } private boolean isInClickableArea(Point pt) { + Insets insets = getInsets(); // border is set + pt.translate(-insets.left, -insets.top); if (getIcon() != null) { if (pt.getX() < getIcon().getIconWidth() && pt.getY() < getIcon().getIconHeight()) { return true; From 68c36c58b0bf91844b16b7ace7d3396b17a5e7e2 Mon Sep 17 00:00:00 2001 From: Sergey Simonchik Date: Thu, 4 Sep 2014 14:37:42 +0400 Subject: [PATCH 45/60] ConfigurableExtensionPointUtilTest fixed --- .../options/ex/ConfigurableExtensionPointUtil.java | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableExtensionPointUtil.java b/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableExtensionPointUtil.java index 2ead77c297e5..ca72bf30c541 100644 --- a/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableExtensionPointUtil.java +++ b/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableExtensionPointUtil.java @@ -75,16 +75,13 @@ public class ConfigurableExtensionPointUtil { } } } - //leave only roots (i.e. configurables without parents) - for (final Iterator iterator = idToConfigurable.keySet().iterator(); iterator.hasNext(); ) { - final String key = iterator.next(); - final ConfigurableWrapper wrapper = idToConfigurable.get(key); - final String parentId = wrapper.getParentId(); - if (parentId != null && idToConfigurable.containsKey(parentId)) { - iterator.remove(); // remove only processed parents + // add roots only (i.e. configurables without parents) + for (ConfigurableWrapper wrapper : idToConfigurable.values()) { + String parentId = wrapper.getParentId(); + if (parentId == null || !idToConfigurable.containsKey(parentId)) { + result.add(wrapper); } } - ContainerUtil.addAll(result, idToConfigurable.values()); return result; } From e63e63e7dd88f5b698a119a6ca27516271b5f836 Mon Sep 17 00:00:00 2001 From: Dennis Ushakov Date: Thu, 4 Sep 2014 14:21:53 +0400 Subject: [PATCH 46/60] #IDEA-129395 fixed --- .../src/com/intellij/ui/messages/JBMacMessages.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/ui/messages/JBMacMessages.java b/platform/platform-impl/src/com/intellij/ui/messages/JBMacMessages.java index 2a70b61c6e8a..47ebb829adc2 100644 --- a/platform/platform-impl/src/com/intellij/ui/messages/JBMacMessages.java +++ b/platform/platform-impl/src/com/intellij/ui/messages/JBMacMessages.java @@ -190,7 +190,7 @@ public class JBMacMessages extends MacMessagesEmulation { SheetMessage sheetMessage = new SheetMessage(window, title, message, UIUtil.getQuestionIcon(), new String [] {yesButton, noButton}, doNotAskDialogOption, yesButton, noButton); int result = sheetMessage.getResult().equals(yesButton) ? Messages.YES : Messages.NO; - if (doNotAskDialogOption != null) { + if (doNotAskDialogOption != null && (result == Messages.YES || doNotAskDialogOption.shouldSaveOptionsOnCancel())) { doNotAskDialogOption.setToBeShown(sheetMessage.toBeShown(), result); } return result; From f7dce61d411e67bbfbd83fec84990052f4726773 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Thu, 4 Sep 2014 14:28:27 +0400 Subject: [PATCH 47/60] simplify: unwrap multiple unnecessary async layers --- .../com/intellij/concurrency/AsyncUtil.java | 46 ++- .../src/com/intellij/concurrency/DoWhile.java | 59 --- .../src/com/intellij/concurrency/Iterate.java | 36 -- .../src/com/intellij/util/AbstractQuery.java | 23 +- .../src/com/intellij/util/ArrayQuery.java | 11 +- .../com/intellij/util/CollectionQuery.java | 13 +- .../src/com/intellij/util/EmptyQuery.java | 6 +- .../src/com/intellij/util/MergeQuery.java | 17 +- .../core/CoreApplicationEnvironment.java | 15 +- .../intellij/psi/search/PsiSearchHelper.java | 3 +- .../psi/impl/search/PsiSearchHelperImpl.java | 346 ++++++------------ .../intellij/concurrency/JobLauncherImpl.java | 12 +- 12 files changed, 187 insertions(+), 400 deletions(-) delete mode 100644 platform/core-api/src/com/intellij/concurrency/DoWhile.java delete mode 100644 platform/core-api/src/com/intellij/concurrency/Iterate.java diff --git a/platform/core-api/src/com/intellij/concurrency/AsyncUtil.java b/platform/core-api/src/com/intellij/concurrency/AsyncUtil.java index 93c7573c0381..72c0a85aac72 100644 --- a/platform/core-api/src/com/intellij/concurrency/AsyncUtil.java +++ b/platform/core-api/src/com/intellij/concurrency/AsyncUtil.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,12 +18,17 @@ package com.intellij.concurrency; import org.jetbrains.annotations.NotNull; import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executor; import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; /** * Author: dmitrylomov */ public class AsyncUtil { + private static final AsyncFuture TRUE = createConst(true); + private static final AsyncFuture FALSE = createConst(false); + public static V get(@NotNull Future result) { try { return result.get(); @@ -41,4 +46,43 @@ public class AsyncUtil { } } } + + private static AsyncFuture createConst(final boolean result) { + return new AsyncFuture() { + @Override + public void addConsumer(@NotNull Executor executor, @NotNull ResultConsumer consumer) { + consumer.onSuccess(result); + } + + @Override + public boolean cancel(boolean mayInterruptIfRunning) { + return false; + } + + @Override + public boolean isCancelled() { + return false; + } + + @Override + public boolean isDone() { + return true; + } + + @Override + public Boolean get() { + return result; + } + + @Override + public Boolean get(long timeout, @NotNull TimeUnit unit) { + return result; + } + }; + } + + @NotNull + public static AsyncFuture wrapBoolean(boolean result) { + return result ? TRUE : FALSE; + } } diff --git a/platform/core-api/src/com/intellij/concurrency/DoWhile.java b/platform/core-api/src/com/intellij/concurrency/DoWhile.java deleted file mode 100644 index b77e3258c984..000000000000 --- a/platform/core-api/src/com/intellij/concurrency/DoWhile.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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 com.intellij.concurrency; - -import org.jetbrains.annotations.NotNull; - -/** - * Author: dmitrylomov - */ -public abstract class DoWhile { - private final AsyncFutureResult myResult = AsyncFutureFactory.getInstance().createAsyncFutureResult(); - private final SameThreadExecutorWithTrampoline myExecutor = new SameThreadExecutorWithTrampoline(); - - @NotNull - public AsyncFutureResult getResult() { - body().addConsumer(myExecutor, new MyConsumer()); - return myResult; - } - - @NotNull - protected abstract AsyncFuture body(); - protected abstract boolean condition(); - - private class MyConsumer extends DefaultResultConsumer { - public MyConsumer() { - super(DoWhile.this.myResult); - } - - @Override - public void onSuccess(Boolean value) { - if (!value.booleanValue()) { - myResult.set(false); - } - else { - if(!condition()) { - myResult.set(true); - } - else { - body().addConsumer(myExecutor, this); - } - } - } - } - - -} diff --git a/platform/core-api/src/com/intellij/concurrency/Iterate.java b/platform/core-api/src/com/intellij/concurrency/Iterate.java deleted file mode 100644 index e158999f4da5..000000000000 --- a/platform/core-api/src/com/intellij/concurrency/Iterate.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.intellij.concurrency; - -import org.jetbrains.annotations.NotNull; - -import java.util.Iterator; - -/** - * Author: dmitrylomov - */ -public abstract class Iterate extends DoWhile { - private final Iterator myIterator; - private boolean myIsDone; - - public Iterate(@NotNull Iterable iterable) { - myIterator = iterable.iterator(); - myIsDone = false; - } - - @NotNull - @Override - protected final AsyncFuture body() { - if (!myIterator.hasNext()) { - myIsDone = true; - return AsyncFutureFactory.wrap(true); - } - return process(myIterator.next()); - } - - @NotNull - protected abstract AsyncFuture process(T t); - - @Override - protected boolean condition() { - return !myIsDone; - } -} diff --git a/platform/core-api/src/com/intellij/util/AbstractQuery.java b/platform/core-api/src/com/intellij/util/AbstractQuery.java index 1c29ef6437ac..219aae614140 100644 --- a/platform/core-api/src/com/intellij/util/AbstractQuery.java +++ b/platform/core-api/src/com/intellij/util/AbstractQuery.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 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. @@ -16,9 +16,7 @@ package com.intellij.util; import com.intellij.concurrency.AsyncFuture; -import com.intellij.concurrency.AsyncFutureFactory; -import com.intellij.concurrency.AsyncFutureResult; -import com.intellij.concurrency.FinallyFuture; +import com.intellij.concurrency.AsyncUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -84,26 +82,13 @@ public abstract class AbstractQuery implements Query { @NotNull @Override public AsyncFuture forEachAsync(@NotNull Processor consumer) { - assertNotProcessing(); - myIsProcessing = true; - return new FinallyFuture(processResultsAsync(consumer), new Runnable() { - @Override - public void run() { - myIsProcessing = false; - } - }); + return AsyncUtil.wrapBoolean(forEach(consumer)); } protected abstract boolean processResults(@NotNull Processor consumer); @NotNull protected AsyncFuture processResultsAsync(@NotNull Processor consumer) { - final AsyncFutureResult result = AsyncFutureFactory.getInstance().createAsyncFutureResult(); - try { - result.set(processResults(consumer)); - } catch (Throwable t) { - result.setException(t); - } - return result; + return AsyncUtil.wrapBoolean(processResults(consumer)); } } diff --git a/platform/core-api/src/com/intellij/util/ArrayQuery.java b/platform/core-api/src/com/intellij/util/ArrayQuery.java index abe2f1001fe0..1b7760146de6 100644 --- a/platform/core-api/src/com/intellij/util/ArrayQuery.java +++ b/platform/core-api/src/com/intellij/util/ArrayQuery.java @@ -17,8 +17,7 @@ package com.intellij.util; import com.intellij.concurrency.AsyncFuture; -import com.intellij.concurrency.AsyncFutureFactory; -import com.intellij.concurrency.AsyncFutureResult; +import com.intellij.concurrency.AsyncUtil; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; @@ -55,13 +54,7 @@ public class ArrayQuery implements Query { @NotNull @Override public AsyncFuture forEachAsync(@NotNull final Processor consumer) { - final AsyncFutureResult result = AsyncFutureFactory.getInstance().createAsyncFutureResult(); - try { - result.set(forEach(consumer)); - } catch (Throwable t){ - result.setException(t); - } - return result; + return AsyncUtil.wrapBoolean(forEach(consumer)); } diff --git a/platform/core-api/src/com/intellij/util/CollectionQuery.java b/platform/core-api/src/com/intellij/util/CollectionQuery.java index cd90ab55edd9..253182cef0c1 100644 --- a/platform/core-api/src/com/intellij/util/CollectionQuery.java +++ b/platform/core-api/src/com/intellij/util/CollectionQuery.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 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. @@ -17,8 +17,7 @@ package com.intellij.util; import com.intellij.concurrency.AsyncFuture; -import com.intellij.concurrency.AsyncFutureFactory; -import com.intellij.concurrency.AsyncFutureResult; +import com.intellij.concurrency.AsyncUtil; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; @@ -55,13 +54,7 @@ public class CollectionQuery implements Query { @NotNull @Override public AsyncFuture forEachAsync(@NotNull Processor consumer) { - AsyncFutureResult result = AsyncFutureFactory.getInstance().createAsyncFutureResult(); - try { - result.set(forEach(consumer)); - } catch (Throwable t) { - result.setException(t); - } - return result; + return AsyncUtil.wrapBoolean(forEach(consumer)); } @NotNull diff --git a/platform/core-api/src/com/intellij/util/EmptyQuery.java b/platform/core-api/src/com/intellij/util/EmptyQuery.java index 465100505450..18a32a5a94b4 100644 --- a/platform/core-api/src/com/intellij/util/EmptyQuery.java +++ b/platform/core-api/src/com/intellij/util/EmptyQuery.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. @@ -16,7 +16,7 @@ package com.intellij.util; import com.intellij.concurrency.AsyncFuture; -import com.intellij.concurrency.AsyncFutureFactory; +import com.intellij.concurrency.AsyncUtil; import org.jetbrains.annotations.NotNull; import java.util.Collection; @@ -48,7 +48,7 @@ public class EmptyQuery implements Query { @NotNull @Override public AsyncFuture forEachAsync(@NotNull Processor consumer) { - return AsyncFutureFactory.wrap(true); + return AsyncUtil.wrapBoolean(true); } @NotNull diff --git a/platform/core-api/src/com/intellij/util/MergeQuery.java b/platform/core-api/src/com/intellij/util/MergeQuery.java index 699659b93055..35d122639cd3 100644 --- a/platform/core-api/src/com/intellij/util/MergeQuery.java +++ b/platform/core-api/src/com/intellij/util/MergeQuery.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. @@ -66,13 +66,13 @@ public class MergeQuery implements Query{ fq.addConsumer(SameThreadExecutor.INSTANCE, new DefaultResultConsumer(result) { @Override public void onSuccess(Boolean value) { - if (!value.booleanValue()) { - result.set(false); - } - else { + if (value.booleanValue()) { final AsyncFuture fq2 = processSubQueryAsync(consumer, myQuery2); fq2.addConsumer(SameThreadExecutor.INSTANCE, new DefaultResultConsumer(result)); } + else { + result.set(false); + } } }); return result; @@ -85,12 +85,7 @@ public class MergeQuery implements Query{ } private AsyncFuture processSubQueryAsync(@NotNull final Processor consumer, @NotNull Query query1) { - return query1.forEachAsync(new Processor() { - @Override - public boolean process(final V t) { - return consumer.process(t); - } - }); + return query1.forEachAsync((Processor)consumer); } @NotNull diff --git a/platform/core-impl/src/com/intellij/core/CoreApplicationEnvironment.java b/platform/core-impl/src/com/intellij/core/CoreApplicationEnvironment.java index f82e7a80d5fb..cbb35b4f9812 100644 --- a/platform/core-impl/src/com/intellij/core/CoreApplicationEnvironment.java +++ b/platform/core-impl/src/com/intellij/core/CoreApplicationEnvironment.java @@ -36,10 +36,7 @@ import com.intellij.openapi.extensions.ExtensionsArea; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.fileTypes.*; import com.intellij.openapi.progress.*; -import com.intellij.openapi.util.ClassExtension; -import com.intellij.openapi.util.Disposer; -import com.intellij.openapi.util.KeyedExtensionCollector; -import com.intellij.openapi.util.StaticGetter; +import com.intellij.openapi.util.*; import com.intellij.openapi.vfs.VirtualFileManager; import com.intellij.openapi.vfs.VirtualFileSystem; import com.intellij.openapi.vfs.encoding.EncodingRegistry; @@ -175,15 +172,7 @@ public class CoreApplicationEnvironment { ProgressIndicator progress, boolean failFastOnAcquireReadAction, @NotNull Processor thingProcessor) { - final AsyncFutureResult asyncFutureResult = AsyncFutureFactory.getInstance().createAsyncFutureResult(); - try { - final boolean result = invokeConcurrentlyUnderProgress(things, progress, failFastOnAcquireReadAction, thingProcessor); - asyncFutureResult.set(result); - } - catch (Throwable t) { - asyncFutureResult.setException(t); - } - return asyncFutureResult; + return AsyncUtil.wrapBoolean(invokeConcurrentlyUnderProgress(things, progress, failFastOnAcquireReadAction, thingProcessor)); } @NotNull diff --git a/platform/indexing-api/src/com/intellij/psi/search/PsiSearchHelper.java b/platform/indexing-api/src/com/intellij/psi/search/PsiSearchHelper.java index bef3d0350563..8f2db591888d 100644 --- a/platform/indexing-api/src/com/intellij/psi/search/PsiSearchHelper.java +++ b/platform/indexing-api/src/com/intellij/psi/search/PsiSearchHelper.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. @@ -58,7 +58,6 @@ public interface PsiSearchHelper { * * @param identifier the identifier to search. * @param searchScope the scope in which occurrences are searched. - * @param processor * @return false if processor returned false, true otherwise */ boolean processCommentsContainingIdentifier(@NotNull String identifier, @NotNull SearchScope searchScope, @NotNull Processor processor); diff --git a/platform/indexing-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java b/platform/indexing-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java index b5c3dd17afb7..ba8d9ce3500e 100644 --- a/platform/indexing-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java +++ b/platform/indexing-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java @@ -23,7 +23,6 @@ import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressIndicatorProvider; -import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.progress.util.TooManyUsagesStatus; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.FileIndexFacade; @@ -56,7 +55,6 @@ import org.jetbrains.annotations.Nullable; import java.io.IOException; import java.util.*; -import java.util.concurrent.ExecutionException; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; @@ -132,9 +130,7 @@ public class PsiSearchHelperImpl implements PsiSearchHelper { short searchContext, boolean caseSensitive, boolean processInjectedPsi) { - final AsyncFuture result = - processElementsWithWordAsync(processor, searchScope, text, searchContext, caseSensitive, processInjectedPsi, null); - return AsyncUtil.get(result); + return processElementsWithWord(processor, searchScope, text, searchContext, caseSensitive, processInjectedPsi, null); } @NotNull @@ -144,50 +140,39 @@ public class PsiSearchHelperImpl implements PsiSearchHelper { @NotNull final String text, final short searchContext, final boolean caseSensitively) { - return processElementsWithWordAsync(processor, searchScope, text, searchContext, caseSensitively, shouldProcessInjectedPsi(searchScope), null); + boolean result = + processElementsWithWord(processor, searchScope, text, searchContext, caseSensitively, shouldProcessInjectedPsi(searchScope), null); + return AsyncUtil.wrapBoolean(result); } - @NotNull - private AsyncFuture processElementsWithWordAsync(@NotNull final TextOccurenceProcessor processor, - @NotNull SearchScope searchScope, - @NotNull final String text, - final short searchContext, - final boolean caseSensitively, - boolean processInjectedPsi, - @Nullable String containerName) { + private boolean processElementsWithWord(@NotNull final TextOccurenceProcessor processor, + @NotNull SearchScope searchScope, + @NotNull final String text, + final short searchContext, + final boolean caseSensitively, + boolean processInjectedPsi, + @Nullable String containerName) { if (text.isEmpty()) { - return AsyncFutureFactory.wrapException(new IllegalArgumentException("Cannot search for elements with empty text")); + throw new IllegalArgumentException("Cannot search for elements with empty text"); } final ProgressIndicator progress = ProgressIndicatorProvider.getGlobalProgressIndicator(); if (searchScope instanceof GlobalSearchScope) { StringSearcher searcher = new StringSearcher(text, caseSensitively, true, searchContext == UsageSearchContext.IN_STRINGS); - return processElementsWithTextInGlobalScopeAsync(processor, - (GlobalSearchScope)searchScope, - searcher, - searchContext, caseSensitively, containerName, progress, processInjectedPsi); + return processElementsWithTextInGlobalScope(processor, + (GlobalSearchScope)searchScope, + searcher, + searchContext, caseSensitively, containerName, progress, processInjectedPsi); } LocalSearchScope scope = (LocalSearchScope)searchScope; PsiElement[] scopeElements = scope.getScope(); final StringSearcher searcher = new StringSearcher(text, caseSensitively, true, searchContext == UsageSearchContext.IN_STRINGS); Processor localProcessor = localProcessor(processor, progress, processInjectedPsi, searcher); - return wrapInFuture(Arrays.asList(scopeElements), progress, localProcessor); - } - - private static AsyncFuture wrapInFuture(@NotNull List files, final ProgressIndicator progress, @NotNull Processor processor) { - AsyncFutureResult asyncFutureResult = AsyncFutureFactory.getInstance().createAsyncFutureResult(); - try { - boolean result = JobLauncher.getInstance().invokeConcurrentlyUnderProgress(files, progress, true, true, processor); - asyncFutureResult.set(result); - } - catch (Throwable t) { - asyncFutureResult.setException(t); - } - return asyncFutureResult; + return JobLauncher.getInstance().invokeConcurrentlyUnderProgress(Arrays.asList(scopeElements), progress, true, true, localProcessor); } private static boolean shouldProcessInjectedPsi(SearchScope scope) { - return scope instanceof LocalSearchScope ? !((LocalSearchScope)scope).isIgnoreInjectedPsi() : true; + return !(scope instanceof LocalSearchScope) || !((LocalSearchScope)scope).isIgnoreInjectedPsi(); } @NotNull @@ -213,14 +198,13 @@ public class PsiSearchHelperImpl implements PsiSearchHelper { }; } - @NotNull - private AsyncFuture processElementsWithTextInGlobalScopeAsync(@NotNull final TextOccurenceProcessor processor, - @NotNull final GlobalSearchScope scope, - @NotNull final StringSearcher searcher, - final short searchContext, - final boolean caseSensitively, - String containerName, - final ProgressIndicator progress, final boolean processInjectedPsi) { + private boolean processElementsWithTextInGlobalScope(@NotNull final TextOccurenceProcessor processor, + @NotNull final GlobalSearchScope scope, + @NotNull final StringSearcher searcher, + final short searchContext, + final boolean caseSensitively, + String containerName, + final ProgressIndicator progress, final boolean processInjectedPsi) { if (Thread.holdsLock(PsiLock.LOCK)) { throw new AssertionError("You must not run search from within updating PSI activity. Please consider invokeLatering it instead."); } @@ -244,70 +228,28 @@ public class PsiSearchHelperImpl implements PsiSearchHelper { getFilesWithText(scope, searchContext, caseSensitively, text+" "+containerName, progress, intersectionWithContainerFiles); if (!intersectionWithContainerFiles.isEmpty()) { int totalSize = fileSet.size(); - AsyncFuture intersectionResult = processPsiFileRootsAsync(intersectionWithContainerFiles, totalSize, 0, progress, localProcessor); - AsyncFuture result; - try { - if (intersectionResult.get()) { - fileSet.removeAll(intersectionWithContainerFiles); - if (fileSet.isEmpty()) { - result = intersectionResult; - } - else { - AsyncFuture restResult = - processPsiFileRootsAsync(new ArrayList(fileSet), totalSize, intersectionWithContainerFiles.size(), progress, localProcessor); - result = bind(intersectionResult, restResult); - } - } - else { - result = intersectionResult; + boolean result = processPsiFileRoots(intersectionWithContainerFiles, totalSize, 0, progress, + localProcessor); + + if (result) { + fileSet.removeAll(intersectionWithContainerFiles); + if (!fileSet.isEmpty()) { + result = processPsiFileRoots(new ArrayList(fileSet), totalSize, intersectionWithContainerFiles.size(), progress, localProcessor); } } - catch (ExecutionException e) { - Throwable cause = e.getCause(); - if (cause instanceof RuntimeException) throw (RuntimeException)cause; - if (cause instanceof Error) throw (Error)cause; - result = AsyncFutureFactory.wrapException(cause); - } - catch (InterruptedException e) { - result = AsyncFutureFactory.wrapException(e); - } - return popStateAfter(result, progress); - } - } - - AsyncFuture result = fileSet.isEmpty() - ? AsyncFutureFactory.wrap(Boolean.TRUE) - : processPsiFileRootsAsync(new ArrayList(fileSet), fileSet.size(), 0, progress, localProcessor); - return popStateAfter(result, progress); - } - - @NotNull - private static FinallyFuture popStateAfter(@NotNull AsyncFuture result, final ProgressIndicator progress) { - return new FinallyFuture(result, new Runnable() { - @Override - public void run() { if (progress != null) { progress.popState(); } + return result; } - }); - } + } - @NotNull - private static AsyncFuture bind(@NotNull AsyncFuture first, @NotNull final AsyncFuture second) { - final AsyncFutureResult totalResult = AsyncFutureFactory.getInstance().createAsyncFutureResult(); - first.addConsumer(SameThreadExecutor.INSTANCE, new ResultConsumer() { - @Override - public void onSuccess(Boolean value) { - second.addConsumer(SameThreadExecutor.INSTANCE, new DefaultResultConsumer(totalResult)); - } - - @Override - public void onFailure(Throwable t) { - totalResult.setException(t); - } - }); - return totalResult; + boolean result = + fileSet.isEmpty() || processPsiFileRoots(new ArrayList(fileSet), fileSet.size(), 0, progress, localProcessor); + if (progress != null) { + progress.popState(); + } + return result; } /** @@ -315,20 +257,19 @@ public class PsiSearchHelperImpl implements PsiSearchHelper { * @param totalSize the number of files to scan in both passes. Can be different from files.size() in case of * two-pass scan, where we first scan files containing container name and then all the rest files. * @param alreadyProcessedFiles the number of files scanned in previous pass. + * @return true if completed */ - @NotNull - private AsyncFuture processPsiFileRootsAsync(@NotNull List files, - final int totalSize, - int alreadyProcessedFiles, - final ProgressIndicator progress, - @NotNull final Processor localProcessor) { + private boolean processPsiFileRoots(@NotNull List files, + final int totalSize, + int alreadyProcessedFiles, + final ProgressIndicator progress, + @NotNull final Processor localProcessor) { myManager.startBatchFilesProcessingMode(); - final AtomicInteger counter = new AtomicInteger(alreadyProcessedFiles); - final AtomicBoolean canceled = new AtomicBoolean(false); - - AsyncFutureResult asyncFutureResult = AsyncFutureFactory.getInstance().createAsyncFutureResult(); - final List failedFiles = Collections.synchronizedList(new SmartList()); try { + final AtomicInteger counter = new AtomicInteger(alreadyProcessedFiles); + final AtomicBoolean canceled = new AtomicBoolean(false); + + final List failedFiles = Collections.synchronizedList(new SmartList()); boolean completed = JobLauncher.getInstance().invokeConcurrentlyUnderProgress(files, progress, false, false, new Processor() { @Override @@ -357,14 +298,12 @@ public class PsiSearchHelperImpl implements PsiSearchHelper { }); } } - asyncFutureResult.set(completed); + return completed; + } + finally { myManager.finishBatchFilesProcessingMode(); } - catch (Throwable t) { - asyncFutureResult.setException(t); - } - return asyncFutureResult; } private void processVirtualFile(@NotNull final VirtualFile vfile, @@ -423,9 +362,6 @@ public class PsiSearchHelperImpl implements PsiSearchHelper { if (progress != null) { progress.checkCanceled(); } - else { - ProgressManager.checkCanceled(); - } } private void getFilesWithText(@NotNull GlobalSearchScope scope, @@ -648,65 +584,32 @@ public class PsiSearchHelperImpl implements PsiSearchHelper { final Map> collectors = ContainerUtil.newHashMap(); collectors.put(collector, processor); + ProgressIndicator progress = ProgressIndicatorProvider.getGlobalProgressIndicator(); appendCollectorsFromQueryRequests(collectors); - - final ProgressIndicator progress = ProgressIndicatorProvider.getGlobalProgressIndicator(); - final DoWhile doWhile = new DoWhile() { - @NotNull - @Override - protected AsyncFuture body() { - final AsyncFutureResult result = AsyncFutureFactory.getInstance().createAsyncFutureResult(); - MultiMap, RequestWithProcessor> globals = new MultiMap, RequestWithProcessor>(); - final List> customs = ContainerUtil.newArrayList(); - final Set locals = ContainerUtil.newLinkedHashSet(); - Map> localProcessors = new THashMap>(); - distributePrimitives(collectors, locals, globals, customs, localProcessors, progress); - AsyncFuture future = processGlobalRequestsOptimizedAsync(globals, progress, localProcessors); - future.addConsumer(SameThreadExecutor.INSTANCE, new DefaultResultConsumer(result) { - @Override - public void onSuccess(Boolean value) { - if (!value.booleanValue()) { - result.set(value); - } - else { - final Iterate iterate = new Iterate(locals) { - @NotNull - @Override - protected AsyncFuture process(RequestWithProcessor local) { - return processSingleRequestAsync(local.request, local.refProcessor); - } - }; - - iterate.getResult() - .addConsumer(SameThreadExecutor.INSTANCE, new DefaultResultConsumer(result) { - @Override - public void onSuccess(Boolean value) { - if (!value.booleanValue()) { - result.set(false); - return; - } - for (Computable custom : customs) { - if (!custom.compute()) { - result.set(false); - return; - } - } - result.set(true); - } - }); - } + boolean result; + do { + MultiMap, RequestWithProcessor> globals = new MultiMap, RequestWithProcessor>(); + final List> customs = ContainerUtil.newArrayList(); + final Set locals = ContainerUtil.newLinkedHashSet(); + Map> localProcessors = new THashMap>(); + distributePrimitives(collectors, locals, globals, customs, localProcessors, progress); + result = processGlobalRequestsOptimized(globals, progress, localProcessors); + if (result) { + for (RequestWithProcessor local : locals) { + result = processSingleRequest(local.request, local.refProcessor); + if (!result) break; + } + if (result) { + for (Computable custom : customs) { + result = custom.compute(); + if (!result) break; } - }); - return result; + } + if (!result) break; } - - @Override - protected boolean condition() { - return appendCollectorsFromQueryRequests(collectors); - } - }; - - return doWhile.getResult(); + } + while(appendCollectorsFromQueryRequests(collectors)); + return AsyncUtil.wrapBoolean(result); } private static boolean appendCollectorsFromQueryRequests(@NotNull Map> collectors) { @@ -725,19 +628,18 @@ public class PsiSearchHelperImpl implements PsiSearchHelper { return changed; } - @NotNull - private AsyncFuture processGlobalRequestsOptimizedAsync(@NotNull MultiMap, RequestWithProcessor> singles, - final ProgressIndicator progress, - @NotNull final Map> localProcessors) { + private boolean processGlobalRequestsOptimized(@NotNull MultiMap, RequestWithProcessor> singles, + final ProgressIndicator progress, + @NotNull final Map> localProcessors) { if (singles.isEmpty()) { - return AsyncFutureFactory.wrap(true); + return true; } if (singles.size() == 1) { final Collection requests = singles.values(); if (requests.size() == 1) { final RequestWithProcessor theOnly = requests.iterator().next(); - return processSingleRequestAsync(theOnly.request, theOnly.refProcessor); + return processSingleRequest(theOnly.request, theOnly.refProcessor); } } @@ -745,64 +647,55 @@ public class PsiSearchHelperImpl implements PsiSearchHelper { progress.pushState(); progress.setText(PsiBundle.message("psi.scanning.files.progress")); } + boolean result; - // intersectionCandidateFiles holds files containing words from all requests in `singles` and words in corresponding container names - final MultiMap intersectionCandidateFiles = createMultiMap(); - // restCandidateFiles holds files containing words from all requests in `singles` but EXCLUDING words in corresponding container names - final MultiMap restCandidateFiles = createMultiMap(); - collectFiles(singles, progress, intersectionCandidateFiles, restCandidateFiles); + try { + // intersectionCandidateFiles holds files containing words from all requests in `singles` and words in corresponding container names + final MultiMap intersectionCandidateFiles = createMultiMap(); + // restCandidateFiles holds files containing words from all requests in `singles` but EXCLUDING words in corresponding container names + final MultiMap restCandidateFiles = createMultiMap(); + collectFiles(singles, progress, intersectionCandidateFiles, restCandidateFiles); - if (intersectionCandidateFiles.isEmpty() && restCandidateFiles.isEmpty()) { - return AsyncFutureFactory.wrap(true); - } - - if (progress != null) { - final Set allWords = new TreeSet(); - for (RequestWithProcessor singleRequest : localProcessors.keySet()) { - allWords.add(singleRequest.request.word); + if (intersectionCandidateFiles.isEmpty() && restCandidateFiles.isEmpty()) { + return true; } - progress.setText(PsiBundle.message("psi.search.for.word.progress", getPresentableWordsDescription(allWords))); - } - AsyncFuture result; - if (intersectionCandidateFiles.isEmpty()) { - result = processCandidatesAsync(progress, localProcessors, restCandidateFiles, restCandidateFiles.size(), 0); - } - else { - int totalSize = restCandidateFiles.size() + intersectionCandidateFiles.size(); - AsyncFuture intersectionResult = processCandidatesAsync(progress, localProcessors, intersectionCandidateFiles, totalSize, 0); - try { - if (intersectionResult.get()) { - AsyncFuture restResult = processCandidatesAsync(progress, localProcessors, restCandidateFiles, totalSize, intersectionCandidateFiles.size()); - result = bind(intersectionResult, restResult); + if (progress != null) { + final Set allWords = new TreeSet(); + for (RequestWithProcessor singleRequest : localProcessors.keySet()) { + allWords.add(singleRequest.request.word); } - else { - result = intersectionResult; + progress.setText(PsiBundle.message("psi.search.for.word.progress", getPresentableWordsDescription(allWords))); + } + + if (intersectionCandidateFiles.isEmpty()) { + result = processCandidates(progress, localProcessors, restCandidateFiles, restCandidateFiles.size(), 0); + } + else { + int totalSize = restCandidateFiles.size() + intersectionCandidateFiles.size(); + result = processCandidates(progress, localProcessors, intersectionCandidateFiles, totalSize, 0); + if (result) { + result = processCandidates(progress, localProcessors, restCandidateFiles, totalSize, intersectionCandidateFiles.size()); } } - catch (ExecutionException e) { - Throwable cause = e.getCause(); - if (cause instanceof RuntimeException) throw (RuntimeException)cause; - if (cause instanceof Error) throw (Error)cause; - result = AsyncFutureFactory.wrapException(cause); - } - catch (InterruptedException e) { - result = AsyncFutureFactory.wrapException(e); + } + finally { + if (progress != null) { + progress.popState(); } } - return popStateAfter(result, progress); + return result; } - @NotNull - private AsyncFuture processCandidatesAsync(final ProgressIndicator progress, - @NotNull final Map> localProcessors, - @NotNull final MultiMap candidateFiles, - int totalSize, - int alreadyProcessedFiles) { + private boolean processCandidates(final ProgressIndicator progress, + @NotNull final Map> localProcessors, + @NotNull final MultiMap candidateFiles, + int totalSize, + int alreadyProcessedFiles) { List files = new ArrayList(candidateFiles.keySet()); - return processPsiFileRootsAsync(files, totalSize, alreadyProcessedFiles, progress, new Processor() { + return processPsiFileRoots(files, totalSize, alreadyProcessedFiles, progress, new Processor() { @Override public boolean process(final PsiFile psiRoot) { return ApplicationUtil.tryRunReadAction(new Computable() { @@ -1023,10 +916,9 @@ public class PsiSearchHelperImpl implements PsiSearchHelper { collection.add(singleRequest); } - @NotNull - private AsyncFuture processSingleRequestAsync(@NotNull PsiSearchRequest single, @NotNull Processor consumer) { - return processElementsWithWordAsync(adaptProcessor(single, consumer), single.searchScope, single.word, single.searchContext, - single.caseSensitive, shouldProcessInjectedPsi(single.searchScope), single.containerName); + private boolean processSingleRequest(@NotNull PsiSearchRequest single, @NotNull Processor consumer) { + return processElementsWithWord(adaptProcessor(single, consumer), single.searchScope, single.word, single.searchContext, + single.caseSensitive, shouldProcessInjectedPsi(single.searchScope), single.containerName); } @NotNull diff --git a/platform/platform-impl/src/com/intellij/concurrency/JobLauncherImpl.java b/platform/platform-impl/src/com/intellij/concurrency/JobLauncherImpl.java index b33611da8866..876474b9124b 100644 --- a/platform/platform-impl/src/com/intellij/concurrency/JobLauncherImpl.java +++ b/platform/platform-impl/src/com/intellij/concurrency/JobLauncherImpl.java @@ -146,19 +146,11 @@ public class JobLauncherImpl extends JobLauncher { // This implementation is not really async @NotNull @Override - public AsyncFutureResult invokeConcurrentlyUnderProgressAsync(@NotNull List things, + public AsyncFuture invokeConcurrentlyUnderProgressAsync(@NotNull List things, ProgressIndicator progress, boolean failFastOnAcquireReadAction, @NotNull Processor thingProcessor) { - final AsyncFutureResult asyncFutureResult = AsyncFutureFactory.getInstance().createAsyncFutureResult(); - try { - final boolean result = invokeConcurrentlyUnderProgress(things, progress, failFastOnAcquireReadAction, thingProcessor); - asyncFutureResult.set(result); - } - catch (Throwable t) { - asyncFutureResult.setException(t); - } - return asyncFutureResult; + return AsyncUtil.wrapBoolean(invokeConcurrentlyUnderProgress(things, progress, failFastOnAcquireReadAction, thingProcessor)); } @NotNull From 4aa282d3099073486f29ffc8456a6668ec97f9a9 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Thu, 4 Sep 2014 14:30:57 +0400 Subject: [PATCH 48/60] notnull --- .../concurrency/DefaultResultConsumer.java | 8 +++-- .../intellij/concurrency/ResultConsumer.java | 6 ++-- .../impl/PsiAwareFileEditorManagerImpl.java | 7 ++-- .../impl/TestEditorManagerImpl.java | 14 ++++---- .../ui/tabs/EditorTabColorProviderImpl.java | 5 +-- .../openapi/fileEditor/FileEditorManager.java | 2 +- .../fileEditor/ex/FileEditorManagerEx.java | 1 + .../fileEditor/impl/EditorComposite.java | 4 +-- .../fileEditor/impl/EditorHistoryManager.java | 4 +-- .../impl/EditorTabColorProvider.java | 5 +-- .../impl/EditorTabbedContainer.java | 4 +-- .../openapi/fileEditor/impl/EditorWindow.java | 11 ++++--- .../fileEditor/impl/EditorWindowHolder.java | 5 ++- .../fileEditor/impl/EditorsSplitters.java | 14 ++++---- .../impl/IdeDocumentHistoryImpl.java | 32 ++++++++----------- .../ui/docking/impl/DockManagerImpl.java | 7 ++-- .../src/com/intellij/mock/Mock.java | 2 +- .../intellij/openapi/util/io/FileUtil.java | 9 ++---- .../messages/impl/MessageListenerList.java | 10 +++--- .../DebuggerTreeWithHistoryContainer.java | 4 +-- 20 files changed, 81 insertions(+), 73 deletions(-) diff --git a/platform/core-api/src/com/intellij/concurrency/DefaultResultConsumer.java b/platform/core-api/src/com/intellij/concurrency/DefaultResultConsumer.java index 7230cd469e13..0e54993fe84b 100644 --- a/platform/core-api/src/com/intellij/concurrency/DefaultResultConsumer.java +++ b/platform/core-api/src/com/intellij/concurrency/DefaultResultConsumer.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. @@ -15,13 +15,15 @@ */ package com.intellij.concurrency; +import org.jetbrains.annotations.NotNull; + /** * Author: dmitrylomov */ public class DefaultResultConsumer implements ResultConsumer { private final AsyncFutureResult myResult; - public DefaultResultConsumer(AsyncFutureResult result) { + public DefaultResultConsumer(@NotNull AsyncFutureResult result) { myResult = result; } @@ -31,7 +33,7 @@ public class DefaultResultConsumer implements ResultConsumer { } @Override - public void onFailure(Throwable t) { + public void onFailure(@NotNull Throwable t) { myResult.setException(t); } } diff --git a/platform/core-api/src/com/intellij/concurrency/ResultConsumer.java b/platform/core-api/src/com/intellij/concurrency/ResultConsumer.java index 80618f0b9c79..409d5a9439a4 100644 --- a/platform/core-api/src/com/intellij/concurrency/ResultConsumer.java +++ b/platform/core-api/src/com/intellij/concurrency/ResultConsumer.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. @@ -15,10 +15,12 @@ */ package com.intellij.concurrency; +import org.jetbrains.annotations.NotNull; + /** * Author: dmitrylomov */ public interface ResultConsumer { void onSuccess(V value); - void onFailure(Throwable t); + void onFailure(@NotNull Throwable t); } diff --git a/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/PsiAwareFileEditorManagerImpl.java b/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/PsiAwareFileEditorManagerImpl.java index 7713734d07de..eaed20f2960d 100644 --- a/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/PsiAwareFileEditorManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/PsiAwareFileEditorManagerImpl.java @@ -102,8 +102,9 @@ public class PsiAwareFileEditorManagerImpl extends FileEditorManagerImpl { return myProblemSolver.isProblemFile(file); } + @NotNull @Override - public String getFileTooltipText(final VirtualFile file) { + public String getFileTooltipText(@NotNull final VirtualFile file) { final StringBuilder tooltipText = new StringBuilder(); final Module module = ModuleUtilCore.findModuleForFile(file, getProject()); if (module != null) { @@ -116,7 +117,7 @@ public class PsiAwareFileEditorManagerImpl extends FileEditorManagerImpl { } @Override - protected Editor getOpenedEditor(final Editor editor, final boolean focusEditor) { + protected Editor getOpenedEditor(@NotNull final Editor editor, final boolean focusEditor) { PsiDocumentManager documentManager = PsiDocumentManager.getInstance(getProject()); Document document = editor.getDocument(); PsiFile psiFile = documentManager.getPsiFile(document); @@ -200,7 +201,7 @@ public class PsiAwareFileEditorManagerImpl extends FileEditorManagerImpl { updateFile(file); } - private void updateFile(final VirtualFile file) { + private void updateFile(@NotNull VirtualFile file) { queueUpdateFile(file); } } diff --git a/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/TestEditorManagerImpl.java b/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/TestEditorManagerImpl.java index 79ac777a6fd8..958daee0098a 100644 --- a/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/TestEditorManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/TestEditorManagerImpl.java @@ -38,6 +38,7 @@ import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiManager; import com.intellij.testFramework.LightVirtualFile; +import com.intellij.util.IncorrectOperationException; import com.intellij.util.containers.HashMap; import org.jdom.Element; import org.jetbrains.annotations.NonNls; @@ -195,7 +196,7 @@ public class TestEditorManagerImpl extends FileEditorManagerEx implements Applic return openTextEditor(descriptor, false); } - private FileEditorProvider getProvider(FileEditor editor) { + private static FileEditorProvider getProvider(FileEditor editor) { return new FileEditorProvider() { @Override public boolean accept(@NotNull Project project, @NotNull VirtualFile file) { @@ -205,18 +206,17 @@ public class TestEditorManagerImpl extends FileEditorManagerEx implements Applic @Override @NotNull public FileEditor createEditor(@NotNull Project project, @NotNull VirtualFile file) { - return null; + throw new IncorrectOperationException(); } @Override public void disposeEditor(@NotNull FileEditor editor) { - //Disposer.dispose(editor); } @Override @NotNull public FileEditorState readState(@NotNull Element sourceElement, @NotNull Project project, @NotNull VirtualFile file) { - return null; + throw new IncorrectOperationException(); } @Override @@ -233,7 +233,7 @@ public class TestEditorManagerImpl extends FileEditorManagerEx implements Applic @Override @NotNull public FileEditorPolicy getPolicy() { - return null; + throw new IncorrectOperationException(); } }; } @@ -482,7 +482,7 @@ public class TestEditorManagerImpl extends FileEditorManagerEx implements Applic @NotNull @Override public EditorsSplitters getSplitters() { - return null; + throw new IncorrectOperationException(); } @NotNull @@ -492,6 +492,6 @@ public class TestEditorManagerImpl extends FileEditorManagerEx implements Applic } @Override - public void setSelectedEditor(@NotNull VirtualFile file, String fileEditorProviderId) { + public void setSelectedEditor(@NotNull VirtualFile file, @NotNull String fileEditorProviderId) { } } diff --git a/platform/lang-impl/src/com/intellij/ui/tabs/EditorTabColorProviderImpl.java b/platform/lang-impl/src/com/intellij/ui/tabs/EditorTabColorProviderImpl.java index 93ebe1f0573a..5c2083710f2a 100644 --- a/platform/lang-impl/src/com/intellij/ui/tabs/EditorTabColorProviderImpl.java +++ b/platform/lang-impl/src/com/intellij/ui/tabs/EditorTabColorProviderImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 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. @@ -20,6 +20,7 @@ import com.intellij.openapi.fileEditor.impl.EditorTabColorProvider; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.FileColorManager; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.awt.*; @@ -31,7 +32,7 @@ public class EditorTabColorProviderImpl implements EditorTabColorProvider { @Override @Nullable - public Color getEditorTabColor(Project project, VirtualFile file) { + public Color getEditorTabColor(@NotNull Project project, @NotNull VirtualFile file) { FileColorManager colorManager = FileColorManager.getInstance(project); return colorManager.isEnabledForTabs() ? colorManager.getFileColor(file) : null; } diff --git a/platform/platform-api/src/com/intellij/openapi/fileEditor/FileEditorManager.java b/platform/platform-api/src/com/intellij/openapi/fileEditor/FileEditorManager.java index 86e719eef48d..dcb1327f1a10 100644 --- a/platform/platform-api/src/com/intellij/openapi/fileEditor/FileEditorManager.java +++ b/platform/platform-api/src/com/intellij/openapi/fileEditor/FileEditorManager.java @@ -197,5 +197,5 @@ public abstract class FileEditorManager { * @param fileEditorProviderId the ID of the file editor to open; matches the return value of * {@link com.intellij.openapi.fileEditor.FileEditorProvider#getEditorTypeId()} */ - public abstract void setSelectedEditor(@NotNull VirtualFile file, String fileEditorProviderId); + public abstract void setSelectedEditor(@NotNull VirtualFile file, @NotNull String fileEditorProviderId); } diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/ex/FileEditorManagerEx.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/ex/FileEditorManagerEx.java index 30eb78cf706f..c074a4965493 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/ex/FileEditorManagerEx.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/ex/FileEditorManagerEx.java @@ -164,6 +164,7 @@ public abstract class FileEditorManagerEx extends FileEditorManager implements B public abstract boolean isInsideChange(); + @Override @Nullable public final Object getData(@NotNull String dataId, @NotNull Editor editor, @NotNull Caret caret) { for (final EditorDataProvider dataProvider : myDataProviders) { diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorComposite.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorComposite.java index 48a5b7c9a4dc..d8a704d891bf 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorComposite.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorComposite.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. @@ -66,7 +66,7 @@ public abstract class EditorComposite implements Disposable { /** * File for which composite is created */ - private final VirtualFile myFile; + @NotNull private final VirtualFile myFile; /** * Whether the composite is pinned or not */ diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorHistoryManager.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorHistoryManager.java index 32169662ba2a..ddd5395805ff 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorHistoryManager.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorHistoryManager.java @@ -287,7 +287,7 @@ public final class EditorHistoryManager extends AbstractProjectComponent impleme } } - public FileEditorState getState(final VirtualFile file, final FileEditorProvider provider) { + public FileEditorState getState(@NotNull VirtualFile file, final FileEditorProvider provider) { validateEntries(); final HistoryEntry entry = getEntry(file); return entry != null ? entry.getState(provider) : null; @@ -302,7 +302,7 @@ public final class EditorHistoryManager extends AbstractProjectComponent impleme return entry != null ? entry.mySelectedProvider : null; } - private HistoryEntry getEntry(final VirtualFile file){ + private HistoryEntry getEntry(@NotNull VirtualFile file){ validateEntries(); for (int i = myEntriesList.size() - 1; i >= 0; i--) { final HistoryEntry entry = myEntriesList.get(i); diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorTabColorProvider.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorTabColorProvider.java index babf76dd3709..58f5470aca07 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorTabColorProvider.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorTabColorProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 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,7 @@ package com.intellij.openapi.fileEditor.impl; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.extensions.ExtensionPointName; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.awt.*; @@ -29,5 +30,5 @@ public interface EditorTabColorProvider { ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.editorTabColorProvider"); @Nullable - Color getEditorTabColor(Project project, VirtualFile file); + Color getEditorTabColor(@NotNull Project project, @NotNull VirtualFile file); } diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorTabbedContainer.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorTabbedContainer.java index 03b03faffe03..3fa0f751e9cb 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorTabbedContainer.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorTabbedContainer.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. @@ -381,7 +381,7 @@ public final class EditorTabbedContainer implements Disposable, CloseAction.Clos } @Nullable - public static Color calcTabColor(final Project project, final VirtualFile file) { + public static Color calcTabColor(@NotNull Project project, @NotNull VirtualFile file) { for (EditorTabColorProvider provider : Extensions.getExtensions(EditorTabColorProvider.EP_NAME)) { final Color result = provider.getEditorTabColor(project, file); if (result != null) { diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWindow.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWindow.java index c1515a817b26..1bf86ea5d62c 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWindow.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWindow.java @@ -287,7 +287,7 @@ public class EditorWindow { } } - public void closeFile(final VirtualFile file, final boolean disposeIfNeeded, final boolean transferFocus) { + public void closeFile(@NotNull final VirtualFile file, final boolean disposeIfNeeded, final boolean transferFocus) { final FileEditorManagerImpl editorManager = getManager(); editorManager.runChange(new FileEditorManagerChange() { @Override @@ -525,7 +525,7 @@ public class EditorWindow { myOwner.setCurrentWindow(this, requestFocus); } - public void updateFileBackgroundColor(final VirtualFile file) { + public void updateFileBackgroundColor(@NotNull VirtualFile file) { final int index = findEditorIndex(findFileComposite(file)); if (index != -1) { final Color color = EditorTabbedContainer.calcTabColor(getManager().getProject(), file); @@ -569,10 +569,10 @@ public class EditorWindow { } protected static class TComp extends JPanel implements DataProvider, EditorWindowHolder { - final EditorWithProviderComposite myEditor; + @NotNull final EditorWithProviderComposite myEditor; protected final EditorWindow myWindow; - TComp(final EditorWindow window, final EditorWithProviderComposite editor) { + TComp(@NotNull EditorWindow window, @NotNull EditorWithProviderComposite editor) { super(new BorderLayout()); myEditor = editor; myWindow = window; @@ -594,6 +594,7 @@ public class EditorWindow { }); } + @NotNull @Override public EditorWindow getEditorWindow() { return myWindow; @@ -613,7 +614,7 @@ public class EditorWindow { } protected static class TCompForTablessMode extends TComp implements CloseAction.CloseTarget { - TCompForTablessMode(final EditorWindow window, final EditorWithProviderComposite editor) { + TCompForTablessMode(@NotNull EditorWindow window, @NotNull EditorWithProviderComposite editor) { super(window, editor); } diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWindowHolder.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWindowHolder.java index c708d058b63b..2d27bb853531 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWindowHolder.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWindowHolder.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 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. @@ -15,9 +15,12 @@ */ package com.intellij.openapi.fileEditor.impl; +import org.jetbrains.annotations.NotNull; + /** * @author Konstantin Bulenkov */ public interface EditorWindowHolder { + @NotNull EditorWindow getEditorWindow(); } diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java index b0f274e9e5a4..f7ba3b99156d 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java @@ -463,7 +463,7 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener myCurrentWindow = currentWindow; } - public void updateFileBackgroundColor(final VirtualFile file) { + public void updateFileBackgroundColor(@NotNull VirtualFile file) { final EditorWindow[] windows = getWindows(); for (int i = 0; i != windows.length; ++ i) { windows [i].updateFileBackgroundColor(file); @@ -629,7 +629,7 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener * @param requestFocus whether to request focus to the editor currently selected in this window */ public void setCurrentWindow(@Nullable final EditorWindow window, final boolean requestFocus) { - final EditorWithProviderComposite newEditor = window != null? window.getSelectedEditor() : null; + final EditorWithProviderComposite newEditor = window == null ? null : window.getSelectedEditor(); Runnable fireRunnable = new Runnable() { @Override @@ -659,7 +659,7 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener //--------------------------------------------------------- public EditorWithProviderComposite[] getEditorsComposites() { - final ArrayList res = new ArrayList(); + List res = new ArrayList(); for (final EditorWindow myWindow : myWindows) { final EditorWithProviderComposite[] editors = myWindow.getEditors(); @@ -671,8 +671,8 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener //--------------------------------------------------------- @NotNull - public List findEditorComposites(final VirtualFile file) { - final ArrayList res = new ArrayList(); + public List findEditorComposites(@NotNull VirtualFile file) { + List res = new ArrayList(); for (final EditorWindow window : myWindows) { final EditorWithProviderComposite fileComposite = window.findFileComposite(file); if (fileComposite != null) { @@ -684,7 +684,7 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener @NotNull public List findWindows(final VirtualFile file) { - final ArrayList res = new ArrayList(); + List res = new ArrayList(); for (final EditorWindow window : myWindows) { if (window.findFileComposite(file) != null) { res.add(window); @@ -698,7 +698,7 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener } @NotNull public EditorWindow[] getOrderedWindows() { - final ArrayList res = new ArrayList(); + final List res = new ArrayList(); // Collector for windows in tree ordering: class Inner{ diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/IdeDocumentHistoryImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/IdeDocumentHistoryImpl.java index 752ab1228c3e..0e4f057dbeaf 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/IdeDocumentHistoryImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/IdeDocumentHistoryImpl.java @@ -145,16 +145,12 @@ public class IdeDocumentHistoryImpl extends IdeDocumentHistory implements Projec } public static class RecentlyChangedFilesState { - @Transient private List CHANGED_PATHS = new ArrayList(); + @Transient private final List CHANGED_PATHS = new ArrayList(); public List getChangedFiles() { return CHANGED_PATHS; } - public void setChangedFiles(List changed) { - CHANGED_PATHS = changed; - } - public void register(VirtualFile file) { final String path = file.getPath(); CHANGED_PATHS.remove(path); @@ -275,7 +271,7 @@ public class IdeDocumentHistoryImpl extends IdeDocumentHistory implements Projec myCurrentChangePlace = placeInfo; if (!myChangePlaces.isEmpty()) { - final PlaceInfo lastInfo = myChangePlaces.get(myChangePlaces.size() - 1); + final PlaceInfo lastInfo = myChangePlaces.getLast(); if (isSame(placeInfo, lastInfo)) { myChangePlaces.removeLast(); } @@ -430,7 +426,7 @@ public class IdeDocumentHistoryImpl extends IdeDocumentHistory implements Projec } } - private static boolean removeInvalidFilesFrom(final LinkedList backPlaces) { + private static boolean removeInvalidFilesFrom(@NotNull List backPlaces) { boolean removed = false; for (Iterator iterator = backPlaces.iterator(); iterator.hasNext();) { PlaceInfo info = iterator.next(); @@ -456,7 +452,7 @@ public class IdeDocumentHistoryImpl extends IdeDocumentHistory implements Projec myEditorManager.setSelectedEditor(info.getFile(), info.getEditorTypeId()); - final FileEditor [] editors = editorsWithProviders.getFirst(); + final FileEditor[] editors = editorsWithProviders.getFirst(); final FileEditorProvider[] providers = editorsWithProviders.getSecond(); for (int i = 0; i < editors.length; i++) { String typeId = providers [i].getEditorTypeId(); @@ -483,7 +479,7 @@ public class IdeDocumentHistoryImpl extends IdeDocumentHistory implements Projec return new PlaceInfo(file, state, fileProvider.getEditorTypeId(), myEditorManager.getCurrentWindow()); } - private static void clearPlaceList(LinkedList list) { + private static void clearPlaceList(@NotNull List list) { list.clear(); } @@ -494,9 +490,9 @@ public class IdeDocumentHistoryImpl extends IdeDocumentHistory implements Projec return "IdeDocumentHistory"; } - private static void putLastOrMerge(LinkedList list, PlaceInfo next, int limitSizeLimit) { + private static void putLastOrMerge(@NotNull LinkedList list, @NotNull PlaceInfo next, int limitSizeLimit) { if (!list.isEmpty()) { - PlaceInfo prev = list.get(list.size() - 1); + PlaceInfo prev = list.getLast(); if (isSame(prev, next)) { list.removeLast(); } @@ -522,7 +518,7 @@ public class IdeDocumentHistoryImpl extends IdeDocumentHistory implements Projec private final String myEditorTypeId; private final WeakReference myWindow; - public PlaceInfo(@NotNull VirtualFile file, FileEditorState navigationState, String editorTypeId, @Nullable EditorWindow window) { + public PlaceInfo(@NotNull VirtualFile file, @NotNull FileEditorState navigationState, @NotNull String editorTypeId, @Nullable EditorWindow window) { myNavigationState = navigationState; myFile = file; myEditorTypeId = editorTypeId; @@ -533,6 +529,7 @@ public class IdeDocumentHistoryImpl extends IdeDocumentHistory implements Projec return myWindow.get(); } + @NotNull public FileEditorState getNavigationState() { return myNavigationState; } @@ -542,24 +539,23 @@ public class IdeDocumentHistoryImpl extends IdeDocumentHistory implements Projec return myFile; } + @NotNull public String getEditorTypeId() { return myEditorTypeId; } + @Override public String toString() { return getFile().getName() + " " + getNavigationState(); } } - public LinkedList getBackPlaces() { + @NotNull + public List getBackPlaces() { return myBackPlaces; } - public LinkedList getForwardPlaces() { - return myForwardPlaces; - } - @Override public final void initComponent() { } @@ -572,7 +568,7 @@ public class IdeDocumentHistoryImpl extends IdeDocumentHistory implements Projec myCmdProcessor.executeCommand(myProject, runnable, name, groupId); } - private static boolean isSame(PlaceInfo first, PlaceInfo second) { + private static boolean isSame(@NotNull PlaceInfo first, @NotNull PlaceInfo second) { if (first.getFile().equals(second.getFile())) { FileEditorState firstState = first.getNavigationState(); FileEditorState secondState = second.getNavigationState(); diff --git a/platform/platform-impl/src/com/intellij/ui/docking/impl/DockManagerImpl.java b/platform/platform-impl/src/com/intellij/ui/docking/impl/DockManagerImpl.java index ee586418dbd6..37646a19292f 100644 --- a/platform/platform-impl/src/com/intellij/ui/docking/impl/DockManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/ui/docking/impl/DockManagerImpl.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. @@ -94,6 +94,7 @@ public class DockManagerImpl extends DockManager implements PersistentStateCompo myProject = project; } + @Override public void register(final DockContainer container) { myContainers.add(container); Disposer.register(container, new Disposable() { @@ -147,6 +148,7 @@ public class DockManagerImpl extends DockManager implements PersistentStateCompo return wnd != null ? key + "#" + wnd.myId : key; } + @Override public DockContainer getContainerFor(Component c) { if (c == null) return null; @@ -401,7 +403,8 @@ public class DockManagerImpl extends DockManager implements PersistentStateCompo }); } - public Pair createNewDockContainerFor(@NotNull VirtualFile file, FileEditorManagerImpl fileEditorManager) { + @NotNull + public Pair createNewDockContainerFor(@NotNull VirtualFile file, @NotNull FileEditorManagerImpl fileEditorManager) { DockContainer container = getFactory(DockableEditorContainerFactory.TYPE).createContainer(null); register(container); diff --git a/platform/testFramework/src/com/intellij/mock/Mock.java b/platform/testFramework/src/com/intellij/mock/Mock.java index 73d6538c52b9..a2768f2e1851 100644 --- a/platform/testFramework/src/com/intellij/mock/Mock.java +++ b/platform/testFramework/src/com/intellij/mock/Mock.java @@ -435,7 +435,7 @@ public class Mock { } @Override - public void setSelectedEditor(@NotNull VirtualFile file, String fileEditorProviderId) { + public void setSelectedEditor(@NotNull VirtualFile file, @NotNull String fileEditorProviderId) { } } diff --git a/platform/util/src/com/intellij/openapi/util/io/FileUtil.java b/platform/util/src/com/intellij/openapi/util/io/FileUtil.java index 7d3d6f557249..bc41f70e933a 100644 --- a/platform/util/src/com/intellij/openapi/util/io/FileUtil.java +++ b/platform/util/src/com/intellij/openapi/util/io/FileUtil.java @@ -1249,18 +1249,15 @@ public class FileUtil extends FileUtilRt { } public static boolean isWindowsAbsolutePath(@NotNull String pathString) { - if (pathString.length() >= 2 && Character.isLetter(pathString.charAt(0)) && pathString.charAt(1) == ':') { - return true; - } - return false; + return pathString.length() >= 2 && Character.isLetter(pathString.charAt(0)) && pathString.charAt(1) == ':'; } - @Contract("null -> null") + @Contract("null -> null; !null -> !null") public static String getLocationRelativeToUserHome(@Nullable String path) { return getLocationRelativeToUserHome(path, true); } - @Contract("null,_ -> null") + @Contract("null,_ -> null; !null,_ -> !null") public static String getLocationRelativeToUserHome(@Nullable String path, boolean unixOnly) { if (path == null) return null; diff --git a/platform/util/src/com/intellij/util/messages/impl/MessageListenerList.java b/platform/util/src/com/intellij/util/messages/impl/MessageListenerList.java index d054416846a1..6d7bf76ccde7 100644 --- a/platform/util/src/com/intellij/util/messages/impl/MessageListenerList.java +++ b/platform/util/src/com/intellij/util/messages/impl/MessageListenerList.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. @@ -15,14 +15,14 @@ */ package com.intellij.util.messages.impl; +import com.intellij.openapi.Disposable; +import com.intellij.openapi.util.Disposer; +import com.intellij.util.containers.ConcurrentHashMap; import com.intellij.util.messages.MessageBus; import com.intellij.util.messages.MessageBusConnection; import com.intellij.util.messages.Topic; -import com.intellij.openapi.Disposable; -import com.intellij.openapi.util.Disposer; import org.jetbrains.annotations.NotNull; -import java.util.HashMap; import java.util.Map; /** @@ -31,7 +31,7 @@ import java.util.Map; public class MessageListenerList { private final MessageBus myMessageBus; private final Topic myTopic; - private final Map myListenerToConnectionMap = new HashMap(); + private final Map myListenerToConnectionMap = new ConcurrentHashMap(); public MessageListenerList(@NotNull MessageBus messageBus, @NotNull Topic topic) { myTopic = topic; diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/common/DebuggerTreeWithHistoryContainer.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/common/DebuggerTreeWithHistoryContainer.java index c7c5af9f6fb4..2851c701ef70 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/common/DebuggerTreeWithHistoryContainer.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/common/DebuggerTreeWithHistoryContainer.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 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. @@ -170,7 +170,7 @@ abstract class DebuggerTreeWithHistoryContainer { } @Override - public void onFailure(Throwable t) { + public void onFailure(@NotNull Throwable t) { LOG.debug(t); } }); From 8e88104130d00b7d04f660f5cde68350edddfd0c Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Thu, 4 Sep 2014 14:50:11 +0400 Subject: [PATCH 49/60] IDEA-129381 Settings dialog: not the whole area of hyperlinks is clickable (fix popup on the edge) --- .../platform-impl/src/com/intellij/ui/popup/WizardPopup.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/ui/popup/WizardPopup.java b/platform/platform-impl/src/com/intellij/ui/popup/WizardPopup.java index 1b9190f6a740..d8b512367f26 100644 --- a/platform/platform-impl/src/com/intellij/ui/popup/WizardPopup.java +++ b/platform/platform-impl/src/com/intellij/ui/popup/WizardPopup.java @@ -189,7 +189,7 @@ public abstract class WizardPopup extends AbstractPopup implements ActionListene targetBounds.x = getParent().getBounds().x - targetBounds.width - STEP_X_PADDING; } } else { - ScreenUtil.moveToFit(targetBounds, ScreenUtil.getScreenRectangle(aScreenX, aScreenY), null); + ScreenUtil.moveToFit(targetBounds, ScreenUtil.getScreenRectangle(aScreenX + 1, aScreenY + 1), null); } if (getParent() == null) { From 46fafc29fcd04d4909c0353bc91f45a776df6c5a Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Thu, 4 Sep 2014 14:59:46 +0400 Subject: [PATCH 50/60] IDEA-128022 Missing "adjust range" for arrays/collections --- .../actions/AdjustArrayRangeAction.java | 58 ++++++++++++------- .../debugger/actions/DebuggerAction.java | 16 +++++ .../debugger/actions/ViewAsGroup.java | 11 ++-- .../debugger/engine/JavaDebugProcess.java | 39 ++++++++----- .../intellij/debugger/engine/JavaValue.java | 1 + .../debugger/impl/DebuggerSession.java | 1 + .../impl/watch/NodeDescriptorFactoryImpl.java | 9 ++- .../ui/impl/watch/NodeManagerImpl.java | 8 ++- .../ui/tree/render/ArrayRenderer.java | 12 +++- resources/src/idea/JavaActions.xml | 4 +- 10 files changed, 108 insertions(+), 51 deletions(-) diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/AdjustArrayRangeAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/AdjustArrayRangeAction.java index ce375815bb77..0f5398a56cba 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/AdjustArrayRangeAction.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/AdjustArrayRangeAction.java @@ -16,6 +16,7 @@ package com.intellij.debugger.actions; import com.intellij.debugger.engine.DebugProcessImpl; +import com.intellij.debugger.engine.JavaValue; import com.intellij.debugger.engine.events.SuspendContextCommandImpl; import com.intellij.debugger.impl.DebuggerContextImpl; import com.intellij.debugger.settings.ArrayRendererConfigurable; @@ -27,6 +28,9 @@ import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.options.Configurable; import com.intellij.openapi.options.ShowSettingsUtil; import com.intellij.openapi.project.Project; +import com.intellij.xdebugger.frame.XValue; +import com.intellij.xdebugger.impl.ui.tree.actions.XDebuggerTreeActionBase; +import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl; import org.jetbrains.annotations.Nullable; public class AdjustArrayRangeAction extends DebuggerAction { @@ -44,42 +48,48 @@ public class AdjustArrayRangeAction extends DebuggerAction { final Project project = debuggerContext.getProject(); - final DebuggerTreeNodeImpl selectedNode = getSelectedNode(e.getDataContext()); - if (selectedNode == null) { - return; - } - NodeDescriptorImpl descriptor = selectedNode.getDescriptor(); - if(!(descriptor instanceof ValueDescriptorImpl /*&& ((ValueDescriptorImpl)descriptor).isArray()*/)) { + final XValueNodeImpl node = XDebuggerTreeActionBase.getSelectedNode(e.getDataContext()); + if (node == null) { return; } - final ArrayRenderer renderer = getArrayRenderer((ValueDescriptorImpl)descriptor)/*(ArrayRenderer)((ValueDescriptorImpl)selectedNode.getDescriptor()).getLastRenderer()*/; + XValue container = node.getValueContainer(); + if (!(container instanceof JavaValue)) { + return; + } + + final ValueDescriptorImpl descriptor = ((JavaValue)container).getDescriptor(); + ArrayRenderer renderer = getArrayRenderer(descriptor); if (renderer == null) { return; } - String title = createNodeTitle("", selectedNode); - String label = selectedNode.toString(); - int index = label.indexOf('='); - if (index > 0) { - title = title + " " + label.substring(index); - } + //String title = createNodeTitle("", selectedNode); + //String label = selectedNode.toString(); + //int index = label.indexOf('='); + //if (index > 0) { + // title = title + " " + label.substring(index); + //} + String title = node.getName(); final ArrayRenderer clonedRenderer = renderer.clone(); + clonedRenderer.setForced(true); if (ShowSettingsUtil.getInstance().editConfigurable(project, new NamedArrayConfigurable(title, clonedRenderer))) { debugProcess.getManagerThread().schedule(new SuspendContextCommandImpl(debuggerContext.getSuspendContext()) { @Override public void contextAction() throws Exception { - final ValueDescriptorImpl nodeDescriptor = (ValueDescriptorImpl)selectedNode.getDescriptor(); - final Renderer lastRenderer = nodeDescriptor.getLastRenderer(); + final Renderer lastRenderer = descriptor.getLastRenderer(); if (lastRenderer instanceof ArrayRenderer) { - selectedNode.setRenderer(clonedRenderer); + descriptor.setRenderer(clonedRenderer); + refreshViews(node); + //selectedNode.setRenderer(clonedRenderer); } else if (lastRenderer instanceof CompoundNodeRenderer) { final CompoundNodeRenderer compoundRenderer = (CompoundNodeRenderer)lastRenderer; final ChildrenRenderer childrenRenderer = compoundRenderer.getChildrenRenderer(); if (childrenRenderer instanceof ExpressionChildrenRenderer) { - ExpressionChildrenRenderer.setPreferableChildrenRenderer(nodeDescriptor, clonedRenderer); - selectedNode.calcRepresentation(); + ExpressionChildrenRenderer.setPreferableChildrenRenderer(descriptor, clonedRenderer); + refreshViews(node); + //selectedNode.calcRepresentation(); } } } @@ -90,10 +100,14 @@ public class AdjustArrayRangeAction extends DebuggerAction { @Override public void update(AnActionEvent e) { boolean enable = false; - DebuggerTreeNodeImpl selectedNode = getSelectedNode(e.getDataContext()); - if(selectedNode != null) { - NodeDescriptorImpl descriptor = selectedNode.getDescriptor(); - enable = descriptor instanceof ValueDescriptorImpl && getArrayRenderer((ValueDescriptorImpl)descriptor) != null; + XValueNodeImpl node = XDebuggerTreeActionBase.getSelectedNode(e.getDataContext()); + if (node == null) { + return; + } + XValue container = node.getValueContainer(); + if (container instanceof JavaValue) { + ValueDescriptorImpl descriptor = ((JavaValue)container).getDescriptor(); + enable = getArrayRenderer(descriptor) != null; } e.getPresentation().setVisible(enable); } diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/DebuggerAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/DebuggerAction.java index 86ddfaa5fc08..b369a25e2e09 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/DebuggerAction.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/DebuggerAction.java @@ -22,6 +22,7 @@ package com.intellij.debugger.actions; import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.debugger.engine.JavaDebugProcess; import com.intellij.debugger.impl.DebuggerContextImpl; import com.intellij.debugger.impl.DebuggerStateManager; import com.intellij.debugger.ui.impl.DebuggerTreePanel; @@ -32,6 +33,10 @@ import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.project.Project; import com.intellij.ui.DoubleClickListener; +import com.intellij.xdebugger.XDebugProcess; +import com.intellij.xdebugger.XDebugSession; +import com.intellij.xdebugger.impl.frame.XDebugView; +import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl; import org.jetbrains.annotations.Nullable; import javax.swing.*; @@ -153,4 +158,15 @@ public abstract class DebuggerAction extends AnAction { } }); } + + public static void refreshViews(XValueNodeImpl node) { + final XDebugSession session = XDebugView.getSession(node.getTree()); + if (session != null) { + XDebugProcess process = session.getDebugProcess(); + if (process instanceof JavaDebugProcess) { + ((JavaDebugProcess)process).saveNodeHistory(); + } + session.rebuildViews(); + } + } } diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/ViewAsGroup.java b/java/debugger/impl/src/com/intellij/debugger/actions/ViewAsGroup.java index bd8efab637ac..fd0d8f6785b3 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/ViewAsGroup.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/ViewAsGroup.java @@ -22,13 +22,11 @@ import com.intellij.debugger.impl.DebuggerContextImpl; import com.intellij.debugger.settings.NodeRendererSettings; import com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl; import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl; -import com.intellij.debugger.ui.tree.render.DescriptorLabelListener; import com.intellij.debugger.ui.tree.render.NodeRenderer; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.DumbAware; import com.intellij.xdebugger.frame.XValue; -import com.intellij.xdebugger.frame.XValuePlace; import com.intellij.xdebugger.impl.ui.tree.actions.XDebuggerTreeActionBase; import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl; import org.jetbrains.annotations.NotNull; @@ -66,7 +64,7 @@ public class ViewAsGroup extends ActionGroup implements DumbAware { } XValue container = node.getValueContainer(); if (container instanceof JavaValue) { - if (((ValueDescriptorImpl)((JavaValue)container).getDescriptor()).getLastRenderer() != myNodeRenderer) { + if (((JavaValue)container).getDescriptor().getLastRenderer() != myNodeRenderer) { return false; } } @@ -83,11 +81,12 @@ public class ViewAsGroup extends ActionGroup implements DumbAware { public void threadAction() { XValue container = node.getValueContainer(); if (container instanceof JavaValue) { - final ValueDescriptorImpl valueDescriptor = (ValueDescriptorImpl)((JavaValue)container).getDescriptor(); + final ValueDescriptorImpl valueDescriptor = ((JavaValue)container).getDescriptor(); if (state) { valueDescriptor.setRenderer(myNodeRenderer); - valueDescriptor.updateRepresentation(debuggerContext.createEvaluationContext(), DescriptorLabelListener.DUMMY_LISTENER); - container.computePresentation(node, XValuePlace.TREE); + DebuggerAction.refreshViews(node); + //valueDescriptor.updateRepresentation(debuggerContext.createEvaluationContext(), DescriptorLabelListener.DUMMY_LISTENER); + //container.computePresentation(node, XValuePlace.TREE); } } } diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaDebugProcess.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaDebugProcess.java index 37ee00b94eaf..34b18bbc4da7 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/JavaDebugProcess.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaDebugProcess.java @@ -18,20 +18,18 @@ package com.intellij.debugger.engine; import com.intellij.debugger.DebuggerBundle; import com.intellij.debugger.actions.DebuggerActions; import com.intellij.debugger.engine.evaluation.EvaluationContext; -import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; import com.intellij.debugger.engine.events.DebuggerCommandImpl; import com.intellij.debugger.engine.events.DebuggerContextCommandImpl; import com.intellij.debugger.impl.*; +import com.intellij.debugger.jdi.StackFrameProxyImpl; import com.intellij.debugger.settings.DebuggerSettings; import com.intellij.debugger.ui.DebuggerContentInfo; import com.intellij.debugger.ui.breakpoints.Breakpoint; import com.intellij.debugger.ui.impl.ThreadsPanel; import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl; import com.intellij.debugger.ui.impl.watch.MessageDescriptor; -import com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl; import com.intellij.debugger.ui.impl.watch.NodeManagerImpl; import com.intellij.debugger.ui.tree.NodeDescriptor; -import com.intellij.debugger.ui.tree.render.DescriptorLabelListener; import com.intellij.execution.process.ProcessHandler; import com.intellij.execution.ui.ExecutionConsole; import com.intellij.execution.ui.ExecutionConsoleEx; @@ -150,29 +148,40 @@ public class JavaDebugProcess extends XDebugProcess { }; session.addSessionListener(new XDebugSessionAdapter() { @Override - public void beforeSessionResume() { - myJavaSession.getProcess().getManagerThread().schedule(new DebuggerCommandImpl() { - @Override - protected void action() throws Exception { - myNodeManager.setHistoryByContext(getDebuggerStateManager().getContext()); - } - @Override - public Priority getPriority() { - return Priority.NORMAL; - } - }); + public void sessionPaused() { + saveNodeHistory(); } @Override public void stackFrameChanged() { XStackFrame frame = session.getCurrentStackFrame(); if (frame instanceof JavaStackFrame) { - DebuggerContextUtil.setStackFrame(javaSession.getContextManager(), ((JavaStackFrame)frame).getStackFrameProxy()); + StackFrameProxyImpl frameProxy = ((JavaStackFrame)frame).getStackFrameProxy(); + DebuggerContextUtil.setStackFrame(javaSession.getContextManager(), frameProxy); + saveNodeHistory(frameProxy); } } }); } + public void saveNodeHistory() { + saveNodeHistory(getDebuggerStateManager().getContext().getFrameProxy()); + } + + private void saveNodeHistory(final StackFrameProxyImpl frameProxy) { + myJavaSession.getProcess().getManagerThread().invoke(new DebuggerCommandImpl() { + @Override + protected void action() throws Exception { + myNodeManager.setHistoryByContext(frameProxy); + } + + @Override + public Priority getPriority() { + return Priority.NORMAL; + } + }); + } + private DebuggerStateManager getDebuggerStateManager() { return myJavaSession.getContextManager(); } diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java index fd3a15bd8943..85957cb2120a 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java @@ -103,6 +103,7 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider, XV } @Override + @NotNull public ValueDescriptorImpl getDescriptor() { return myValueDescriptor; } diff --git a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerSession.java b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerSession.java index 0a5210f16c36..2c515f2302a9 100644 --- a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerSession.java +++ b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerSession.java @@ -199,6 +199,7 @@ public class DebuggerSession implements AbstractDebuggerSession { ValueLookupManager.getInstance(getProject()).startListening(); } + @NotNull public DebuggerStateManager getContextManager() { return myContextManager; } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/NodeDescriptorFactoryImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/NodeDescriptorFactoryImpl.java index 3455672fa4dc..0a94548338d4 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/NodeDescriptorFactoryImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/NodeDescriptorFactoryImpl.java @@ -93,6 +93,10 @@ public class NodeDescriptorFactoryImpl implements NodeDescriptorFactory { } public void deriveHistoryTree(DescriptorTree tree, final StackFrameContext context) { + deriveHistoryTree(tree, context.getFrameProxy()); + } + + public void deriveHistoryTree(DescriptorTree tree, final StackFrameProxy frameProxy) { final MarkedDescriptorTree descriptorTree = new MarkedDescriptorTree(); final MarkedDescriptorTree displayDescriptorTree = new MarkedDescriptorTree(); @@ -109,13 +113,12 @@ public class NodeDescriptorFactoryImpl implements NodeDescriptorFactory { myDescriptorSearcher = new DescriptorTreeSearcher(descriptorTree); myDisplayDescriptorSearcher = new DisplayDescriptorTreeSearcher(displayDescriptorTree); - myCurrentHistoryTree = createDescriptorTree(context, tree); + myCurrentHistoryTree = createDescriptorTree(frameProxy, tree); } - private static DescriptorTree createDescriptorTree(final StackFrameContext context, final DescriptorTree fromTree) { + private static DescriptorTree createDescriptorTree(final StackFrameProxy frameProxy, final DescriptorTree fromTree) { int frameCount = -1; int frameIndex = -1; - final StackFrameProxy frameProxy = context.getFrameProxy(); if (frameProxy != null) { try { final ThreadReferenceProxy threadReferenceProxy = frameProxy.threadProxy(); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/NodeManagerImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/NodeManagerImpl.java index 53e820da02fd..b76022122594 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/NodeManagerImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/NodeManagerImpl.java @@ -75,11 +75,15 @@ public class NodeManagerImpl extends NodeDescriptorFactoryImpl implements NodeMa } public void setHistoryByContext(final DebuggerContextImpl context) { + setHistoryByContext(context.getFrameProxy()); + } + + public void setHistoryByContext(StackFrameProxyImpl frameProxy) { if (myHistoryKey != null) { myHistories.put(myHistoryKey, getCurrentHistoryTree()); } - final String historyKey = getContextKey(context.getFrameProxy()); + final String historyKey = getContextKey(frameProxy); final DescriptorTree descriptorTree; if (historyKey != null) { final DescriptorTree historyTree = myHistories.get(historyKey); @@ -89,7 +93,7 @@ public class NodeManagerImpl extends NodeDescriptorFactoryImpl implements NodeMa descriptorTree = new DescriptorTree(true); } - deriveHistoryTree(descriptorTree, context); + deriveHistoryTree(descriptorTree, frameProxy); myHistoryKey = historyKey; } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ArrayRenderer.java b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ArrayRenderer.java index 9615aae98233..f7f05fcc496f 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ArrayRenderer.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ArrayRenderer.java @@ -65,6 +65,8 @@ public class ArrayRenderer extends NodeRendererImpl{ public int ENTRIES_LIMIT = 101; private final static String MORE_ELEMENTS = "..."; + private boolean myForced = false; + public ArrayRenderer() { myProperties.setEnabled(true); } @@ -97,13 +99,19 @@ public class ArrayRenderer extends NodeRendererImpl{ return ClassRenderer.calcLabel(descriptor); } + public void setForced(boolean forced) { + myForced = forced; + } + public void buildChildren(Value value, ChildrenBuilder builder, EvaluationContext evaluationContext) { DebuggerManagerThreadImpl.assertIsManagerThread(); List children = new ArrayList(); NodeManagerImpl nodeManager = (NodeManagerImpl)builder.getNodeManager(); NodeDescriptorFactory descriptorFactory = builder.getDescriptorManager(); - builder.initChildrenArrayRenderer(this); + if (!myForced) { + builder.initChildrenArrayRenderer(this); + } ArrayReference array = (ArrayReference)value; if (array.length() > 0) { @@ -182,7 +190,7 @@ public class ArrayRenderer extends NodeRendererImpl{ // children.add(0, nodeManager.createMessageNode(new MessageDescriptor(MORE_ELEMENTS, MessageDescriptor.SPECIAL))); //} - if(END_INDEX < array.length() - 1) { + if(!myForced && END_INDEX < array.length() - 1) { //children.add(nodeManager.createMessageNode(new MessageDescriptor(MORE_ELEMENTS, MessageDescriptor.SPECIAL))); builder.setRemaining(array.length()-END_INDEX); } diff --git a/resources/src/idea/JavaActions.xml b/resources/src/idea/JavaActions.xml index 81a791f42208..31f6d9ad84f4 100644 --- a/resources/src/idea/JavaActions.xml +++ b/resources/src/idea/JavaActions.xml @@ -153,7 +153,6 @@ - @@ -178,6 +177,9 @@ + + + From fa8f5fe61d03c2ab626313fafb8d846cc4e0ca5e Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Thu, 4 Sep 2014 15:01:09 +0400 Subject: [PATCH 51/60] lock free way to get active editor (work in progress) --- .../openapi/fileEditor/impl/FileEditorManagerImpl.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java index f0d5c8df807c..483571f786cb 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java @@ -1154,9 +1154,13 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec @Override public Editor getSelectedTextEditor() { - assertReadAccess(); + return getSelectedTextEditor(false); + } - final EditorWindow currentWindow = getSplitters().getCurrentWindow(); + public Editor getSelectedTextEditor(boolean lockfree) { + assertDispatchThread(); + + final EditorWindow currentWindow = lockfree ? getMainSplitters().getCurrentWindow() : getSplitters().getCurrentWindow(); if (currentWindow != null) { final EditorWithProviderComposite selectedEditor = currentWindow.getSelectedEditor(); if (selectedEditor != null && selectedEditor.getSelectedEditor() instanceof TextEditor) { @@ -1168,6 +1172,7 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec } + @Override public boolean isFileOpen(@NotNull final VirtualFile file) { return !getEditorComposites(file).isEmpty(); From db08dbc429dbec3c3268c0bb3de8008d4aafedec Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Thu, 4 Sep 2014 15:01:28 +0400 Subject: [PATCH 52/60] fix deadlock --- .../com/intellij/debugger/impl/DebuggerContextUtil.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerContextUtil.java b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerContextUtil.java index 8408364f7e73..f36c9f14cee6 100644 --- a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerContextUtil.java +++ b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerContextUtil.java @@ -23,11 +23,12 @@ import com.intellij.debugger.jdi.StackFrameProxyImpl; import com.intellij.debugger.ui.impl.watch.ThreadDescriptorImpl; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.impl.FileEditorManagerImpl; import com.intellij.openapi.util.Couple; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; -import com.intellij.psi.util.PsiUtilBase; import com.intellij.xdebugger.XDebugSession; import com.intellij.xdebugger.XSourcePosition; import org.jetbrains.annotations.NotNull; @@ -75,7 +76,9 @@ public class DebuggerContextUtil { final XDebugSession debugSession = session.getXDebugSession(); if (debugSession != null) { final XSourcePosition position = debugSession.getCurrentPosition(); - final Editor editor = PsiUtilBase.findEditor(psi); + Editor editor = ((FileEditorManagerImpl)FileEditorManager.getInstance(file.getProject())).getSelectedTextEditor(true); + + //final Editor editor = fileEditor instanceof TextEditorImpl ? ((TextEditorImpl)fileEditor).getEditor() : null; if (editor != null && position != null && file.getVirtualFile().equals(position.getFile())) { final Couple> usages = IdentifierHighlighterPass.getHighlightUsages(psi, file); final List ranges = new ArrayList(); From f35847c96252db1ed0ee65065f716553e8529f46 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Thu, 4 Sep 2014 14:22:17 +0400 Subject: [PATCH 53/60] support for disjunction types in create from usage intentions (IDEA-129453) --- .../ChangeMethodSignatureFromUsageFix.java | 1 + .../src/com/intellij/psi/GenericsUtil.java | 3 +++ .../afterDisjunctionType.java | 15 +++++++++++++++ .../beforeDisjunctionType.java | 15 +++++++++++++++ 4 files changed, 34 insertions(+) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeMethodSignatureFromUsage8/afterDisjunctionType.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeMethodSignatureFromUsage8/beforeDisjunctionType.java diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeMethodSignatureFromUsageFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeMethodSignatureFromUsageFix.java index dbf454207cca..d85fb72894d7 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeMethodSignatureFromUsageFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeMethodSignatureFromUsageFix.java @@ -403,6 +403,7 @@ public class ChangeMethodSignatureFromUsageFix implements IntentionAction/*, Hig if (varargParam != null && pi >= parameters.length) return false; PsiType exprType = RefactoringUtil.getTypeByExpression(expression); if (exprType == null) return false; + exprType = GenericsUtil.getVariableTypeByExpressionType(exprType); JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(expression.getProject()); String name = suggestUniqueParameterName(codeStyleManager, expression, exprType, existingNames); final ParameterInfoImpl newParameterInfo = new ParameterInfoImpl(-1, name, exprType, expression.getText().replace('\n', ' ')); diff --git a/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java b/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java index 4646aea635b3..163055f442fa 100644 --- a/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java @@ -351,6 +351,9 @@ public class GenericsUtil { @Nullable public static PsiType getVariableTypeByExpressionType(@Nullable PsiType type, final boolean openCaptured) { if (type == null) return null; + if (type instanceof PsiDisjunctionType) { + type = ((PsiDisjunctionType)type).getLeastUpperBound(); + } if (type instanceof PsiCapturedWildcardType) { type = ((PsiCapturedWildcardType)type).getWildcard(); } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeMethodSignatureFromUsage8/afterDisjunctionType.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeMethodSignatureFromUsage8/afterDisjunctionType.java new file mode 100644 index 000000000000..7835cfb40ae9 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeMethodSignatureFromUsage8/afterDisjunctionType.java @@ -0,0 +1,15 @@ +// "Add 'Exception' as 1st parameter to method 'f'" "true" +import java.io.FileInputStream; +import java.io.IOException; + +class Test { + public void createFileInputStream() { + try { + new FileInputStream("test"); + } catch (IOException |NullPointerException e) { + f(e); + } + } + + public void f(Exception e) { } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeMethodSignatureFromUsage8/beforeDisjunctionType.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeMethodSignatureFromUsage8/beforeDisjunctionType.java new file mode 100644 index 000000000000..ab28d7484f4d --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeMethodSignatureFromUsage8/beforeDisjunctionType.java @@ -0,0 +1,15 @@ +// "Add 'Exception' as 1st parameter to method 'f'" "true" +import java.io.FileInputStream; +import java.io.IOException; + +class Test { + public void createFileInputStream() { + try { + new FileInputStream("test"); + } catch (IOException |NullPointerException e) { + f(e); + } + } + + public void f() { } +} From 17b77be48b13d230357332f9e7665c4eed0e9020 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Thu, 4 Sep 2014 14:56:13 +0400 Subject: [PATCH 54/60] do not generate captured wildcard from unbound captured wildcard with same context --- .../src/com/intellij/psi/impl/PsiSubstitutorImpl.java | 2 +- .../CaptureWildcardFromUnboundCaptureWildcard.java | 9 +++++++++ .../codeInsight/daemon/GenericsHighlightingTest.java | 1 + 3 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/CaptureWildcardFromUnboundCaptureWildcard.java diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java index 9c9525aef859..d53bb2e26820 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java @@ -389,7 +389,7 @@ public class PsiSubstitutorImpl implements PsiSubstitutor { } else { //unbounded - substituted = PsiWildcardType.createExtends(manager, substitutedBoundType); + substituted = substitutedBoundType instanceof PsiCapturedWildcardType ? ((PsiCapturedWildcardType)substitutedBoundType).getWildcard() : PsiWildcardType.createExtends(manager, substitutedBoundType); } } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/CaptureWildcardFromUnboundCaptureWildcard.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/CaptureWildcardFromUnboundCaptureWildcard.java new file mode 100644 index 000000000000..0abec87dc335 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/CaptureWildcardFromUnboundCaptureWildcard.java @@ -0,0 +1,9 @@ +class Test & Runnable> {} + +interface Supplier { + K get(); +} + +interface Getter extends Supplier { + public S get(); +} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java index 09225b64bc1d..54685fb23c3c 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java @@ -372,6 +372,7 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase { public void testIDEA126633() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); } public void testIDEA124363() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); } public void testIDEA78402() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); } + public void testCaptureWildcardFromUnboundCaptureWildcard() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); } public void testSuperCaptureSubstitutionWhenTypeParameterHasUpperBounds() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); } public void testParameterBoundsWithCapturedWildcard() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); } //jdk should propagate LL 1.4 but actually it provides LL 1.7?! From 8e353cebff5dde0fc30e09fee0ecc1f845f87956 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Thu, 4 Sep 2014 15:03:01 +0400 Subject: [PATCH 55/60] testdata for IDEA-106985 --- .../genericsHighlighting/IDEA106985.java | 15 +++++++++++++++ .../IncompatibleBoundsFromAssignment.java | 15 +++++++++++++++ .../daemon/GenericsHighlightingTest.java | 1 + .../lambda/GraphInferenceHighlightingTest.java | 4 ++++ .../daemon/lambda/NewLambdaHighlightingTest.java | 11 ++++++++++- 5 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA106985.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/IncompatibleBoundsFromAssignment.java diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA106985.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA106985.java new file mode 100644 index 000000000000..b11bfa46632c --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA106985.java @@ -0,0 +1,15 @@ + +import java.util.Map; + +class Test { + + public static void main(String[] args) { + Map map = make(); + } + + + public static Map make() { + return null; + } + +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/IncompatibleBoundsFromAssignment.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/IncompatibleBoundsFromAssignment.java new file mode 100644 index 000000000000..d5b8b03050d5 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/IncompatibleBoundsFromAssignment.java @@ -0,0 +1,15 @@ +import java.util.Map; + +class Test { + + public static void main(String[] args) { + Map b = newMapTrie(); + Map> c = newMapTrie(); + Map>> d = newMapTrie(); + Map>>> e = newMapTrie(); + } + + public static > T newMapTrie() { + return null; + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java index 54685fb23c3c..0a93d8f7f193 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java @@ -372,6 +372,7 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase { public void testIDEA126633() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); } public void testIDEA124363() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); } public void testIDEA78402() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); } + public void testIDEA106985() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); } public void testCaptureWildcardFromUnboundCaptureWildcard() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); } public void testSuperCaptureSubstitutionWhenTypeParameterHasUpperBounds() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); } public void testParameterBoundsWithCapturedWildcard() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java index e6e4534b6560..9ec2d29b71e3 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java @@ -236,6 +236,10 @@ public class GraphInferenceHighlightingTest extends LightDaemonAnalyzerTestCase doTest(); } + public void testIncompatibleBoundsFromAssignment() throws Exception { + doTest(); + } + private void doTest() throws Exception { doTest(false); } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java index 1b56554333b0..712df26e356f 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java @@ -22,6 +22,8 @@ import com.intellij.idea.Bombed; import com.intellij.openapi.projectRoots.JavaSdkVersion; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.testFramework.IdeaTestUtil; +import junit.framework.Test; +import junit.framework.TestSuite; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -107,7 +109,6 @@ public class NewLambdaHighlightingTest extends LightDaemonAnalyzerTestCase { doTest(); } - @Bombed(day = 30, month = Calendar.SEPTEMBER) public void testIDEA124983() throws Exception { doTest(); } @@ -145,4 +146,12 @@ public class NewLambdaHighlightingTest extends LightDaemonAnalyzerTestCase { protected Sdk getProjectJDK() { return IdeaTestUtil.getMockJdk18(); } +/* + public static Test suite() { + final TestSuite suite = new TestSuite(); + for (int i = 0; i < 100; i++) { + suite.addTestSuite(NewLambdaHighlightingTest.class); + } + return suite; + }*/ } From 01db84e63a193082322ab7b9615477ad995e2a6b Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Thu, 4 Sep 2014 15:12:00 +0400 Subject: [PATCH 56/60] testdata fix after moreSpecific change --- .../com/siyeh/ipp/types/lambda2anonymous/Ambiguity.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/lambda2anonymous/Ambiguity.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/lambda2anonymous/Ambiguity.java index 6df5c30ae69a..e8be7a9d0b0c 100644 --- a/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/lambda2anonymous/Ambiguity.java +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/lambda2anonymous/Ambiguity.java @@ -2,14 +2,14 @@ interface I1 { void m(); } -interface I2 { - X m(); +interface I2 { + void m(); } class Ambiguity1 { static void m(I1 i1) {} - static void m(I2 i2) {} + static void m(I2 i2) {} { m(()->{throw new AssertionError();}); From f63a8d740c12e891b5d2ce09de988dd654ec4076 Mon Sep 17 00:00:00 2001 From: nik Date: Thu, 4 Sep 2014 15:14:27 +0400 Subject: [PATCH 57/60] PathManager: unnecessary 'toCanonicalPath' removed --- .../util/src/com/intellij/openapi/application/PathManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/util/src/com/intellij/openapi/application/PathManager.java b/platform/util/src/com/intellij/openapi/application/PathManager.java index 9956959f0e22..852f00cb7a68 100644 --- a/platform/util/src/com/intellij/openapi/application/PathManager.java +++ b/platform/util/src/com/intellij/openapi/application/PathManager.java @@ -418,7 +418,7 @@ public class PathManager { private static String getAbsolutePath(String path) { path = FileUtil.expandUserHome(path); - return FileUtil.toCanonicalPath(new File(FileUtil.toCanonicalPath(path)).getAbsolutePath()); + return FileUtil.toCanonicalPath(new File(path).getAbsolutePath()); } private static String trimPathQuotes(String path){ From c2c3599029e7462257463f7938ad71283fffdbb1 Mon Sep 17 00:00:00 2001 From: Dennis Ushakov Date: Thu, 4 Sep 2014 15:36:15 +0400 Subject: [PATCH 58/60] set User-Agent to keep some CDN's happy #WEB-13155 fixed --- .../com/intellij/platform/templates/github/DownloadUtil.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/platform/templates/github/DownloadUtil.java b/platform/lang-impl/src/com/intellij/platform/templates/github/DownloadUtil.java index bbffc7c98ba4..02ddd0b64608 100644 --- a/platform/lang-impl/src/com/intellij/platform/templates/github/DownloadUtil.java +++ b/platform/lang-impl/src/com/intellij/platform/templates/github/DownloadUtil.java @@ -1,5 +1,6 @@ package com.intellij.platform.templates.github; +import com.intellij.openapi.application.ex.ApplicationInfoEx; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; @@ -19,7 +20,6 @@ import java.net.HttpURLConnection; import java.net.URLConnection; import java.util.Locale; import java.util.concurrent.Callable; -import java.util.concurrent.TimeUnit; /** * @author Sergey Simonchik @@ -176,6 +176,7 @@ public class DownloadUtil { URLConnection urlConnection = HttpConfigurable.getInstance().openConnection(location); HttpURLConnection httpURLConnection = ObjectUtils.tryCast(urlConnection, HttpURLConnection.class); try { + urlConnection.setRequestProperty("User-Agent", ApplicationInfoEx.getInstanceEx().getFullApplicationName()); urlConnection.connect(); InputStream in = urlConnection.getInputStream(); int contentLength = urlConnection.getContentLength(); From 2708e484a36621959e5908bbb6dae1f1b86d38e4 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Thu, 4 Sep 2014 15:44:35 +0400 Subject: [PATCH 59/60] make ui editor consistent with general editor settings --- .../designSurface/GridCaptionPanel.java | 20 +++++++++++++++++-- .../uiDesigner/designSurface/GuiEditor.java | 15 ++++++++++---- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/designSurface/GridCaptionPanel.java b/plugins/ui-designer/src/com/intellij/uiDesigner/designSurface/GridCaptionPanel.java index 77d3104abccc..99a982f5acd3 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/designSurface/GridCaptionPanel.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/designSurface/GridCaptionPanel.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. @@ -20,7 +20,10 @@ import com.intellij.ide.DeleteProvider; import com.intellij.ide.dnd.*; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.colors.EditorColors; +import com.intellij.openapi.editor.colors.EditorColorsManager; import com.intellij.openapi.util.Pair; +import com.intellij.ui.JBColor; import com.intellij.ui.LightColors; import com.intellij.uiDesigner.CaptionSelection; import com.intellij.uiDesigner.FormEditingUtil; @@ -33,7 +36,9 @@ import com.intellij.uiDesigner.radComponents.RadContainer; import com.intellij.uiDesigner.radComponents.RadRootContainer; import com.intellij.util.Alarm; import com.intellij.util.ArrayUtil; +import com.intellij.util.NotNullProducer; import com.intellij.util.ui.PlatformColors; +import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -72,7 +77,7 @@ public class GridCaptionPanel extends JPanel implements ComponentSelectionListen myEditor.fireSelectedComponentChanged(); } }); - setBackground(Color.LIGHT_GRAY); + setBackground(getGutterColor()); editor.addComponentSelectionListener(this); final MyMouseListener listener = new MyMouseListener(); @@ -101,6 +106,17 @@ public class GridCaptionPanel extends JPanel implements ComponentSelectionListen }); } + public static JBColor getGutterColor() { + return new JBColor(new NotNullProducer() { + @NotNull + @Override + public Color produce() { + Color color = EditorColorsManager.getInstance().getGlobalScheme().getColor(EditorColors.GUTTER_BACKGROUND); + return color == null ? UIUtil.getPanelBackground() : color; + } + }); + } + public RadContainer getSelectedContainer() { // when the selected component changes, and we have focus, PropertyInspector asks us about our container and selection. // PropertyInspector's selection changed listener can be called before our own listener, so we need to update ourselves diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/designSurface/GuiEditor.java b/plugins/ui-designer/src/com/intellij/uiDesigner/designSurface/GuiEditor.java index dbbc27655f4e..96969998edf4 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/designSurface/GuiEditor.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/designSurface/GuiEditor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 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. @@ -27,6 +27,7 @@ import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.command.undo.UndoManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.colors.EditorColorsManager; import com.intellij.openapi.editor.event.DocumentAdapter; import com.intellij.openapi.editor.event.DocumentEvent; import com.intellij.openapi.fileEditor.FileDocumentManager; @@ -61,7 +62,7 @@ import com.intellij.uiDesigner.radComponents.RadContainer; import com.intellij.uiDesigner.radComponents.RadRootContainer; import com.intellij.uiDesigner.radComponents.RadTabbedPane; import com.intellij.util.Alarm; -import com.intellij.util.ui.UIUtil; +import com.intellij.util.NotNullProducer; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -288,7 +289,7 @@ public final class GuiEditor extends JPanel implements DataProvider, ModuleProvi readFromFile(false); JPanel panel = new JPanel(new GridBagLayout()); - panel.setBackground(Color.LIGHT_GRAY); + panel.setBackground(GridCaptionPanel.getGutterColor()); myHorzCaptionPanel = new GridCaptionPanel(this, false); myVertCaptionPanel = new GridCaptionPanel(this, true); @@ -311,7 +312,13 @@ public final class GuiEditor extends JPanel implements DataProvider, ModuleProvi gbc.weighty = 1.0; myScrollPane = ScrollPaneFactory.createScrollPane(myLayeredPane); - myScrollPane.setBackground(new JBColor(Color.WHITE, UIUtil.getListBackground())); + myScrollPane.setBackground(new JBColor(new NotNullProducer() { + @NotNull + @Override + public Color produce() { + return EditorColorsManager.getInstance().getGlobalScheme().getDefaultBackground(); + } + })); panel.add(myScrollPane, gbc); myHorzCaptionPanel.attachToScrollPane(myScrollPane); myVertCaptionPanel.attachToScrollPane(myScrollPane); From 79d6ebbfc52d564a6adff5a368b44c10cfa2d441 Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Thu, 4 Sep 2014 15:59:37 +0400 Subject: [PATCH 60/60] IDEA-108491: add workaround for merge application --- platform/platform-resources/src/launcher.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/platform/platform-resources/src/launcher.py b/platform/platform-resources/src/launcher.py index 0a679eec98fe..f04a26cb2c83 100644 --- a/platform/platform-resources/src/launcher.py +++ b/platform/platform-resources/src/launcher.py @@ -18,10 +18,13 @@ for i, arg in enumerate(sys.argv[1:]): print(('Usage:\n' + \ ' {0} -h |-? | --help\n' + \ ' {0} [-l|--line line] file[:line]\n' + \ - ' {0} diff file1 file2').format(sys.argv[0])) + ' {0} diff \n' + \ + ' {0} merge [base] ').format(sys.argv[0])) exit(0) elif arg == 'diff' and i == 0: args.append(arg) + elif arg == 'merge' and i == 0: + args.append(arg) elif arg == '-l' or arg == '--line': args.append(arg) skip_next = True @@ -96,4 +99,4 @@ else: # unix common bin_dir, bin_file = os.path.split(RUN_PATH) os.chdir(bin_dir) - os.execv(bin_file, [bin_file] + args) + os.execv(bin_file, [bin_file] + args) \ No newline at end of file