diff --git a/.idea/libraries/gson.xml b/.idea/libraries/gson.xml index 38af989a0d75..71942d6c4994 100644 --- a/.idea/libraries/gson.xml +++ b/.idea/libraries/gson.xml @@ -1,11 +1,11 @@ - + - + \ No newline at end of file diff --git a/RegExpSupport/gen/org/intellij/lang/regexp/_RegExLexer.java b/RegExpSupport/gen/org/intellij/lang/regexp/_RegExLexer.java index 531087761da2..cc1fd353a327 100644 --- a/RegExpSupport/gen/org/intellij/lang/regexp/_RegExLexer.java +++ b/RegExpSupport/gen/org/intellij/lang/regexp/_RegExLexer.java @@ -1,4 +1,4 @@ -/* The following code was generated by JFlex 1.4.3 on 10/24/14 4:28 PM */ +/* The following code was generated by JFlex 1.4.3 on 10/28/14 3:07 PM */ /* It's an automatically generated code. Do not modify it. */ package org.intellij.lang.regexp; @@ -15,7 +15,7 @@ import java.util.EnumSet; /** * This class is a scanner generated by * JFlex 1.4.3 - * on 10/24/14 4:28 PM from the specification file + * on 10/28/14 3:07 PM from the specification file * /Users/bas/Projects/IntelliJ IDEA Ultimate/tools/lexer/../../community/RegExpSupport/src/org/intellij/lang/regexp/regexp-lexer.flex */ class _RegExLexer implements FlexLexer { @@ -62,84 +62,64 @@ class _RegExLexer implements FlexLexer { "\1\46\1\34\4\47\1\22\1\47\1\35\1\47\1\22\1\27\1\22"+ "\1\43\1\27\1\27\1\42\1\47\1\25\1\6\1\21\1\7\54\0"+ "\1\47\12\0\1\47\4\0\1\47\5\0\27\47\1\0\37\47\1\0"+ - "\u01ca\47\4\0\14\47\16\0\5\47\7\0\1\47\1\0\1\47\201\0"+ - "\5\47\1\0\2\47\2\0\4\47\10\0\1\47\1\0\3\47\1\0"+ - "\1\47\1\0\24\47\1\0\123\47\1\0\213\47\10\0\236\47\11\0"+ - "\46\47\2\0\1\47\7\0\47\47\110\0\33\47\5\0\3\47\55\0"+ - "\53\47\25\0\12\53\4\0\2\47\1\0\143\47\1\0\1\47\17\0"+ - "\2\47\7\0\2\47\12\53\3\47\2\0\1\47\20\0\1\47\1\0"+ - "\36\47\35\0\131\47\13\0\1\47\16\0\12\53\41\47\11\0\2\47"+ - "\4\0\1\47\5\0\26\47\4\0\1\47\11\0\1\47\3\0\1\47"+ - "\27\0\31\47\107\0\1\47\1\0\13\47\127\0\66\47\3\0\1\47"+ - "\22\0\1\47\7\0\12\47\4\0\12\53\1\0\7\47\1\0\7\47"+ - "\5\0\10\47\2\0\2\47\2\0\26\47\1\0\7\47\1\0\1\47"+ - "\3\0\4\47\3\0\1\47\20\0\1\47\15\0\2\47\1\0\3\47"+ - "\4\0\12\53\2\47\23\0\6\47\4\0\2\47\2\0\26\47\1\0"+ - "\7\47\1\0\2\47\1\0\2\47\1\0\2\47\37\0\4\47\1\0"+ - "\1\47\7\0\12\53\2\0\3\47\20\0\11\47\1\0\3\47\1\0"+ - "\26\47\1\0\7\47\1\0\2\47\1\0\5\47\3\0\1\47\22\0"+ - "\1\47\17\0\2\47\4\0\12\53\25\0\10\47\2\0\2\47\2\0"+ - "\26\47\1\0\7\47\1\0\2\47\1\0\5\47\3\0\1\47\36\0"+ - "\2\47\1\0\3\47\4\0\12\53\1\0\1\47\21\0\1\47\1\0"+ - "\6\47\3\0\3\47\1\0\4\47\3\0\2\47\1\0\1\47\1\0"+ - "\2\47\3\0\2\47\3\0\3\47\3\0\14\47\26\0\1\47\25\0"+ - "\12\53\25\0\10\47\1\0\3\47\1\0\27\47\1\0\12\47\1\0"+ - "\5\47\3\0\1\47\32\0\2\47\6\0\2\47\4\0\12\53\25\0"+ - "\10\47\1\0\3\47\1\0\27\47\1\0\12\47\1\0\5\47\3\0"+ - "\1\47\40\0\1\47\1\0\2\47\4\0\12\53\1\0\2\47\22\0"+ - "\10\47\1\0\3\47\1\0\51\47\2\0\1\47\20\0\1\47\21\0"+ - "\2\47\4\0\12\53\12\0\6\47\5\0\22\47\3\0\30\47\1\0"+ - "\11\47\1\0\1\47\2\0\7\47\72\0\60\47\1\0\2\47\14\0"+ - "\7\47\11\0\12\53\47\0\2\47\1\0\1\47\2\0\2\47\1\0"+ - "\1\47\2\0\1\47\6\0\4\47\1\0\7\47\1\0\3\47\1\0"+ - "\1\47\1\0\1\47\2\0\2\47\1\0\4\47\1\0\2\47\11\0"+ - "\1\47\2\0\5\47\1\0\1\47\11\0\12\53\2\0\4\47\40\0"+ - "\1\47\37\0\12\53\26\0\10\47\1\0\44\47\33\0\5\47\163\0"+ - "\53\47\24\0\1\47\12\53\6\0\6\47\4\0\4\47\3\0\1\47"+ - "\3\0\2\47\7\0\3\47\4\0\15\47\14\0\1\47\1\0\12\53"+ - "\6\0\46\47\1\0\1\47\5\0\1\47\2\0\53\47\1\0\u014d\47"+ - "\1\0\4\47\2\0\7\47\1\0\1\47\1\0\4\47\2\0\51\47"+ - "\1\0\4\47\2\0\41\47\1\0\4\47\2\0\7\47\1\0\1\47"+ - "\1\0\4\47\2\0\17\47\1\0\71\47\1\0\4\47\2\0\103\47"+ - "\45\0\20\47\20\0\125\47\14\0\u026c\47\2\0\21\47\1\0\32\47"+ - "\5\0\113\47\25\0\15\47\1\0\4\47\16\0\22\47\16\0\22\47"+ - "\16\0\15\47\1\0\3\47\17\0\64\47\43\0\1\47\4\0\1\47"+ - "\3\0\12\53\46\0\12\53\6\0\130\47\10\0\51\47\1\0\1\47"+ - "\5\0\106\47\12\0\35\47\51\0\12\53\36\47\2\0\5\47\13\0"+ - "\54\47\25\0\7\47\10\0\12\53\46\0\27\47\11\0\65\47\53\0"+ - "\12\53\6\0\12\53\15\0\1\47\135\0\57\47\21\0\7\47\4\0"+ - "\12\53\51\0\36\47\15\0\2\47\12\53\54\47\32\0\44\47\34\0"+ - "\12\53\3\0\3\47\12\53\44\47\153\0\4\47\1\0\4\47\3\0"+ - "\2\47\11\0\300\47\100\0\u0116\47\2\0\6\47\2\0\46\47\2\0"+ + "\u013f\47\31\0\162\47\4\0\14\47\16\0\5\47\11\0\1\47\213\0"+ + "\1\47\13\0\1\47\1\0\3\47\1\0\1\47\1\0\24\47\1\0"+ + "\54\47\1\0\46\47\1\0\5\47\4\0\202\47\10\0\105\47\1\0"+ + "\46\47\2\0\2\47\6\0\20\47\41\0\46\47\2\0\1\47\7\0"+ + "\47\47\110\0\33\47\5\0\3\47\56\0\32\47\5\0\13\47\25\0"+ + "\12\53\4\0\2\47\1\0\143\47\1\0\1\47\17\0\2\47\7\0"+ + "\2\47\12\53\3\47\2\0\1\47\20\0\1\47\1\0\36\47\35\0"+ + "\3\47\60\0\46\47\13\0\1\47\u0152\0\66\47\3\0\1\47\22\0"+ + "\1\47\7\0\12\47\4\0\12\53\25\0\10\47\2\0\2\47\2\0"+ + "\26\47\1\0\7\47\1\0\1\47\3\0\4\47\3\0\1\47\36\0"+ + "\2\47\1\0\3\47\4\0\12\53\2\47\23\0\6\47\4\0\2\47"+ + "\2\0\26\47\1\0\7\47\1\0\2\47\1\0\2\47\1\0\2\47"+ + "\37\0\4\47\1\0\1\47\7\0\12\53\2\0\3\47\20\0\11\47"+ + "\1\0\3\47\1\0\26\47\1\0\7\47\1\0\2\47\1\0\5\47"+ + "\3\0\1\47\22\0\1\47\17\0\2\47\4\0\12\53\25\0\10\47"+ + "\2\0\2\47\2\0\26\47\1\0\7\47\1\0\2\47\1\0\5\47"+ + "\3\0\1\47\36\0\2\47\1\0\3\47\4\0\12\53\1\0\1\47"+ + "\21\0\1\47\1\0\6\47\3\0\3\47\1\0\4\47\3\0\2\47"+ + "\1\0\1\47\1\0\2\47\3\0\2\47\3\0\3\47\3\0\10\47"+ + "\1\0\3\47\55\0\11\53\25\0\10\47\1\0\3\47\1\0\27\47"+ + "\1\0\12\47\1\0\5\47\46\0\2\47\4\0\12\53\25\0\10\47"+ + "\1\0\3\47\1\0\27\47\1\0\12\47\1\0\5\47\3\0\1\47"+ + "\40\0\1\47\1\0\2\47\4\0\12\53\25\0\10\47\1\0\3\47"+ + "\1\0\27\47\1\0\20\47\46\0\2\47\4\0\12\53\25\0\22\47"+ + "\3\0\30\47\1\0\11\47\1\0\1\47\2\0\7\47\72\0\60\47"+ + "\1\0\2\47\14\0\7\47\11\0\12\53\47\0\2\47\1\0\1\47"+ + "\2\0\2\47\1\0\1\47\2\0\1\47\6\0\4\47\1\0\7\47"+ + "\1\0\3\47\1\0\1\47\1\0\1\47\2\0\2\47\1\0\4\47"+ + "\1\0\2\47\11\0\1\47\2\0\5\47\1\0\1\47\11\0\12\53"+ + "\2\0\2\47\42\0\1\47\37\0\12\53\26\0\10\47\1\0\42\47"+ + "\35\0\4\47\164\0\42\47\1\0\5\47\1\0\2\47\25\0\12\53"+ + "\6\0\6\47\112\0\46\47\12\0\51\47\7\0\132\47\5\0\104\47"+ + "\5\0\122\47\6\0\7\47\1\0\77\47\1\0\1\47\1\0\4\47"+ + "\2\0\7\47\1\0\1\47\1\0\4\47\2\0\47\47\1\0\1\47"+ + "\1\0\4\47\2\0\37\47\1\0\1\47\1\0\4\47\2\0\7\47"+ + "\1\0\1\47\1\0\4\47\2\0\7\47\1\0\7\47\1\0\27\47"+ + "\1\0\37\47\1\0\1\47\1\0\4\47\2\0\7\47\1\0\47\47"+ + "\1\0\23\47\16\0\11\53\56\0\125\47\14\0\u026c\47\2\0\10\47"+ + "\12\0\32\47\5\0\113\47\25\0\15\47\1\0\4\47\16\0\22\47"+ + "\16\0\22\47\16\0\15\47\1\0\3\47\17\0\64\47\43\0\1\47"+ + "\4\0\1\47\3\0\12\53\46\0\12\53\6\0\130\47\10\0\51\47"+ + "\127\0\35\47\51\0\12\53\36\47\2\0\5\47\u038b\0\154\47\224\0"+ + "\234\47\4\0\132\47\6\0\26\47\2\0\6\47\2\0\46\47\2\0"+ "\6\47\2\0\10\47\1\0\1\47\1\0\1\47\1\0\1\47\1\0"+ "\37\47\2\0\65\47\1\0\7\47\1\0\1\47\3\0\3\47\1\0"+ "\7\47\3\0\4\47\2\0\6\47\4\0\15\47\5\0\3\47\1\0"+ - "\7\47\164\0\1\47\15\0\1\47\20\0\15\47\145\0\1\47\4\0"+ - "\1\47\2\0\12\47\1\0\1\47\3\0\5\47\6\0\1\47\1\0"+ - "\1\47\1\0\1\47\1\0\4\47\1\0\13\47\2\0\4\47\5\0"+ - "\5\47\4\0\1\47\64\0\2\47\u0a7b\0\57\47\1\0\57\47\1\0"+ - "\205\47\6\0\4\47\3\0\2\47\14\0\46\47\1\0\1\47\5\0"+ - "\1\47\2\0\70\47\7\0\1\47\20\0\27\47\11\0\7\47\1\0"+ - "\7\47\1\0\7\47\1\0\7\47\1\0\7\47\1\0\7\47\1\0"+ - "\7\47\1\0\7\47\120\0\1\47\u01d5\0\2\47\52\0\5\47\5\0"+ - "\2\47\4\0\126\47\6\0\3\47\1\0\132\47\1\0\4\47\5\0"+ - "\51\47\3\0\136\47\21\0\33\47\65\0\20\47\u0200\0\u19b6\47\112\0"+ - "\u51cd\47\63\0\u048d\47\103\0\56\47\2\0\u010d\47\3\0\20\47\12\53"+ - "\2\47\24\0\57\47\20\0\31\47\10\0\106\47\61\0\11\47\2\0"+ - "\147\47\2\0\4\47\1\0\4\47\14\0\13\47\115\0\12\47\1\0"+ - "\3\47\1\0\4\47\1\0\27\47\35\0\64\47\16\0\62\47\34\0"+ - "\12\53\30\0\6\47\3\0\1\47\4\0\12\53\34\47\12\0\27\47"+ - "\31\0\35\47\7\0\57\47\34\0\1\47\12\53\46\0\51\47\27\0"+ - "\3\47\1\0\10\47\4\0\12\53\6\0\27\47\3\0\1\47\5\0"+ - "\60\47\1\0\1\47\3\0\2\47\2\0\5\47\2\0\1\47\1\0"+ - "\1\47\30\0\3\47\2\0\13\47\7\0\3\47\14\0\6\47\2\0"+ - "\6\47\2\0\6\47\11\0\7\47\1\0\7\47\221\0\43\47\15\0"+ - "\12\53\6\0\u2ba4\47\14\0\27\47\4\0\61\47\u2104\0\u016e\47\2\0"+ - "\152\47\46\0\7\47\14\0\5\47\5\0\1\47\1\0\12\47\1\0"+ - "\15\47\1\0\5\47\1\0\1\47\1\0\2\47\1\0\2\47\1\0"+ - "\154\47\41\0\u016b\47\22\0\100\47\2\0\66\47\50\0\14\47\164\0"+ - "\5\47\1\0\207\47\23\0\12\53\7\0\32\47\6\0\32\47\13\0"+ - "\131\47\3\0\6\47\2\0\6\47\2\0\6\47\2\0\3\47\43\0"; + "\7\47\164\0\1\47\15\0\1\47\202\0\1\47\4\0\1\47\2\0"+ + "\12\47\1\0\1\47\3\0\5\47\6\0\1\47\1\0\1\47\1\0"+ + "\1\47\1\0\4\47\1\0\3\47\1\0\7\47\3\0\3\47\5\0"+ + "\5\47\u0ebb\0\2\47\52\0\5\47\5\0\2\47\4\0\126\47\6\0"+ + "\3\47\1\0\132\47\1\0\4\47\5\0\50\47\4\0\136\47\21\0"+ + "\30\47\70\0\20\47\u0200\0\u19b6\47\112\0\u51a6\47\132\0\u048d\47\u0773\0"+ + "\u2ba4\47\u215c\0\u012e\47\2\0\73\47\225\0\7\47\14\0\5\47\5\0"+ + "\1\47\1\0\12\47\1\0\15\47\1\0\5\47\1\0\1\47\1\0"+ + "\2\47\1\0\2\47\1\0\154\47\41\0\u016b\47\22\0\100\47\2\0"+ + "\66\47\50\0\14\47\164\0\5\47\1\0\207\47\23\0\12\53\7\0"+ + "\32\47\6\0\32\47\13\0\131\47\3\0\6\47\2\0\6\47\2\0"+ + "\6\47\2\0\3\47\43\0"; /** * Translates characters to character classes @@ -405,13 +385,13 @@ class _RegExLexer implements FlexLexer { /* user code: */ // This adds support for nested states. I'm no JFlex pro, so maybe this is overkill, but it works quite well. - private final ArrayList states = new ArrayList(); + final ArrayList states = new ArrayList(); // This was an idea to use the regex implementation for XML schema regexes (which use a slightly different syntax) // as well, but is currently unfinished as it requires to tweak more places than just the lexer. private boolean xmlSchemaMode; - private int capturingGroupCount = 0; + int capturingGroupCount = 0; private boolean allowDanglingMetacharacters; private boolean allowNestedCharacterClasses; @@ -480,7 +460,7 @@ class _RegExLexer implements FlexLexer { char [] map = new char[0x10000]; int i = 0; /* index in packed string */ int j = 0; /* index in unpacked array */ - while (i < 1760) { + while (i < 1348) { int count = packed.charAt(i++); char value = packed.charAt(i++); do map[j++] = value; while (--count > 0); @@ -866,14 +846,22 @@ class _RegExLexer implements FlexLexer { { return RegExpTT.POS_LOOKBEHIND; } case 113: break; + case 20: + { if (allowDanglingMetacharacters) { + yypopstate(); yypushback(1); + } else { + return RegExpTT.BAD_CHARACTER; + } + } + case 114: break; case 73: { return RegExpTT.HEX_CHAR; } - case 114: break; + case 115: break; case 1: { handleOptions(); return RegExpTT.OPTIONS_ON; } - case 115: break; + case 116: break; case 43: { if (yystate() == CLASS2) return RegExpTT.ESC_CHARACTER; while (yylength() > 2 && Integer.parseInt(yytext().toString().substring(1)) > capturingGroupCount) { @@ -881,54 +869,46 @@ class _RegExLexer implements FlexLexer { } return RegExpTT.BACKREF; } - case 116: break; + case 117: break; case 59: { return allowNestedCharacterClasses ? RegExpTT.ANDAND : RegExpTT.CHARACTER; } - case 117: break; + case 118: break; case 2: { yypopstate(); return RegExpTT.COMMENT; } - case 118: break; + case 119: break; case 17: { return RegExpTT.MINUS; } - case 119: break; + case 120: break; case 47: { return RegExpTT.ESC_CTRL_CHARACTER; } - case 120: break; + case 121: break; case 32: { yypopstate(); yypushstate(EMBRACED); return RegExpTT.LBRACE; } - case 121: break; + case 122: break; case 13: { return RegExpTT.QUEST; } - case 122: break; + case 123: break; case 5: { capturingGroupCount++; return RegExpTT.GROUP_BEGIN; } - case 123: break; + case 124: break; case 15: { return RegExpTT.PLUS; } - case 124: break; + case 125: break; case 67: { return RegExpTT.OCT_CHAR; } - case 125: break; + case 126: break; case 39: { yybegin(YYINITIAL); return RegExpTT.QUOTE; } - case 126: break; - case 20: - { if (allowDanglingMetacharacters) { - yypopstate(); yypushback(1); - } else { - return RegExpTT.BAD_CHARACTER; - } - } case 127: break; case 31: { yypopstate(); yypushback(1); diff --git a/RegExpSupport/src/org/intellij/lang/regexp/RegExpLexer.java b/RegExpSupport/src/org/intellij/lang/regexp/RegExpLexer.java index 09ee6a5bd471..b028a08df024 100644 --- a/RegExpSupport/src/org/intellij/lang/regexp/RegExpLexer.java +++ b/RegExpSupport/src/org/intellij/lang/regexp/RegExpLexer.java @@ -23,12 +23,14 @@ import java.util.EnumSet; public class RegExpLexer extends FlexAdapter { private static final int COMMENT_MODE = 1 << 14; + private static final int NESTED_STATES = 1 << 15; + private static final int CAPTURING_GROUPS = 1 << 16; private final EnumSet myCapabilities; public RegExpLexer(EnumSet capabilities) { super(new _RegExLexer(capabilities)); myCapabilities = capabilities; - } + } public void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState) { getFlex().commentMode = (initialState & COMMENT_MODE) != 0 || myCapabilities.contains(RegExpCapability.COMMENT_MODE); @@ -40,8 +42,17 @@ public class RegExpLexer extends FlexAdapter { } public int getState() { - final boolean commentMode = getFlex().commentMode; - final int state = super.getState(); - return commentMode ? state | COMMENT_MODE : state; + final _RegExLexer flex = getFlex(); + int state = super.getState(); + if (flex.commentMode) { + state |= COMMENT_MODE; + } + if (!flex.states.isEmpty()) { + state |= NESTED_STATES; + } + if (flex.capturingGroupCount != 0) { + state |= CAPTURING_GROUPS; + } + return state; } } diff --git a/RegExpSupport/src/org/intellij/lang/regexp/regexp-lexer.flex b/RegExpSupport/src/org/intellij/lang/regexp/regexp-lexer.flex index d429bd24c6ac..2d5daf7f65ab 100644 --- a/RegExpSupport/src/org/intellij/lang/regexp/regexp-lexer.flex +++ b/RegExpSupport/src/org/intellij/lang/regexp/regexp-lexer.flex @@ -21,13 +21,13 @@ import java.util.EnumSet; %{ // This adds support for nested states. I'm no JFlex pro, so maybe this is overkill, but it works quite well. - private final ArrayList states = new ArrayList(); + final ArrayList states = new ArrayList(); // This was an idea to use the regex implementation for XML schema regexes (which use a slightly different syntax) // as well, but is currently unfinished as it requires to tweak more places than just the lexer. private boolean xmlSchemaMode; - private int capturingGroupCount = 0; + int capturingGroupCount = 0; private boolean allowDanglingMetacharacters; private boolean allowNestedCharacterClasses; @@ -202,7 +202,7 @@ HEX_CHAR=[0-9a-fA-F] {RBRACE} { yypopstate(); return RegExpTT.RBRACE; } {ANY} { if (allowDanglingMetacharacters) { - yypopstate(); yypushback(1); + yypopstate(); yypushback(1); } else { return RegExpTT.BAD_CHARACTER; } diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java index 132e631e4052..e61e6773c422 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java @@ -112,6 +112,7 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb private ExecutionResult myExecutionResult; private RemoteConnection myConnection; + private JavaDebugProcess myXDebugProcess; private ConnectionServiceWrapper myConnectionService; private Map myArguments; @@ -1990,10 +1991,13 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb return mySession.getContextManager().getContext(); } + public void setXDebugProcess(JavaDebugProcess XDebugProcess) { + myXDebugProcess = XDebugProcess; + } + @Nullable public JavaDebugProcess getXdebugProcess() { - XDebugSession session = mySession.getXDebugSession(); - return session != null ? (JavaDebugProcess)session.getDebugProcess() : null; + return myXDebugProcess; } public boolean areBreakpointsMuted() { 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 9ccfb1664c64..50500c3864a7 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/JavaDebugProcess.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaDebugProcess.java @@ -72,7 +72,13 @@ public class JavaDebugProcess extends XDebugProcess { private final XBreakpointHandler[] myBreakpointHandlers; private final NodeManagerImpl myNodeManager; - public JavaDebugProcess(@NotNull final XDebugSession session, final DebuggerSession javaSession) { + public static JavaDebugProcess create(@NotNull final XDebugSession session, final DebuggerSession javaSession) { + JavaDebugProcess res = new JavaDebugProcess(session, javaSession); + javaSession.getProcess().setXDebugProcess(res); + return res; + } + + private JavaDebugProcess(@NotNull final XDebugSession session, final DebuggerSession javaSession) { super(session); myJavaSession = javaSession; myEditorsProvider = new JavaDebuggerEditorsProvider(); 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 53f298853139..26d0820fedc9 100644 --- a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerSession.java +++ b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerSession.java @@ -57,9 +57,7 @@ import com.intellij.unscramble.ThreadState; import com.intellij.util.Alarm; import com.intellij.util.TimeoutUtil; import com.intellij.xdebugger.AbstractDebuggerSession; -import com.intellij.xdebugger.XDebugProcess; import com.intellij.xdebugger.XDebugSession; -import com.intellij.xdebugger.XDebuggerManager; import com.intellij.xdebugger.impl.actions.XDebuggerActions; import com.intellij.xdebugger.impl.evaluate.quick.common.ValueLookupManager; import com.sun.jdi.ObjectCollectedException; @@ -690,12 +688,7 @@ public class DebuggerSession implements AbstractDebuggerSession { @Nullable public XDebugSession getXDebugSession() { - for (XDebugSession xDebugSession : XDebuggerManager.getInstance(getProject()).getDebugSessions()) { - XDebugProcess process = xDebugSession.getDebugProcess(); - if (process instanceof JavaDebugProcess && ((JavaDebugProcess)process).getDebuggerSession() == this) { - return xDebugSession; - } - } - return null; + JavaDebugProcess process = myDebugProcess.getXdebugProcess(); + return process != null ? process.getSession() : null; } } diff --git a/java/debugger/impl/src/com/intellij/debugger/impl/GenericDebuggerRunner.java b/java/debugger/impl/src/com/intellij/debugger/impl/GenericDebuggerRunner.java index c6491a2b8a3f..06408ce2a27a 100644 --- a/java/debugger/impl/src/com/intellij/debugger/impl/GenericDebuggerRunner.java +++ b/java/debugger/impl/src/com/intellij/debugger/impl/GenericDebuggerRunner.java @@ -122,7 +122,7 @@ public class GenericDebuggerRunner extends JavaPatchableProgramRunner myMethodToOccurrenceMap = new HashMap(); - private final Map myOccurences = new HashMap(); + private final Set myProcessedFrames = new HashSet(); public final class MethodOccurrence { private final Method myMethod; @@ -50,13 +53,13 @@ public class MethodsTracker { } } - public MethodOccurrence getMethodOccurrence(int frameIndex, Method method) { - MethodOccurrence occurrence = myOccurences.get(frameIndex); - if (occurrence == null) { - occurrence = new MethodOccurrence(method, assignOccurrenceIndex(method)); - myOccurences.put(frameIndex, occurrence); + public MethodOccurrence getMethodOccurrence(int frameIndex, @Nullable Method method) { + int occurenceIndex = getOccurrenceCount(method); + if (!myProcessedFrames.contains(frameIndex)) { + myMethodToOccurrenceMap.put(method, occurenceIndex + 1); + myProcessedFrames.add(frameIndex); } - return occurrence; + return new MethodOccurrence(method, occurenceIndex); } private int getOccurrenceCount(Method method) { @@ -66,13 +69,4 @@ public class MethodsTracker { final Integer integer = myMethodToOccurrenceMap.get(method); return integer != null? integer.intValue(): 0; } - - private int assignOccurrenceIndex(Method method) { - if (method == null) { - return 0; - } - final int count = getOccurrenceCount(method); - myMethodToOccurrenceMap.put(method, count + 1); - return count; - } } diff --git a/java/debugger/openapi/src/com/intellij/debugger/NoDataException.java b/java/debugger/openapi/src/com/intellij/debugger/NoDataException.java index b3f30af716be..707ba0f445f3 100644 --- a/java/debugger/openapi/src/com/intellij/debugger/NoDataException.java +++ b/java/debugger/openapi/src/com/intellij/debugger/NoDataException.java @@ -15,7 +15,16 @@ */ package com.intellij.debugger; -public class NoDataException extends Exception{ +public class NoDataException extends Exception { + public static final NoDataException INSTANCE = new NoDataException(); + + /** + * @deprecated Use shared {@link com.intellij.debugger.NoDataException#INSTANCE} instead + */ + @Deprecated + public NoDataException() { + } + @Override public Throwable fillInStackTrace() { return this; diff --git a/java/debugger/openapi/src/com/intellij/debugger/engine/JSR45PositionManager.java b/java/debugger/openapi/src/com/intellij/debugger/engine/JSR45PositionManager.java index d33e9ade7e08..df2d9bb2e415 100644 --- a/java/debugger/openapi/src/com/intellij/debugger/engine/JSR45PositionManager.java +++ b/java/debugger/openapi/src/com/intellij/debugger/engine/JSR45PositionManager.java @@ -97,7 +97,7 @@ public abstract class JSR45PositionManager implements PositionManager { LOG.info(e); } if(sourcePosition == null) { - throw new NoDataException(); + throw NoDataException.INSTANCE; } return sourcePosition; } @@ -135,7 +135,7 @@ public abstract class JSR45PositionManager implements PositionManager { private void checkSourcePositionFileType(final SourcePosition classPosition) throws NoDataException { final FileType fileType = classPosition.getFile().getFileType(); if(!myFileTypes.contains(fileType)) { - throw new NoDataException(); + throw NoDataException.INSTANCE; } } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurable.java index d72269f41733..21626c32a7cf 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurable.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurable.java @@ -19,6 +19,7 @@ import com.intellij.compiler.server.BuildManager; import com.intellij.facet.Facet; import com.intellij.ide.util.PropertiesComponent; import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.application.AccessToken; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; @@ -352,7 +353,7 @@ public class ProjectStructureConfigurable extends BaseConfigurable implements Se public void reset() { // need this to ensure VFS operations will not block because of storage flushing // and other maintenance IO tasks run in background - HeavyProcessLatch.INSTANCE.processStarted("Resetting Project Structure"); + AccessToken token = HeavyProcessLatch.INSTANCE.processStarted("Resetting Project Structure"); try { myWasUiDisposed = false; @@ -387,7 +388,7 @@ public class ProjectStructureConfigurable extends BaseConfigurable implements Se } } finally { - HeavyProcessLatch.INSTANCE.processFinished(); + token.finish(); } } diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/InferredAnnotationsManagerImpl.java b/java/java-analysis-impl/src/com/intellij/codeInsight/InferredAnnotationsManagerImpl.java index 5b30ad6941cc..ed34299f4c35 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/InferredAnnotationsManagerImpl.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/InferredAnnotationsManagerImpl.java @@ -65,19 +65,23 @@ public class InferredAnnotationsManagerImpl extends InferredAnnotationsManager { return null; } + @Nullable private PsiAnnotation getHardcodedContractAnnotation(PsiMethod method) { List contracts = HardcodedContracts.getHardcodedContracts(method, null); return contracts.isEmpty() ? null : createContractAnnotation(contracts, HardcodedContracts.isHardcodedPure(method)); } - private static boolean ignoreBytecodeInference(PsiModifierListOwner owner, String annotationFQN) { + private static boolean ignoreBytecodeInference(PsiModifierListOwner owner, @Nullable String annotationFQN) { if (ORG_JETBRAINS_ANNOTATIONS_CONTRACT.equals(annotationFQN) && hasHardcodedContracts(owner)) { return true; } - if (AnnotationUtil.NOT_NULL.equals(annotationFQN) && - owner instanceof PsiParameter && owner.getParent() != null && - hasHardcodedContracts(owner.getParent().getParent())) { - return true; + if (AnnotationUtil.NOT_NULL.equals(annotationFQN) && owner instanceof PsiParameter && owner.getParent() != null) { + if (AnnotationUtil.isAnnotated(owner, NullableNotNullManager.getInstance(owner.getProject()).getNullables(), false, false)) { + return true; + } + if (hasHardcodedContracts(owner.getParent().getParent())) { + return true; + } } return false; } diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspectionBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspectionBase.java index 736cb4dec27d..0ade64997b4a 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspectionBase.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspectionBase.java @@ -161,8 +161,7 @@ public class NullableStuffInspectionBase extends BaseJavaBatchLocalInspectionToo addAnnoFix); } if (PropertyUtil.isSimpleSetter(setter)) { - if (annotated.isDeclaredNotNull && isNullableNotInferred(parameter, false) || - annotated.isDeclaredNullable && isNotNullNotInferred(parameter, false, false)) { + if (annotated.isDeclaredNotNull && isNullableNotInferred(parameter, false)) { final PsiIdentifier nameIdentifier1 = parameter.getNameIdentifier(); assertValidElement(setter, parameter, nameIdentifier1); holder.registerProblem(nameIdentifier1, InspectionsBundle.message( diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SideEffectWarningDialog.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SideEffectWarningDialog.java index 8a992662935d..e5c8694cb860 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SideEffectWarningDialog.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SideEffectWarningDialog.java @@ -131,8 +131,8 @@ public class SideEffectWarningDialog extends DialogWrapper { "There are possible side effects found in expressions assigned to the variable ''{0}''
\n" + "You can:\n" + "
\n" + - "— Remove variable usages along with all expressions involved, or
\n" + - "— Transform expressions assigned to variable into the statements on their own.
\n" + + "- Remove variable usages along with all expressions involved, or
\n" + + "- Transform expressions assigned to variable into the statements on their own.
\n" + "
\n" + " That is,
\n" + " \n" + diff --git a/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationPresentation.java b/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationPresentation.java index cdc8fdd15c7d..76602ca1c660 100644 --- a/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationPresentation.java +++ b/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationPresentation.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. @@ -54,7 +54,7 @@ import java.awt.event.KeyEvent; import java.util.*; public class UnusedDeclarationPresentation extends DefaultInspectionToolPresentation { - private Map> myPackageContents = new HashMap>(); + private final Map> myPackageContents = Collections.synchronizedMap(new HashMap>()); private Map> myOldPackageContents = null; @@ -335,7 +335,7 @@ public class UnusedDeclarationPresentation extends DefaultInspectionToolPresenta @Override public void updateContent() { getTool().checkForReachables(getContext()); - myPackageContents = new HashMap>(); + myPackageContents.clear(); getContext().getRefManager().iterate(new RefJavaVisitor() { @Override public void visitElement(@NotNull RefEntity refEntity) { if (!(refEntity instanceof RefJavaElement)) return;//dead code doesn't work with refModule | refPackage @@ -378,6 +378,7 @@ public class UnusedDeclarationPresentation extends DefaultInspectionToolPresenta return false; } + @NotNull @Override public Map> getContent() { return myPackageContents; diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java b/java/java-psi-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java index c0742de3c7f6..975af4a8dd67 100644 --- a/java/java-psi-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java +++ b/java/java-psi-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java @@ -2053,7 +2053,7 @@ public class JavaDocInfoGenerator { @Override public void visitMethodCallExpression(PsiMethodCallExpression expression) { - myBuffer.append(expression.getMethodExpression().getText()).append("("); + myBuffer.append(StringUtil.escapeXml(expression.getMethodExpression().getText())).append("("); expression.getArgumentList().accept(this); myBuffer.append(")"); } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/SeeDocTagInfo.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/SeeDocTagInfo.java index 287afdc18f6d..5356938959e1 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/SeeDocTagInfo.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/SeeDocTagInfo.java @@ -120,7 +120,7 @@ class SeeDocTagInfo implements JavadocTagInfo { @Override public boolean isValidInContext(PsiElement element) { - if (myInline && myName.equals(LINKPLAIN_TAG)) + if (myInline && myName.equals(LINKPLAIN_TAG) && element != null) return PsiUtil.getLanguageLevel(element).compareTo(LanguageLevel.JDK_1_4) >= 0; return true; diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/SimpleDocTagInfo.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/SimpleDocTagInfo.java index d16f4d8be4a7..ddb6187a6420 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/SimpleDocTagInfo.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/SimpleDocTagInfo.java @@ -57,7 +57,7 @@ class SimpleDocTagInfo implements JavadocTagInfo { @Override public boolean isValidInContext(PsiElement element) { - if (PsiUtil.getLanguageLevel(element).compareTo(myLanguageLevel) < 0) { + if (element != null && PsiUtil.getLanguageLevel(element).compareTo(myLanguageLevel) < 0) { return false; } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javaDoc/resolve/pkg1/package-info.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javaDoc/resolve/pkg1/package-info.java new file mode 100644 index 000000000000..a49965c56f18 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javaDoc/resolve/pkg1/package-info.java @@ -0,0 +1,6 @@ +/** + * {@linkplain #foo} + * @see List + * @author #mycompanyname + */ +package mycompanypackagename; \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/javadocIG/methodExpressionWithLiteral.html b/java/java-tests/testData/codeInsight/javadocIG/methodExpressionWithLiteral.html new file mode 100644 index 000000000000..5d73a26bc75f --- /dev/null +++ b/java/java-tests/testData/codeInsight/javadocIG/methodExpressionWithLiteral.html @@ -0,0 +1 @@ + A
public byte[] bytes = "&amp;".getBytes()
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/javadocIG/methodExpressionWithLiteral.java b/java/java-tests/testData/codeInsight/javadocIG/methodExpressionWithLiteral.java new file mode 100644 index 000000000000..3d13bcd7296a --- /dev/null +++ b/java/java-tests/testData/codeInsight/javadocIG/methodExpressionWithLiteral.java @@ -0,0 +1,3 @@ +class A { + public byte[] bytes = "&".getBytes(); +} diff --git a/java/java-tests/testData/inspection/nullableProblems/GetterSetterProblems.java b/java/java-tests/testData/inspection/nullableProblems/GetterSetterProblems.java index c8a5816ec741..e12d8e2de3d4 100644 --- a/java/java-tests/testData/inspection/nullableProblems/GetterSetterProblems.java +++ b/java/java-tests/testData/inspection/nullableProblems/GetterSetterProblems.java @@ -1,4 +1,7 @@ import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.lang.Object; class B { @NotNull @@ -26,16 +29,16 @@ class C { this.c = c; } - C(@Nullable C c, int i) { + C(@Nullable C c, int i) { this.c = c; } - @Nullable - public C getC() { + @Nullable + public C getC() { return c; } - public void setC(@Nullable C c) { + public void setC(@Nullable C c) { this.c = c; } @@ -50,7 +53,7 @@ class C { } class D { - @Nullable Long myL; + @Nullable Long myL; D(long l) { myL = l; @@ -64,4 +67,11 @@ class E { this.c = c; } +} +class F { + @Nullable Object field; + + public void setField(@NotNull Object field) { + this.field = field; + } } \ No newline at end of file diff --git a/java/java-tests/testData/inspection/nullableProblems/HonorParameterDefaultInSetters.java b/java/java-tests/testData/inspection/nullableProblems/HonorParameterDefaultInSetters.java index a6b9b17afe42..8d74c640e574 100644 --- a/java/java-tests/testData/inspection/nullableProblems/HonorParameterDefaultInSetters.java +++ b/java/java-tests/testData/inspection/nullableProblems/HonorParameterDefaultInSetters.java @@ -7,7 +7,7 @@ class C { private String a; private String b; - public void setA(String a) { + public void setA(String a) { this.a = a; } diff --git a/java/java-tests/testData/refactoring/moveMembers/scr40064/after/Test.java b/java/java-tests/testData/refactoring/moveMembers/scr40064/after/Test.java index bf7239b2509f..4afb887f978b 100644 --- a/java/java-tests/testData/refactoring/moveMembers/scr40064/after/Test.java +++ b/java/java-tests/testData/refactoring/moveMembers/scr40064/after/Test.java @@ -6,9 +6,9 @@ class Test { } class Test1 { + static int i; + { i = 0; } - - static int i; } \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy index 41e2b5bd71fc..5748716cb2e7 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy @@ -650,6 +650,47 @@ public interface Test { assert !lookup } + public void testMulticaretLeftRightMovements() { + myFixture.configureByText("a.java", """ + class Foo { + void foo(String iterable) { + ter x + ter x + } + } + """) + type('i') + assert lookup + + edt { myFixture.performEditorAction(IdeActions.ACTION_EDITOR_MOVE_CARET_RIGHT) } + myFixture.checkResult """ + class Foo { + void foo(String iterable) { + iter x + iter x + } + } + """ + joinAutopopup() + joinCompletion() + assert lookup + assert !lookup.calculating + + edt { myFixture.performEditorAction(IdeActions.ACTION_EDITOR_MOVE_CARET_LEFT) } + myFixture.checkResult """ + class Foo { + void foo(String iterable) { + iter x + iter x + } + } + """ + joinAutopopup() + joinCompletion() + assert lookup + assert !lookup.calculating + } + public void testTypingInAnotherEditor() { myFixture.configureByText("a.java", "") type 'c' diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/JavadocResolveTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/JavadocResolveTest.java index 2dd4f9c00eb2..2fea76a290e7 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/JavadocResolveTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/JavadocResolveTest.java @@ -32,6 +32,7 @@ public class JavadocResolveTest extends DaemonAnalyzerTestCase { public void testSee2() throws Exception { doTest(); } public void testSee3() throws Exception { doTest(); } public void testPackageInfo() throws Exception { doTest(BASE_PATH + "/pkg/package-info.java", BASE_PATH, false, false); } + public void testBrokenPackageInfo() throws Exception { doTest(BASE_PATH + "/pkg1/package-info.java", BASE_PATH, false, false); } private void doTest() throws Exception { doTest(BASE_PATH + "/pkg/" + getTestName(false) + ".java", BASE_PATH, false, false); diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingTest.groovy index 408130f74f66..7347fe3b190a 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingTest.groovy @@ -33,6 +33,7 @@ import com.intellij.psi.PsiClass import com.intellij.psi.PsiLiteralExpression import com.intellij.psi.PsiMethod import com.intellij.psi.search.GlobalSearchScope +import com.intellij.testFramework.EditorTestUtil import com.intellij.testFramework.LightProjectDescriptor import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase @@ -1087,6 +1088,35 @@ class Foo { assertEquals 0, expandedFoldRegionsCount } + public void "test processing of tabs inside fold regions"() { + String text = """public class Foo { +\tpublic static void main(String[] args) { +\t\tjavax.swing.SwingUtilities.invokeLater(new Runnable() { +\t\t\t@Override +\t\t\tpublic void run() { +\t\t\t\tSystem.out.println(); +\t\t\t} +\t\t}); +\t} +}"""; + configure text + assert myFixture.editor.getFoldingModel().getCollapsedRegionAtOffset(text.indexOf("new")) + myFixture.editor.settings.useTabCharacter = true + EditorTestUtil.configureSoftWraps(myFixture.editor, 1000) + myFixture.editor.caretModel.moveToOffset(text.indexOf("System")) + myFixture.performEditorAction(IdeActions.ACTION_EDITOR_TAB) + myFixture.checkResult("""public class Foo { +\tpublic static void main(String[] args) { +\t\tjavax.swing.SwingUtilities.invokeLater(new Runnable() { +\t\t\t@Override +\t\t\tpublic void run() { +\t\t\t\t\tSystem.out.println(); +\t\t\t} +\t\t}); +\t} +}"""); + } + private int getFoldRegionsCount() { return myFixture.editor.foldingModel.allFoldRegions.length } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java index 871c758d08fd..bda17baaa0ce 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java @@ -1,3 +1,18 @@ +/* + * 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.codeInsight.javadoc; import com.intellij.JavaTestUtil; @@ -72,6 +87,10 @@ public class JavaDocInfoGeneratorTest extends CodeInsightTestCase { doTestField(); } + public void testMethodExpressionWithLiteral() throws Exception { + doTestField(); + } + public void testInitializerWithReference() throws Exception { doTestField(); } diff --git a/java/testFramework/src/com/intellij/debugger/DebuggerTestCase.java b/java/testFramework/src/com/intellij/debugger/DebuggerTestCase.java index 06ebf7875e6e..cefceb3977e0 100644 --- a/java/testFramework/src/com/intellij/debugger/DebuggerTestCase.java +++ b/java/testFramework/src/com/intellij/debugger/DebuggerTestCase.java @@ -169,7 +169,7 @@ public abstract class DebuggerTestCase extends ExecutionWithDebuggerToolsTestCas @Override @NotNull public XDebugProcess start(@NotNull XDebugSession session) { - return new JavaDebugProcess(session, myDebuggerSession); + return JavaDebugProcess.create(session, myDebuggerSession); } }); } @@ -471,7 +471,7 @@ public abstract class DebuggerTestCase extends ExecutionWithDebuggerToolsTestCas @Override @NotNull public XDebugProcess start(@NotNull XDebugSession session) { - return new JavaDebugProcess(session, debuggerSession); + return JavaDebugProcess.create(session, debuggerSession); } }); return debuggerSession; diff --git a/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildMain.java b/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildMain.java index 7837b954da81..19d55e28c5b5 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildMain.java +++ b/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildMain.java @@ -36,11 +36,14 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.jps.api.CmdlineProtoUtil; import org.jetbrains.jps.api.CmdlineRemoteProto; import org.jetbrains.jps.api.GlobalOptions; +import org.jetbrains.jps.builders.BuildTarget; +import org.jetbrains.jps.incremental.BuilderRegistry; import org.jetbrains.jps.incremental.MessageHandler; import org.jetbrains.jps.incremental.Utils; import org.jetbrains.jps.incremental.fs.BuildFSState; import org.jetbrains.jps.incremental.fs.FSState; import org.jetbrains.jps.incremental.messages.BuildMessage; +import org.jetbrains.jps.incremental.storage.BuildTargetsState; import org.jetbrains.jps.service.SharedThreadPool; import java.io.*; @@ -77,6 +80,7 @@ public class BuildMain { private static PreloadedData ourPreloadedData; public static void main(String[] args){ + final long processStart = System.currentTimeMillis(); System.out.println("Build process started. Classpath: " + System.getProperty("java.class.path")); final String host = args[HOST_ARG]; final int port = Integer.parseInt(args[PORT_ARG]); @@ -125,7 +129,6 @@ public class BuildMain { final String projectPathToPreload = System.getProperty(PRELOAD_PROJECT_PATH, null); final String globalsPathToPreload = System.getProperty(PRELOAD_CONFIG_PATH, null); if (projectPathToPreload != null && globalsPathToPreload != null) { - final long preloadStart = System.currentTimeMillis(); final PreloadedData data = new PreloadedData(); ourPreloadedData = data; try { @@ -166,7 +169,16 @@ public class BuildMain { LOG.info("Error pre-loading FS state", e); fsState.clearAll(); } - LOG.info("Pre-loaded project model in " + (System.currentTimeMillis() - preloadStart) + " ms"); + + // preloading target configurations + final BuildTargetsState targetsState = pd.getTargetsState(); + for (BuildTarget target : pd.getBuildTargetIndex().getAllTargets()) { + targetsState.getTargetConfiguration(target); + } + + BuilderRegistry.getInstance(); + + LOG.info("Pre-loaded process ready in " + (System.currentTimeMillis() - processStart) + " ms"); } catch (Throwable e) { LOG.info("Failed to pre-load project " + projectPathToPreload, e); diff --git a/jps/jps-builders/testSrc/org/jetbrains/jps/builders/BuildResult.java b/jps/jps-builders/testSrc/org/jetbrains/jps/builders/BuildResult.java index 1dc08ba8d8ce..157495ef0a4a 100644 --- a/jps/jps-builders/testSrc/org/jetbrains/jps/builders/BuildResult.java +++ b/jps/jps-builders/testSrc/org/jetbrains/jps/builders/BuildResult.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. @@ -17,7 +17,6 @@ package org.jetbrains.jps.builders; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.Function; -import junit.framework.Assert; import org.jetbrains.annotations.NotNull; import org.jetbrains.jps.incremental.MessageHandler; import org.jetbrains.jps.incremental.messages.BuildMessage; @@ -26,9 +25,11 @@ import org.jetbrains.jps.incremental.messages.DoneSomethingNotification; import java.util.ArrayList; import java.util.List; +import static org.junit.Assert.*; + /** -* @author nik -*/ + * @author nik + */ public class BuildResult implements MessageHandler { private final List myErrorMessages; private final List myWarnMessages; @@ -59,11 +60,11 @@ public class BuildResult implements MessageHandler { } public void assertUpToDate() { - Assert.assertTrue("Project sources weren't up to date", myUpToDate); + assertTrue("Project sources weren't up to date", myUpToDate); } public void assertFailed() { - Assert.assertFalse("Build not failed as expected", isSuccessful()); + assertFalse("Build not failed as expected", isSuccessful()); } public boolean isSuccessful() { @@ -71,9 +72,12 @@ public class BuildResult implements MessageHandler { } public void assertSuccessful() { - final Function toStringFunction = StringUtil.createToStringFunction(BuildMessage.class); - Assert.assertTrue("Build failed. \nErrors:\n" + StringUtil.join(myErrorMessages, toStringFunction, "\n") + - "\nInfo messages:\n" + StringUtil.join(myInfoMessages, toStringFunction, "\n"), isSuccessful()); + if (!isSuccessful()) { + Function toStringFunction = StringUtil.createToStringFunction(BuildMessage.class); + fail("Build failed.\n" + + "Errors:\n" + StringUtil.join(myErrorMessages, toStringFunction, "\n") + "\n" + + "Info messages:\n" + StringUtil.join(myInfoMessages, toStringFunction, "\n")); + } } @NotNull diff --git a/json/src/com/intellij/json/codeinsight/JsonStandardComplianceInspection.java b/json/src/com/intellij/json/codeinsight/JsonStandardComplianceInspection.java index 0124c48fa7fe..8c17715d696c 100644 --- a/json/src/com/intellij/json/codeinsight/JsonStandardComplianceInspection.java +++ b/json/src/com/intellij/json/codeinsight/JsonStandardComplianceInspection.java @@ -6,6 +6,7 @@ import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel; import com.intellij.json.JsonBundle; import com.intellij.json.JsonElementTypes; import com.intellij.json.psi.*; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiComment; @@ -22,15 +23,17 @@ import javax.swing.*; /** * Compliance checks include *
    - *
  • Usage of line and block commentaries
  • - *
  • Usage of single quoted strings
  • - *
  • Usage of identifiers (unqouted words)
  • - *
  • Not double quoted string literal is used as property key
  • + *
  • Usage of line and block commentaries
  • + *
  • Usage of single quoted strings
  • + *
  • Usage of identifiers (unqouted words)
  • + *
  • Not double quoted string literal is used as property key
  • *
* * @author Mikhail Golubev */ public class JsonStandardComplianceInspection extends LocalInspectionTool { + private static final Logger LOG = Logger.getInstance(JsonStandardComplianceInspection.class); + public boolean myWarnAboutComments = true; @NotNull @@ -58,8 +61,10 @@ public class JsonStandardComplianceInspection extends LocalInspectionTool { @Override public void visitStringLiteral(@NotNull JsonStringLiteral stringLiteral) { if (stringLiteral.getText().startsWith("'")) { - holder.registerProblem(stringLiteral, JsonBundle.message("msg.compliance.problem.single.quoted.strings"), new AddDoubleQuotesFix()); + holder + .registerProblem(stringLiteral, JsonBundle.message("msg.compliance.problem.single.quoted.strings"), new AddDoubleQuotesFix()); } + // May be illegal property key as well super.visitStringLiteral(stringLiteral); } @@ -76,6 +81,8 @@ public class JsonStandardComplianceInspection extends LocalInspectionTool { @Override public void visitReferenceExpression(@NotNull JsonReferenceExpression reference) { holder.registerProblem(reference, JsonBundle.message("msg.compliance.problem.identifier"), new AddDoubleQuotesFix()); + // May be illegal property key as well + super.visitReferenceExpression(reference); } @Override @@ -133,9 +140,13 @@ public class JsonStandardComplianceInspection extends LocalInspectionTool { @Override public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { final PsiElement element = descriptor.getPsiElement(); - assert element instanceof JsonLiteral || element instanceof JsonReferenceExpression; - final String content = StringUtil.stripQuotesAroundValue(element.getText()); - element.replace(new JsonElementGenerator(project).createStringLiteral(content)); + if (element instanceof JsonLiteral || element instanceof JsonReferenceExpression) { + final String content = StringUtil.stripQuotesAroundValue(element.getText()); + element.replace(new JsonElementGenerator(project).createStringLiteral(content)); + } + else if (element != null) { + LOG.error("Quick fix was applied to unexpected element", element.getText(), element.getParent().getText()); + } } } } diff --git a/lib/gson-2.2.4.jar b/lib/gson-2.2.4.jar deleted file mode 100644 index 9478253e8cb6..000000000000 Binary files a/lib/gson-2.2.4.jar and /dev/null differ diff --git a/lib/gson-2.3.jar b/lib/gson-2.3.jar new file mode 100644 index 000000000000..a7f7ce5e993d Binary files /dev/null and b/lib/gson-2.3.jar differ diff --git a/lib/jsch-0.1.51.jar b/lib/jsch-0.1.51.jar index 70d13988ccec..725745f81a6d 100644 Binary files a/lib/jsch-0.1.51.jar and b/lib/jsch-0.1.51.jar differ diff --git a/lib/required_for_dist.txt b/lib/required_for_dist.txt index a989728f72e1..60d8770051a9 100644 --- a/lib/required_for_dist.txt +++ b/lib/required_for_dist.txt @@ -16,7 +16,7 @@ freemarker.jar httpmime-4.3.2.jar ecj-4.4.jar groovy-all-2.2.1.jar -gson-2.2.4.jar +gson-2.3.jar guava-17.0.jar hamcrest-core-1.3.jar hamcrest-library-1.3.jar diff --git a/lib/src/gson-2.2.4-sources.jar b/lib/src/gson-2.2.4-sources.jar deleted file mode 100644 index 30b13f653e57..000000000000 Binary files a/lib/src/gson-2.2.4-sources.jar and /dev/null differ diff --git a/lib/src/gson-2.3-sources.jar b/lib/src/gson-2.3-sources.jar new file mode 100644 index 000000000000..c62e327f8126 Binary files /dev/null and b/lib/src/gson-2.3-sources.jar differ diff --git a/platform/core-api/src/com/intellij/openapi/application/AccessToken.java b/platform/core-api/src/com/intellij/openapi/application/AccessToken.java deleted file mode 100644 index f567c15c51c3..000000000000 --- a/platform/core-api/src/com/intellij/openapi/application/AccessToken.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.intellij.openapi.application; - -public abstract class AccessToken { - protected void acquired() { - } - - protected void released() { - } - - public abstract void finish(); - - public static final AccessToken EMPTY_ACCESS_TOKEN = new AccessToken() { - @Override - public void finish() {} - }; -} diff --git a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerManagerImpl.java b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerManagerImpl.java index aad577c6ca95..42c3da458229 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerManagerImpl.java +++ b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerManagerImpl.java @@ -31,24 +31,20 @@ import com.intellij.psi.impl.PsiManagerEx; import com.intellij.psi.impl.source.tree.MarkersHolderFileViewProvider; import com.intellij.reference.SoftReference; import com.intellij.util.containers.UnsafeWeakList; -import gnu.trove.THashMap; -import gnu.trove.THashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.TestOnly; import java.lang.ref.Reference; import java.util.List; -import java.util.Map; -import java.util.Set; public class SmartPointerManagerImpl extends SmartPointerManager { private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.smartPointers.SmartPointerManagerImpl"); private final Project myProject; private final Object lock = new Object(); - private final Map> pointers = new THashMap>(); - private final Set fastenedFiles = new THashSet(); + private static final Key> POINTERS_KEY = Key.create("SMART_POINTERS"); + private static final Key POINTERS_ARE_FASTENED_KEY = Key.create("SMART_POINTERS_ARE_FASTENED"); public SmartPointerManagerImpl(Project project) { myProject = project; @@ -63,7 +59,7 @@ public class SmartPointerManagerImpl extends SmartPointerManager { if (getAndFasten(file)) return; if (pointers.isEmpty()) { - this.pointers.remove(file); + file.putUserData(POINTERS_KEY, null); } else { for (SmartPointerEx pointer : pointers) { @@ -101,7 +97,7 @@ public class SmartPointerManagerImpl extends SmartPointerManager { if (!getAndUnfasten(file)) return; if (pointers.isEmpty()) { - this.pointers.remove(file); + file.putUserData(POINTERS_KEY, null); } else { for (SmartPointerEx pointer : pointers) { @@ -169,6 +165,7 @@ public class SmartPointerManagerImpl extends SmartPointerManager { return null; } } + //noinspection unchecked return cachedPointer; } @@ -189,7 +186,7 @@ public class SmartPointerManagerImpl extends SmartPointerManager { List pointers = getPointers(containingFile); if (pointers == null) { pointers = new UnsafeWeakList(); // we synchronise access anyway - this.pointers.put(containingFile, pointers); + containingFile.putUserData(POINTERS_KEY, pointers); } pointers.add(pointer); @@ -222,8 +219,8 @@ public class SmartPointerManagerImpl extends SmartPointerManager { return false; } - private List getPointers(@NotNull VirtualFile containingFile) { - return pointers.get(containingFile); + private static List getPointers(@NotNull VirtualFile containingFile) { + return containingFile.getUserData(POINTERS_KEY); } @TestOnly @@ -234,14 +231,18 @@ public class SmartPointerManagerImpl extends SmartPointerManager { } } - private boolean getAndFasten(@NotNull VirtualFile file) { - return !fastenedFiles.add(file); + private static boolean getAndFasten(@NotNull VirtualFile file) { + boolean fastened = areBeltsFastened(file); + file.putUserData(POINTERS_ARE_FASTENED_KEY, Boolean.TRUE); + return fastened; } - private boolean getAndUnfasten(@NotNull VirtualFile file) { - return fastenedFiles.remove(file); + private static boolean getAndUnfasten(@NotNull VirtualFile file) { + boolean fastened = areBeltsFastened(file); + file.putUserData(POINTERS_ARE_FASTENED_KEY, null); + return fastened; } - private boolean areBeltsFastened(VirtualFile file) { - return fastenedFiles.contains(file); + private static boolean areBeltsFastened(VirtualFile file) { + return file.getUserData(POINTERS_ARE_FASTENED_KEY) == Boolean.TRUE; } @Override diff --git a/platform/core-impl/src/com/intellij/psi/impl/source/tree/FileElement.java b/platform/core-impl/src/com/intellij/psi/impl/source/tree/FileElement.java index a2348eabbe97..2e0d1a768a3c 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/source/tree/FileElement.java +++ b/platform/core-impl/src/com/intellij/psi/impl/source/tree/FileElement.java @@ -26,6 +26,7 @@ import com.intellij.psi.impl.source.PsiFileImpl; import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.IFileElementType; import com.intellij.psi.tree.ILightStubFileElementType; +import com.intellij.reference.SoftReference; import com.intellij.util.CharTable; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -50,7 +51,7 @@ public class FileElement extends LazyParseableElement implements FileASTNode, Ge return myCharTable; } - private static final Key ourTreeKey = Key.create("lighter.key"); + private static final Key> ourTreeKey = Key.create("lighter.key"); @Nullable @Override @@ -60,11 +61,11 @@ public class FileElement extends LazyParseableElement implements FileASTNode, Ge LighterAST tree; if (!isParsed()) { - tree = getUserData(ourTreeKey); + tree = SoftReference.dereference(getUserData(ourTreeKey)); if (tree == null) { final ILightStubFileElementType type = (ILightStubFileElementType)contentType; tree = new FCTSBackedLighterAST(getCharTable(), type.parseContentsLight(this)); - putUserData(ourTreeKey, tree); + putUserData(ourTreeKey, new SoftReference(tree)); } } else { diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/DvcsUtil.java b/platform/dvcs-impl/src/com/intellij/dvcs/DvcsUtil.java index bd30a10362b3..14643c274702 100644 --- a/platform/dvcs-impl/src/com/intellij/dvcs/DvcsUtil.java +++ b/platform/dvcs-impl/src/com/intellij/dvcs/DvcsUtil.java @@ -18,6 +18,7 @@ package com.intellij.dvcs; import com.intellij.dvcs.repo.Repository; import com.intellij.dvcs.repo.RepositoryManager; import com.intellij.ide.file.BatchFileChangeListener; +import com.intellij.openapi.application.AccessToken; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; @@ -189,13 +190,14 @@ public class DvcsUtil { return DateFormatUtil.formatPrettyDateTime(commit.getTimestamp()) + " "; } - public static void workingTreeChangeStarted(@NotNull Project project) { - HeavyProcessLatch.INSTANCE.processStarted("Changing DVCS working tree"); + @NotNull + public static AccessToken workingTreeChangeStarted(@NotNull Project project) { ApplicationManager.getApplication().getMessageBus().syncPublisher(BatchFileChangeListener.TOPIC).batchChangeStarted(project); + return HeavyProcessLatch.INSTANCE.processStarted("Changing DVCS working tree"); } - public static void workingTreeChangeFinished(@NotNull Project project) { - HeavyProcessLatch.INSTANCE.processFinished(); + public static void workingTreeChangeFinished(@NotNull Project project, @NotNull AccessToken token) { + token.finish(); ApplicationManager.getApplication().getMessageBus().syncPublisher(BatchFileChangeListener.TOPIC).batchChangeCompleted(project); } diff --git a/platform/icons/src/general/searchEverywhereGear.png b/platform/icons/src/general/searchEverywhereGear.png index 8500a59800e7..f220111a8812 100644 Binary files a/platform/icons/src/general/searchEverywhereGear.png and b/platform/icons/src/general/searchEverywhereGear.png differ diff --git a/platform/icons/src/general/searchEverywhereGear@2x.png b/platform/icons/src/general/searchEverywhereGear@2x.png index bbc8c4eaf04b..6cb1fd49d8d1 100644 Binary files a/platform/icons/src/general/searchEverywhereGear@2x.png and b/platform/icons/src/general/searchEverywhereGear@2x.png differ diff --git a/platform/icons/src/general/searchEverywhereGear@2x_dark.png b/platform/icons/src/general/searchEverywhereGear@2x_dark.png index a3658d816448..80364b2f7591 100644 Binary files a/platform/icons/src/general/searchEverywhereGear@2x_dark.png and b/platform/icons/src/general/searchEverywhereGear@2x_dark.png differ diff --git a/platform/icons/src/general/searchEverywhereGear_dark.png b/platform/icons/src/general/searchEverywhereGear_dark.png index d5848c477552..5d347e7d0ca6 100644 Binary files a/platform/icons/src/general/searchEverywhereGear_dark.png and b/platform/icons/src/general/searchEverywhereGear_dark.png differ diff --git a/platform/icons/src/providers/eclipse.png b/platform/icons/src/providers/eclipse.png index ff3f9a87e5e7..decb2e419889 100644 Binary files a/platform/icons/src/providers/eclipse.png and b/platform/icons/src/providers/eclipse.png differ diff --git a/platform/icons/src/providers/eclipse@2x.png b/platform/icons/src/providers/eclipse@2x.png index 3d2882f7d2e1..3d636e1cbbcb 100644 Binary files a/platform/icons/src/providers/eclipse@2x.png and b/platform/icons/src/providers/eclipse@2x.png differ diff --git a/platform/icons/src/providers/eclipse@2x_dark.png b/platform/icons/src/providers/eclipse@2x_dark.png index e46e0e907d6f..69c2860063de 100644 Binary files a/platform/icons/src/providers/eclipse@2x_dark.png and b/platform/icons/src/providers/eclipse@2x_dark.png differ diff --git a/platform/icons/src/providers/eclipse_dark.png b/platform/icons/src/providers/eclipse_dark.png index d7ad507ca70a..67979cc0a13b 100644 Binary files a/platform/icons/src/providers/eclipse_dark.png and b/platform/icons/src/providers/eclipse_dark.png differ diff --git a/platform/lang-api/src/com/intellij/execution/filters/CompositeInputFilter.java b/platform/lang-api/src/com/intellij/execution/filters/CompositeInputFilter.java index 1801f74869dc..0f7469dfc6a6 100644 --- a/platform/lang-api/src/com/intellij/execution/filters/CompositeInputFilter.java +++ b/platform/lang-api/src/com/intellij/execution/filters/CompositeInputFilter.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. @@ -59,6 +59,24 @@ public class CompositeInputFilter implements InputFilter { } public void addFilter(@NotNull final InputFilter filter) { - myFilters.add(Pair.create(filter, DumbService.isDumbAware(filter))); + InputFilter wrapper = new InputFilter() { + boolean isBroken; + + @Nullable + @Override + public List> applyFilter(String text, ConsoleViewContentType contentType) { + if (!isBroken) { + try { + return filter.applyFilter(text, contentType); + } + catch (Throwable e) { + isBroken = true; + LOG.error(e); + } + } + return null; + } + }; + myFilters.add(Pair.create(wrapper, DumbService.isDumbAware(filter))); } } diff --git a/platform/lang-api/src/com/intellij/execution/runners/ExecutionUtil.java b/platform/lang-api/src/com/intellij/execution/runners/ExecutionUtil.java index 5a395ab5dd79..1c3d265e4c86 100644 --- a/platform/lang-api/src/com/intellij/execution/runners/ExecutionUtil.java +++ b/platform/lang-api/src/com/intellij/execution/runners/ExecutionUtil.java @@ -122,7 +122,7 @@ public class ExecutionUtil { toolWindowManager.notifyByBalloon(toolWindowId, MessageType.ERROR, fullMessage, null, finalListener); } else { - Messages.showErrorDialog(project, fullMessage, ""); + Messages.showErrorDialog(project, UIUtil.toHtml(fullMessage), ""); } NotificationListener notificationListener = ObjectUtils.tryCast(finalListener, NotificationListener.class); ourNotificationGroup.createNotification(title, finalDescription, NotificationType.ERROR, notificationListener).notify(project); diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/DisplayPriority.java b/platform/lang-api/src/com/intellij/psi/codeStyle/DisplayPriority.java index feaff97d018b..b88105bec5f4 100644 --- a/platform/lang-api/src/com/intellij/psi/codeStyle/DisplayPriority.java +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/DisplayPriority.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. @@ -34,7 +34,7 @@ public enum DisplayPriority { */ CODE_SETTINGS, /** - * Key IDE language priority (depends on product), for exmaple, Java for IDEA, PHP for PhpStorm etc. + * Key IDE language priority (depends on product), for example, Java for IntelliJ IDEA, PHP for PhpStorm etc. */ KEY_LANGUAGE_SETTINGS, /** diff --git a/platform/lang-impl/src/com/intellij/codeInsight/actions/FormatChangedTextUtil.java b/platform/lang-impl/src/com/intellij/codeInsight/actions/FormatChangedTextUtil.java index dadafc7a7d84..72fe48a46e42 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/actions/FormatChangedTextUtil.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/actions/FormatChangedTextUtil.java @@ -86,15 +86,7 @@ public class FormatChangedTextUtil { return false; } final List ranges = lineStatusTracker.getRanges(); - if (ranges == null || ranges.isEmpty()) { - return false; - } - for (Range range : ranges) { - if (range.getType() != Range.DELETED) { - return true; - } - } - return false; + return !ranges.isEmpty(); } /** diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/EmacsStyleIndentAction.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/EmacsStyleIndentAction.java index 5709982ca892..83b85b1d842e 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/EmacsStyleIndentAction.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/EmacsStyleIndentAction.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. @@ -25,7 +25,6 @@ import com.intellij.lang.LanguageFormatting; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.editor.LogicalPosition; import com.intellij.openapi.editor.ScrollType; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.project.DumbAware; @@ -76,17 +75,12 @@ public class EmacsStyleIndentAction extends BaseCodeInsightAction implements Dum final Document document = editor.getDocument(); final int startOffset = editor.getCaretModel().getOffset(); final int line = editor.offsetToLogicalPosition(startOffset).line; - final int col = editor.getCaretModel().getLogicalPosition().column; final int lineStart = document.getLineStartOffset(line); - final int initLineEnd = document.getLineEndOffset(line); try{ final CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(project); final int newPos = codeStyleManager.adjustLineIndent(file, lineStart); - final int newCol = newPos - lineStart; - final int lineInc = document.getLineEndOffset(line) - initLineEnd; - if (newCol >= col + lineInc && newCol >= 0) { - final LogicalPosition pos = new LogicalPosition(line, newCol); - editor.getCaretModel().moveToLogicalPosition(pos); + if (editor.getCaretModel().getOffset() < newPos) { + editor.getCaretModel().moveToOffset(newPos); editor.getSelectionModel().removeSelection(); editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/generation/CommentByLineCommentHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/generation/CommentByLineCommentHandler.java index c6c281dc4114..47fc9e204c27 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/generation/CommentByLineCommentHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/generation/CommentByLineCommentHandler.java @@ -486,7 +486,7 @@ public class CommentByLineCommentHandler extends MultiCaretCodeInsightActionHand } if (endOffset >= suffix.length() && CharArrayUtil.regionMatches(document.getCharsSequence(), endOffset - suffix.length(), suffix)) { document.deleteString(endOffset - suffix.length(), endOffset); - endOffset = document.getTextLength(); + endOffset -= suffix.length(); } if (commentedPrefix != null && commentedSuffix != null) { CommentByBlockCommentHandler.commentNestedComments(document, new TextRange(startOffset, endOffset), commenter); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupActionHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupActionHandler.java index 80a0d05cb913..1ea0f9862af3 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupActionHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupActionHandler.java @@ -26,6 +26,7 @@ import com.intellij.featureStatistics.FeatureUsageTracker; import com.intellij.ide.ui.UISettings; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.editor.Caret; +import com.intellij.openapi.editor.CaretAction; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.actionSystem.EditorActionHandler; import com.intellij.openapi.project.DumbAwareAction; @@ -211,7 +212,7 @@ public abstract class LookupActionHandler extends EditorActionHandler { } @Override - protected void executeInLookup(LookupImpl lookup, DataContext context, Caret caret) { + protected void executeInLookup(LookupImpl lookup, DataContext context, final Caret caret) { final Editor editor = lookup.getEditor(); final int offset = editor.getCaretModel().getOffset(); CharSequence seq = editor.getDocument().getCharsSequence(); @@ -231,8 +232,19 @@ public abstract class LookupActionHandler extends EditorActionHandler { if (!lookup.performGuardedChange(new Runnable() { @Override public void run() { - editor.getSelectionModel().removeSelection(); - editor.getCaretModel().moveToOffset(offset + 1); + CaretAction action = new CaretAction() { + @Override + public void perform(Caret caret) { + caret.removeSelection(); + caret.moveToOffset(caret.getOffset() + 1); + } + }; + if (caret == null) { + editor.getCaretModel().runForEachCaret(action); + } + else { + action.perform(caret); + } } })) { return; diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionRVContentProvider.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionRVContentProvider.java index ec31a29b7f63..001930c3cbfc 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionRVContentProvider.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionRVContentProvider.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. @@ -21,6 +21,7 @@ package com.intellij.codeInspection.ex; import com.intellij.codeInspection.CommonProblemDescriptor; +import com.intellij.codeInspection.offlineViewer.OfflineInspectionRVContentProvider; import com.intellij.codeInspection.reference.RefEntity; import com.intellij.codeInspection.ui.*; import com.intellij.openapi.application.ApplicationManager; @@ -79,8 +80,7 @@ public abstract class InspectionRVContentProvider { InspectionToolPresentation presentation = context.getPresentation(wrapper); Map> content = presentation.getContent(); Map problems = presentation.getProblemElements(); - Map> contents = content == null ? new HashMap>() : content; - appendToolNodeContent(context, toolNode, parentNode, showStructure, contents, problems, null); + appendToolNodeContent(context, toolNode, parentNode, showStructure, content, problems, null); } public abstract void appendToolNodeContent(@NotNull GlobalInspectionContextImpl context, @@ -235,7 +235,9 @@ public abstract class InspectionRVContentProvider { public boolean accept(Object node) { if (node instanceof RefElementNode) { final RefElementNode refElementNode = (RefElementNode)node; - if (finalContainer.areEqual(refElementNode.getUserObject(), finalContainer.getUserObject())) { + final Object userObject = finalContainer.getUserObject(); + final Object object = refElementNode.getUserObject(); + if ((object == null || userObject.getClass().equals(object.getClass())) && finalContainer.areEqual(object, userObject)) { if (firstLevel.get()) { result.set(refElementNode); return false; diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionRVContentProviderImpl.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionRVContentProviderImpl.java index 83c4885d9334..28d4861e5348 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionRVContentProviderImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionRVContentProviderImpl.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. @@ -55,23 +55,21 @@ public class InspectionRVContentProviderImpl extends InspectionRVContentProvider final SearchScope searchScope = context.getCurrentScope().toSearchScope(); if (searchScope instanceof LocalSearchScope) { final Map> contents = presentation.getContent(); - if (contents != null) { - final Map problemElements = presentation.getProblemElements(); - for (Set entities : contents.values()) { - for (Iterator iterator = entities.iterator(); iterator.hasNext(); ) { - RefEntity entity = iterator.next(); - if (entity instanceof RefElement) { - final PsiElement element = ((RefElement)entity).getElement(); - if (element != null) { - final TextRange range = element.getTextRange(); - if (range != null && ((LocalSearchScope)searchScope).containsRange(element.getContainingFile(), range)) { - continue; - } + final Map problemElements = presentation.getProblemElements(); + for (Set entities : contents.values()) { + for (Iterator iterator = entities.iterator(); iterator.hasNext(); ) { + RefEntity entity = iterator.next(); + if (entity instanceof RefElement) { + final PsiElement element = ((RefElement)entity).getElement(); + if (element != null) { + final TextRange range = element.getTextRange(); + if (range != null && ((LocalSearchScope)searchScope).containsRange(element.getContainingFile(), range)) { + continue; } } - problemElements.remove(entity); - iterator.remove(); } + problemElements.remove(entity); + iterator.remove(); } } } @@ -106,7 +104,7 @@ public class InspectionRVContentProviderImpl extends InspectionRVContentProvider }; InspectionToolPresentation presentation = context.getPresentation(toolWrapper); final Set moduleProblems = presentation.getModuleProblems(); - if (moduleProblems != null && !moduleProblems.isEmpty()) { + if (!moduleProblems.isEmpty()) { Set entities = contents.get(""); if (entities == null) { entities = new HashSet(); diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/DefaultInspectionToolPresentation.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/DefaultInspectionToolPresentation.java index fe7c3ab22b81..131c8002af70 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/DefaultInspectionToolPresentation.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/DefaultInspectionToolPresentation.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. @@ -42,6 +42,7 @@ import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.HashSet; import com.intellij.util.ui.UIUtil; import gnu.trove.THashMap; +import gnu.trove.THashSet; import org.jdom.Element; import org.jdom.IllegalDataException; import org.jetbrains.annotations.NonNls; @@ -63,13 +64,13 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro protected InspectionNode myToolNode; private static final Object lock = new Object(); - private Map myProblemElements; - private Map> myContents = null; - private Set myModulesProblems = null; - private Map myProblemToElements; + private final Map myProblemElements = Collections.synchronizedMap(new THashMap()); + private final Map> myContents = Collections.synchronizedMap(new com.intellij.util.containers.HashMap>()); // keys can be null + private final Set myModulesProblems = Collections.synchronizedSet(new THashSet()); + private final Map myProblemToElements = Collections.synchronizedMap(new THashMap()); private DescriptorComposer myComposer; - private Map> myQuickFixActions; - private Map myIgnoredElements; + private final Map> myQuickFixActions = Collections.synchronizedMap(new com.intellij.util.containers.HashMap>()); + private final Map myIgnoredElements = Collections.synchronizedMap(new com.intellij.util.containers.HashMap()); private Map myOldProblemElements = null; protected static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.ex.DescriptorProviderInspection"); @@ -223,13 +224,16 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro if (view == null || !(refElement instanceof RefElement)) { return; } - InspectionNode toolNode = myToolNode; - if (toolNode == null) { + final InspectionNode toolNode; + if (myToolNode == null) { final HighlightSeverity currentSeverity = getSeverity((RefElement)refElement); - view.addTool(myToolWrapper, HighlightDisplayLevel.find(currentSeverity), context.getUIOptions().GROUP_BY_SEVERITY); + toolNode = view.addTool(myToolWrapper, HighlightDisplayLevel.find(currentSeverity), context.getUIOptions().GROUP_BY_SEVERITY); } - else if (toolNode.isTooBigForOnlineRefresh()) { - return; + else { + toolNode = myToolNode; + if (toolNode.isTooBigForOnlineRefresh()) { + return; + } } final Map problems = new HashMap(); problems.put(refElement, descriptors); @@ -246,8 +250,8 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro @Override public void run() { if (!isDisposed()) { - view.getProvider().appendToolNodeContent(context, myToolNode, - (InspectionTreeNode)myToolNode.getParent(), context.getUIOptions().SHOW_STRUCTURE, + view.getProvider().appendToolNodeContent(context, toolNode, + (InspectionTreeNode)toolNode.getParent(), context.getUIOptions().SHOW_STRUCTURE, contents, problems, (DefaultTreeModel)view.getTree().getModel()); context.addView(view); } @@ -275,7 +279,7 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro final File file = new File(fileName); final CharArrayWriter writer = new CharArrayWriter(); if (!file.exists()) { - writer.append("<").append(InspectionsBundle.message("inspection.problems")).append(" " + GlobalInspectionContextImpl.LOCAL_TOOL_ATTRIBUTE + "=\"") + writer.append("<").append(InspectionsBundle.message("inspection.problems")).append(" " + GlobalInspectionContextBase.LOCAL_TOOL_ATTRIBUTE + "=\"") .append(Boolean.toString(myToolWrapper instanceof LocalInspectionToolWrapper)).append("\">\n"); } for (Object o : list) { @@ -393,14 +397,14 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro myOldProblemElements = null; synchronized (lock) { - myProblemElements = null; - myProblemToElements = null; - myQuickFixActions = null; - myIgnoredElements = null; + myProblemElements.clear(); + myProblemToElements.clear(); + myQuickFixActions.clear(); + myIgnoredElements.clear(); + myContents.clear(); + myModulesProblems.clear(); } - myContents = null; - myModulesProblems = null; isDisposed = true; } @@ -525,8 +529,8 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro @Override public void updateContent() { - myContents = new com.intellij.util.containers.HashMap>(); - myModulesProblems = new HashSet(); + myContents.clear(); + myModulesProblems.clear(); final Set elements = getProblemElements().keySet(); for (RefEntity element : elements) { if (getContext().getUIOptions().FILTER_RESOLVED_ITEMS && getIgnoredElements().containsKey(element)) continue; @@ -545,6 +549,7 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro } } + @NotNull @Override public Map> getContent() { return myContents; @@ -553,8 +558,7 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro @Override public Map> getOldContent() { if (myOldProblemElements == null) return null; - final com.intellij.util.containers.HashMap> - oldContents = new com.intellij.util.containers.HashMap>(); + final Map> oldContents = new com.intellij.util.containers.HashMap>(); final Set elements = myOldProblemElements.keySet(); for (RefEntity element : elements) { String groupName = element instanceof RefElement ? element.getRefManager().getGroupName((RefElement)element) : element.getName(); @@ -573,6 +577,7 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro return oldContents; } + @NotNull @Override public Set getModuleProblems() { return myModulesProblems; @@ -719,12 +724,7 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro @Override @NotNull public Map getProblemElements() { - synchronized (lock) { - if (myProblemElements == null) { - myProblemElements = Collections.synchronizedMap(new THashMap()); - } - return myProblemElements; - } + return myProblemElements; } @Override @@ -735,32 +735,17 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro @NotNull private Map getProblemToElements() { - synchronized (lock) { - if (myProblemToElements == null) { - myProblemToElements = Collections.synchronizedMap(new THashMap()); - } - return myProblemToElements; - } + return myProblemToElements; } @NotNull private Map> getQuickFixActions() { - synchronized (lock) { - if (myQuickFixActions == null) { - myQuickFixActions = Collections.synchronizedMap(new com.intellij.util.containers.HashMap>()); - } - return myQuickFixActions; - } + return myQuickFixActions; } @NotNull private Map getIgnoredElements() { - synchronized (lock) { - if (myIgnoredElements == null) { - myIgnoredElements = Collections.synchronizedMap(new com.intellij.util.containers.HashMap()); - } - return myIgnoredElements; - } + return myIgnoredElements; } @NotNull diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionToolPresentation.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionToolPresentation.java index 87263fec882c..c7f632575815 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionToolPresentation.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionToolPresentation.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. @@ -45,6 +45,7 @@ public interface InspectionToolPresentation extends ProblemDescriptionsProcessor boolean hasReportedProblems(); + @NotNull Map> getContent(); Map> getOldContent(); @@ -63,6 +64,7 @@ public interface InspectionToolPresentation extends ProblemDescriptionsProcessor @NotNull HTMLComposerImpl getComposer(); void exportResults(@NotNull final Element parentNode, @NotNull RefEntity refEntity); + @NotNull Set getModuleProblems(); @Nullable QuickFixAction[] getQuickFixes(@NotNull final RefEntity[] refElements); diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/ExportHTMLAction.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/ExportHTMLAction.java index 4604de37b915..b633b8de98dc 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/ExportHTMLAction.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/ExportHTMLAction.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. @@ -19,7 +19,10 @@ package com.intellij.codeInspection.ui.actions; import com.intellij.codeEditor.printing.ExportToHTMLSettings; import com.intellij.codeInspection.InspectionApplication; import com.intellij.codeInspection.InspectionsBundle; -import com.intellij.codeInspection.ex.*; +import com.intellij.codeInspection.ex.GlobalInspectionContextImpl; +import com.intellij.codeInspection.ex.InspectionToolWrapper; +import com.intellij.codeInspection.ex.ScopeToolState; +import com.intellij.codeInspection.ex.Tools; import com.intellij.codeInspection.export.ExportToHTMLDialog; import com.intellij.codeInspection.export.HTMLExportFrameMaker; import com.intellij.codeInspection.export.HTMLExportUtil; @@ -247,9 +250,7 @@ public class ExportHTMLAction extends AnAction implements DumbAware { for (InspectionToolWrapper toolWrapper : toolWrappers) { InspectionToolPresentation presentation = myView.getGlobalInspectionContext().getPresentation(toolWrapper); final Map> toolContent = presentation.getContent(); - if (toolContent != null) { - content.putAll(toolContent); - } + content.putAll(toolContent); } final Set defaultPackageEntities = content.remove(null); @@ -285,9 +286,7 @@ public class ExportHTMLAction extends AnAction implements DumbAware { for (InspectionToolWrapper toolWrapper : toolWrappers) { InspectionToolPresentation presentation = myView.getGlobalInspectionContext().getPresentation(toolWrapper); final Set problems = presentation.getModuleProblems(); - if (problems != null) { - modules.addAll(problems); - } + modules.addAll(problems); } final List sortedModules = new ArrayList(modules); diff --git a/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java b/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java index 711184d9b705..87e2f12a18d8 100644 --- a/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java @@ -750,7 +750,7 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider { history.getSettings().setAdditionalColumnsCount(2 + (width - historySize.width) / EditorUtil.getSpaceWidth(Font.PLAIN, history)); } - // deal with height, WEB-11122 we cannot trust editor width — it could be 0 in case of soft wrap even if editor has text + // deal with height, WEB-11122 we cannot trust editor width - it could be 0 in case of soft wrap even if editor has text if (history.getDocument().getLineCount() == 0) { historySize.height = 0; } diff --git a/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java b/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java index c20c8195ac56..325cd41dc501 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java @@ -316,25 +316,8 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo myInputMessageFilter = compositeInputFilter; for (ConsoleInputFilterProvider eachProvider : inputFilters) { InputFilter[] filters = eachProvider.getDefaultFilters(project); - for (final InputFilter filter : filters) { - compositeInputFilter.addFilter(new InputFilter() { - boolean isBroken; - - @Nullable - @Override - public List> applyFilter(String text, ConsoleViewContentType contentType) { - if (!isBroken) { - try { - return filter.applyFilter(text, contentType); - } - catch (Throwable e) { - isBroken = true; - LOG.error(e); - } - } - return null; - } - }); + for (InputFilter filter : filters) { + compositeInputFilter.addFilter(filter); } } } diff --git a/platform/lang-impl/src/com/intellij/injected/editor/EditorWindowImpl.java b/platform/lang-impl/src/com/intellij/injected/editor/EditorWindowImpl.java index 10bf53bce6bb..f1619d483e85 100644 --- a/platform/lang-impl/src/com/intellij/injected/editor/EditorWindowImpl.java +++ b/platform/lang-impl/src/com/intellij/injected/editor/EditorWindowImpl.java @@ -570,9 +570,15 @@ public class EditorWindowImpl extends UserDataHolderBase implements EditorWindow @Override public int logicalPositionToOffset(@NotNull final LogicalPosition pos) { + return logicalPositionToOffset(pos, true); + } + + @Override + public int logicalPositionToOffset(@NotNull LogicalPosition pos, boolean softWrapAware) { int lineStartOffset = myDocumentWindow.getLineStartOffset(pos.line); return calcOffset(pos.column, pos.line, lineStartOffset); } + private int calcLogicalColumnNumber(int offsetInLine, int lineNumber, int lineStartOffset) { if (myDocumentWindow.getTextLength() == 0) return 0; @@ -583,13 +589,25 @@ public class EditorWindowImpl extends UserDataHolderBase implements EditorWindow CharSequence text = myDocumentWindow.getCharsSequence(); return EditorUtil.calcColumnNumber(this, text, lineStartOffset, lineStartOffset +offsetInLine); } + private int calcOffset(int col, int lineNumber, int lineStartOffset) { if (myDocumentWindow.getTextLength() == 0) return 0; int end = myDocumentWindow.getLineEndOffset(lineNumber); - CharSequence text = myDocumentWindow.getCharsSequence(); - return EditorUtil.calcOffset(this, text, lineStartOffset, end, col, EditorUtil.getTabSize(myDelegate), null); + int x = getDocument().getLineNumber(lineStartOffset) == 0 ? getPrefixTextWidthInPixels() : 0; + + // There is a possible case that target column points inside soft wrap-introduced virtual space. + if (col <= 0) { + return lineStartOffset; + } + + int result = EditorUtil.calcSoftWrapUnawareOffset(this, myDocumentWindow.getCharsSequence(), lineStartOffset, end, col, + EditorUtil.getTabSize(myDelegate), x, new int[]{0}, null); + if (result >= 0) { + return result; + } + return end; } @Override diff --git a/platform/lang-impl/src/com/intellij/unscramble/AnnotateStackTraceAction.java b/platform/lang-impl/src/com/intellij/unscramble/AnnotateStackTraceAction.java index 450b82e3cddc..42b1ef5e79be 100644 --- a/platform/lang-impl/src/com/intellij/unscramble/AnnotateStackTraceAction.java +++ b/platform/lang-impl/src/com/intellij/unscramble/AnnotateStackTraceAction.java @@ -37,6 +37,7 @@ import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.progress.Task; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vcs.AbstractVcs; import com.intellij.openapi.vcs.FilePath; import com.intellij.openapi.vcs.VcsException; @@ -46,15 +47,13 @@ import com.intellij.openapi.vcs.actions.VcsContextFactory; import com.intellij.openapi.vcs.annotate.AnnotationSource; import com.intellij.openapi.vcs.annotate.ShowAllAffectedGenericAction; import com.intellij.openapi.vcs.ex.ProjectLevelVcsManagerEx; -import com.intellij.openapi.vcs.history.VcsFileRevision; -import com.intellij.openapi.vcs.history.VcsHistoryProvider; -import com.intellij.openapi.vcs.history.VcsHistorySession; -import com.intellij.openapi.vcs.history.VcsRevisionNumber; +import com.intellij.openapi.vcs.history.*; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.text.DateFormatUtil; import com.intellij.vcsUtil.VcsUtil; import com.intellij.xml.util.XmlStringUtil; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.awt.*; import java.util.*; @@ -65,7 +64,7 @@ import java.util.List; */ public class AnnotateStackTraceAction extends AnAction implements DumbAware { private final EditorHyperlinkSupport myHyperlinks; - private Map cache; + private Map cache; private int newestLine = -1; private int maxDateLength = 0; private final Editor myEditor; @@ -81,8 +80,8 @@ public class AnnotateStackTraceAction extends AnAction implements DumbAware { } @Override - public void actionPerformed(AnActionEvent e) { - cache = new HashMap(); + public void actionPerformed(final AnActionEvent e) { + cache = new HashMap(); ProgressManager.getInstance().run( new Task.Backgroundable(myEditor.getProject(), "Getting file history", true, PerformInBackgroundOption.ALWAYS_BACKGROUND) { @@ -99,7 +98,7 @@ public class AnnotateStackTraceAction extends AnAction implements DumbAware { final EditorGutterAction action = new EditorGutterAction() { @Override public void doAction(int lineNum) { - final VcsFileRevision revision = cache.get(lineNum); + final LastRevision revision = cache.get(lineNum); final List links = myHyperlinks.findAllHyperlinksOnLine(lineNum); if (!links.isEmpty()) { final RangeHighlighter key = links.get(links.size() - 1); @@ -110,7 +109,7 @@ public class AnnotateStackTraceAction extends AnAction implements DumbAware { final Project project = getProject(); final AbstractVcs vcs = ProjectLevelVcsManagerEx.getInstanceEx(project).getVcsFor(file); if (vcs != null) { - final VcsRevisionNumber number = revision.getRevisionNumber(); + final VcsRevisionNumber number = revision.getNumber(); final VcsKey vcsKey = vcs.getKeyInstanceMethod(); ShowAllAffectedGenericAction.showSubmittedFiles(project, number, file, vcsKey); } @@ -136,23 +135,23 @@ public class AnnotateStackTraceAction extends AnAction implements DumbAware { @Override public String getLineText(int line, Editor editor) { - final VcsFileRevision revision = cache.get(line); + final LastRevision revision = cache.get(line); if (revision != null) { - return String.format("%"+maxDateLength+"s", DateFormatUtil.formatPrettyDate(revision.getRevisionDate())) + " " + revision.getAuthor(); + return String.format("%"+maxDateLength+"s", DateFormatUtil.formatPrettyDate(revision.getDate())) + " " + revision.getAuthor(); } return ""; } @Override public String getToolTip(int line, Editor editor) { - final VcsFileRevision revision = cache.get(line); + final LastRevision revision = cache.get(line); if (revision != null) { return XmlStringUtil.wrapInHtml( revision.getAuthor() + " " + - DateFormatUtil.formatDateTime(revision.getRevisionDate()) + + DateFormatUtil.formatDateTime(revision.getDate()) + "
" + - revision.getCommitMessage() + revision.getMessage() ); } return null; @@ -218,51 +217,66 @@ public class AnnotateStackTraceAction extends AnAction implements DumbAware { for (VirtualFile file : files) { indicator.checkCanceled(); - final AbstractVcs vcs = VcsUtil.getVcsFor(myEditor.getProject(), file); - FilePath filePath = VcsContextFactory.SERVICE.getInstance().createFilePathOn(file); - if (vcs != null) { - try { - final VcsHistoryProvider provider = vcs.getVcsHistoryProvider(); - final VcsHistorySession session; - if (provider != null) { - session = provider.createSessionFor(filePath); - final List list; - if (session != null) { - list = session.getRevisionList(); - final List lines = files2lines.get(file); - if (list != null && !list.isEmpty()) { - final VcsFileRevision revision = list.get(0); - final Date date = revision.getRevisionDate(); - if (newestDate == null || date.after(newestDate)) { - newestDate = date; - newestLine = lines.get(0); - } - final int length = DateFormatUtil.formatPrettyDate(date).length(); - if (length > maxDateLength) { - maxDateLength = length; - } - for (Integer line : lines) { - cache.put(line, revision); - } - ApplicationManager.getApplication().invokeLater(new Runnable() { - @Override - public void run() { - if (!myGutterShowed) { - showGutter(); - } else { - ((EditorGutterComponentEx)myEditor.getGutter()).revalidateMarkup(); - } - } - }); - } + + LastRevision revision = getLastRevision(file); + if (revision != null) { + final List lines = files2lines.get(file); + + final Date date = revision.getDate(); + if (newestDate == null || date.after(newestDate)) { + newestDate = date; + newestLine = lines.get(0); + } + final int length = DateFormatUtil.formatPrettyDate(date).length(); + if (length > maxDateLength) { + maxDateLength = length; + } + for (Integer line : lines) { + cache.put(line, revision); + } + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + if (!myGutterShowed) { + showGutter(); + } + else { + ((EditorGutterComponentEx)myEditor.getGutter()).revalidateMarkup(); } } - } - catch (VcsException ignored) { - ignored.printStackTrace(); - } + }); } + } + } + @Nullable + private LastRevision getLastRevision(@NotNull VirtualFile file) { + try { + final AbstractVcs vcs = VcsUtil.getVcsFor(myEditor.getProject(), file); + if (vcs == null) return null; + + VcsHistoryProvider historyProvider = vcs.getVcsHistoryProvider(); + if (historyProvider == null) return null; + + FilePath filePath = VcsContextFactory.SERVICE.getInstance().createFilePathOn(file); + + if (historyProvider instanceof VcsHistoryProviderEx) { + VcsFileRevision revision = ((VcsHistoryProviderEx)historyProvider).getLastRevision(filePath); + if (revision == null) return null; + return LastRevision.create(revision); + } else { + VcsHistorySession session = historyProvider.createSessionFor(filePath); + if (session == null) return null; + + List list = session.getRevisionList(); + if (list == null || list.isEmpty()) return null; + + return LastRevision.create(list.get(0)); + } + } + catch (VcsException ignored) { + ignored.printStackTrace(); + return null; } } }); @@ -272,4 +286,47 @@ public class AnnotateStackTraceAction extends AnAction implements DumbAware { public void update(AnActionEvent e) { e.getPresentation().setEnabled(cache == null || !myGutterShowed); } + + private static class LastRevision { + @NotNull private final VcsRevisionNumber myNumber; + @NotNull private final String myAuthor; + @NotNull private final Date myDate; + @NotNull private final String myMessage; + + public LastRevision(@NotNull VcsRevisionNumber number, @NotNull String author, @NotNull Date date, @NotNull String message) { + myNumber = number; + myAuthor = author; + myDate = date; + myMessage = message; + } + + @NotNull + public static LastRevision create(@NotNull VcsFileRevision revision) { + VcsRevisionNumber number = revision.getRevisionNumber(); + String author = StringUtil.notNullize(revision.getAuthor(), "Unknown"); + Date date = revision.getRevisionDate(); + String message = StringUtil.notNullize(revision.getCommitMessage()); + return new LastRevision(number, author, date, message); + } + + @NotNull + public VcsRevisionNumber getNumber() { + return myNumber; + } + + @NotNull + public String getAuthor() { + return myAuthor; + } + + @NotNull + public Date getDate() { + return myDate; + } + + @NotNull + public String getMessage() { + return myMessage; + } + } } diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/IdeActions.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/IdeActions.java index 9d7a307615dc..a5e9f1da7fc1 100644 --- a/platform/platform-api/src/com/intellij/openapi/actionSystem/IdeActions.java +++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/IdeActions.java @@ -49,6 +49,7 @@ public interface IdeActions { @NonNls String ACTION_EDITOR_NEXT_WORD_WITH_SELECTION = "EditorNextWordWithSelection"; @NonNls String ACTION_EDITOR_PREVIOUS_WORD_WITH_SELECTION = "EditorPreviousWordWithSelection"; @NonNls String ACTION_EDITOR_TAB = "EditorTab"; + @NonNls String ACTION_EDITOR_EMACS_TAB = "EmacsStyleIndent"; @NonNls String ACTION_EDITOR_ESCAPE = "EditorEscape"; @NonNls String ACTION_EDITOR_JOIN_LINES = "EditorJoinLines"; @NonNls String ACTION_EDITOR_COMPLETE_STATEMENT = "EditorCompleteStatement"; diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/TypeSafeDataProvider.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/TypeSafeDataProvider.java index ac9ef8b1599a..5919c3928946 100644 --- a/platform/platform-api/src/com/intellij/openapi/actionSystem/TypeSafeDataProvider.java +++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/TypeSafeDataProvider.java @@ -22,6 +22,10 @@ */ package com.intellij.openapi.actionSystem; +/** + * @deprecated This API proved to be rather inconvenient + * @see com.intellij.openapi.actionSystem.DataProvider + */ public interface TypeSafeDataProvider { void calcData(DataKey key, DataSink sink); } \ No newline at end of file diff --git a/platform/platform-api/src/com/intellij/openapi/ui/SimpleToolWindowPanel.java b/platform/platform-api/src/com/intellij/openapi/ui/SimpleToolWindowPanel.java index c4523819c0f1..dfbaa33999fb 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/SimpleToolWindowPanel.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/SimpleToolWindowPanel.java @@ -22,9 +22,11 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Ref; import com.intellij.openapi.wm.ToolWindow; import com.intellij.ui.content.Content; +import com.intellij.ui.content.ContentManager; import com.intellij.ui.content.ContentManagerAdapter; import com.intellij.ui.content.ContentManagerEvent; import com.intellij.ui.switcher.QuickActionProvider; +import com.intellij.ui.tabs.JBTabs; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.AwtVisitor; import com.intellij.util.ui.UIUtil; @@ -189,7 +191,21 @@ public class SimpleToolWindowPanel extends JPanel implements QuickActionProvider myToolWindow.getContentManager().addContentManagerListener(new ContentManagerAdapter() { @Override public void contentAdded(ContentManagerEvent event) { - setContentToolbarVisible(event.getContent(), getVisibilityValue()); + JComponent component = event.getContent().getComponent(); + setContentToolbarVisible(component, getVisibilityValue()); + + // support nested content managers, e.g. RunnerLayoutUi as content component + ContentManager contentManager = + component instanceof DataProvider ? PlatformDataKeys.CONTENT_MANAGER.getData((DataProvider)component) : null; + if (contentManager != null) contentManager.addContentManagerListener(this); + } + + @Override + public void selectionChanged(ContentManagerEvent event) { + Content content = event.getContent(); + if (content != null) { + setContentToolbarVisible(content.getComponent(), getVisibilityValue()); + } } }); } @@ -203,7 +219,7 @@ public class SimpleToolWindowPanel extends JPanel implements QuickActionProvider public void setSelected(AnActionEvent e, boolean state) { myPropertiesComponent.setValue(getProperty(), String.valueOf(state), String.valueOf(true)); for (Content content : myToolWindow.getContentManager().getContents()) { - setContentToolbarVisible(content, state); + setContentToolbarVisible(content.getComponent(), state); } } @@ -216,19 +232,17 @@ public class SimpleToolWindowPanel extends JPanel implements QuickActionProvider return myPropertiesComponent.getBoolean(getProperty(), true); } - private static void setContentToolbarVisible(Content content, boolean state) { - LinkedList deque = ContainerUtil.newLinkedList(content.getComponent()); + private static void setContentToolbarVisible(@NotNull JComponent root, boolean state) { + LinkedList deque = ContainerUtil.newLinkedList(root); while(!deque.isEmpty()) { JComponent component = deque.pollFirst(); - if (!(component instanceof JPanel)) continue; - for (int i = 0, count = component.getComponentCount(); i < count; i++) { Component c = component.getComponent(i); if (c instanceof ActionToolbar) { c.setVisible(state); } - else if (c instanceof JPanel) { - deque.addLast((JPanel)c); + else if (c instanceof JPanel || c instanceof JLayeredPane || c instanceof JBTabs) { + deque.addLast((JComponent)c); } } } diff --git a/platform/platform-api/src/com/intellij/ui/ScrollPaneFactory.java b/platform/platform-api/src/com/intellij/ui/ScrollPaneFactory.java index 21c400d0ac0b..a5a17ff09270 100644 --- a/platform/platform-api/src/com/intellij/ui/ScrollPaneFactory.java +++ b/platform/platform-api/src/com/intellij/ui/ScrollPaneFactory.java @@ -58,6 +58,7 @@ public class ScrollPaneFactory implements ScrollPaneConstants { JBScrollPane scrollPane = new JBScrollPane(view); if (withoutBorder) { scrollPane.setBorder(IdeBorderFactory.createEmptyBorder()); // set empty border, because setting null doesn't always take effect + scrollPane.setViewportBorder(IdeBorderFactory.createEmptyBorder()); } return scrollPane; } diff --git a/platform/platform-api/src/com/intellij/ui/tabs/impl/TabLabel.java b/platform/platform-api/src/com/intellij/ui/tabs/impl/TabLabel.java index 7e0054db4f66..34728f1093b8 100644 --- a/platform/platform-api/src/com/intellij/ui/tabs/impl/TabLabel.java +++ b/platform/platform-api/src/com/intellij/ui/tabs/impl/TabLabel.java @@ -242,9 +242,9 @@ public class TabLabel extends JPanel { }); final Composite oldComposite = ((Graphics2D)g).getComposite(); - if (myTabs instanceof JBEditorTabs && !myTabs.isSingleRow() && myTabs.getSelectedInfo() != myInfo) { - ((Graphics2D)g).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.9f)); - } + //if (myTabs instanceof JBEditorTabs && !myTabs.isSingleRow() && myTabs.getSelectedInfo() != myInfo) { + // ((Graphics2D)g).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.9f)); + //} super.paint(g); ((Graphics2D)g).setComposite(oldComposite); diff --git a/platform/platform-api/src/com/intellij/util/Url.java b/platform/platform-api/src/com/intellij/util/Url.java index f78b237d7070..80d3fe9cd668 100644 --- a/platform/platform-api/src/com/intellij/util/Url.java +++ b/platform/platform-api/src/com/intellij/util/Url.java @@ -1,9 +1,24 @@ +/* + * 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.util; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -// We don't use Java URI due to problem — http://cns-etuat-2.localnet.englishtown.com/school/e12/#school/45383/201/221/382?c=countrycode=cc|culturecode=en-us|partnercode=mkge +// We don't use Java URI due to problem - http://cns-etuat-2.localnet.englishtown.com/school/e12/#school/45383/201/221/382?c=countrycode=cc|culturecode=en-us|partnercode=mkge // it is illegal URI (fragment before query), but we must support such URI // Semicolon as parameters separator is supported (WEB-6671) public interface Url { diff --git a/platform/platform-impl/src/com/intellij/execution/ExecutableValidator.java b/platform/platform-impl/src/com/intellij/execution/ExecutableValidator.java index 023c059d4f8d..c8597c393c07 100644 --- a/platform/platform-impl/src/com/intellij/execution/ExecutableValidator.java +++ b/platform/platform-impl/src/com/intellij/execution/ExecutableValidator.java @@ -48,10 +48,10 @@ public abstract class ExecutableValidator { private static final NotificationGroup ourNotificationGroup = new NotificationGroup("External Executable Critical Failures", STICKY_BALLOON, true); @NotNull protected final Project myProject; - @NotNull private final NotificationsManager myNotificationManager; + @NotNull protected final NotificationsManager myNotificationManager; @NotNull private final String myNotificationErrorTitle; - @NotNull private String myNotificationErrorDescription; + @NotNull private final String myNotificationErrorDescription; /** * Configures notification and dialog by setting text messages and titles specific to the whoever uses the validator. @@ -76,6 +76,16 @@ public abstract class ExecutableValidator { @NotNull protected abstract String getConfigurableDisplayName(); + @Nullable + protected Notification validate(@NotNull String executable) { + return !isExecutableValid(executable) ? createDefaultNotification() : null; + } + + @NotNull + protected ExecutableNotValidNotification createDefaultNotification() { + return new ExecutableNotValidNotification(); + } + /** * Returns true if the supplied executable is valid. * Default implementation: try to execute the given executable and test if output returned errors. @@ -109,41 +119,44 @@ public abstract class ExecutableValidator { } } - public void setNotificationErrorDescription(@NotNull String notificationErrorDescription) { - myNotificationErrorDescription = notificationErrorDescription; - } - /** * Shows a notification about not configured executable with a link to the Settings to fix it. * Expires the notification if user fixes the path from the opened Settings dialog. * Makes sure that there is always only one notification about the problem in the stack of notifications. */ - private void showExecutableNotConfiguredNotification() { + private void showExecutableNotConfiguredNotification(@NotNull Notification notification) { if (ApplicationManager.getApplication().isUnitTestMode() || ApplicationManager.getApplication().isHeadlessEnvironment()) { return; } LOG.info("Executable is not valid: " + getCurrentExecutable()); - if (myNotificationManager.getNotificationsOfType(ExecutableNotValidNotification.class, myProject).length == 0) { // show only once - new ExecutableNotValidNotification().notify(myProject.isDefault() ? null : myProject); + if (myNotificationManager.getNotificationsOfType(notification.getClass(), myProject).length == 0) { // show only once + notification.notify(myProject.isDefault() ? null : myProject); } } @NotNull - private String prepareDescription() { + protected String prepareDescription(@NotNull String description, boolean appendFixIt) { + StringBuilder result = new StringBuilder(); String executable = getCurrentExecutable(); + if (executable.isEmpty()) { - return String.format("%s%s Fix it.", myNotificationErrorTitle, myNotificationErrorDescription); + result.append(String.format("%s%s", myNotificationErrorTitle, description)); } else { - return String.format("%s: %s
%s Fix it.", - myNotificationErrorTitle, executable, myNotificationErrorDescription); + result.append( + String.format("%s: %s
%s", myNotificationErrorTitle, executable, description)); } + if (appendFixIt) { + result.append(" Fix it."); + } + + return result.toString(); } protected void showSettingsAndExpireIfFixed(@NotNull Notification notification) { showSettings(); - if (isExecutableValid(getCurrentExecutable())) { + if (validate(getCurrentExecutable()) == null) { notification.expire(); } } @@ -161,8 +174,14 @@ public abstract class ExecutableValidator { if (myProject.isDisposed()) { return false; } - if (!isExecutableValid(getCurrentExecutable())) { - showExecutableNotConfiguredNotification(); + Notification notification = validate(getCurrentExecutable()); + + return notify(notification); + } + + protected boolean notify(@Nullable Notification notification) { + if (notification != null) { + showExecutableNotConfiguredNotification(notification); return false; } return true; @@ -209,9 +228,18 @@ public abstract class ExecutableValidator { return isExecutableValid(getCurrentExecutable()); } - private class ExecutableNotValidNotification extends Notification { - private ExecutableNotValidNotification() { - super(ourNotificationGroup.getDisplayId(), "", prepareDescription(), NotificationType.ERROR, new NotificationListener.Adapter() { + public class ExecutableNotValidNotification extends Notification { + + public ExecutableNotValidNotification() { + this(myNotificationErrorDescription); + } + + public ExecutableNotValidNotification(@NotNull String description) { + this(prepareDescription(description, true), NotificationType.ERROR); + } + + public ExecutableNotValidNotification(@NotNull String preparedDescription, @NotNull NotificationType type) { + super(ourNotificationGroup.getDisplayId(), "", preparedDescription, type, new NotificationListener.Adapter() { @Override protected void hyperlinkActivated(@NotNull Notification notification, @NotNull HyperlinkEvent event) { showSettingsAndExpireIfFixed(notification); diff --git a/platform/platform-impl/src/com/intellij/ide/customize/CustomizeFeaturedPluginsStepPanel.java b/platform/platform-impl/src/com/intellij/ide/customize/CustomizeFeaturedPluginsStepPanel.java index 61b3ac4ab20c..5800120dd4ce 100644 --- a/platform/platform-impl/src/com/intellij/ide/customize/CustomizeFeaturedPluginsStepPanel.java +++ b/platform/platform-impl/src/com/intellij/ide/customize/CustomizeFeaturedPluginsStepPanel.java @@ -20,7 +20,6 @@ import com.intellij.icons.AllIcons; import com.intellij.ide.plugins.IdeaPluginDescriptor; import com.intellij.ide.plugins.PluginManagerCore; import com.intellij.ide.plugins.PluginNode; -import com.intellij.openapi.options.OptionsBundle; import com.intellij.openapi.progress.util.AbstractProgressIndicatorExBase; import com.intellij.openapi.ui.VerticalFlowLayout; import com.intellij.openapi.updateSettings.impl.PluginDownloader; @@ -262,7 +261,6 @@ public class CustomizeFeaturedPluginsStepPanel extends AbstractCustomizeWizardSt public String getHTMLFooter() { return "New plugins can also be downloaded in " + CommonBundle.settingsTitle() - + " | " + OptionsBundle.message("configurable.group.appearance.settings.display.name") + " | " + "Plugins"; } diff --git a/platform/platform-impl/src/com/intellij/ide/impl/DataManagerImpl.java b/platform/platform-impl/src/com/intellij/ide/impl/DataManagerImpl.java index bea92c9626b9..2a13e1c73889 100644 --- a/platform/platform-impl/src/com/intellij/ide/impl/DataManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/ide/impl/DataManagerImpl.java @@ -30,7 +30,9 @@ import com.intellij.openapi.util.Key; import com.intellij.openapi.util.UserDataHolder; import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.wm.IdeFocusManager; +import com.intellij.openapi.wm.IdeFrame; import com.intellij.openapi.wm.ex.WindowManagerEx; +import com.intellij.openapi.wm.impl.FloatingDecorator; import com.intellij.util.KeyedLazyInstanceEP; import com.intellij.util.containers.WeakValueHashMap; import gnu.trove.THashMap; @@ -248,6 +250,21 @@ public class DataManagerImpl extends DataManager { } } + // In case we have an active floating toolwindow and some component in another window focused, + // we want this other component to receive key events. + // Walking up the window ownership hierarchy from the floating toolwindow would have led us to the main IdeFrame + // whereas we want to be able to type in other frames as well. + if (activeWindow instanceof FloatingDecorator) { + IdeFocusManager ideFocusManager = IdeFocusManager.findInstanceByComponent(activeWindow); + IdeFrame lastFocusedFrame = ideFocusManager.getLastFocusedFrame(); + JComponent frameComponent = lastFocusedFrame != null ? lastFocusedFrame.getComponent() : null; + Window lastFocusedWindow = frameComponent != null ? SwingUtilities.getWindowAncestor(frameComponent) : null; + boolean toolWindowIsNotFocused = myWindowManager.getFocusedComponent(activeWindow) == null; + if (toolWindowIsNotFocused && lastFocusedWindow != null) { + activeWindow = lastFocusedWindow; + } + } + // try to find first parent window that has focus Window window = activeWindow; Component focusedComponent = null; diff --git a/platform/platform-impl/src/com/intellij/ide/startup/impl/StartupManagerImpl.java b/platform/platform-impl/src/com/intellij/ide/startup/impl/StartupManagerImpl.java index b4128553a480..b3b23dc86a56 100644 --- a/platform/platform-impl/src/com/intellij/ide/startup/impl/StartupManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/ide/startup/impl/StartupManagerImpl.java @@ -17,6 +17,7 @@ package com.intellij.ide.startup.impl; import com.intellij.ide.caches.CacheUpdater; import com.intellij.ide.startup.StartupManagerEx; +import com.intellij.openapi.application.AccessToken; import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationBundle; import com.intellij.openapi.application.ApplicationManager; @@ -113,7 +114,7 @@ public class StartupManagerImpl extends StartupManagerEx { @Override @SuppressWarnings("SynchronizeOnThis") public void run() { - HeavyProcessLatch.INSTANCE.processStarted("Running Startup Activities"); + AccessToken token = HeavyProcessLatch.INSTANCE.processStarted("Running Startup Activities"); try { runActivities(myPreStartupActivities); @@ -133,7 +134,7 @@ public class StartupManagerImpl extends StartupManagerEx { } } finally { - HeavyProcessLatch.INSTANCE.processFinished(); + token.finish(); } } }); diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionMenuItem.java b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionMenuItem.java index 1c6fa05e4fb5..e9eb88fec11d 100644 --- a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionMenuItem.java +++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionMenuItem.java @@ -56,11 +56,11 @@ public class ActionMenuItem extends JCheckBoxMenuItem { private final Presentation myPresentation; private final String myPlace; private final boolean myInsideCheckedGroup; + private final boolean myEnableMnemonics; + private final boolean myToggleable; private DataContext myContext; private AnActionEvent myEvent; private MenuItemSynchronizer myMenuItemSynchronizer; - private final boolean myEnableMnemonics; - private final boolean myToggleable; private boolean myToggled; public ActionMenuItem(final AnAction action, @@ -92,6 +92,10 @@ public class ActionMenuItem extends JCheckBoxMenuItem { } } + private static boolean isEnterKeyStroke(KeyStroke keyStroke) { + return keyStroke.getKeyCode() == KeyEvent.VK_ENTER && keyStroke.getModifiers() == 0; + } + public void prepare() { init(); installSynchronizer(); @@ -170,10 +174,6 @@ public class ActionMenuItem extends JCheckBoxMenuItem { } } - private static boolean isEnterKeyStroke(KeyStroke keyStroke) { - return keyStroke.getKeyCode() == KeyEvent.VK_ENTER && keyStroke.getModifiers() == 0; - } - @Override public void updateUI() { if (UIUtil.isStandardMenuLAF()) { @@ -208,6 +208,52 @@ public class ActionMenuItem extends JCheckBoxMenuItem { myEvent = new AnActionEvent(null, context, myPlace, myPresentation, ActionManager.getInstance(), 0); } + private void updateIcon(AnAction action) { + if (isToggleable() && (myPresentation.getIcon() == null || myInsideCheckedGroup || !UISettings.getInstance().SHOW_ICONS_IN_MENUS)) { + action.update(myEvent); + myToggled = Boolean.TRUE.equals(myEvent.getPresentation().getClientProperty(Toggleable.SELECTED_PROPERTY)); + if (ActionPlaces.MAIN_MENU.equals(myPlace) && SystemInfo.isMacSystemMenu || + UIUtil.isUnderNimbusLookAndFeel() || + UIUtil.isUnderWindowsLookAndFeel() && SystemInfo.isWin7OrNewer) { + setState(myToggled); + } + else if (!(getUI() instanceof GtkMenuItemUI)) { + if (myToggled) { + setIcon(ourCheckedIcon); + setDisabledIcon(IconLoader.getDisabledIcon(ourCheckedIcon)); + } + else { + setIcon(ourUncheckedIcon); + setDisabledIcon(IconLoader.getDisabledIcon(ourUncheckedIcon)); + } + } + } + else { + if (UISettings.getInstance().SHOW_ICONS_IN_MENUS) { + Icon icon = myPresentation.getIcon(); + if (action instanceof ToggleAction && ((ToggleAction)action).isSelected(myEvent)) { + icon = new PoppedIcon(icon, 16, 16); + } + setIcon(icon); + if (myPresentation.getDisabledIcon() != null) { + setDisabledIcon(myPresentation.getDisabledIcon()); + } + else { + setDisabledIcon(IconLoader.getDisabledIcon(icon)); + } + } + } + } + + public boolean isToggleable() { + return myToggleable; + } + + @Override + public boolean isSelected() { + return myToggled; + } + private final class ActionTransmitter implements ActionListener { /** * @param component component @@ -274,52 +320,6 @@ public class ActionMenuItem extends JCheckBoxMenuItem { } } - private void updateIcon(AnAction action) { - if (isToggleable() && (myPresentation.getIcon() == null || myInsideCheckedGroup)) { - action.update(myEvent); - myToggled = Boolean.TRUE.equals(myEvent.getPresentation().getClientProperty(Toggleable.SELECTED_PROPERTY)); - if (ActionPlaces.MAIN_MENU.equals(myPlace) && SystemInfo.isMacSystemMenu || - UIUtil.isUnderNimbusLookAndFeel() || - UIUtil.isUnderWindowsLookAndFeel() && SystemInfo.isWin7OrNewer) { - setState(myToggled); - } - else if (!(getUI() instanceof GtkMenuItemUI)) { - if (myToggled) { - setIcon(ourCheckedIcon); - setDisabledIcon(IconLoader.getDisabledIcon(ourCheckedIcon)); - } - else { - setIcon(ourUncheckedIcon); - setDisabledIcon(IconLoader.getDisabledIcon(ourUncheckedIcon)); - } - } - } - else { - if (UISettings.getInstance().SHOW_ICONS_IN_MENUS) { - Icon icon = myPresentation.getIcon(); - if (action instanceof ToggleAction && ((ToggleAction)action).isSelected(myEvent)) { - icon = new PoppedIcon(icon, 16, 16); - } - setIcon(icon); - if (myPresentation.getDisabledIcon() != null) { - setDisabledIcon(myPresentation.getDisabledIcon()); - } - else { - setDisabledIcon(IconLoader.getDisabledIcon(icon)); - } - } - } - } - - public boolean isToggleable() { - return myToggleable; - } - - @Override - public boolean isSelected() { - return myToggled; - } - private final class MenuItemSynchronizer implements PropertyChangeListener, Disposable { @NonNls private static final String SELECTED = "selected"; diff --git a/platform/platform-impl/src/com/intellij/openapi/application/ConfigImportHelper.java b/platform/platform-impl/src/com/intellij/openapi/application/ConfigImportHelper.java index b376ad8c324d..10c1b8078c6f 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/ConfigImportHelper.java +++ b/platform/platform-impl/src/com/intellij/openapi/application/ConfigImportHelper.java @@ -22,10 +22,7 @@ import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.AppUIUtil; -import com.intellij.util.PlatformUtils; -import com.intellij.util.ReflectionUtil; -import com.intellij.util.SmartList; -import com.intellij.util.ThreeState; +import com.intellij.util.*; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -74,7 +71,7 @@ public class ConfigImportHelper { } assert oldConfigDir != null; - doImport(newConfigDir, oldConfigDir); + doImport(newConfigDir, oldConfigDir, settings, installationHome); settings.importFinished(newConfigPath); System.setProperty(CONFIG_IMPORTED_IN_CURRENT_SESSION_KEY, Boolean.TRUE.toString()); } @@ -139,9 +136,9 @@ public class ConfigImportHelper { return (SystemInfo.isMac ? "" : ".") + selector.replaceAll("\\d", ""); } - private static void doImport(@NotNull File newConfigDir, @NotNull File oldConfigDir) { + private static void doImport(@NotNull File newConfigDir, @NotNull File oldConfigDir, ConfigImportSettings settings, File installationHome) { try { - copy(oldConfigDir, newConfigDir); + copy(oldConfigDir, newConfigDir, settings, installationHome); } catch (IOException e) { JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), @@ -169,7 +166,7 @@ public class ConfigImportHelper { return true; } - private static void copy(@NotNull File src, @NotNull File dest) throws IOException { + private static void copy(@NotNull File src, @NotNull File dest, ConfigImportSettings settings, File oldInstallationHome) throws IOException { src = src.getCanonicalFile(); dest = dest.getCanonicalFile(); if (!src.isDirectory()) { @@ -207,6 +204,23 @@ public class ConfigImportHelper { } File plugins = new File(src, PLUGINS_PATH); + if (!loadOldPlugins(plugins, dest) && SystemInfo.isMac) { + File oldPluginsDir = getOldPath(oldInstallationHome, settings, PathManager.PROPERTY_PLUGINS_PATH, + new Function() { + @Override + public String fun(String pathSelector) { + return PathManager.getDefaultPluginPathFor(pathSelector); + } + }); + if (oldPluginsDir == null) { + //e.g. installation home referred to config home. Try with default selector, same as config name + oldPluginsDir = new File(PathManager.getDefaultPluginPathFor(src.getName())); + } + loadOldPlugins(oldPluginsDir, dest); + } + } + + private static boolean loadOldPlugins(File plugins, File dest) throws IOException { if (plugins.exists()) { List descriptors = new SmartList(); PluginManagerCore.loadDescriptors(plugins, descriptors, null, 0); @@ -220,7 +234,9 @@ public class ConfigImportHelper { if (!oldPlugins.isEmpty()) { PluginManagerCore.savePluginsList(oldPlugins, false, new File(dest, PluginManager.INSTALLED_TXT)); } + return true; } + return false; } @Nullable @@ -244,12 +260,24 @@ public class ConfigImportHelper { return new File(oldInstallHome, "config"); } + return getOldPath(oldInstallHome, settings, PathManager.PROPERTY_CONFIG_PATH, new Function() { + @Override + public String fun(String pathsSelector) { + return PathManager.getDefaultConfigPathFor(pathsSelector); + } + }); + } + + private static File getOldPath(final File oldInstallHome, + final ConfigImportSettings settings, + final String propertyName, + final Function fromPathSelector) { final File[] launchFileCandidates = getLaunchFilesCandidates(oldInstallHome, settings); // custom config folder for (File candidate : launchFileCandidates) { if (candidate.exists()) { - String configDir = PathManager.substituteVars(getPropertyFromLaxFile(candidate, PathManager.PROPERTY_CONFIG_PATH), + String configDir = PathManager.substituteVars(getPropertyFromLaxFile(candidate, propertyName), oldInstallHome.getPath()); if (configDir != null) { File probableConfig = new File(configDir); @@ -263,7 +291,7 @@ public class ConfigImportHelper { if (candidate.exists()) { final String pathsSelector = getPropertyFromLaxFile(candidate, PathManager.PROPERTY_PATHS_SELECTOR); if (pathsSelector != null) { - final String configDir = PathManager.getDefaultConfigPathFor(pathsSelector); + final String configDir = fromPathSelector.fun(pathsSelector); final File probableConfig = new File(configDir); if (probableConfig.exists()) { return probableConfig; diff --git a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java index 7194dbddaecb..4a500fc2a321 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java @@ -502,7 +502,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App myIsFiringLoadingEvent = false; } - HeavyProcessLatch.INSTANCE.processStarted("Loading application components"); + AccessToken token = HeavyProcessLatch.INSTANCE.processStarted("Loading application components"); try { store.load(); } @@ -510,7 +510,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App throw new IOException(e.getMessage()); } finally { - HeavyProcessLatch.INSTANCE.processFinished(); + token.finish(); } myLoaded = true; diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/ServiceManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/ServiceManagerImpl.java index a315e8f2560c..b568ce9e6bad 100644 --- a/platform/platform-impl/src/com/intellij/openapi/components/impl/ServiceManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/ServiceManagerImpl.java @@ -16,6 +16,7 @@ package com.intellij.openapi.components.impl; import com.intellij.openapi.Disposable; +import com.intellij.openapi.application.AccessToken; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.BaseComponent; import com.intellij.openapi.components.ComponentConfig; @@ -199,7 +200,7 @@ public class ServiceManagerImpl implements BaseComponent { @Override public Object compute() { // prevent storages from flushing and blocking FS - HeavyProcessLatch.INSTANCE.processStarted("Creating component '" + myDescriptor.getImplementation()+"'"); + AccessToken token = HeavyProcessLatch.INSTANCE.processStarted("Creating component '" + myDescriptor.getImplementation() + "'"); try { synchronized (MyComponentAdapter.this) { Object instance = myInitializedComponentInstance; @@ -209,7 +210,7 @@ public class ServiceManagerImpl implements BaseComponent { } } finally { - HeavyProcessLatch.INSTANCE.processFinished(); + token.finish(); } } }); diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorEx.java b/platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorEx.java index 237f272266f0..2776693048fa 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorEx.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorEx.java @@ -178,6 +178,8 @@ public interface EditorEx extends Editor { @NotNull VisualPosition logicalToVisualPosition(@NotNull LogicalPosition logicalPos, boolean softWrapAware); + int logicalPositionToOffset(@NotNull LogicalPosition logicalPos, boolean softWrapAware); + /** * Creates color scheme delegate which is bound to current editor. E.g. all schema changes will update editor state. * @param customGlobalScheme diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/ex/SoftWrapModelEx.java b/platform/platform-impl/src/com/intellij/openapi/editor/ex/SoftWrapModelEx.java index e3c03c2fbbd4..ed7bd263cf6c 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/ex/SoftWrapModelEx.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/ex/SoftWrapModelEx.java @@ -50,6 +50,14 @@ public interface SoftWrapModelEx extends SoftWrapModel { @NotNull LogicalPosition offsetToLogicalPosition(int offset); + /** + * Asks current model to map given logical position to document offset + * + * @param logicalPosition target editor logical position + * @return document offset for the given editor logical position + */ + int logicalPositionToOffset(@NotNull LogicalPosition logicalPosition); + /** * Asks current model to adjust visual position that corresponds to the given logical position if necessary. *

diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/ex/util/EditorUtil.java b/platform/platform-impl/src/com/intellij/openapi/editor/ex/util/EditorUtil.java index 7d9973fed2d3..037bbc8337bc 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/ex/util/EditorUtil.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/ex/util/EditorUtil.java @@ -222,7 +222,12 @@ public final class EditorUtil { * @param tabSize number of desired visual columns to use for tabulation representation * @param debugBuffer buffer to hold debug info during the processing (if any) * @return given text offset that identifies the same position that is pointed by the given visual column + * + * @deprecated This function can give incorrect results when soft wraps are enabled in editor. It is also slow in case of + * long document lines - {@link com.intellij.openapi.editor.Editor#logicalPositionToOffset(com.intellij.openapi.editor.LogicalPosition)} + * should be faster when soft wraps are enabled. To be removed in IDEA 16. */ + @SuppressWarnings("UnusedDeclaration") public static int calcOffset(@NotNull EditorEx editor, @NotNull CharSequence text, int start, @@ -291,7 +296,7 @@ public final class EditorUtil { * @return target offset that belongs to the [start; end) range and points to the target logical * column if any; -1 otherwise */ - private static int calcSoftWrapUnawareOffset(@NotNull Editor editor, + public static int calcSoftWrapUnawareOffset(@NotNull Editor editor, @NotNull CharSequence text, int start, int end, diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretImpl.java index a84baee39f19..ca6de1b8c65f 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretImpl.java @@ -200,15 +200,14 @@ public class CaretImpl extends UserDataHolderBase implements Caret { final DocumentEx document = myEditor.getDocument(); int textEnd = Math.min(document.getTextLength() - 1, Math.max(offset, myOffset) + 1); CharSequence text = document.getCharsSequence().subSequence(textStart, textEnd); - StringBuilder positionToOffsetTrace = new StringBuilder(); - int inverseOffset = myEditor.logicalPositionToOffset(logicalPosition, positionToOffsetTrace); + int inverseOffset = myEditor.logicalPositionToOffset(logicalPosition); LogMessageEx.error( LOG, "caret moved to wrong offset. Please submit a dedicated ticket and attach current editor's text to it.", String.format( "Requested: offset=%d, logical position='%s' but actual: offset=%d, logical position='%s' (%s). %s%n" - + "interested text [%d;%d): '%s'%n debug trace: %s%nLogical position -> offset ('%s'->'%d') trace: %s", + + "interested text [%d;%d): '%s'%n debug trace: %s%nLogical position -> offset ('%s'->'%d')", offset, logicalPosition, myOffset, myLogicalCaret, positionByOffsetAfterMove, myEditor.dumpState(), - textStart, textEnd, text, debugBuffer, logicalPosition, inverseOffset, positionToOffsetTrace + textStart, textEnd, text, debugBuffer, logicalPosition, inverseOffset ) ); } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/DefaultEditorTextRepresentationHelper.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/DefaultEditorTextRepresentationHelper.java index 61415eb90ce4..483d179fac3a 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/DefaultEditorTextRepresentationHelper.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/DefaultEditorTextRepresentationHelper.java @@ -19,7 +19,6 @@ import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.ex.util.EditorUtil; import gnu.trove.TObjectIntHashMap; import org.intellij.lang.annotations.JdkConstants; -import org.jetbrains.annotations.NotNull; /** * Not thread-safe. Performs caching of char widths, so cache reset must be invoked (via {@link #clearSymbolWidthCache()} method) when @@ -52,8 +51,8 @@ public class DefaultEditorTextRepresentationHelper implements EditorTextRepresen } @Override - public int toVisualColumnSymbolsNumber(@NotNull CharSequence text, int start, int end, int x) { - return EditorUtil.textWidthInColumns(myEditor, text, start, end, x); + public int toVisualColumnSymbolsNumber(int start, int end, int x) { + return EditorUtil.textWidthInColumns(myEditor, myEditor.getDocument().getImmutableCharSequence(), start, end, x); } @Override @@ -67,7 +66,14 @@ public class DefaultEditorTextRepresentationHelper implements EditorTextRepresen } @Override - public int textWidth(@NotNull CharSequence text, int start, int end, int fontType, int x) { + public int calcSoftWrapUnawareOffset(int startOffset, int endOffset, int startColumn, int column, int startX) { + return EditorUtil.calcSoftWrapUnawareOffset(myEditor, myEditor.getDocument().getImmutableCharSequence(), startOffset, endOffset, + column, EditorUtil.getTabSize(myEditor), startX, new int[]{startColumn}, null); + } + + @Override + public int textWidth(int start, int end, int fontType, int x) { + CharSequence text = myEditor.getDocument().getImmutableCharSequence(); int startToUse = start; for (int i = end - 1; i >= start; i--) { if (text.charAt(i) == '\n') { diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java index 861287d8558b..5179512af245 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java @@ -1340,7 +1340,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi if (softWrapAware) { return mySoftWrapModel.offsetToLogicalPosition(offset); } - int line = offsetToLogicalLine(offset, false); + int line = offsetToLogicalLine(offset); int column = calcColumnNumber(offset, line, false, myDocument.getImmutableCharSequence()); return new LogicalPosition(line, column); } @@ -3656,11 +3656,14 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi @Override public int logicalPositionToOffset(@NotNull LogicalPosition pos) { - return logicalPositionToOffset(pos, null); + return logicalPositionToOffset(pos, true); } - - public int logicalPositionToOffset(@NotNull LogicalPosition pos, @Nullable StringBuilder debugBuffer) { + @Override + public int logicalPositionToOffset(@NotNull LogicalPosition pos, boolean softWrapAware) { + if (softWrapAware) { + return mySoftWrapModel.logicalPositionToOffset(pos); + } assertReadAccess(); if (myDocument.getLineCount() == 0) return 0; @@ -3675,9 +3678,15 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi if (pos.column == 0) return start; int end = myDocument.getLineEndOffset(pos.line); - CharSequence text = myDocument.getImmutableCharSequence(); + int x = getDocument().getLineNumber(start) == 0 ? getPrefixTextWidthInPixels() : 0; - return EditorUtil.calcOffset(this, text, start, end, pos.column, EditorUtil.getTabSize(this), debugBuffer); + int result = EditorUtil.calcSoftWrapUnawareOffset(this, myDocument.getImmutableCharSequence(), start, end, pos.column, + EditorUtil.getTabSize(this), x, new int[]{0}, null); + if (result >= 0) { + return result; + } + + return end; } @Override @@ -3872,7 +3881,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi FoldRegion lastCollapsedBefore = getLastCollapsedBeforePosition(visiblePos); if (lastCollapsedBefore != null) { - int logFoldEndLine = offsetToLogicalLine(lastCollapsedBefore.getEndOffset(), false); + int logFoldEndLine = offsetToLogicalLine(lastCollapsedBefore.getEndOffset()); int visFoldEndLine = logicalToVisualLine(logFoldEndLine); line = logFoldEndLine + visiblePos.line - visFoldEndLine; @@ -3894,10 +3903,6 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi } int offsetToLogicalLine(int offset) { - return offsetToLogicalLine(offset, true); - } - - private int offsetToLogicalLine(int offset, boolean softWrapAware) { int textLength = myDocument.getTextLength(); if (textLength == 0) return 0; @@ -3908,13 +3913,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi int lineIndex = myDocument.getLineNumber(offset); LOG.assertTrue(lineIndex >= 0 && lineIndex < myDocument.getLineCount()); - if (softWrapAware && getSoftWrapModel().isSoftWrappingEnabled()) { - int column = calcColumnNumber(offset, lineIndex, false, myDocument.getImmutableCharSequence()); - return mySoftWrapModel.adjustLogicalPosition(new LogicalPosition(lineIndex, column), offset).line; - } - else { - return lineIndex; - } + return lineIndex; } @Override @@ -3930,7 +3929,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi int column = EditorUtil.calcColumnNumber(this, documentCharSequence, lineStartOffset, offset); if (softWrapAware) { - int line = offsetToLogicalLine(offset, false); + int line = offsetToLogicalLine(offset); return mySoftWrapModel.adjustLogicalPosition(new LogicalPosition(line, column), offset).column; } else { diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorTextRepresentationHelper.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorTextRepresentationHelper.java index 85f5bd11ed5d..5c66c0bc64f5 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorTextRepresentationHelper.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorTextRepresentationHelper.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 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,6 @@ package com.intellij.openapi.editor.impl; import org.intellij.lang.annotations.JdkConstants; -import org.jetbrains.annotations.NotNull; /** * Strategy interface for various utility methods used for representing document text at the editor. @@ -37,13 +36,12 @@ public interface EditorTextRepresentationHelper { * Allows to answer how many visual columns is necessary for representing target fragment of the given text assuming * that it belongs to the single visual line and should be shown at given 'x' offset from the visual line start. * - * @param text target text holder * @param start start offset of the target text sub-sequence (inclusive) * @param end end offset of the target text sub-sequence (exclusive) * @param x 'x' offset from the visual line start * @return number of visual columns necessary for the target text sub-sequence representation */ - int toVisualColumnSymbolsNumber(@NotNull CharSequence text, int start, int end, int x); + int toVisualColumnSymbolsNumber(int start, int end, int x); /** * Allows to retrieve width (in pixels) necessary to represent given region ([start; end)) starting @@ -52,17 +50,16 @@ public interface EditorTextRepresentationHelper { * Note: target region is allows to contain line feeds, the width is calculated as a difference between 'x' * coordinates of the last and first symbols. * - * @param text target text holder * @param start start offset of the target text sub-sequence (inclusive) * @param end end offset of the target text sub-sequence (exclusive) * @param fontType font type used for the given substring representation * @param x 'x' offset from the visual line start * @return width in pixels necessary for the target text sub-sequence representation */ - int textWidth(@NotNull CharSequence text, int start, int end, @JdkConstants.FontStyle int fontType, int x); + int textWidth(int start, int end, @JdkConstants.FontStyle int fontType, int x); /** - * This is specification of {@link #textWidth(CharSequence, int, int, int, int)} in case of the single character + * This is specification of {@link #textWidth(int, int, int, int)} in case of the single character * (in comparison with the situation when we need to calculate width of particular text). *

* Note: it's assumed that given symbols is a regular one (non-tabulation, non-line feed etc). @@ -72,4 +69,16 @@ public interface EditorTextRepresentationHelper { * @return width in pixels necessary for the target char representation */ int charWidth(char c, @JdkConstants.FontStyle int fontType); + + /** + * Translates column number to offset in the given document interval (which is assumed not to contain line breaks or soft wraps). + * + * @param startOffset interval start offset + * @param endOffset interval end offset + * @param startColumn interval start column + * @param column target column + * @param startX interval start visual coordinate + * @return offset, corresponding to the given column, in the range [startOffset; endOffset), or -1 if such offset doesn't exist + */ + int calcSoftWrapUnawareOffset(int startOffset, int endOffset, int startColumn, int column, int startX); } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java index 94aad9480c12..83cc0387866c 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java @@ -16,6 +16,7 @@ package com.intellij.openapi.editor.impl; import com.intellij.diagnostic.Dumpable; +import com.intellij.injected.editor.EditorWindow; import com.intellij.openapi.Disposable; import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; @@ -62,6 +63,7 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi private static final Logger LOG = Logger.getInstance("#" + SoftWrapModelImpl.class.getName()); + private final LogicalPositionToOffsetTask myLogicalToOffsetTask = new LogicalPositionToOffsetTask(); private final OffsetToLogicalTask myOffsetToLogicalTask = new OffsetToLogicalTask(); private final VisualToLogicalTask myVisualToLogicalTask = new VisualToLogicalTask(); private final LogicalToVisualTask myLogicalToVisualTask = new LogicalToVisualTask(); @@ -148,8 +150,7 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi } } }); - EditorSettings settings = myEditor.getSettings(); - myUseSoftWraps = settings.isUseSoftWraps(); + myUseSoftWraps = areSoftWrapsEnabledInEditor(); myFontPreferences = myEditor.getColorsScheme().getFontPreferences(); editor.addPropertyChangeListener(this); @@ -157,13 +158,16 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi myApplianceManager.addListener(myDataMapper); } + private boolean areSoftWrapsEnabledInEditor() { + return !(myEditor instanceof EditorWindow) && myEditor.getSettings().isUseSoftWraps(); + } + /** * Called on editor settings change. Current model is expected to drop all cached information about the settings if any. */ public void reinitSettings() { boolean softWrapsUsedBefore = myUseSoftWraps; - EditorSettings settings = myEditor.getSettings(); - myUseSoftWraps = settings.isUseSoftWraps(); + myUseSoftWraps = areSoftWrapsEnabledInEditor(); int tabWidthBefore = myTabWidth; myTabWidth = EditorUtil.getTabSize(myEditor); @@ -372,6 +376,21 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi } } + @Override + public int logicalPositionToOffset(@NotNull LogicalPosition logicalPosition) { + if (myBulkUpdateInProgress || myUpdateInProgress || !prepareToMapping()) { + return myEditor.logicalPositionToOffset(logicalPosition, false); + } + myActive++; + try { + myLogicalToOffsetTask.input = logicalPosition; + executeSafely(myLogicalToOffsetTask); + return myLogicalToOffsetTask.output; + } finally { + myActive--; + } + } + @NotNull public LogicalPosition adjustLogicalPosition(LogicalPosition defaultLogical, int offset) { if (myBulkUpdateInProgress || myUpdateInProgress || !prepareToMapping()) { @@ -788,6 +807,22 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi } } + private class LogicalPositionToOffsetTask implements SoftWrapAwareTask { + + public LogicalPosition input; + public int output; + + @Override + public void run(boolean softWrapAware) throws IllegalStateException { + output = softWrapAware ? myDataMapper.logicalPositionToOffset(input) : myEditor.logicalPositionToOffset(input, false); + } + + @Override + public String toString() { + return "mapping from logical position (" + input + ") to offset"; + } + } + private class FoldProcessingEndTask implements SoftWrapAwareTask { @Override public void run(boolean softWrapAware) { diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/SoftWrapDataMapper.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/SoftWrapDataMapper.java index 874b0c47355c..ae6d115dc270 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/SoftWrapDataMapper.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/SoftWrapDataMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 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. @@ -62,4 +62,13 @@ public interface SoftWrapDataMapper { */ VisualPosition logicalToVisualPosition(@NotNull LogicalPosition logical, @NotNull VisualPosition softWrapUnawareVisual) throws IllegalStateException; + + /** + * Maps given logical position to corresponding offset. + * + * @param logical logical position to map + * @return offset that corresponds to the given logical position + * @throws IllegalStateException if it's not possible to perform a mapping + */ + int logicalPositionToOffset(@NotNull LogicalPosition logical) throws IllegalStateException; } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/AbstractMappingStrategy.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/AbstractMappingStrategy.java index bccdf4c59336..7e068caea39e 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/AbstractMappingStrategy.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/AbstractMappingStrategy.java @@ -16,9 +16,9 @@ package com.intellij.openapi.editor.impl.softwrap.mapping; import com.intellij.openapi.editor.Document; -import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.FoldRegion; import com.intellij.openapi.editor.LogicalPosition; +import com.intellij.openapi.editor.ex.EditorEx; import com.intellij.openapi.editor.impl.softwrap.SoftWrapsStorage; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -37,7 +37,7 @@ import java.util.List; */ abstract class AbstractMappingStrategy implements MappingStrategy { - protected final Editor myEditor; + protected final EditorEx myEditor; protected final SoftWrapsStorage myStorage; protected final List myCache; @@ -46,7 +46,7 @@ abstract class AbstractMappingStrategy implements MappingStrategy { private T myEagerMatch; private int myLastEntryOffset; - AbstractMappingStrategy(@NotNull Editor editor, + AbstractMappingStrategy(@NotNull EditorEx editor, @NotNull SoftWrapsStorage storage, @NotNull List cache) { @@ -154,7 +154,11 @@ abstract class AbstractMappingStrategy implements MappingStrategy { if (result != null) { return result; } + advancePositionOnFolding(position, foldRegion); + return null; + } + protected void advancePositionOnFolding(@NotNull EditorPosition position, @NotNull FoldRegion foldRegion) { Document document = myEditor.getDocument(); int endOffsetLogicalLine = document.getLineNumber(foldRegion.getEndOffset()); if (position.logicalLine != endOffsetLogicalLine) { @@ -171,7 +175,6 @@ abstract class AbstractMappingStrategy implements MappingStrategy { } position.advance(foldRegion, collapsedSymbolsWidthInColumns); - return null; } @Nullable diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/CachingSoftWrapDataMapper.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/CachingSoftWrapDataMapper.java index 2f21b0319af2..38b03c706a15 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/CachingSoftWrapDataMapper.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/CachingSoftWrapDataMapper.java @@ -67,6 +67,7 @@ public class CachingSoftWrapDataMapper implements SoftWrapDataMapper, SoftWrapAw private final CacheState myBeforeChangeState = new CacheState(); private final CacheState myAfterChangeState = new CacheState(); + private final LogicalToOffsetCalculationStrategy myLogicalToOffsetStrategy; private final OffsetToLogicalCalculationStrategy myOffsetToLogicalStrategy; private final VisualToLogicalCalculationStrategy myVisualToLogicalStrategy; private final EditorEx myEditor; @@ -79,6 +80,7 @@ public class CachingSoftWrapDataMapper implements SoftWrapDataMapper, SoftWrapAw myStorage = storage; mySearchKey = new CacheEntry(0, editor); + myLogicalToOffsetStrategy = new LogicalToOffsetCalculationStrategy(editor, storage, myCache); myOffsetToLogicalStrategy = new OffsetToLogicalCalculationStrategy(editor, storage, myCache); myVisualToLogicalStrategy = new VisualToLogicalCalculationStrategy(editor, storage, myCache); } @@ -101,6 +103,12 @@ public class CachingSoftWrapDataMapper implements SoftWrapDataMapper, SoftWrapAw return calculate(myOffsetToLogicalStrategy); } + @Override + public int logicalPositionToOffset(@NotNull LogicalPosition logical) throws IllegalStateException { + myLogicalToOffsetStrategy.init(logical); + return calculate(myLogicalToOffsetStrategy); + } + @Override public VisualPosition logicalToVisualPosition(@NotNull LogicalPosition logical, @NotNull VisualPosition softWrapUnawareVisual) throws IllegalStateException @@ -144,7 +152,7 @@ public class CachingSoftWrapDataMapper implements SoftWrapDataMapper, SoftWrapAw // Count soft wrap column offset only if it's located at the same line as the target offset. if (column < 0 && softWrap.getStart() >= targetLogicalLineStartOffset) { column = softWrap.getIndentInColumns() + SoftWrapModelImpl.getEditorTextRepresentationHelper(myEditor).toVisualColumnSymbolsNumber( - myEditor.getDocument().getCharsSequence(), softWrap.getStart(), maxOffset, softWrap.getIndentInPixels() + softWrap.getStart(), maxOffset, softWrap.getIndentInPixels() ); // Count lines introduced by the current soft wrap. We assume that every soft wrap has a single line feed. diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/EditorPosition.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/EditorPosition.java index 1097f2824445..e1547d069686 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/EditorPosition.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/EditorPosition.java @@ -144,10 +144,7 @@ class EditorPosition implements Cloneable { // Single-line fold region. if (collapsedSymbolsWidthInColumns < 0) { collapsedSymbolsWidthInColumns = SoftWrapModelImpl.getEditorTextRepresentationHelper(myEditor) - .toVisualColumnSymbolsNumber(document.getCharsSequence(), - foldRegion.getStartOffset(), - foldRegion.getEndOffset(), - x); + .toVisualColumnSymbolsNumber(foldRegion.getStartOffset(), foldRegion.getEndOffset(), x); } logicalColumn += collapsedSymbolsWidthInColumns; foldingColumnDiff += placeholder.length() - collapsedSymbolsWidthInColumns; @@ -156,10 +153,7 @@ class EditorPosition implements Cloneable { // Multi-line fold region. if (collapsedSymbolsWidthInColumns < 0) { collapsedSymbolsWidthInColumns = SoftWrapModelImpl.getEditorTextRepresentationHelper(myEditor) - .toVisualColumnSymbolsNumber(document.getCharsSequence(), - foldRegion.getStartOffset(), - foldRegion.getEndOffset(), - 0); + .toVisualColumnSymbolsNumber(foldRegion.getStartOffset(), foldRegion.getEndOffset(), 0); } int linesDiff = endOffsetLogicalLine - logicalLine; logicalLine += linesDiff; diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/LogicalToOffsetCalculationStrategy.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/LogicalToOffsetCalculationStrategy.java new file mode 100644 index 000000000000..1fcee26d6f77 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/LogicalToOffsetCalculationStrategy.java @@ -0,0 +1,120 @@ +/* + * 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.editor.impl.softwrap.mapping; + +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.FoldRegion; +import com.intellij.openapi.editor.LogicalPosition; +import com.intellij.openapi.editor.SoftWrap; +import com.intellij.openapi.editor.ex.EditorEx; +import com.intellij.openapi.editor.impl.SoftWrapModelImpl; +import com.intellij.openapi.editor.impl.softwrap.SoftWrapsStorage; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +class LogicalToOffsetCalculationStrategy extends AbstractMappingStrategy { + + private LogicalPosition targetPosition; + + LogicalToOffsetCalculationStrategy(@NotNull EditorEx editor, @NotNull SoftWrapsStorage storage, @NotNull List cache) { + super(editor, storage, cache); + } + + void init(LogicalPosition logical) { + CacheEntry entry = MappingUtil.getCacheEntryForLogicalPosition(logical, myCache); + if (entry == null) { + if (logical.line >= myEditor.getDocument().getLineCount()) { + setEagerMatch(myEditor.getDocument().getTextLength()); + } + else { + setEagerMatch(Math.min(myEditor.getDocument().getLineStartOffset(logical.line) + logical.column, + myEditor.getDocument().getLineEndOffset(logical.line))); + } + return; + } + if (entry.endLogicalLine == logical.line && entry.endLogicalColumn <= logical.column) { + setEagerMatch(entry.endOffset); + return; + } + reset(); + targetPosition = logical; + setTargetEntry(entry, true); + } + + @Nullable + @Override + protected Integer buildIfExceeds(EditorPosition position, int offset) { + if (position.logicalLine != targetPosition.line) { + return null; + } + int result = position.offset + targetPosition.column - position.logicalColumn; + return result > offset ? null : result; + } + + @Override + public Integer processFoldRegion(@NotNull EditorPosition position, @NotNull FoldRegion foldRegion) { + int startLine = position.logicalLine; + int startColumn = position.logicalColumn; + int startX = position.x; + + advancePositionOnFolding(position, foldRegion); + + if (position.logicalLine < targetPosition.line + || position.logicalLine == targetPosition.line && position.logicalColumn <= targetPosition.column) { + return null; + } + + Document document = myEditor.getDocument(); + int lineEndOffset = document.getLineEndOffset(targetPosition.line); + int result = SoftWrapModelImpl.getEditorTextRepresentationHelper(myEditor) + .calcSoftWrapUnawareOffset(targetPosition.line == startLine ? foldRegion.getStartOffset() + : document.getLineStartOffset(targetPosition.line), + lineEndOffset, + targetPosition.line == startLine ? startColumn : 0, + targetPosition.column, + targetPosition.line == startLine ? startX : 0); + return result < 0 ? lineEndOffset : result; + } + + @Nullable + @Override + protected Integer buildIfExceeds(@NotNull EditorPosition position, @NotNull FoldRegion foldRegion) { + throw new RuntimeException("Unexpected invocation"); + } + + @Nullable + @Override + protected Integer buildIfExceeds(EditorPosition position, TabData tabData) { + if (position.logicalLine != targetPosition.line) { + return null; + } + return position.logicalColumn + tabData.widthInColumns > targetPosition.column ? position.offset : null; + } + + @Nullable + @Override + public Integer processSoftWrap(@NotNull EditorPosition position, SoftWrap softWrap) { + return null; + } + + @NotNull + @Override + public Integer build(@NotNull EditorPosition position) { + return position.offset + targetPosition.column - position.logicalColumn; + } +} diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/LogicalToVisualMappingStrategy.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/LogicalToVisualMappingStrategy.java index 6ed904624fa6..90375ca0a888 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/LogicalToVisualMappingStrategy.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/LogicalToVisualMappingStrategy.java @@ -16,6 +16,7 @@ package com.intellij.openapi.editor.impl.softwrap.mapping; import com.intellij.openapi.editor.*; +import com.intellij.openapi.editor.ex.EditorEx; import com.intellij.openapi.editor.impl.SoftWrapModelImpl; import com.intellij.openapi.editor.impl.softwrap.SoftWrapsStorage; import org.jetbrains.annotations.NotNull; @@ -31,7 +32,7 @@ class LogicalToVisualMappingStrategy extends AbstractMappingStrategy cache) throws IllegalStateException { @@ -122,7 +123,7 @@ class LogicalToVisualMappingStrategy extends AbstractMappingStrategy cache) { + int start = 0; + int end = cache.size() - 1; + + while (start <= end) { + int i = (end + start) >>> 1; + CacheEntry cacheEntry = cache.get(i); + if (cacheEntry.startLogicalLine < position.line + || cacheEntry.startLogicalLine == position.line && cacheEntry.startLogicalColumn < position.column) { + start = i + 1; + continue; + } + if (cacheEntry.startLogicalLine > position.line + || cacheEntry.startLogicalLine == position.line && cacheEntry.startLogicalColumn > position.column) { + end = i - 1; + continue; + } + + return assertEnd(position, cache.get(i)); + } + return end < 0 ? null : assertEnd(position, cache.get(end)); + } + + @Nullable + private static CacheEntry assertEnd(@NotNull LogicalPosition position, @NotNull CacheEntry entry) { + return position.line <= entry.endLogicalLine ? entry : null; + } } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/OffsetToLogicalCalculationStrategy.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/OffsetToLogicalCalculationStrategy.java index 399406f2db32..a7bf6917c5da 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/OffsetToLogicalCalculationStrategy.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/OffsetToLogicalCalculationStrategy.java @@ -16,6 +16,7 @@ package com.intellij.openapi.editor.impl.softwrap.mapping; import com.intellij.openapi.editor.*; +import com.intellij.openapi.editor.ex.EditorEx; import com.intellij.openapi.editor.impl.SoftWrapModelImpl; import com.intellij.openapi.editor.impl.softwrap.SoftWrapsStorage; import org.jetbrains.annotations.NotNull; @@ -31,7 +32,7 @@ class OffsetToLogicalCalculationStrategy extends AbstractMappingStrategy cache) + OffsetToLogicalCalculationStrategy(@NotNull EditorEx editor, @NotNull SoftWrapsStorage storage, @NotNull List cache) { super(editor, storage, cache); } @@ -157,13 +158,13 @@ class OffsetToLogicalCalculationStrategy extends AbstractMappingStrategy cache) + VisualToLogicalCalculationStrategy(@NotNull EditorEx editor, @NotNull SoftWrapsStorage storage, @NotNull List cache) { super(editor, storage, cache); mySearchKey = new CacheEntry(0, editor); diff --git a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/ConfigurableEditor.java b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/ConfigurableEditor.java index 6aa4f51611e5..c834799ea6b7 100644 --- a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/ConfigurableEditor.java +++ b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/ConfigurableEditor.java @@ -34,6 +34,7 @@ import com.intellij.openapi.util.ActionCallback; import com.intellij.ui.JBColor; import com.intellij.ui.RelativeFont; import com.intellij.ui.ScrollPaneFactory; +import com.intellij.ui.components.GradientViewport; import com.intellij.ui.components.labels.LinkLabel; import com.intellij.util.ui.update.MergingUpdateQueue; import com.intellij.util.ui.update.Update; @@ -269,7 +270,8 @@ class ConfigurableEditor extends AbstractEditor implements AnActionListener, AWT content.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); } if (ConfigurableWrapper.cast(Configurable.NoScroll.class, configurable) == null) { - JScrollPane scroll = ScrollPaneFactory.createScrollPane(content, true); + JScrollPane scroll = ScrollPaneFactory.createScrollPane(null, true); + scroll.setViewport(new GradientViewport(content, 5, 0, 0, 0, true)); scroll.getVerticalScrollBar().setUnitIncrement(10); content = scroll; } diff --git a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsEditor.java b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsEditor.java index 7e15a693312f..69617643a14c 100644 --- a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsEditor.java +++ b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsEditor.java @@ -39,6 +39,7 @@ import com.intellij.openapi.util.registry.Registry; import com.intellij.ui.LightColors; import com.intellij.ui.OnePixelSplitter; import com.intellij.ui.ScrollPaneFactory; +import com.intellij.ui.components.GradientViewport; import com.intellij.ui.components.labels.LinkLabel; import com.intellij.ui.components.panels.NonOpaquePanel; import com.intellij.ui.components.panels.Wrapper; @@ -712,11 +713,9 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat if (c != null) { if (scrollable) { - JScrollPane scroll = ScrollPaneFactory.createScrollPane(c); - scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); - scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); + JScrollPane scroll = ScrollPaneFactory.createScrollPane(null, true); + scroll.setViewport(new GradientViewport(c, 5, 5, 5, 5, false)); scroll.getVerticalScrollBar().setUnitIncrement(10); - scroll.setBorder(null); add(scroll, BorderLayout.CENTER); } else { diff --git a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsTreeView.java b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsTreeView.java index 1761196eec36..2d3db611ae91 100644 --- a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsTreeView.java +++ b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsTreeView.java @@ -25,6 +25,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.ActionCallback; import com.intellij.openapi.util.Disposer; import com.intellij.ui.*; +import com.intellij.ui.components.GradientViewport; import com.intellij.ui.treeStructure.CachingSimpleNode; import com.intellij.ui.treeStructure.SimpleNode; import com.intellij.ui.treeStructure.SimpleTree; @@ -79,7 +80,6 @@ final class SettingsTreeView extends JComponent implements Disposable, OptionsEd private final SettingsFilter myFilter; private final MyRoot myRoot; private final JScrollPane myScroller; - private JLabel mySeparator; private final IdentityHashMap myConfigurableToNodeMap = new IdentityHashMap(); private final IdentityHashMap myConfigurableToWrapperMap = new IdentityHashMap(); @@ -107,18 +107,38 @@ final class SettingsTreeView extends JComponent implements Disposable, OptionsEd myTree.setExpandableItemsEnabled(false); RelativeFont.BOLD.install(myTree); - myScroller = ScrollPaneFactory.createScrollPane(myTree, true); + myScroller = ScrollPaneFactory.createScrollPane(null, true); + myScroller.setViewport(new GradientViewport(myTree, 5, 0, 0, 0, true) { + private JLabel myHeader; + + @Override + protected Component getHeader() { + if (0 == myTree.getY()) { + return null; // separator is not needed without scrolling + } + if (myHeader == null) { + myHeader = new JLabel(); + myHeader.setForeground(FOREGROUND); + myHeader.setIconTextGap(ICON_GAP); + myHeader.setBorder(BorderFactory.createEmptyBorder(1, 10 + getLeftMargin(0), 0, 0)); + } + myHeader.setFont(myTree.getFont()); + myHeader.setIcon(myTree.getEmptyHandle()); + int height = myHeader.getPreferredSize().height; + String group = findGroupNameAt(0, height + 3); + if (group == null || !group.equals(findGroupNameAt(0, 0))) { + return null; // do not show separator over another group + } + myHeader.setText(group); + return myHeader; + } + }); myScroller.getVerticalScrollBar().setUI(ButtonlessScrollBarUI.createTransparent()); myScroller.setBackground(BACKGROUND); myScroller.getViewport().setBackground(BACKGROUND); myScroller.getVerticalScrollBar().setBackground(BACKGROUND); add(myScroller); - mySeparator = new JLabel(); - mySeparator.setForeground(FOREGROUND); - mySeparator.setIconTextGap(ICON_GAP); - mySeparator.setBorder(BorderFactory.createEmptyBorder(1, 10 + getLeftMargin(0), 0, 0)); - myTree.addComponentListener(new ComponentAdapter() { @Override public void componentResized(ComponentEvent e) { @@ -271,39 +291,6 @@ final class SettingsTreeView extends JComponent implements Disposable, OptionsEd myScroller.setBounds(0, 0, getWidth(), getHeight()); } - @Override - public void paint(Graphics g) { - super.paint(g); - - if (0 == myTree.getY()) { - return; // separator is not needed without scrolling - } - mySeparator.setFont(myTree.getFont()); - mySeparator.setIcon(myTree.getEmptyHandle()); - int height = mySeparator.getPreferredSize().height; - String group = findGroupNameAt(0, height + 3); - if (group != null && group.equals(findGroupNameAt(0, 0))) { - mySeparator.setText(group); - - Rectangle bounds = myScroller.getViewport().getBounds(); - if (bounds.height > height) { - bounds.height = height; - } - g.setColor(myTree.getBackground()); - g.fillRect(bounds.x, bounds.y, bounds.width, bounds.height); - if (g instanceof Graphics2D) { - int h = 6; // gradient height - int y = bounds.y + bounds.height; - ((Graphics2D)g).setPaint(UIUtil.getGradientPaint( - 0, y, g.getColor(), - 0, y + h, ColorUtil.toAlpha(g.getColor(), 0))); - g.fillRect(bounds.x, y, bounds.width, h); - } - mySeparator.setBounds(bounds); - mySeparator.paint(g); - } - } - void selectFirst() { for (ConfigurableGroup eachGroup : myRoot.myGroups) { Configurable[] kids = eachGroup.getConfigurables(); diff --git a/platform/platform-impl/src/com/intellij/openapi/project/DumbServiceImpl.java b/platform/platform-impl/src/com/intellij/openapi/project/DumbServiceImpl.java index 7860d4364f9d..18d0f692e6ad 100644 --- a/platform/platform-impl/src/com/intellij/openapi/project/DumbServiceImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/project/DumbServiceImpl.java @@ -18,6 +18,7 @@ package com.intellij.openapi.project; import com.intellij.ide.IdeBundle; import com.intellij.ide.caches.CacheUpdater; import com.intellij.openapi.Disposable; +import com.intellij.openapi.application.AccessToken; import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; @@ -152,12 +153,12 @@ public class DumbServiceImpl extends DumbService implements Disposable { if (indicator != null) { indicator.pushState(); } + AccessToken token = HeavyProcessLatch.INSTANCE.processStarted("Performing indexing task"); try { - HeavyProcessLatch.INSTANCE.processStarted("Performing indexing task"); task.performInDumbMode(indicator != null ? indicator : new EmptyProgressIndicator()); } finally { - HeavyProcessLatch.INSTANCE.processFinished(); + token.finish(); if (indicator != null) { indicator.popState(); } @@ -336,8 +337,8 @@ public class DumbServiceImpl extends DumbService implements Disposable { public void run(@NotNull final ProgressIndicator visibleIndicator) { final ShutDownTracker shutdownTracker = ShutDownTracker.getInstance(); final Thread self = Thread.currentThread(); + AccessToken token = HeavyProcessLatch.INSTANCE.processStarted("Performing indexing tasks"); try { - HeavyProcessLatch.INSTANCE.processStarted("Performing indexing tasks"); shutdownTracker.registerStopperThread(self); if (visibleIndicator instanceof ProgressIndicatorEx) { @@ -362,7 +363,7 @@ public class DumbServiceImpl extends DumbService implements Disposable { } finally { shutdownTracker.unregisterStopperThread(self); - HeavyProcessLatch.INSTANCE.processFinished(); + token.finish(); } } }); diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/EncodingProjectManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/EncodingProjectManagerImpl.java index 722865c2ff07..c61bd9e79362 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/EncodingProjectManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/EncodingProjectManagerImpl.java @@ -67,6 +67,10 @@ public class EncodingProjectManagerImpl extends EncodingProjectManager implement private Charset myDefaultCharsetForPropertiesFiles; private final SimpleModificationTracker myModificationTracker = new SimpleModificationTracker(); + // we should avoid changed file + private String myOldUTFGuessing; + private boolean myNative2AsciiForPropertiesFilesWasSpecified; + public EncodingProjectManagerImpl(Project project, PsiDocumentManager documentManager) { myProject = project; documentManager.addListener(new PsiDocumentManager.Listener() { @@ -87,23 +91,32 @@ public class EncodingProjectManagerImpl extends EncodingProjectManager implement @Override public Element getState() { Element element = new Element("x"); - List files = new ArrayList(myMapping.keySet()); - ContainerUtil.quickSort(files, new Comparator() { - @Override - public int compare(final VirtualFile o1, final VirtualFile o2) { - if (o1 == null || o2 == null) return o1 == null ? o2 == null ? 0 : 1 : -1; - return o1.getPath().compareTo(o2.getPath()); + if (!myMapping.isEmpty()) { + List files = new ArrayList(myMapping.keySet()); + ContainerUtil.quickSort(files, new Comparator() { + @Override + public int compare(final VirtualFile o1, final VirtualFile o2) { + if (o1 == null || o2 == null) return o1 == null ? o2 == null ? 0 : 1 : -1; + return o1.getPath().compareTo(o2.getPath()); + } + }); + for (VirtualFile file : files) { + Charset charset = myMapping.get(file); + Element child = new Element("file"); + element.addContent(child); + child.setAttribute("url", file == null ? PROJECT_URL : file.getUrl()); + child.setAttribute("charset", charset.name()); } - }); - for (VirtualFile file : files) { - Charset charset = myMapping.get(file); - Element child = new Element("file"); - element.addContent(child); - child.setAttribute("url", file == null ? PROJECT_URL : file.getUrl()); - child.setAttribute("charset", charset.name()); } - element.setAttribute("useUTFGuessing", Boolean.toString(true)); - element.setAttribute("native2AsciiForPropertiesFiles", Boolean.toString(myNative2AsciiForPropertiesFiles)); + + if (myOldUTFGuessing != null) { + element.setAttribute("useUTFGuessing", myOldUTFGuessing); + } + + if (myNative2AsciiForPropertiesFiles || myNative2AsciiForPropertiesFilesWasSpecified) { + element.setAttribute("native2AsciiForPropertiesFiles", Boolean.toString(myNative2AsciiForPropertiesFiles)); + } + if (myDefaultCharsetForPropertiesFiles != null) { element.setAttribute("defaultCharsetForPropertiesFiles", myDefaultCharsetForPropertiesFiles.name()); } @@ -112,25 +125,31 @@ public class EncodingProjectManagerImpl extends EncodingProjectManager implement @Override public void loadState(Element element) { - List files = element.getChildren("file"); - final Map mapping = new HashMap(); - for (Element fileElement : files) { - String url = fileElement.getAttributeValue("url"); - String charsetName = fileElement.getAttributeValue("charset"); - Charset charset = CharsetToolkit.forName(charsetName); - if (charset == null) continue; - VirtualFile file = url.equals(PROJECT_URL) ? null : VirtualFileManager.getInstance().findFileByUrl(url); - if (file != null || url.equals(PROJECT_URL)) { - mapping.put(file, charset); - } - } myMapping.clear(); - myMapping.putAll(mapping); + List files = element.getChildren("file"); + if (!files.isEmpty()) { + Map mapping = new HashMap(); + for (Element fileElement : files) { + String url = fileElement.getAttributeValue("url"); + String charsetName = fileElement.getAttributeValue("charset"); + Charset charset = CharsetToolkit.forName(charsetName); + if (charset == null) continue; + VirtualFile file = url.equals(PROJECT_URL) ? null : VirtualFileManager.getInstance().findFileByUrl(url); + if (file != null || url.equals(PROJECT_URL)) { + mapping.put(file, charset); + } + } + myMapping.putAll(mapping); + } - myNative2AsciiForPropertiesFiles = Boolean.parseBoolean(element.getAttributeValue("native2AsciiForPropertiesFiles")); + String native2AsciiForPropertiesFiles = element.getAttributeValue("native2AsciiForPropertiesFiles"); + myNative2AsciiForPropertiesFiles = Boolean.parseBoolean(native2AsciiForPropertiesFiles); myDefaultCharsetForPropertiesFiles = CharsetToolkit.forName(element.getAttributeValue("defaultCharsetForPropertiesFiles")); myModificationTracker.incModificationCount(); + + myOldUTFGuessing = element.getAttributeValue("useUTFGuessing"); + myNative2AsciiForPropertiesFilesWasSpecified = native2AsciiForPropertiesFiles != null; } @Override diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/RefreshQueueImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/RefreshQueueImpl.java index 8c777e75d21e..12765fedb7a7 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/RefreshQueueImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/RefreshQueueImpl.java @@ -15,6 +15,7 @@ */ package com.intellij.openapi.vfs.newvfs; +import com.intellij.openapi.application.AccessToken; import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; @@ -74,12 +75,12 @@ public class RefreshQueueImpl extends RefreshQueue { public void run() { try { myRefreshIndicator.start(); - HeavyProcessLatch.INSTANCE.processStarted("Doing file refresh. "+session.toString()); + AccessToken token = HeavyProcessLatch.INSTANCE.processStarted("Doing file refresh. " + session.toString()); try { doScan(session); } finally { - HeavyProcessLatch.INSTANCE.processFinished(); + token.finish(); myRefreshIndicator.stop(); } } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java index 95b3d54f8030..c0c27ba8c128 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java @@ -56,10 +56,7 @@ import com.intellij.ui.ColorUtil; import com.intellij.ui.awt.RelativePoint; import com.intellij.ui.switcher.QuickAccessSettings; import com.intellij.ui.switcher.SwitchManager; -import com.intellij.util.Alarm; -import com.intellij.util.ArrayUtil; -import com.intellij.util.EventDispatcher; -import com.intellij.util.IJSwingUtilities; +import com.intellij.util.*; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.HashMap; import com.intellij.util.ui.PositionTracker; @@ -414,7 +411,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements appendSetEditorComponentCmd(editorComponent, commandsList); if (myEditorWasActive && editorComponent instanceof EditorsSplitters) { - activateEditorComponentImpl(FileEditorManagerEx.getInstanceEx(myProject).getSplitters(), commandsList, true); + activateEditorComponentImpl(commandsList, true); } execute(commandsList); @@ -610,7 +607,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements @Override public void run() { final ArrayList commandList = new ArrayList(); - activateEditorComponentImpl(getSplittersFromFocus(), commandList, forced); + activateEditorComponentImpl(commandList, forced); execute(commandList); } }; @@ -637,16 +634,10 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements } } - private EditorsSplitters getSplittersFromFocus() { - return FileEditorManagerEx.getInstanceEx(myProject).getSplitters(); - } - - private void activateEditorComponentImpl(EditorsSplitters splitters, - List commandList, - final boolean forced) { + private void activateEditorComponentImpl(List commandList, final boolean forced) { final String active = getActiveToolWindowId(); // Now we have to request focus into most recent focused editor - appendRequestFocusInEditorComponentCmd(splitters, commandList, forced).doWhenDone(new Runnable() { + appendRequestFocusInEditorComponentCmd(commandList, forced).doWhenDone(new Runnable() { @Override public void run() { final ArrayList postExecute = new ArrayList(); @@ -949,7 +940,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements } } - activateEditorComponentImpl(getSplittersFromFocus(), commandList, true); + activateEditorComponentImpl(commandList, true); } else if (isStackEnabled()) { @@ -988,7 +979,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements if (wasActive && moveFocus) { if (myActiveStack.isEmpty()) { if (hasOpenEditorFiles()) { - activateEditorComponentImpl(getSplittersFromFocus(), commandList, false); + activateEditorComponentImpl(commandList, false); } else { focusToolWinowByDefault(id); @@ -1008,7 +999,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements //todo[kb] it's just a temporary solution due a number of focus issues in JDK 7 if (SystemInfo.isJavaVersionAtLeast("1.7")) { if (hasOpenEditorFiles()) { - activateEditorComponentImpl(getSplittersFromFocus(), commandList, false); + activateEditorComponentImpl(commandList, false); } else { focusToolWinowByDefault(id); @@ -1213,7 +1204,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements } } else if (wasActive) { // tool window was active but it cannot be activate again - activateEditorComponentImpl(getSplittersFromFocus(), commandsList, true); + activateEditorComponentImpl(commandsList, true); } execute(commandsList); @@ -1353,7 +1344,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements // if there is no any active tool window and editor is also inactive // then activate editor if (!myEditorWasActive && getActiveToolWindowId() == null) { - activateEditorComponentImpl(getSplittersFromFocus(), commandList, true); + activateEditorComponentImpl(commandList, true); } execute(commandList); } @@ -1798,13 +1789,11 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements commandsList.add(command); } - private ActionCallback appendRequestFocusInEditorComponentCmd(EditorsSplitters splitters, - List commandList, - boolean forced) { + private ActionCallback appendRequestFocusInEditorComponentCmd(List commandList, boolean forced) { if (myProject.isDisposed()) return new ActionCallback.Done(); - final CommandProcessor commandProcessor = myWindowManager.getCommandProcessor(); - final RequestFocusInEditorComponentCmd command = - new RequestFocusInEditorComponentCmd(splitters, getFocusManager(), commandProcessor, forced); + EditorsSplitters splitters = getSplittersToFocus(); + CommandProcessor commandProcessor = myWindowManager.getCommandProcessor(); + RequestFocusInEditorComponentCmd command = new RequestFocusInEditorComponentCmd(splitters, getFocusManager(), commandProcessor, forced); commandList.add(command); return command.getDoneCallback(); } @@ -1831,6 +1820,22 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements commandsList.add(command); } + private EditorsSplitters getSplittersToFocus() { + Window activeWindow = myWindowManager.getMostRecentFocusedWindow(); + + if (activeWindow instanceof FloatingDecorator) { + IdeFocusManager ideFocusManager = IdeFocusManager.findInstanceByComponent(activeWindow); + IdeFrame lastFocusedFrame = ideFocusManager.getLastFocusedFrame(); + JComponent frameComponent = lastFocusedFrame != null ? lastFocusedFrame.getComponent() : null; + Window lastFocusedWindow = frameComponent != null ? SwingUtilities.getWindowAncestor(frameComponent) : null; + activeWindow = ObjectUtils.notNull(lastFocusedWindow, activeWindow); + } + + FileEditorManagerEx fem = FileEditorManagerEx.getInstanceEx(myProject); + EditorsSplitters splitters = activeWindow != null ? fem.getSplittersFor(activeWindow) : null; + return splitters != null ? splitters : fem.getSplitters(); + } + /** * @return true if tool window with the specified id * is floating and has modal showing child dialog. Such windows should not be closed diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/InfoAndProgressPanel.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/InfoAndProgressPanel.java index 386eae1ef478..0aa196baedef 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/InfoAndProgressPanel.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/InfoAndProgressPanel.java @@ -388,7 +388,7 @@ public class InfoAndProgressPanel extends JPanel implements CustomStatusBarWidge final Component anchor = getAnchor(pane); - JBPopupFactory.getInstance().createBalloonBuilder(panel.getRootPanel()) + JBPopupFactory.getInstance().createBalloonBuilder(panel.getProgressPanel()) .setFadeoutTime(0) .setFillColor(Gray.TRANSPARENT) .setShowCallout(false) diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/PresentationModeProgressPanel.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/PresentationModeProgressPanel.java index 9f82a2f60cdf..f62910ffd556 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/PresentationModeProgressPanel.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/PresentationModeProgressPanel.java @@ -16,6 +16,7 @@ package com.intellij.openapi.wm.impl.status; import com.intellij.icons.AllIcons; +import com.intellij.openapi.editor.colors.EditorColorsManager; import com.intellij.openapi.ui.popup.IconButton; import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.InplaceButton; @@ -48,6 +49,7 @@ public class PresentationModeProgressPanel { myText.setIcon(EmptyIcon.create(1, 16)); myText2.setIcon(EmptyIcon.create(1, 16)); } + public void update() { UIUtil.invokeLaterIfNeeded(new Runnable() { @Override @@ -57,7 +59,15 @@ public class PresentationModeProgressPanel { }); } + @NotNull + public Color getTextForeground() { + return EditorColorsManager.getInstance().getGlobalScheme().getDefaultForeground(); + } + private void updateImpl() { + myText.setForeground(getTextForeground()); + myText2.setForeground(getTextForeground()); + if (!StringUtil.equals(myText.getText(), myProgress.getText())) { myText.setText(myProgress.getText()); } @@ -74,7 +84,8 @@ public class PresentationModeProgressPanel { } } - public JPanel getRootPanel() { + @NotNull + public JComponent getProgressPanel() { return myRootPanel; } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/FlatWelcomeFrame.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/FlatWelcomeFrame.java index b93a024a1660..72f9fbf05459 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/FlatWelcomeFrame.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/FlatWelcomeFrame.java @@ -283,7 +283,7 @@ public class FlatWelcomeFrame extends JFrame implements IdeFrame { panel.add(toolbar, BorderLayout.EAST); - panel.setBorder(new EmptyBorder(0,0,8,21)); + panel.setBorder(new EmptyBorder(0,0,8,11)); return panel; } @@ -302,7 +302,7 @@ public class FlatWelcomeFrame extends JFrame implements IdeFrame { ref.get().setPaintUnderline(false); ref.get().setNormalColor(getLinkNormalColor()); NonOpaquePanel panel = new NonOpaquePanel(new BorderLayout()); - panel.setBorder(new EmptyBorder(4, 10, 4, 10)); + panel.setBorder(new EmptyBorder(4, 6, 4, 6)); panel.add(ref.get()); panel.add(createArrow(ref.get()), BorderLayout.EAST); installFocusable(panel, action, KeyEvent.VK_UP, KeyEvent.VK_DOWN, focusListOnLeft); @@ -346,7 +346,6 @@ public class FlatWelcomeFrame extends JFrame implements IdeFrame { } } - actions.setBorder(new EmptyBorder(0, 0, 0, 0)); WelcomeScreenActionsPanel panel = new WelcomeScreenActionsPanel(); panel.actions.add(actions); return panel.root; @@ -366,6 +365,7 @@ public class FlatWelcomeFrame extends JFrame implements IdeFrame { NonOpaquePanel panel = new NonOpaquePanel(new BorderLayout()); ApplicationInfoEx app = ApplicationInfoEx.getInstanceEx(); JLabel logo = new JLabel(IconLoader.getIcon(app.getWelcomeScreenLogoUrl())); + logo.setBorder(new EmptyBorder(30,0,10,0)); logo.setHorizontalAlignment(SwingConstants.CENTER); panel.add(logo, BorderLayout.NORTH); JLabel appName = new JLabel(ApplicationNamesInfo.getInstance().getFullProductName()); @@ -380,13 +380,13 @@ public class FlatWelcomeFrame extends JFrame implements IdeFrame { } JLabel version = new JLabel(appVersion); - version.setFont(font.deriveFont(16f).deriveFont(Font.PLAIN)); + version.setFont(getProductFont().deriveFont(16f)); version.setHorizontalAlignment(SwingConstants.CENTER); version.setForeground(Gray._128); panel.add(appName); panel.add(version, BorderLayout.SOUTH); - panel.setBorder(new EmptyBorder(20, 10, 30, 10)); + panel.setBorder(new EmptyBorder(0, 0, 20, 0)); return panel; } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/NewRecentProjectPanel.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/NewRecentProjectPanel.java index fb1fc55c32ae..827c9ba5d1ab 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/NewRecentProjectPanel.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/NewRecentProjectPanel.java @@ -98,8 +98,8 @@ public class NewRecentProjectPanel extends RecentProjectPanel { @Override protected void layoutComponents() { setLayout(new BorderLayout()); - myName.setBorder(new EmptyBorder(6, 5, 1, 5)); - myPath.setBorder(new EmptyBorder(1, 5, 6, 5)); + myName.setBorder(new EmptyBorder(6, 0, 1, 5)); + myPath.setBorder(new EmptyBorder(1, 0, 6, 5)); add(myName, BorderLayout.NORTH); add(myPath, BorderLayout.SOUTH); } diff --git a/platform/platform-impl/src/com/intellij/ui/components/GradientViewport.java b/platform/platform-impl/src/com/intellij/ui/components/GradientViewport.java new file mode 100644 index 000000000000..bf3ba32c9cb9 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/ui/components/GradientViewport.java @@ -0,0 +1,126 @@ +/* + * 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.ui.components; + +import com.intellij.openapi.util.registry.Registry; +import com.intellij.ui.ColorUtil; + +import javax.swing.*; +import java.awt.*; + +/** + * @author Sergey.Malenkov + */ +public class GradientViewport extends JViewport { + private final Insets myInsets; + private final boolean myAlways; + + public GradientViewport(Component view, int top, int left, int bottom, int right, boolean forScrollBars) { + myInsets = new Insets(top, left, bottom, right); + myAlways = forScrollBars; + setView(view); + } + + protected Component getHeader() { + return null; + } + + @Override + public void paint(Graphics g) { + super.paint(g); + g = g.create(); + try { + Color background = getBackground(); + Component header = getHeader(); + if (header != null) { + header.setBounds(0, 0, getWidth(), header.getPreferredSize().height); + if (background != null) { + g.setColor(background); + g.fillRect(header.getX(), header.getY(), header.getWidth(), header.getHeight()); + } + } + if (g instanceof Graphics2D && background != null && !Registry.is("ui.no.bangs.and.whistles")) { + paintGradient((Graphics2D)g, background, 0, header == null ? 0 : header.getHeight()); + } + if (header != null) { + header.paint(g); + } + } + finally { + g.dispose(); + } + } + + private void paintGradient(Graphics2D g2d, Color background, int x1, int y1) { + Component view = getView(); + if (background != null && view != null) { + int x2 = x1, x3 = getWidth() - x2, x4 = x3; + int y2 = y1, y3 = getHeight() - y2, y4 = y3; + + if (myInsets.left > 0 && view.getX() < 0) { + x2 += myInsets.left; + } + if (myInsets.top > 0 && view.getY() < 0) { + y2 += myInsets.top; + } + if (myInsets.right > 0 && view.getX() > getWidth() - view.getWidth()) { + x3 -= myInsets.right; + } + if (myInsets.bottom > 0 && view.getY() > getHeight() - view.getHeight()) { + y3 -= myInsets.bottom; + } + Component parent = myAlways ? null : getParent(); + if (parent instanceof JScrollPane) { + JScrollPane pane = (JScrollPane)parent; + JScrollBar vBar = pane.getVerticalScrollBar(); + if (vBar != null && vBar.isVisible()) { + if (vBar.getX() < getX()) { + x2 = x1; + } + else { + x3 = x4; + } + } + JScrollBar hBar = pane.getHorizontalScrollBar(); + if (hBar != null && hBar.isVisible()) { + if (hBar.getY() < getY()) { + y2 = y1; + } + else { + y3 = y4; + } + } + } + Color transparent = ColorUtil.toAlpha(background, 0); + if (x1 != x2) { + g2d.setPaint(new GradientPaint(x1, y1, background, x2, y1, transparent)); + g2d.fillPolygon(new int[]{x1, x2, x2, x1}, new int[]{y1, y2, y3, y4}, 4); + } + if (x3 != x4) { + g2d.setPaint(new GradientPaint(x3, y1, transparent, x4, y1, background)); + g2d.fillPolygon(new int[]{x4, x3, x3, x4}, new int[]{y1, y2, y3, y4}, 4); + } + if (y1 != y2) { + g2d.setPaint(new GradientPaint(x1, y1, background, x1, y2, transparent)); + g2d.fillPolygon(new int[]{x1, x2, x3, x4}, new int[]{y1, y2, y2, y1}, 4); + } + if (y3 != y4) { + g2d.setPaint(new GradientPaint(x1, y3, transparent, x1, y4, background)); + g2d.fillPolygon(new int[]{x1, x2, x3, x4}, new int[]{y4, y3, y3, y4}, 4); + } + } + } +} diff --git a/platform/platform-impl/src/com/intellij/util/Urls.java b/platform/platform-impl/src/com/intellij/util/Urls.java index a09b1dbcf96a..abe4c5ae75b2 100644 --- a/platform/platform-impl/src/com/intellij/util/Urls.java +++ b/platform/platform-impl/src/com/intellij/util/Urls.java @@ -99,7 +99,7 @@ public final class Urls { } if (asLocalIfNoScheme && !URLUtil.containsScheme(url)) { - // nodejs debug — files only in local filesystem + // nodejs debug - files only in local filesystem return newLocalFileUrl(url); } return parseUrl(VfsUtilCore.toIdeaUrl(url)); diff --git a/platform/platform-resources/src/META-INF/XmlPlugin.xml b/platform/platform-resources/src/META-INF/XmlPlugin.xml index 00f42a06cd93..b2c30eb04746 100644 --- a/platform/platform-resources/src/META-INF/XmlPlugin.xml +++ b/platform/platform-resources/src/META-INF/XmlPlugin.xml @@ -198,6 +198,7 @@ + diff --git a/platform/platform-resources/src/launcher.py b/platform/platform-resources/src/launcher.py index 57ecceda01e1..e60cfb3b0f8f 100644 --- a/platform/platform-resources/src/launcher.py +++ b/platform/platform-resources/src/launcher.py @@ -22,16 +22,27 @@ for i, arg in enumerate(sys.argv[1:]): ' {0} diff ' + ' {0} merge [base] ').format(sys.argv[0])) exit(0) - elif ':' in arg: - file_path, line_number = arg.rsplit(':', 1) - if line_number.isdigit(): - args.append('-l') - args.append(line_number) - args.append(file_path) - else: - args.append(arg) - else: + 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 + elif skip_next: + args.append(arg) + skip_next = False + else: + if ':' in arg: + file_path, line_number = arg.rsplit(':', 1) + if line_number.isdigit(): + args.append('-l') + args.append(line_number) + args.append(os.path.abspath(file_path)) + else: + args.append(os.path.abspath(arg)) + else: + args.append(os.path.abspath(arg)) def launch_with_port(port): diff --git a/platform/platform-tests/testSrc/com/intellij/codeInsight/actions/ReformatOnlyVcsChangedTextTest.java b/platform/platform-tests/testSrc/com/intellij/codeInsight/actions/ReformatOnlyVcsChangedTextTest.java index d66988ab2ef5..4b7ac648fd95 100644 --- a/platform/platform-tests/testSrc/com/intellij/codeInsight/actions/ReformatOnlyVcsChangedTextTest.java +++ b/platform/platform-tests/testSrc/com/intellij/codeInsight/actions/ReformatOnlyVcsChangedTextTest.java @@ -141,6 +141,24 @@ public class ReformatOnlyVcsChangedTextTest extends LightPlatformTestCase { ); } + public void testNoReformatOn_DeletionModification() throws IOException { + doTest( + "public class B {\n" + + " int a = 3;\n" + + " String text;\n" + + " Object last = null;\n" + + " Object first = null;\n" + + " Object second = null;\n" + + "}", + + "public class B {\n" + + " int a = 3;\n" + + " String text;\n" + + " Object last = null;\n" + + "}" + ); + } + public void testModification() throws IOException { doTest( "public class B {\n" + diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/softwrap/MockEditorTextRepresentationHelper.java b/platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/softwrap/MockEditorTextRepresentationHelper.java index 8d9f4eedb20b..6edd72f54219 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/softwrap/MockEditorTextRepresentationHelper.java +++ b/platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/softwrap/MockEditorTextRepresentationHelper.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 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,6 @@ package com.intellij.openapi.editor.impl.softwrap; import com.intellij.openapi.editor.impl.EditorTextRepresentationHelper; -import org.jetbrains.annotations.NotNull; /** * @author Denis Zhdanov @@ -24,23 +23,26 @@ import org.jetbrains.annotations.NotNull; */ public class MockEditorTextRepresentationHelper implements EditorTextRepresentationHelper { + private final CharSequence myText; private final int mySpaceSizeInPixels; private final int myTabSizeInColumns; - public MockEditorTextRepresentationHelper(int spaceSizeInPixels, int tabSizeInColumns) { + public MockEditorTextRepresentationHelper(CharSequence text, int spaceSizeInPixels, int tabSizeInColumns) { + myText = text; mySpaceSizeInPixels = spaceSizeInPixels; myTabSizeInColumns = tabSizeInColumns; } public int toVisualColumnSymbolsNumber(char c, int x) { - return toVisualColumnSymbolsNumber(new String(new char[] {c}), 0, 1, x); + return new MockEditorTextRepresentationHelper(new String(new char[] {c}), mySpaceSizeInPixels, myTabSizeInColumns) + .toVisualColumnSymbolsNumber(0, 1, x); } @Override - public int toVisualColumnSymbolsNumber(@NotNull CharSequence text, int start, int end, int x) { + public int toVisualColumnSymbolsNumber(int start, int end, int x) { int result = 0; for (int i = start; i < end; i++) { - char c = text.charAt(i); + char c = myText.charAt(i); if (c == '\n') { result = 0; x = 0; @@ -57,10 +59,10 @@ public class MockEditorTextRepresentationHelper implements EditorTextRepresentat } @Override - public int textWidth(@NotNull CharSequence text, int start, int end, int fontType, int x) { + public int textWidth(int start, int end, int fontType, int x) { int result = 0; for (int i = start; i < end; i++) { - char c = text.charAt(i); + char c = myText.charAt(i); switch (c) { case '\n': result = 0; break; default: result += charWidth(c, result); @@ -79,4 +81,23 @@ public class MockEditorTextRepresentationHelper implements EditorTextRepresentat return mySpaceSizeInPixels; } } + + @Override + public int calcSoftWrapUnawareOffset(int startOffset, int endOffset, int startColumn, int targetColumn, int startX) { + int x = startX; + int column = startColumn; + for (int i = startOffset; i < endOffset; i++) { + if (column == targetColumn) { + return i; + } + char c = myText.charAt(i); + int width = charWidth(c, x); + column += width / mySpaceSizeInPixels; + if (width % mySpaceSizeInPixels > 0) { + column++; + } + x += width; + } + return -1; + } } diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/softwrap/mapping/CachingSoftWrapDataMapperTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/softwrap/mapping/CachingSoftWrapDataMapperTest.java index 7448c6c867f6..6a0abd6a667c 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/softwrap/mapping/CachingSoftWrapDataMapperTest.java +++ b/platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/softwrap/mapping/CachingSoftWrapDataMapperTest.java @@ -104,6 +104,7 @@ public class CachingSoftWrapDataMapperTest { private Mockery myMockery; private EditorEx myEditor; private DocumentEx myDocument; + private StringBuilder myChars; private SoftWrapsStorage myStorage; private SoftWrapModelEx mySoftWrapModel; private FoldingModelEx myFoldingModel; @@ -115,6 +116,7 @@ public class CachingSoftWrapDataMapperTest { myEditor = myMockery.mock(EditorEx.class); myDocument = myMockery.mock(DocumentEx.class); + myChars = new StringBuilder(); myStorage = new SoftWrapsStorage(); mySoftWrapModel = myMockery.mock(SoftWrapModelEx.class); myFoldingModel = myMockery.mock(FoldingModelEx.class); @@ -122,7 +124,7 @@ public class CachingSoftWrapDataMapperTest { final Project project = myMockery.mock(Project.class); final SoftWrapPainter painter = myMockery.mock(SoftWrapPainter.class); - myRepresentationHelper = new MockEditorTextRepresentationHelper(SPACE_SIZE, TAB_SIZE); + myRepresentationHelper = new MockEditorTextRepresentationHelper(myChars, SPACE_SIZE, TAB_SIZE); myMockery.checking(new Expectations() {{ // Document @@ -584,19 +586,19 @@ public class CachingSoftWrapDataMapperTest { allowing(myDocument).getCharsSequence(); will(new CustomAction("getCharsSequence()") { @Override public Object invoke(Invocation invocation) throws Throwable { - return context.document; + return myChars; } }); allowing(myDocument).getText(); will(new CustomAction("getCharsSequence()") { @Override public Object invoke(Invocation invocation) throws Throwable { - return context.document.toString(); + return myChars.toString(); } }); allowing(myDocument).getTextLength(); will(new CustomAction("getTextLength()") { @Override public Object invoke(Invocation invocation) throws Throwable { - return context.document.length(); + return myChars.length(); } }); }}); @@ -629,7 +631,7 @@ public class CachingSoftWrapDataMapperTest { context.onNewSymbol(c); } - myLineRanges.add(new TextRange(context.logicalLineStartOffset, context.document.length())); + myLineRanges.add(new TextRange(context.logicalLineStartOffset, myChars.length())); } private static boolean isSoftWrapStart(String document, int index) { @@ -685,7 +687,6 @@ public class CachingSoftWrapDataMapperTest { private class TestEditorPosition extends EditorPosition { private final StringBuilder mySoftWrapBuffer = new StringBuilder(); - final StringBuilder document = new StringBuilder(); EditorPosition lineStartPosition; @@ -741,7 +742,7 @@ public class CachingSoftWrapDataMapperTest { insideFolding = false; MockFoldRegion foldRegion = new MockFoldRegion(foldingStartOffset, offset); myFoldRegions.add(foldRegion); - myMapper.onCollapsedFoldRegion(foldRegion, myRepresentationHelper.toVisualColumnSymbolsNumber(document, foldingStartOffset, offset, prevX), foldingStartVisualLine); + myMapper.onCollapsedFoldRegion(foldRegion, myRepresentationHelper.toVisualColumnSymbolsNumber(foldingStartOffset, offset, prevX), foldingStartVisualLine); } public void onNewSymbol(char c) { @@ -868,7 +869,7 @@ public class CachingSoftWrapDataMapperTest { } private void onNonSoftWrapSymbol(char c) { - document.append(c); + myChars.append(c); if (c == '\n') { myLineRanges.add(new TextRange(logicalLineStartOffset, offset)); diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryTableBase.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryTableBase.java index 86bdce6a4a9d..1bc1c4c1c32c 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryTableBase.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryTableBase.java @@ -156,6 +156,7 @@ public abstract class LibraryTableBase implements PersistentStateComponent addedLibraries = ContainerUtil.newIdentityTroveSet(model.myLibraries); diff --git a/platform/script-debugger/backend/src/org/jetbrains/rpc/CommandProcessor.java b/platform/script-debugger/backend/src/org/jetbrains/rpc/CommandProcessor.java index 49a45554600f..035da28f1685 100644 --- a/platform/script-debugger/backend/src/org/jetbrains/rpc/CommandProcessor.java +++ b/platform/script-debugger/backend/src/org/jetbrains/rpc/CommandProcessor.java @@ -11,7 +11,7 @@ public abstract class CommandProcessor, ResultReader, MessageProcessor { - public static final Logger LOG = Logger.getInstance(MessageManager.class); + public static final Logger LOG = Logger.getInstance(CommandProcessor.class); private final AtomicInteger currentSequence = new AtomicInteger(); protected final MessageManager messageManager; diff --git a/platform/script-debugger/backend/src/org/jetbrains/rpc/CommandSender.java b/platform/script-debugger/backend/src/org/jetbrains/rpc/CommandSender.java index 8df0824db5ae..d1ec67796bf8 100644 --- a/platform/script-debugger/backend/src/org/jetbrains/rpc/CommandSender.java +++ b/platform/script-debugger/backend/src/org/jetbrains/rpc/CommandSender.java @@ -12,6 +12,8 @@ import org.jetbrains.jsonProtocol.RequestWithResponse; public interface CommandSender { ActionCallback send(Request message); + AsyncResult send(@NotNull RequestWithResponse message); + AsyncResult send(@NotNull RequestWithResponse message, @NotNull Function transform); AsyncResult send(@NotNull RequestWithResponse message, diff --git a/platform/script-debugger/backend/src/org/jetbrains/rpc/CommandSenderBase.java b/platform/script-debugger/backend/src/org/jetbrains/rpc/CommandSenderBase.java index 381be59ebb93..b1365a1d95a7 100644 --- a/platform/script-debugger/backend/src/org/jetbrains/rpc/CommandSenderBase.java +++ b/platform/script-debugger/backend/src/org/jetbrains/rpc/CommandSenderBase.java @@ -10,6 +10,8 @@ import org.jetbrains.jsonProtocol.Request; import org.jetbrains.jsonProtocol.RequestWithResponse; public abstract class CommandSenderBase implements CommandSender { + private static final Function.Self SELF_TRANSFORM = new Function.Self(); + protected abstract void send(@NotNull Request message, @NotNull AsyncResultCallback callback); @Override @@ -24,6 +26,12 @@ public abstract class CommandSenderBase impleme return send(message, transform, null); } + @Override + public final AsyncResult send(@NotNull RequestWithResponse message) { + //noinspection unchecked + return send(message, SELF_TRANSFORM, null); + } + @Override public final AsyncResult send(@NotNull RequestWithResponse message, @NotNull Function transform, diff --git a/platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/io/JsonReaderEx.java b/platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/io/JsonReaderEx.java index eaf83b872be8..806bfdde7deb 100644 --- a/platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/io/JsonReaderEx.java +++ b/platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/io/JsonReaderEx.java @@ -6,6 +6,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.Closeable; +import java.util.Arrays; public final class JsonReaderEx implements Closeable { /** The only non-execute prefix this parser permits */ @@ -75,7 +76,7 @@ public final class JsonReaderEx implements Closeable { /* * The nesting stack. Using a manual array rather than an ArrayList saves 20%. */ - private int[] stack = new int[32]; + private int[] stack; private int stackSize = 0; private StringBuilder builder; @@ -88,14 +89,16 @@ public final class JsonReaderEx implements Closeable { } public JsonReaderEx(@NotNull CharSequence in, int start) { - this(in, start, JsonScope.EMPTY_DOCUMENT); + this(in, start, new int[32]); + + stack[stackSize++] = JsonScope.EMPTY_DOCUMENT; } - private JsonReaderEx(@NotNull CharSequence in, int start, int scope) { + private JsonReaderEx(@NotNull CharSequence in, int start, @NotNull int[] stack) { this.in = in; position = start; limit = in.length(); - stack[stackSize++] = scope; + this.stack = stack; } private final static class JsonScope { @@ -162,7 +165,8 @@ public final class JsonReaderEx implements Closeable { throw createParseError("Cannot create sub reader, next token " + nextToken + " is not value"); } - JsonReaderEx subReader = new JsonReaderEx(in, position, stack[stackSize - 1]); + JsonReaderEx subReader = new JsonReaderEx(in, position, Arrays.copyOf(stack, stack.length)); + subReader.stackSize = stackSize; subReader.peeked = peeked; subReader.peekedLong = peekedLong; subReader.peekedNumberLength = peekedNumberLength; diff --git a/platform/testFramework/src/com/intellij/testFramework/ExpectedHighlightingData.java b/platform/testFramework/src/com/intellij/testFramework/ExpectedHighlightingData.java index 9022104f6953..897f38ae2c3d 100644 --- a/platform/testFramework/src/com/intellij/testFramework/ExpectedHighlightingData.java +++ b/platform/testFramework/src/com/intellij/testFramework/ExpectedHighlightingData.java @@ -74,6 +74,8 @@ public class ExpectedHighlightingData { private final PsiFile myFile; @NonNls private static final String ANY_TEXT = "*"; private final String myText; + + private boolean myIgnoreExtraHighlighting; public static class ExpectedHighlightingSet { private final HighlightSeverity severity; @@ -149,7 +151,17 @@ public class ExpectedHighlightingData { final boolean checkWeakWarnings, final boolean checkInfos, @Nullable final PsiFile file) { + this(document, checkWarnings, checkWeakWarnings, checkInfos, false, file); + } + + public ExpectedHighlightingData(@NotNull final Document document, + final boolean checkWarnings, + final boolean checkWeakWarnings, + final boolean checkInfos, + final boolean ignoreExtraHighlighting, + @Nullable final PsiFile file) { this(document, file); + myIgnoreExtraHighlighting = ignoreExtraHighlighting; if (checkWarnings) checkWarnings(); if (checkWeakWarnings) checkWeakWarnings(); if (checkInfos) checkInfos(); @@ -423,7 +435,7 @@ public class ExpectedHighlightingData { String failMessage = ""; for (HighlightInfo info : reverseCollection(infos)) { - if (!expectedInfosContainsInfo(info)) { + if (!expectedInfosContainsInfo(info) && !myIgnoreExtraHighlighting) { final int startOffset = info.startOffset; final int endOffset = info.endOffset; String s = text.substring(startOffset, endOffset); diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestFixture.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestFixture.java index 4d6314ecfff4..e4be651d0c18 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestFixture.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestFixture.java @@ -273,6 +273,8 @@ public interface CodeInsightTestFixture extends IdeaProjectTestFixture { * @return duration */ long checkHighlighting(boolean checkWarnings, boolean checkInfos, boolean checkWeakWarnings); + + long checkHighlighting(boolean checkWarnings, boolean checkInfos, boolean checkWeakWarnings, boolean ignoreExtraHighlighting); long checkHighlighting(); diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java index 0c2da8b647a4..a433ccadd30a 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java @@ -404,6 +404,16 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig } } + @Override + public long checkHighlighting(final boolean checkWarnings, final boolean checkInfos, final boolean checkWeakWarnings, boolean ignoreExtraHighlighting) { + try { + return collectAndCheckHighlighting(checkWarnings, checkInfos, checkWeakWarnings); + } + catch (Exception e) { + throw new RuntimeException(e); + } + } + @Override public long checkHighlighting() { return checkHighlighting(true, false, true); @@ -1485,7 +1495,14 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig } private long collectAndCheckHighlighting(boolean checkWarnings, boolean checkInfos, boolean checkWeakWarnings) throws Exception { - ExpectedHighlightingData data = new ExpectedHighlightingData(myEditor.getDocument(), checkWarnings, checkWeakWarnings, checkInfos, getHostFile()); + return collectAndCheckHighlighting(checkWarnings, checkInfos, checkWeakWarnings, false); + } + + private long collectAndCheckHighlighting(boolean checkWarnings, boolean checkInfos, boolean checkWeakWarnings, + boolean ignoreExtraHighlighting) throws Exception { + ExpectedHighlightingData data = new ExpectedHighlightingData(myEditor.getDocument(), + checkWarnings, checkWeakWarnings, ignoreExtraHighlighting, + checkInfos, getHostFile()); data.init(); return collectAndCheckHighlighting(data); } diff --git a/platform/testRunner/src/com/intellij/execution/testframework/TestSearchScope.java b/platform/testRunner/src/com/intellij/execution/testframework/TestSearchScope.java index 33cbb108efe1..efa2d8855123 100644 --- a/platform/testRunner/src/com/intellij/execution/testframework/TestSearchScope.java +++ b/platform/testRunner/src/com/intellij/execution/testframework/TestSearchScope.java @@ -65,7 +65,7 @@ public interface TestSearchScope { class Wrapper implements JDOMExternalizable { @NonNls private static final String DEFAULT_NAME = "defaultName"; - private TestSearchScope myScope = MODULE_WITH_DEPENDENCIES; + private TestSearchScope myScope = SINGLE_MODULE; @NonNls private static final String WHOLE_PROJECT_NAE = "wholeProject"; @NonNls private static final String SINGLE_MODULE_NAME = "singleModule"; @NonNls private static final String MODULE_WITH_DEPENDENCIES_NAME = "moduleWithDependencies"; diff --git a/platform/testRunner/src/com/intellij/execution/testframework/autotest/AutoTestManager.java b/platform/testRunner/src/com/intellij/execution/testframework/autotest/AutoTestManager.java index 3f15ee3f6de3..14e0cf32ef62 100644 --- a/platform/testRunner/src/com/intellij/execution/testframework/autotest/AutoTestManager.java +++ b/platform/testRunner/src/com/intellij/execution/testframework/autotest/AutoTestManager.java @@ -1,3 +1,18 @@ +/* + * 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.testframework.autotest; import com.intellij.execution.DelayedDocumentWatcher; @@ -58,7 +73,7 @@ public class AutoTestManager { }, new Condition() { @Override public boolean value(VirtualFile file) { - // Vladimir.Krivosheev — I don't know, why AutoTestManager checks it, but old behavior is preserved + // Vladimir.Krivosheev - I don't know, why AutoTestManager checks it, but old behavior is preserved return FileEditorManager.getInstance(myProject).isFileOpen(file); } }); diff --git a/platform/util/resources/misc/registry.properties b/platform/util/resources/misc/registry.properties index d9f47ad0209a..49934567f54c 100644 --- a/platform/util/resources/misc/registry.properties +++ b/platform/util/resources/misc/registry.properties @@ -198,7 +198,7 @@ compiler.process.use.memory.temp.cache=true compiler.process.use.memory.temp.cache.description=Store temporary data in memory for faster compilation;\ requires larger heap size for the build process. If parallel build is enabled, the option is ignored and temp data is always stored in memory. -compiler.process.preload=false +compiler.process.preload=true compiler.process.preload.description=After build finishes, the IDE will pre-load and leave waiting in memory the build process for the next compilation. This will save time for process start and project model loading (may be noticeable for big projects).\ compiler.process.debug.port=-1 @@ -361,6 +361,7 @@ search.everywhere.settings=false svn.use.incoming.optimization=false svn.lowest.supported.format.for.command.line=1.7.0 svn.use.svnkit.for.https.server.certificate.check=true +svn.executable.locale=en_US.UTF-8 completion.enable.relevant.method.chain.suggestions=false ide.mac.message.sheets.java.emulation=false diff --git a/platform/util/src/com/intellij/icons/AllIcons.java b/platform/util/src/com/intellij/icons/AllIcons.java index 43dd68c2c370..f81fbc288137 100644 --- a/platform/util/src/com/intellij/icons/AllIcons.java +++ b/platform/util/src/com/intellij/icons/AllIcons.java @@ -482,7 +482,7 @@ public class AllIcons { public static final Icon Reset = IconLoader.getIcon("/general/reset.png"); // 16x16 public static final Icon Run = IconLoader.getIcon("/general/run.png"); // 7x10 public static final Icon RunWithCoverage = IconLoader.getIcon("/general/runWithCoverage.png"); // 16x16 - public static final Icon SearchEverywhereGear = IconLoader.getIcon("/general/searchEverywhereGear.png"); // 12x12 + public static final Icon SearchEverywhereGear = IconLoader.getIcon("/general/searchEverywhereGear.png"); // 16x16 public static final Icon SecondaryGroup = IconLoader.getIcon("/general/secondaryGroup.png"); // 16x16 public static final Icon SeparatorH = IconLoader.getIcon("/general/separatorH.png"); // 17x11 public static final Icon Settings = IconLoader.getIcon("/general/settings.png"); // 16x16 diff --git a/platform/util/src/com/intellij/openapi/application/AccessToken.java b/platform/util/src/com/intellij/openapi/application/AccessToken.java new file mode 100644 index 000000000000..7774b4d17db6 --- /dev/null +++ b/platform/util/src/com/intellij/openapi/application/AccessToken.java @@ -0,0 +1,31 @@ +/* + * 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.application; + +public abstract class AccessToken { + protected void acquired() { + } + + protected void released() { + } + + public abstract void finish(); + + public static final AccessToken EMPTY_ACCESS_TOKEN = new AccessToken() { + @Override + public void finish() {} + }; +} diff --git a/platform/util/src/com/intellij/openapi/application/PathManager.java b/platform/util/src/com/intellij/openapi/application/PathManager.java index f457c6cecd7c..f561652450e6 100644 --- a/platform/util/src/com/intellij/openapi/application/PathManager.java +++ b/platform/util/src/com/intellij/openapi/application/PathManager.java @@ -159,6 +159,11 @@ public class PathManager { return platformPath(selector, "Library/Preferences", CONFIG_FOLDER); } + @NotNull + public static String getDefaultPluginPathFor(@NotNull String selector) { + return platformPath(selector, "Library/Application Support", PLUGINS_FOLDER); + } + public static void ensureConfigFolderExists() { checkAndCreate(getConfigPath(), true); } diff --git a/platform/util/src/com/intellij/ui/mac/foundation/Foundation.java b/platform/util/src/com/intellij/ui/mac/foundation/Foundation.java index e8277dbe0798..f4ad998b1cd4 100644 --- a/platform/util/src/com/intellij/ui/mac/foundation/Foundation.java +++ b/platform/util/src/com/intellij/ui/mac/foundation/Foundation.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. @@ -95,7 +95,7 @@ public class Foundation { * * @param cls The class to which to add a method. * @param selectorName A selector that specifies the name of the method being added. - * @param impl A function which is the implementation of the new method. The function must take at least two arguments—self and _cmd. + * @param impl A function which is the implementation of the new method. The function must take at least two arguments-self and _cmd. * @param types An array of characters that describe the types of the arguments to the method. * See * @return true if the method was added successfully, otherwise false (for example, the class already contains a method implementation with that name). diff --git a/platform/util/src/com/intellij/util/io/storage/HeavyProcessLatch.java b/platform/util/src/com/intellij/util/io/storage/HeavyProcessLatch.java index 29e77633c756..4042844974f6 100644 --- a/platform/util/src/com/intellij/util/io/storage/HeavyProcessLatch.java +++ b/platform/util/src/com/intellij/util/io/storage/HeavyProcessLatch.java @@ -20,16 +20,18 @@ package com.intellij.util.io.storage; import com.intellij.openapi.Disposable; +import com.intellij.openapi.application.AccessToken; import com.intellij.util.EventDispatcher; +import com.intellij.util.containers.ConcurrentHashSet; import org.jetbrains.annotations.NotNull; import java.util.EventListener; -import java.util.Stack; +import java.util.Set; public class HeavyProcessLatch { public static final HeavyProcessLatch INSTANCE = new HeavyProcessLatch(); - private final Stack myHeavyProcesses = new Stack(); + private final Set myHeavyProcesses = new ConcurrentHashSet(); private final EventDispatcher myEventDispatcher = EventDispatcher.create(HeavyProcessListener.class); private HeavyProcessLatch() { @@ -43,13 +45,21 @@ public class HeavyProcessLatch { processStarted(""); } - public void processStarted(@NotNull String operationName) { - myHeavyProcesses.push(operationName); + @NotNull + public AccessToken processStarted(@NotNull final String operationName) { + myHeavyProcesses.add(operationName); myEventDispatcher.getMulticaster().processStarted(); + return new AccessToken() { + @Override + public void finish() { + myHeavyProcesses.remove(operationName); + } + }; } + @Deprecated // use processStarted(String) public void processFinished() { - myHeavyProcesses.pop(); + myHeavyProcesses.remove(""); myEventDispatcher.getMulticaster().processFinished(); } @@ -59,7 +69,7 @@ public class HeavyProcessLatch { public String getRunningOperationName() { synchronized (myHeavyProcesses) { - return myHeavyProcesses.isEmpty() ? null : myHeavyProcesses.peek(); + return myHeavyProcesses.isEmpty() ? null : myHeavyProcesses.iterator().next(); } } diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/VcsApplicationSettings.java b/platform/vcs-api/src/com/intellij/openapi/vcs/VcsApplicationSettings.java index 67e04f2f5241..619c6c460603 100644 --- a/platform/vcs-api/src/com/intellij/openapi/vcs/VcsApplicationSettings.java +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/VcsApplicationSettings.java @@ -19,7 +19,7 @@ import com.intellij.openapi.components.*; import com.intellij.util.xmlb.XmlSerializerUtil; /** - * We don't use roaming type PER_PLATFORM — path macros is enough ($USER_HOME$/Dropbox for example) + * We don't use roaming type PER_PLATFORM - path macros is enough ($USER_HOME$/Dropbox for example) */ @State( name = "VcsApplicationSettings", diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/CompareWithSelectedRevisionAction.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/CompareWithSelectedRevisionAction.java index 2fb5b60e0d39..a4acd1d4864b 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/CompareWithSelectedRevisionAction.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/CompareWithSelectedRevisionAction.java @@ -28,10 +28,7 @@ import com.intellij.openapi.vcs.diff.DiffProvider; import com.intellij.openapi.vcs.history.*; import com.intellij.openapi.vcs.impl.VcsBackgroundableActions; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.ui.IdeBorderFactory; -import com.intellij.ui.ScrollPaneFactory; -import com.intellij.ui.SpeedSearchBase; -import com.intellij.ui.TableUtil; +import com.intellij.ui.*; import com.intellij.ui.dualView.TreeTableView; import com.intellij.ui.table.TableView; import com.intellij.ui.treeStructure.treetable.ListTreeTableModelOnColumns; @@ -322,10 +319,12 @@ public class CompareWithSelectedRevisionAction extends AbstractVcsAction { JPanel jPanel = new JPanel(new BorderLayout()); final JScrollPane textScrollPane = ScrollPaneFactory.createScrollPane(textArea); - textScrollPane.setBorder(IdeBorderFactory.createTitledBorder(VcsBundle.message("border.selected.revision.commit.message"), false - )); - jPanel.add(textScrollPane, BorderLayout.SOUTH); - + // text on title border has some problems if text font size is bigger than expected. + final JLabel commentLabel = new JLabel(VcsBundle.message("border.selected.revision.commit.message")); + jPanel.add(commentLabel, BorderLayout.NORTH); + commentLabel.setBorder(IdeBorderFactory.createBorder(SideBorder.TOP | SideBorder.LEFT | SideBorder.BOTTOM)); + textScrollPane.setBorder(null); + jPanel.add(textScrollPane, BorderLayout.CENTER); jPanel.setPreferredSize(new Dimension(300, 100)); return jPanel; } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/history/VcsHistoryProviderEx.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/history/VcsHistoryProviderEx.java new file mode 100644 index 000000000000..093cbf45185c --- /dev/null +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/history/VcsHistoryProviderEx.java @@ -0,0 +1,27 @@ +/* + * Copyright 2000-2009 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.vcs.history; + +import com.intellij.openapi.vcs.CalledInBackground; +import com.intellij.openapi.vcs.FilePath; +import com.intellij.openapi.vcs.VcsException; +import org.jetbrains.annotations.Nullable; + +public interface VcsHistoryProviderEx extends VcsHistoryProvider { + @Nullable + @CalledInBackground + VcsFileRevision getLastRevision(FilePath filePath) throws VcsException; +} diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/ProjectLevelVcsManagerImpl.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/ProjectLevelVcsManagerImpl.java index 45f550271825..6886dd5098d8 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/ProjectLevelVcsManagerImpl.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/ProjectLevelVcsManagerImpl.java @@ -16,6 +16,7 @@ package com.intellij.openapi.vcs.impl; import com.intellij.icons.AllIcons; +import com.intellij.openapi.actionSystem.DefaultActionGroup; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.components.ProjectComponent; @@ -33,6 +34,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ex.ProjectEx; import com.intellij.openapi.roots.FileIndexFacade; import com.intellij.openapi.startup.StartupManager; +import com.intellij.openapi.ui.SimpleToolWindowPanel; import com.intellij.openapi.util.*; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.registry.Registry; @@ -57,6 +59,7 @@ import com.intellij.openapi.wm.ToolWindow; import com.intellij.openapi.wm.ToolWindowAnchor; import com.intellij.openapi.wm.ToolWindowId; import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.openapi.wm.ex.ToolWindowEx; import com.intellij.ui.content.Content; import com.intellij.ui.content.ContentFactory; import com.intellij.ui.content.ContentManager; @@ -238,6 +241,9 @@ public class ProjectLevelVcsManagerImpl extends ProjectLevelVcsManagerEx impleme toolWindowManager.registerToolWindow(ToolWindowId.VCS, true, ToolWindowAnchor.BOTTOM, myProject, true); myContentManager = toolWindow.getContentManager(); toolWindow.setIcon(AllIcons.Toolwindows.VcsSmallTab); + DefaultActionGroup gearActions = new DefaultActionGroup(); + gearActions.addAction(SimpleToolWindowPanel.createToggleToolbarAction(myProject, toolWindow)).setAsSecondary(true); + ((ToolWindowEx)toolWindow).setAdditionalGearActions(gearActions); toolWindow.installWatcher(myContentManager); } else { diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointImpl.java index 855abaaad74e..0d2fcb000d22 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointImpl.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointImpl.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. @@ -123,7 +123,7 @@ public class XLineBreakpointImpl

extends XBreak if (markupModel == null) { markupModel = (MarkupModelEx)DocumentMarkupModel.forDocument(document, getProject(), false); if (markupModel != null) { - // renderersChanged false — we don't change gutter size + // renderersChanged false - we don't change gutter size markupModel.fireAttributesChanged(highlighter, false); } } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/WatchInplaceEditor.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/WatchInplaceEditor.java index 6804679e7da3..58aa30fe2d84 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/WatchInplaceEditor.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/WatchInplaceEditor.java @@ -66,6 +66,7 @@ public class WatchInplaceEditor extends XDebuggerTreeInplaceEditor { if (myOldNode != null && index != -1) { myWatchesView.addWatchExpression(myOldNode.getExpression(), index, false); } + getTree().setSelectionRow(index); } @Override @@ -77,6 +78,7 @@ public class WatchInplaceEditor extends XDebuggerTreeInplaceEditor { if (!XDebuggerUtilImpl.isEmptyExpression(expression) && index != -1) { myWatchesView.addWatchExpression(expression, index, false); } + getTree().setSelectionRow(index); } @Override diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/WatchesRootNode.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/WatchesRootNode.java index 2e4e168b8d84..1421426809c5 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/WatchesRootNode.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/WatchesRootNode.java @@ -106,6 +106,7 @@ public class WatchesRootNode extends XDebuggerTreeNode { } private void replaceNode(final WatchNode oldNode, final WatchNode newNode) { + int[] selectedRows = getTree().getSelectionRows(); for (int i = 0; i < myChildren.size(); i++) { WatchNode child = myChildren.get(i); if (child == oldNode) { @@ -118,6 +119,7 @@ public class WatchesRootNode extends XDebuggerTreeNode { else { fireNodeStructureChanged(newNode); } + getTree().setSelectionRows(selectedRows); return; } } diff --git a/plugins/devkit/src/references/extensions/ExtensionPointDocumentationProvider.java b/plugins/devkit/src/references/extensions/ExtensionPointDocumentationProvider.java index 2ce1c27e6e38..3ac1702a1567 100644 --- a/plugins/devkit/src/references/extensions/ExtensionPointDocumentationProvider.java +++ b/plugins/devkit/src/references/extensions/ExtensionPointDocumentationProvider.java @@ -61,7 +61,7 @@ public class ExtensionPointDocumentationProvider extends DocumentationProviderEx (epPrefix == null ? "" : " " + epPrefix) + "
" + "" + extensionPoint.getEffectiveName() + "" + - " [" + epDeclarationFile.getName() + "]
" + + " (" + epDeclarationFile.getName() + ")
" + epClassText.toString(); } diff --git a/plugins/devkit/testSources/references/extensions/ExtensionPointDocumentationProviderTest.java b/plugins/devkit/testSources/references/extensions/ExtensionPointDocumentationProviderTest.java index a9c16ec0335a..94214e5b6e50 100644 --- a/plugins/devkit/testSources/references/extensions/ExtensionPointDocumentationProviderTest.java +++ b/plugins/devkit/testSources/references/extensions/ExtensionPointDocumentationProviderTest.java @@ -21,8 +21,7 @@ public class ExtensionPointDocumentationProviderTest extends LightCodeInsightFix DocumentationProvider provider = DocumentationManager.getProviderFromElement(docElement); String epDefinition = "[" + myModule.getName() + "] foo
" + - "bar " + - "[extensionPointDocumentation.xml]
" + + "bar (extensionPointDocumentation.xml)
" + "MyExtensionPoint"; assertEquals(epDefinition, diff --git a/plugins/git4idea/src/git4idea/actions/GitMergeAction.java b/plugins/git4idea/src/git4idea/actions/GitMergeAction.java index c2e172525307..6a730eac7e83 100644 --- a/plugins/git4idea/src/git4idea/actions/GitMergeAction.java +++ b/plugins/git4idea/src/git4idea/actions/GitMergeAction.java @@ -18,6 +18,7 @@ package git4idea.actions; import com.intellij.dvcs.DvcsUtil; import com.intellij.history.Label; import com.intellij.history.LocalHistory; +import com.intellij.openapi.application.AccessToken; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.Task; @@ -86,7 +87,7 @@ abstract class GitMergeAction extends GitRepositoryAction { final GitUntrackedFilesOverwrittenByOperationDetector untrackedFilesDetector = new GitUntrackedFilesOverwrittenByOperationDetector(selectedRoot); - DvcsUtil.workingTreeChangeStarted(project); + AccessToken token = DvcsUtil.workingTreeChangeStarted(project); try { GitCommandResult result = git.runCommand(new Computable() { @Override @@ -109,7 +110,7 @@ abstract class GitMergeAction extends GitRepositoryAction { handleResult(result, project, localChangesDetector, untrackedFilesDetector, repository, currentRev, affectedRoots, beforeLabel); } finally { - DvcsUtil.workingTreeChangeFinished(project); + DvcsUtil.workingTreeChangeFinished(project, token); } } diff --git a/plugins/git4idea/src/git4idea/actions/GitRebaseAbort.java b/plugins/git4idea/src/git4idea/actions/GitRebaseAbort.java index 3edd559a8e51..b36055c118ab 100644 --- a/plugins/git4idea/src/git4idea/actions/GitRebaseAbort.java +++ b/plugins/git4idea/src/git4idea/actions/GitRebaseAbort.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,6 +17,7 @@ package git4idea.actions; import com.intellij.dvcs.DvcsUtil; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.application.AccessToken; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.vcs.VcsException; @@ -75,12 +76,12 @@ public class GitRebaseAbort extends GitRepositoryAction { GitSimpleHandler h = new GitSimpleHandler(project, root, GitCommand.REBASE); h.setStdoutSuppressed(false); h.addParameters("--abort"); - DvcsUtil.workingTreeChangeStarted(project); + AccessToken token = DvcsUtil.workingTreeChangeStarted(project); try { GitHandlerUtil.doSynchronously(h, getActionName(), h.printableCommandLine()); } finally { - DvcsUtil.workingTreeChangeFinished(project); + DvcsUtil.workingTreeChangeFinished(project, token); } } diff --git a/plugins/git4idea/src/git4idea/actions/GitRebaseActionBase.java b/plugins/git4idea/src/git4idea/actions/GitRebaseActionBase.java index 95246459fc1d..19de14769081 100644 --- a/plugins/git4idea/src/git4idea/actions/GitRebaseActionBase.java +++ b/plugins/git4idea/src/git4idea/actions/GitRebaseActionBase.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,6 +16,7 @@ package git4idea.actions; import com.intellij.dvcs.DvcsUtil; +import com.intellij.openapi.application.AccessToken; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.vcs.VcsException; @@ -65,7 +66,7 @@ public abstract class GitRebaseActionBase extends GitRepositoryAction { task.executeInBackground(false, new GitTaskResultHandlerAdapter() { @Override protected void run(GitTaskResult taskResult) { - DvcsUtil.workingTreeChangeStarted(project); + AccessToken token = DvcsUtil.workingTreeChangeStarted(project); try { editor.close(); GitRepositoryManager manager = GitUtil.getRepositoryManager(project); @@ -74,7 +75,7 @@ public abstract class GitRebaseActionBase extends GitRepositoryAction { notifyAboutErrorResult(taskResult, resultListener, exceptions, project); } finally { - DvcsUtil.workingTreeChangeFinished(project); + DvcsUtil.workingTreeChangeFinished(project, token); } } }); diff --git a/plugins/git4idea/src/git4idea/actions/GitResetHead.java b/plugins/git4idea/src/git4idea/actions/GitResetHead.java index 0aa7180fba92..3a739d0e473f 100644 --- a/plugins/git4idea/src/git4idea/actions/GitResetHead.java +++ b/plugins/git4idea/src/git4idea/actions/GitResetHead.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,6 +16,7 @@ package git4idea.actions; import com.intellij.dvcs.DvcsUtil; +import com.intellij.openapi.application.AccessToken; import com.intellij.openapi.project.Project; import com.intellij.openapi.vcs.VcsException; import com.intellij.openapi.vfs.VirtualFile; @@ -57,12 +58,12 @@ public class GitResetHead extends GitRepositoryAction { } GitLineHandler h = d.handler(); affectedRoots.add(d.getGitRoot()); - DvcsUtil.workingTreeChangeStarted(project); + AccessToken token = DvcsUtil.workingTreeChangeStarted(project); try { GitHandlerUtil.doSynchronously(h, GitBundle.getString("resetting.title"), h.printableCommandLine()); } finally { - DvcsUtil.workingTreeChangeFinished(project); + DvcsUtil.workingTreeChangeFinished(project, token); } GitRepositoryManager manager = GitUtil.getRepositoryManager(project); manager.updateRepository(d.getGitRoot()); diff --git a/plugins/git4idea/src/git4idea/actions/GitStash.java b/plugins/git4idea/src/git4idea/actions/GitStash.java index 20fd525929ea..b5a4892a30fd 100644 --- a/plugins/git4idea/src/git4idea/actions/GitStash.java +++ b/plugins/git4idea/src/git4idea/actions/GitStash.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,6 +16,7 @@ package git4idea.actions; import com.intellij.dvcs.DvcsUtil; +import com.intellij.openapi.application.AccessToken; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.vcs.VcsException; @@ -54,12 +55,12 @@ public class GitStash extends GitRepositoryAction { VirtualFile root = d.getGitRoot(); affectedRoots.add(root); final GitLineHandler h = d.handler(); - DvcsUtil.workingTreeChangeStarted(project); + AccessToken token = DvcsUtil.workingTreeChangeStarted(project); try { GitHandlerUtil.doSynchronously(h, GitBundle.getString("stashing.title"), h.printableCommandLine()); } finally { - DvcsUtil.workingTreeChangeFinished(project); + DvcsUtil.workingTreeChangeFinished(project, token); } ServiceManager.getService(project, GitPlatformFacade.class).hardRefresh(root); } diff --git a/plugins/git4idea/src/git4idea/branch/GitCheckoutOperation.java b/plugins/git4idea/src/git4idea/branch/GitCheckoutOperation.java index 5e0a10c039ee..8327a614725c 100644 --- a/plugins/git4idea/src/git4idea/branch/GitCheckoutOperation.java +++ b/plugins/git4idea/src/git4idea/branch/GitCheckoutOperation.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,6 +16,7 @@ package git4idea.branch; import com.intellij.dvcs.DvcsUtil; +import com.intellij.openapi.application.AccessToken; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Pair; @@ -65,7 +66,7 @@ class GitCheckoutOperation extends GitBranchOperation { protected void execute() { saveAllDocuments(); boolean fatalErrorHappened = false; - DvcsUtil.workingTreeChangeStarted(myProject); + AccessToken token = DvcsUtil.workingTreeChangeStarted(myProject); try { while (hasMoreRepositories() && !fatalErrorHappened) { final GitRepository repository = next(); @@ -104,7 +105,7 @@ class GitCheckoutOperation extends GitBranchOperation { } } finally { - DvcsUtil.workingTreeChangeFinished(myProject); + DvcsUtil.workingTreeChangeFinished(myProject, token); } if (!fatalErrorHappened) { diff --git a/plugins/git4idea/src/git4idea/branch/GitMergeOperation.java b/plugins/git4idea/src/git4idea/branch/GitMergeOperation.java index db92107629cf..5a0d6a031f98 100644 --- a/plugins/git4idea/src/git4idea/branch/GitMergeOperation.java +++ b/plugins/git4idea/src/git4idea/branch/GitMergeOperation.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. @@ -18,6 +18,7 @@ package git4idea.branch; import com.intellij.dvcs.DvcsUtil; import com.intellij.notification.Notification; import com.intellij.notification.NotificationListener; +import com.intellij.openapi.application.AccessToken; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; @@ -73,7 +74,7 @@ class GitMergeOperation extends GitBranchOperation { saveAllDocuments(); boolean fatalErrorHappened = false; int alreadyUpToDateRepositories = 0; - DvcsUtil.workingTreeChangeStarted(myProject); + AccessToken token = DvcsUtil.workingTreeChangeStarted(myProject); try { while (hasMoreRepositories() && !fatalErrorHappened) { final GitRepository repository = next(); @@ -147,7 +148,7 @@ class GitMergeOperation extends GitBranchOperation { restoreLocalChanges(); } finally { - DvcsUtil.workingTreeChangeFinished(myProject); + DvcsUtil.workingTreeChangeFinished(myProject, token); } } diff --git a/plugins/git4idea/src/git4idea/changes/GitCommittedChangeListProvider.java b/plugins/git4idea/src/git4idea/changes/GitCommittedChangeListProvider.java index 31e731f44937..f34279bdf6dd 100644 --- a/plugins/git4idea/src/git4idea/changes/GitCommittedChangeListProvider.java +++ b/plugins/git4idea/src/git4idea/changes/GitCommittedChangeListProvider.java @@ -207,7 +207,7 @@ public class GitCommittedChangeListProvider implements CommittedChangesProvider< } } final String afterTime = "--after=" + GitUtil.gitTime(gitCommit.getDate()); - final List history = GitHistoryUtils.history(myProject, filePath, null, afterTime); + final List history = GitHistoryUtils.history(myProject, filePath, (VirtualFile)null, afterTime); if (history.isEmpty()) { return new Pair(commit, filePath); } diff --git a/plugins/git4idea/src/git4idea/cherrypick/GitCherryPicker.java b/plugins/git4idea/src/git4idea/cherrypick/GitCherryPicker.java index 4e3c3183cf16..77196722f24a 100644 --- a/plugins/git4idea/src/git4idea/cherrypick/GitCherryPicker.java +++ b/plugins/git4idea/src/git4idea/cherrypick/GitCherryPicker.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 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 git4idea.cherrypick; import com.intellij.dvcs.DvcsUtil; import com.intellij.notification.Notification; import com.intellij.notification.NotificationListener; +import com.intellij.openapi.application.AccessToken; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; @@ -90,7 +91,7 @@ public class GitCherryPicker { public void cherryPick(@NotNull Map> commitsInRoots) { List successfulCommits = ContainerUtil.newArrayList(); List alreadyPicked = ContainerUtil.newArrayList(); - DvcsUtil.workingTreeChangeStarted(myProject); + AccessToken token = DvcsUtil.workingTreeChangeStarted(myProject); try { for (Map.Entry> entry : commitsInRoots.entrySet()) { GitRepository repository = entry.getKey(); @@ -103,7 +104,7 @@ public class GitCherryPicker { notifyResult(successfulCommits, alreadyPicked); } finally { - DvcsUtil.workingTreeChangeFinished(myProject); + DvcsUtil.workingTreeChangeFinished(myProject, token); } } diff --git a/plugins/git4idea/src/git4idea/history/GitHistoryProvider.java b/plugins/git4idea/src/git4idea/history/GitHistoryProvider.java index 7550f804fb21..0d4942f2add2 100644 --- a/plugins/git4idea/src/git4idea/history/GitHistoryProvider.java +++ b/plugins/git4idea/src/git4idea/history/GitHistoryProvider.java @@ -52,7 +52,7 @@ import java.util.List; /** * Git history provider implementation */ -public class GitHistoryProvider implements VcsHistoryProvider, VcsCacheableHistorySessionFactory, +public class GitHistoryProvider implements VcsHistoryProviderEx, VcsCacheableHistorySessionFactory, VcsBaseRevisionAdviser { private static final Logger log = Logger.getInstance(GitHistoryProvider.class.getName()); @@ -139,6 +139,14 @@ public class GitHistoryProvider implements VcsHistoryProvider, VcsCacheableHisto }; } + @Nullable + @Override + public VcsFileRevision getLastRevision(FilePath filePath) throws VcsException { + List history = GitHistoryUtils.history(myProject, filePath, "--max-count=1"); + if (history == null || history.isEmpty()) return null; + return history.get(0); + } + @Override public boolean getBaseVersionContent(FilePath filePath, Processor processor, diff --git a/plugins/git4idea/src/git4idea/history/GitHistoryUtils.java b/plugins/git4idea/src/git4idea/history/GitHistoryUtils.java index 1337735820ac..1c310492059d 100644 --- a/plugins/git4idea/src/git4idea/history/GitHistoryUtils.java +++ b/plugins/git4idea/src/git4idea/history/GitHistoryUtils.java @@ -650,9 +650,9 @@ public class GitHistoryUtils { * @return the list of the revisions * @throws VcsException if there is problem with running git */ - public static List history(final Project project, final FilePath path) throws VcsException { + public static List history(final Project project, final FilePath path, String... parameters) throws VcsException { final VirtualFile root = GitUtil.getGitRoot(path); - return history(project, path, root); + return history(project, path, root, parameters); } /** diff --git a/plugins/git4idea/src/git4idea/rebase/GitRebaser.java b/plugins/git4idea/src/git4idea/rebase/GitRebaser.java index d44988c48aac..75e28742b965 100644 --- a/plugins/git4idea/src/git4idea/rebase/GitRebaser.java +++ b/plugins/git4idea/src/git4idea/rebase/GitRebaser.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. @@ -16,6 +16,7 @@ package git4idea.rebase; import com.intellij.dvcs.DvcsUtil; +import com.intellij.openapi.application.AccessToken; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProgressIndicator; @@ -91,8 +92,8 @@ public class GitRebaser { rebaseTask.setProgressAnalyzer(new GitStandardProgressAnalyzer()); final AtomicReference updateResult = new AtomicReference(); final AtomicBoolean failure = new AtomicBoolean(); + AccessToken token = DvcsUtil.workingTreeChangeStarted(myProject); try { - DvcsUtil.workingTreeChangeStarted(myProject); rebaseTask.executeInBackground(true, new GitTaskResultHandlerAdapter() { @Override protected void onSuccess() { @@ -118,7 +119,7 @@ public class GitRebaser { } } finally { - DvcsUtil.workingTreeChangeFinished(myProject); + DvcsUtil.workingTreeChangeFinished(myProject, token); } return updateResult.get(); } @@ -146,7 +147,7 @@ public class GitRebaser { * @return true if rebase successfully finished. */ public boolean continueRebase(@NotNull Collection rebasingRoots) { - DvcsUtil.workingTreeChangeStarted(myProject); + AccessToken token = DvcsUtil.workingTreeChangeStarted(myProject); try { boolean success = true; for (VirtualFile root : rebasingRoots) { @@ -155,7 +156,7 @@ public class GitRebaser { return success; } finally { - DvcsUtil.workingTreeChangeFinished(myProject); + DvcsUtil.workingTreeChangeFinished(myProject, token); } } diff --git a/plugins/git4idea/src/git4idea/reset/GitResetOperation.java b/plugins/git4idea/src/git4idea/reset/GitResetOperation.java index 528a9e1277f3..802137737c89 100644 --- a/plugins/git4idea/src/git4idea/reset/GitResetOperation.java +++ b/plugins/git4idea/src/git4idea/reset/GitResetOperation.java @@ -17,6 +17,7 @@ package git4idea.reset; import com.intellij.dvcs.DvcsUtil; import com.intellij.dvcs.repo.RepositoryUtil; +import com.intellij.openapi.application.AccessToken; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.progress.ProgressIndicator; @@ -76,7 +77,7 @@ public class GitResetOperation { public void execute() { saveAllDocuments(); - DvcsUtil.workingTreeChangeStarted(myProject); + AccessToken token = DvcsUtil.workingTreeChangeStarted(myProject); Map results = ContainerUtil.newHashMap(); try { for (Map.Entry entry : myCommits.entrySet()) { @@ -99,7 +100,7 @@ public class GitResetOperation { } } finally { - DvcsUtil.workingTreeChangeFinished(myProject); + DvcsUtil.workingTreeChangeFinished(myProject, token); } notifyResult(results); } diff --git a/plugins/git4idea/src/git4idea/rollback/GitRollbackEnvironment.java b/plugins/git4idea/src/git4idea/rollback/GitRollbackEnvironment.java index 87b256db62d6..ea4570ce30e9 100644 --- a/plugins/git4idea/src/git4idea/rollback/GitRollbackEnvironment.java +++ b/plugins/git4idea/src/git4idea/rollback/GitRollbackEnvironment.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,6 +17,7 @@ package git4idea.rollback; import com.intellij.dvcs.DvcsUtil; import com.intellij.lifecycle.PeriodicalTasksCloser; +import com.intellij.openapi.application.AccessToken; import com.intellij.openapi.project.Project; import com.intellij.openapi.vcs.FilePath; import com.intellij.openapi.vcs.VcsException; @@ -142,7 +143,7 @@ public class GitRollbackEnvironment implements RollbackEnvironment { } } // revert files from HEAD - DvcsUtil.workingTreeChangeStarted(myProject); + AccessToken token = DvcsUtil.workingTreeChangeStarted(myProject); try { for (Map.Entry> entry : toRevert.entrySet()) { listener.accept(entry.getValue()); @@ -155,7 +156,7 @@ public class GitRollbackEnvironment implements RollbackEnvironment { } } finally { - DvcsUtil.workingTreeChangeFinished(myProject); + DvcsUtil.workingTreeChangeFinished(myProject,token); } LocalFileSystem lfs = LocalFileSystem.getInstance(); HashSet filesToRefresh = new HashSet(); diff --git a/plugins/git4idea/src/git4idea/ui/GitUnstashDialog.java b/plugins/git4idea/src/git4idea/ui/GitUnstashDialog.java index 18f1f5ea6d5a..93278d15ee21 100644 --- a/plugins/git4idea/src/git4idea/ui/GitUnstashDialog.java +++ b/plugins/git4idea/src/git4idea/ui/GitUnstashDialog.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. @@ -20,6 +20,7 @@ import com.intellij.dvcs.DvcsUtil; import com.intellij.execution.configurations.GeneralCommandLine; import com.intellij.notification.Notification; import com.intellij.notification.NotificationListener; +import com.intellij.openapi.application.AccessToken; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.components.ServiceManager; @@ -357,7 +358,7 @@ public class GitUnstashDialog extends DialogWrapper { h.addLineListener(untrackedFilesDetector); h.addLineListener(localChangesDetector); - DvcsUtil.workingTreeChangeStarted(myProject); + AccessToken token = DvcsUtil.workingTreeChangeStarted(myProject); try { final Ref result = Ref.create(); ProgressManager.getInstance().run(new Task.Modal(h.project(), GitBundle.getString("unstash.unstashing"), false) { @@ -384,7 +385,7 @@ public class GitUnstashDialog extends DialogWrapper { } } finally { - DvcsUtil.workingTreeChangeFinished(myProject); + DvcsUtil.workingTreeChangeFinished(myProject, token); } super.doOKAction(); } diff --git a/plugins/git4idea/src/git4idea/update/GitUpdateProcess.java b/plugins/git4idea/src/git4idea/update/GitUpdateProcess.java index c7423b2a2112..636ad2c920c2 100644 --- a/plugins/git4idea/src/git4idea/update/GitUpdateProcess.java +++ b/plugins/git4idea/src/git4idea/update/GitUpdateProcess.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. @@ -16,6 +16,7 @@ package git4idea.update; import com.intellij.dvcs.DvcsUtil; +import com.intellij.openapi.application.AccessToken; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.EmptyProgressIndicator; @@ -133,12 +134,12 @@ public class GitUpdateProcess { GitComplexProcess.Operation updateOperation = new GitComplexProcess.Operation() { @Override public void run(ContinuationContext continuationContext) { - DvcsUtil.workingTreeChangeStarted(myProject); + AccessToken token = DvcsUtil.workingTreeChangeStarted(myProject); try { myResult = updateImpl(updateMethod, continuationContext); } finally { - DvcsUtil.workingTreeChangeFinished(myProject); + DvcsUtil.workingTreeChangeFinished(myProject, token); } } }; diff --git a/plugins/github/src/org/jetbrains/plugins/github/GithubRebaseAction.java b/plugins/github/src/org/jetbrains/plugins/github/GithubRebaseAction.java index 7b7bfabf73c8..3efd666d3ed7 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/GithubRebaseAction.java +++ b/plugins/github/src/org/jetbrains/plugins/github/GithubRebaseAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 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 org.jetbrains.plugins.github; import com.intellij.dvcs.DvcsUtil; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CommonDataKeys; +import com.intellij.openapi.application.AccessToken; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProgressIndicator; @@ -229,18 +230,22 @@ public class GithubRebaseAction extends DumbAwareAction { @NotNull final ProgressIndicator indicator) { final Git git = ServiceManager.getService(project, Git.class); final GitPlatformFacade facade = ServiceManager.getService(project, GitPlatformFacade.class); - DvcsUtil.workingTreeChangeStarted(project); - GitPreservingProcess process = - new GitPreservingProcess(project, facade, git, Collections.singletonList(gitRepository), "Rebasing", "upstream/master", indicator, - new Runnable() { - @Override - public void run() { - doRebaseCurrentBranch(project, gitRepository.getRoot(), indicator); + AccessToken token = DvcsUtil.workingTreeChangeStarted(project); + try { + GitPreservingProcess process = + new GitPreservingProcess(project, facade, git, Collections.singletonList(gitRepository), "Rebasing", "upstream/master", indicator, + new Runnable() { + @Override + public void run() { + doRebaseCurrentBranch(project, gitRepository.getRoot(), indicator); + } } - } - ); - process.execute(); - DvcsUtil.workingTreeChangeFinished(project); + ); + process.execute(); + } + finally { + DvcsUtil.workingTreeChangeFinished(project, token); + } } private static void doRebaseCurrentBranch(@NotNull final Project project, diff --git a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubCreatePullRequestDialog.java b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubCreatePullRequestDialog.java index c9b213db4358..47e090f94c14 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubCreatePullRequestDialog.java +++ b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubCreatePullRequestDialog.java @@ -18,7 +18,6 @@ package org.jetbrains.plugins.github.ui; import com.intellij.CommonBundle; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; -import com.intellij.openapi.ui.Messages; import com.intellij.openapi.ui.ValidationInfo; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.text.StringUtil; @@ -151,8 +150,13 @@ public class GithubCreatePullRequestDialog extends DialogWrapper { }); myPanel.setForks(myWorker.getForks()); - myPanel.setSelectedFork(myProjectSettings.getCreatePullRequestDefaultRepo()); - myPanel.setSelectedBranch(myProjectSettings.getCreatePullRequestDefaultBranch()); + + GithubFullPath defaultRepo = myProjectSettings.getCreatePullRequestDefaultRepo(); + String defaultBranch = myProjectSettings.getCreatePullRequestDefaultBranch(); + myPanel.setSelectedFork(defaultRepo); + if (defaultBranch != null) { // do not rewrite default value of Fork.getDefaultBranch() by null + myPanel.setSelectedBranch(defaultBranch); + } setTitle("Create Pull Request - " + myWorker.getCurrentBranch()); init(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyPositionManager.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyPositionManager.java index dbbc4333a02d..74972e6165e1 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyPositionManager.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyPositionManager.java @@ -77,11 +77,11 @@ public class GroovyPositionManager implements PositionManager { List locations = getDebugProcess().getVirtualMachineProxy().versionHigher("1.4") ? type.locationsOfLine(DebugProcess.JAVA_STRATUM, null, line) : type.locationsOfLine(line); - if (locations == null || locations.isEmpty()) throw new NoDataException(); + if (locations == null || locations.isEmpty()) throw NoDataException.INSTANCE; return locations; } catch (AbsentInformationException e) { - throw new NoDataException(); + throw NoDataException.INSTANCE; } } @@ -112,7 +112,7 @@ public class GroovyPositionManager implements PositionManager { private static void checkGroovyFile(@NotNull SourcePosition position) throws NoDataException { if (!(position.getFile() instanceof GroovyFileBase)) { - throw new NoDataException(); + throw NoDataException.INSTANCE; } } @@ -127,7 +127,7 @@ public class GroovyPositionManager implements PositionManager { qName = findEnclosingName(position); - if (qName == null) throw new NoDataException(); + if (qName == null) throw NoDataException.INSTANCE; ClassPrepareRequestor waitRequestor = new ClassPrepareRequestor() { @Override public void processClassPrepare(DebugProcess debuggerProcess, ReferenceType referenceType) { @@ -205,13 +205,13 @@ public class GroovyPositionManager implements PositionManager { @Override public SourcePosition getSourcePosition(final Location location) throws NoDataException { - if (location == null) throw new NoDataException(); + if (location == null) throw NoDataException.INSTANCE; PsiFile psiFile = getPsiFileByLocation(getDebugProcess().getProject(), location); - if (psiFile == null) throw new NoDataException(); + if (psiFile == null) throw NoDataException.INSTANCE; int lineNumber = calcLineIndex(location); - if (lineNumber < 0) throw new NoDataException(); + if (lineNumber < 0) throw NoDataException.INSTANCE; return SourcePosition.createFromLine(psiFile, lineNumber); } @@ -323,7 +323,7 @@ public class GroovyPositionManager implements PositionManager { } }); - if (result == null) throw new NoDataException(); + if (result == null) throw NoDataException.INSTANCE; return result; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/springloaded/SpringLoadedPositionManager.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/springloaded/SpringLoadedPositionManager.java index 6adf50e75094..378c15695fd9 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/springloaded/SpringLoadedPositionManager.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/springloaded/SpringLoadedPositionManager.java @@ -62,7 +62,7 @@ public class SpringLoadedPositionManager implements PositionManager { @Override public SourcePosition getSourcePosition(@Nullable Location location) throws NoDataException { - throw new NoDataException(); + throw NoDataException.INSTANCE; } @NotNull @@ -74,7 +74,7 @@ public class SpringLoadedPositionManager implements PositionManager { AccessToken accessToken = ReadAction.start(); try { className = findEnclosingName(classPosition); - if (className == null) throw new NoDataException(); + if (className == null) throw NoDataException.INSTANCE; line = classPosition.getLine(); } @@ -83,7 +83,7 @@ public class SpringLoadedPositionManager implements PositionManager { } List referenceTypes = myDebugProcess.getVirtualMachineProxy().classesByName(className); - if (referenceTypes.isEmpty()) throw new NoDataException(); + if (referenceTypes.isEmpty()) throw NoDataException.INSTANCE; Set res = new HashSet(); @@ -92,7 +92,7 @@ public class SpringLoadedPositionManager implements PositionManager { } if (res.isEmpty()) { - throw new NoDataException(); + throw NoDataException.INSTANCE; } return new ArrayList(res); @@ -101,7 +101,7 @@ public class SpringLoadedPositionManager implements PositionManager { @NotNull @Override public List locationsOfLine(@NotNull ReferenceType type, @NotNull SourcePosition position) throws NoDataException { - throw new NoDataException(); + throw NoDataException.INSTANCE; } @Nullable @@ -164,7 +164,7 @@ public class SpringLoadedPositionManager implements PositionManager { public ClassPrepareRequest createPrepareRequest(@NotNull ClassPrepareRequestor requestor, @NotNull SourcePosition position) throws NoDataException { String className = getOuterClassName(position); if (className == null) { - throw new NoDataException(); + throw NoDataException.INSTANCE; } return myDebugProcess.getRequestsManager().createClassPrepareRequest(requestor, className + "*"); diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgMergeCommand.java b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgMergeCommand.java index 16c8b7fe0a8b..0a428a9d759e 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgMergeCommand.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgMergeCommand.java @@ -13,6 +13,7 @@ package org.zmlx.hg4idea.command; import com.intellij.dvcs.DvcsUtil; +import com.intellij.openapi.application.AccessToken; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; @@ -50,7 +51,7 @@ public class HgMergeCommand { arguments.add("--rev"); arguments.add(revision); } - DvcsUtil.workingTreeChangeStarted(project); + AccessToken token = DvcsUtil.workingTreeChangeStarted(project); try { final HgCommandResult result = commandExecutor.executeInCurrentThread(repo, "merge", arguments); @@ -58,7 +59,7 @@ public class HgMergeCommand { return result; } finally { - DvcsUtil.workingTreeChangeFinished(project); + DvcsUtil.workingTreeChangeFinished(project, token); } } } diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgRebaseCommand.java b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgRebaseCommand.java index 05a5ebda6d7a..25d174cfcaf0 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgRebaseCommand.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgRebaseCommand.java @@ -13,6 +13,7 @@ package org.zmlx.hg4idea.command; import com.intellij.dvcs.DvcsUtil; +import com.intellij.openapi.application.AccessToken; import com.intellij.openapi.project.Project; import com.intellij.util.ArrayUtil; import com.intellij.util.containers.ContainerUtil; @@ -50,7 +51,7 @@ public class HgRebaseCommand { @Nullable private HgCommandResult performRebase(@NotNull String... args) { - DvcsUtil.workingTreeChangeStarted(project); + AccessToken token = DvcsUtil.workingTreeChangeStarted(project); try { HgCommandResult result = new HgCommandExecutor(project) @@ -60,7 +61,7 @@ public class HgRebaseCommand { return result; } finally { - DvcsUtil.workingTreeChangeFinished(project); + DvcsUtil.workingTreeChangeFinished(project, token); } } } diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgUpdateCommand.java b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgUpdateCommand.java index 0be4e1602b1e..4e8c06a680dd 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgUpdateCommand.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgUpdateCommand.java @@ -13,6 +13,7 @@ package org.zmlx.hg4idea.command; import com.intellij.dvcs.DvcsUtil; +import com.intellij.openapi.application.AccessToken; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.text.StringUtil; @@ -75,7 +76,7 @@ public class HgUpdateCommand { final HgPromptCommandExecutor executor = new HgPromptCommandExecutor(project); executor.setShowOutput(true); HgCommandResult result; - DvcsUtil.workingTreeChangeStarted(project); + AccessToken token = DvcsUtil.workingTreeChangeStarted(project); try { result = executor.executeInCurrentThread(repo, "update", arguments); @@ -89,7 +90,7 @@ public class HgUpdateCommand { } } finally { - DvcsUtil.workingTreeChangeFinished(project); + DvcsUtil.workingTreeChangeFinished(project, token); } project.getMessageBus().syncPublisher(HgVcs.BRANCH_TOPIC).update(project, null); diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgRollbackEnvironment.java b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgRollbackEnvironment.java index 958bac8ef515..3b536c2fecb7 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgRollbackEnvironment.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgRollbackEnvironment.java @@ -13,6 +13,7 @@ package org.zmlx.hg4idea.provider; import com.intellij.dvcs.DvcsUtil; +import com.intellij.openapi.application.AccessToken; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.vcs.FilePath; @@ -71,7 +72,7 @@ public class HgRollbackEnvironment implements RollbackEnvironment { } } } - DvcsUtil.workingTreeChangeStarted(project); + AccessToken token = DvcsUtil.workingTreeChangeStarted(project); try { revert(filePaths); for (FilePath file : toDelete) { @@ -92,18 +93,18 @@ public class HgRollbackEnvironment implements RollbackEnvironment { } } finally { - DvcsUtil.workingTreeChangeFinished(project); + DvcsUtil.workingTreeChangeFinished(project, token); } } public void rollbackMissingFileDeletion(List files, List exceptions, RollbackProgressListener listener) { - DvcsUtil.workingTreeChangeStarted(project); + AccessToken token = DvcsUtil.workingTreeChangeStarted(project); try { revert(files); } finally { - DvcsUtil.workingTreeChangeFinished(project); + DvcsUtil.workingTreeChangeFinished(project, token); } } diff --git a/plugins/junit/src/com/intellij/execution/junit/TestObject.java b/plugins/junit/src/com/intellij/execution/junit/TestObject.java index eb9de875c346..896a1aa24020 100644 --- a/plugins/junit/src/com/intellij/execution/junit/TestObject.java +++ b/plugins/junit/src/com/intellij/execution/junit/TestObject.java @@ -48,7 +48,9 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleUtilCore; +import com.intellij.openapi.project.Project; import com.intellij.openapi.projectRoots.JavaSdkType; +import com.intellij.openapi.projectRoots.JdkUtil; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.projectRoots.ex.JavaSdkUtil; import com.intellij.openapi.roots.ModuleRootManager; @@ -60,9 +62,13 @@ import com.intellij.openapi.util.Key; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.util.text.StringUtilRt; import com.intellij.openapi.vfs.CharsetToolkit; import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.GlobalSearchScopesCore; import com.intellij.refactoring.listeners.RefactoringElementListener; +import com.intellij.rt.execution.CommandLineWrapper; import com.intellij.rt.execution.junit.IDEAJUnitListener; import com.intellij.rt.execution.junit.JUnitStarter; import com.intellij.util.Function; @@ -422,7 +428,29 @@ public abstract class TestObject implements JavaCommandLine { final String workingDirectory = myConfiguration.getWorkingDirectory(); return JUnitConfiguration.TEST_PACKAGE.equals(myConfiguration.getPersistentData().TEST_OBJECT) && myConfiguration.getPersistentData().getScope() != TestSearchScope.SINGLE_MODULE && - ("$" + PathMacroUtil.MODULE_DIR_MACRO_NAME + "$").equals(workingDirectory); + ("$" + PathMacroUtil.MODULE_DIR_MACRO_NAME + "$").equals(workingDirectory) && + spansMultipleModules(); + } + + private boolean spansMultipleModules() { + final String qualifiedName = myConfiguration.getPackage(); + if (qualifiedName != null) { + final Project project = myConfiguration.getProject(); + final PsiPackage aPackage = JavaPsiFacade.getInstance(project).findPackage(qualifiedName); + if (aPackage != null) { + final TestSearchScope scope = myConfiguration.getPersistentData().getScope(); + if (scope != null) { + final SourceScope sourceScope = scope.getSourceScope(myConfiguration); + if (sourceScope != null) { + final GlobalSearchScope configurationSearchScope = GlobalSearchScopesCore.projectTestScope(project).intersectWith( + sourceScope.getGlobalSearchScope()); + final PsiDirectory[] directories = aPackage.getDirectories(configurationSearchScope); + return directories.length > 1; + } + } + } + } + return false; } private void appendForkInfo(Executor executor) throws ExecutionException { @@ -452,12 +480,22 @@ public abstract class TestObject implements JavaCommandLine { final File tempFile = FileUtil.createTempFile("command.line", "", true); final PrintWriter writer = new PrintWriter(tempFile, CharsetToolkit.UTF8); try { + if (JdkUtil.useDynamicClasspath(myConfiguration.getProject())) { + String classpath = PathUtil.getJarPathForClass(CommandLineWrapper.class); + final String utilRtPath = PathUtil.getJarPathForClass(StringUtilRt.class); + if (!classpath.equals(utilRtPath)) { + classpath += File.pathSeparator + utilRtPath; + } + writer.println(classpath); + } + else { + writer.println(""); + } + writer.println(((JavaSdkType)jdk.getSdkType()).getVMExecutablePath(jdk)); for (String vmParameter : javaParameters.getVMParametersList().getList()) { writer.println(vmParameter); } - writer.println("-classpath"); - writer.println(javaParameters.getClassPath().getPathsString()); } finally { writer.close(); @@ -524,6 +562,9 @@ public abstract class TestObject implements JavaCommandLine { JUnitStarter.printClassesList(testNames, packageName, category, myTempFile); if (perModule != null && perModule.size() > 1) { + final String classpath = myConfiguration.getPersistentData().getScope() == TestSearchScope.WHOLE_PROJECT + ? null : myJavaParameters.getClassPath().getPathsString(); + final PrintWriter wWriter = new PrintWriter(myWorkingDirsFile, CharsetToolkit.UTF8); try { wWriter.println(packageName); @@ -531,11 +572,16 @@ public abstract class TestObject implements JavaCommandLine { final String moduleDir = PathMacroUtil.getModuleDir(module.getModuleFilePath()); wWriter.println(moduleDir); - final JavaParameters parameters = new JavaParameters(); - JavaParametersUtil.configureModule(module, parameters, JavaParameters.JDK_AND_CLASSES_AND_TESTS, - myConfiguration.isAlternativeJrePathEnabled() ? myConfiguration.getAlternativeJrePath() : null); - configureAdditionalClasspath(parameters); - wWriter.println(parameters.getClassPath().getPathsString()); + if (classpath == null) { + final JavaParameters parameters = new JavaParameters(); + configureAdditionalClasspath(parameters); + JavaParametersUtil.configureModule(module, parameters, JavaParameters.JDK_AND_CLASSES_AND_TESTS, + myConfiguration.isAlternativeJrePathEnabled() ? myConfiguration.getAlternativeJrePath() : null); + wWriter.println(parameters.getClassPath().getPathsString()); + } else { + wWriter.println(classpath); + } + final List classNames = perModule.get(module); wWriter.println(classNames.size()); for (String className : classNames) { diff --git a/plugins/junit_rt/src/com/intellij/rt/execution/junit/JUnitForkedStarter.java b/plugins/junit_rt/src/com/intellij/rt/execution/junit/JUnitForkedStarter.java index e79ab8e677b3..6b58cd009b87 100644 --- a/plugins/junit_rt/src/com/intellij/rt/execution/junit/JUnitForkedStarter.java +++ b/plugins/junit_rt/src/com/intellij/rt/execution/junit/JUnitForkedStarter.java @@ -15,6 +15,7 @@ */ package com.intellij.rt.execution.junit; +import com.intellij.rt.execution.CommandLineWrapper; import com.intellij.rt.execution.junit.segments.SegmentedOutputStream; import java.io.*; @@ -76,6 +77,7 @@ public class JUnitForkedStarter { String path) throws Exception { final List parameters = new ArrayList(); final BufferedReader bufferedReader = new BufferedReader(new FileReader(path)); + final String dynamicClasspath = bufferedReader.readLine(); try { String line; while ((line = bufferedReader.readLine()) != null) { @@ -99,7 +101,7 @@ public class JUnitForkedStarter { if (workingDirsPath == null || new File(workingDirsPath).length() == 0) { final List children = testRunner.getChildTests(description); final boolean forkTillMethod = forkMode.equalsIgnoreCase("method"); - result = processChildren(isJUnit4, listeners, out, err, parameters, testRunner, children, 0, forkTillMethod, null, System.getProperty("java.class.path")); + result = processChildren(isJUnit4, listeners, out, err, parameters, testRunner, children, 0, forkTillMethod, null, System.getProperty("java.class.path"), dynamicClasspath); } else { final BufferedReader perDirReader = new BufferedReader(new FileReader(workingDirsPath)); try { @@ -129,7 +131,7 @@ public class JUnitForkedStarter { JUnitStarter.printClassesList(classNames, packageName + ", working directory: \'" + workingDir + "\'", "", tempFile); childResult = runChild(isJUnit4, listeners, out, err, parameters, "@" + tempFile.getAbsolutePath(), dir, - String.valueOf(testRunner.getRegistry().getKnownObject(rootDescriptor) - 1), classpath); + String.valueOf(testRunner.getRegistry().getKnownObject(rootDescriptor) - 1), classpath, dynamicClasspath); } else { final List children = new ArrayList(testRunner.getChildTests(description)); for (Iterator iterator = children.iterator(); iterator.hasNext(); ) { @@ -138,7 +140,7 @@ public class JUnitForkedStarter { } } final boolean forkTillMethod = forkMode.equalsIgnoreCase("method"); - childResult = processChildren(isJUnit4, listeners, out, err, parameters, testRunner, children, result, forkTillMethod, dir, classpath); + childResult = processChildren(isJUnit4, listeners, out, err, parameters, testRunner, children, result, forkTillMethod, dir, classpath, dynamicClasspath); } result = Math.min(childResult, result); } @@ -180,7 +182,7 @@ public class JUnitForkedStarter { IdeaTestRunner testRunner, List children, int result, - boolean forkTillMethod, File workingDir, String classpath) throws IOException, InterruptedException { + boolean forkTillMethod, File workingDir, String classpath, String dynamicClasspath) throws IOException, InterruptedException { for (int i = 0, argsLength = children.size(); i < argsLength; i++) { final Object child = children.get(i); final List childTests = testRunner.getChildTests(child); @@ -188,11 +190,11 @@ public class JUnitForkedStarter { if (childTests.isEmpty() || !forkTillMethod) { final int startIndex = testRunner.getRegistry().getKnownObject(child); childResult = - runChild(isJUnit4, listeners, out, err, parameters, testRunner.getStartDescription(child), workingDir, String.valueOf(startIndex), classpath); + runChild(isJUnit4, listeners, out, err, parameters, testRunner.getStartDescription(child), workingDir, String.valueOf(startIndex), classpath, dynamicClasspath); } else { childResult = - processChildren(isJUnit4, listeners, out, err, parameters, testRunner, childTests, result, forkTillMethod, workingDir, classpath); + processChildren(isJUnit4, listeners, out, err, parameters, testRunner, childTests, result, forkTillMethod, workingDir, classpath, dynamicClasspath); } result = Math.min(childResult, result); } @@ -207,7 +209,8 @@ public class JUnitForkedStarter { String description, File workingDir, String startIndex, - String classpath) throws IOException, InterruptedException { + String classpath, + String dynamicClasspath) throws IOException, InterruptedException { //noinspection SSBasedInspection final File tempFile = File.createTempFile("fork", "test"); final String testOutputPath = tempFile.getAbsolutePath(); @@ -215,7 +218,39 @@ public class JUnitForkedStarter { final ProcessBuilder builder = new ProcessBuilder(); builder.add(parameters); builder.add("-classpath"); - builder.add(classpath); + if (dynamicClasspath.length() > 0) { + try { + final File classpathFile = File.createTempFile("classpath", null); + classpathFile.deleteOnExit(); + final PrintWriter writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream(classpathFile), "UTF-8")); + try { + int idx = 0; + while (idx < classpath.length()) { + final int endIdx = classpath.indexOf(File.pathSeparator, idx); + if (endIdx < 0) { + writer.println(classpath.substring(idx)); + break; + } + writer.println(classpath.substring(idx, endIdx)); + idx = endIdx + File.pathSeparator.length(); + } + } + finally { + writer.close(); + } + + builder.add(dynamicClasspath); + builder.add(CommandLineWrapper.class.getName()); + builder.add(classpathFile.getAbsolutePath()); + } + catch (Throwable e) { + builder.add(classpath); + } + } + else { + builder.add(classpath); + } + builder.add(JUnitForkedStarter.class.getName()); builder.add(testOutputPath); builder.add(startIndex); diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnApplicationSettings.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnApplicationSettings.java index 5cf6d6db4389..72a1539efcf4 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnApplicationSettings.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnApplicationSettings.java @@ -18,7 +18,6 @@ package org.jetbrains.idea.svn; import com.intellij.openapi.application.PathManager; import com.intellij.openapi.components.*; import com.intellij.openapi.project.Project; -import org.jetbrains.annotations.NotNull; import org.tmatesoft.svn.core.SVNException; import org.tmatesoft.svn.core.SVNURL; @@ -44,7 +43,6 @@ public class SvnApplicationSettings implements PersistentStateComponent myCheckoutURLs = new ArrayList(); public List myTypedURLs = new ArrayList(); public String mySvnCommandLine = "svn"; - public String myExecutableLocale = SvnConfigurable.EN_US_LOCALE; } private ConfigurationBean myConfigurationBean; @@ -67,24 +65,15 @@ public class SvnApplicationSettings implements PersistentStateComponentEmulates the behavior when Subversion commands are executed directly from the terminal (in the interactive mode).
\ This is required to handle password/passphrase prompts for svn+ssh repositories, and trust invalid server certificates for https repositories. -command.line.locale.label=Locale\: -command.line.locale.system.default.title= +non.english.locale.detected.warning=A non-English locale is used. ssh.settings.title=SSH Settings ssh.settings.executable.label=SSH executable\: diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfigurable.form b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfigurable.form index c09b5cee65cd..5ae0161d59b1 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfigurable.form +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfigurable.form @@ -156,7 +156,7 @@ - + @@ -181,20 +181,6 @@ - - - - - - - - - - - - - - diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfigurable.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfigurable.java index b12a830a722e..c207903bf621 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfigurable.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfigurable.java @@ -24,8 +24,6 @@ import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; import com.intellij.openapi.options.Configurable; import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.project.Project; -import com.intellij.openapi.ui.ComboBox; -import com.intellij.openapi.ui.FixedComboBoxEditor; import com.intellij.openapi.ui.TextFieldWithBrowseButton; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.SystemInfo; @@ -33,13 +31,10 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileManager; -import com.intellij.ui.CollectionComboBoxModel; -import com.intellij.ui.ListCellRendererWrapper; import com.intellij.ui.MultiLineTooltipUI; import com.intellij.ui.components.JBCheckBox; import com.intellij.ui.components.JBRadioButton; import com.intellij.util.Consumer; -import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -56,15 +51,11 @@ import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.io.File; -import java.util.List; public class SvnConfigurable implements Configurable { public static final String DISPLAY_NAME = SvnVcs.VCS_DISPLAY_NAME; - public static final String EN_US_LOCALE = "en_US.UTF-8"; - public static final List EXECUTABLE_LOCALES = ContainerUtil.newArrayList("", EN_US_LOCALE, "C.UTF-8", "C"); - private final Project myProject; private JCheckBox myUseDefaultCheckBox; private TextFieldWithBrowseButton myConfigurationDirectoryText; @@ -81,7 +72,6 @@ public class SvnConfigurable implements Configurable { private JCheckBox myShowMergeSourceInAnnotate; private JBCheckBox myWithCommandLineClient; private JBCheckBox myRunUnderTerminal; - private ComboBox myLocalesList; private JSpinner myNumRevsInAnnotations; private JCheckBox myMaximumNumberOfRevisionsCheckBox; private JSpinner mySSHConnectionTimeout; @@ -125,27 +115,6 @@ public class SvnConfigurable implements Configurable { }); myCommandLineClient.addBrowseFolderListener("Subversion", "Select path to Subversion executable (1.7+)", project, FileChooserDescriptorFactory.createSingleFileNoJarsDescriptor()); - //noinspection unchecked - myLocalesList.setModel(new CollectionComboBoxModel(EXECUTABLE_LOCALES)); - myLocalesList.setEditable(true); - FixedComboBoxEditor editor = new FixedComboBoxEditor(); - editor.getField().getEmptyText().setText(SvnBundle.message("command.line.locale.system.default.title")); - myLocalesList.setEditor(editor); - myLocalesList.setRenderer(new ListCellRendererWrapper() { - - @Override - public void customize(JList list, String value, int index, boolean selected, boolean hasFocus) { - setText(StringUtil.isEmpty(value) ? SvnBundle.message("command.line.locale.system.default.title") : value); - } - }); - myLocalesList.addItemListener(new ItemListener() { - @Override - public void itemStateChanged(ItemEvent e) { - if (e.getStateChange() == ItemEvent.SELECTED) { - myLocalesList.getEditor().setItem(myLocalesList.getSelectedItem()); - } - } - }); myClearAuthButton.addActionListener(new ActionListener(){ public void actionPerformed(final ActionEvent e) { @@ -304,7 +273,6 @@ public class SvnConfigurable implements Configurable { if (! getSelectedSSL().equals(configuration.getSslProtocols())) return true; final SvnApplicationSettings applicationSettings17 = SvnApplicationSettings.getInstance(); if (! Comparing.equal(applicationSettings17.getCommandLinePath(), myCommandLineClient.getText().trim())) return true; - if (!Comparing.equal(applicationSettings17.getExecutableLocale(), myLocalesList.getEditor().getItem())) return true; if (!configuration.getConfigurationDirectory().equals(myConfigurationDirectoryText.getText().trim())) return true; return mySshSettingsPanel.isModified(configuration); } @@ -334,16 +302,13 @@ public class SvnConfigurable implements Configurable { final SvnApplicationSettings applicationSettings17 = SvnApplicationSettings.getInstance(); boolean reloadWorkingCopies = !acceleration().equals(configuration.getUseAcceleration()) || - !StringUtil.equals(applicationSettings17.getCommandLinePath(), myCommandLineClient.getText().trim()) || - !StringUtil.equals(applicationSettings17.getExecutableLocale(), - myLocalesList.getEditor().getItem().toString()); + !StringUtil.equals(applicationSettings17.getCommandLinePath(), myCommandLineClient.getText().trim()); configuration.setUseAcceleration(acceleration()); configuration.setRunUnderTerminal(myRunUnderTerminal.isSelected()); configuration.setSslProtocols(getSelectedSSL()); SvnVcs.getInstance(myProject).getSvnKitManager().refreshSSLProperty(); applicationSettings17.setCommandLinePath(myCommandLineClient.getText().trim()); - applicationSettings17.setExecutableLocale(myLocalesList.getEditor().getItem().toString()); boolean isClientValid = vcs17.checkCommandLineVersion(); if (isClientValid && reloadWorkingCopies) { vcs17.invokeRefreshSvnRoots(); @@ -389,7 +354,6 @@ public class SvnConfigurable implements Configurable { myRunUnderTerminal.setSelected(configuration.isRunUnderTerminal()); final SvnApplicationSettings applicationSettings17 = SvnApplicationSettings.getInstance(); myCommandLineClient.setText(applicationSettings17.getCommandLinePath()); - myLocalesList.setSelectedItem(applicationSettings17.getExecutableLocale()); if (SvnConfiguration.SSLProtocols.sslv3.equals(configuration.getSslProtocols())) { mySSLv3RadioButton.setSelected(true); diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java index b4ac1190009a..531431cd53de 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java @@ -197,7 +197,7 @@ public class SvnVcs extends AbstractVcs { VcsDirtyScopeManager.getInstance(project)); myWorkingCopiesContent = new WorkingCopiesContent(this); - myChecker = new SvnExecutableChecker(myProject); + myChecker = new SvnExecutableChecker(this); Application app = ApplicationManager.getApplication(); myLogExceptions = app != null && (app.isInternal() || app.isUnitTestMode()); diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/BaseSvnClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/BaseSvnClient.java index 01689e586f81..3751c78b365e 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/BaseSvnClient.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/BaseSvnClient.java @@ -106,8 +106,12 @@ public abstract class BaseSvnClient implements SvnClient { command.setResultBuilder(listener); command.put(parameters); - CommandRuntime runtime = new CommandRuntime(vcs, new AuthenticationService(vcs, myIsActive)); - return runtime.runWithAuthenticationAttempt(command); + return newRuntime(vcs).runWithAuthenticationAttempt(command); + } + + @NotNull + public CommandRuntime newRuntime(@NotNull SvnVcs vcs) { + return new CommandRuntime(vcs, new AuthenticationService(vcs, myIsActive)); } protected static void callHandler(@Nullable ProgressTracker handler, @NotNull ProgressEvent event) throws VcsException { diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/CmdVersionClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/CmdVersionClient.java index 95b4734f84d1..5d4e72d7712a 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/CmdVersionClient.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/CmdVersionClient.java @@ -3,9 +3,7 @@ package org.jetbrains.idea.svn.api; import com.intellij.execution.process.ProcessOutput; import com.intellij.openapi.util.Version; import org.jetbrains.annotations.NotNull; -import org.jetbrains.idea.svn.SvnApplicationSettings; import org.jetbrains.idea.svn.commandLine.Command; -import org.jetbrains.idea.svn.commandLine.CommandExecutor; import org.jetbrains.idea.svn.commandLine.SvnBindException; import org.jetbrains.idea.svn.commandLine.SvnCommandName; @@ -18,30 +16,29 @@ import java.util.regex.Pattern; public class CmdVersionClient extends BaseSvnClient implements VersionClient { private static final Pattern VERSION = Pattern.compile("^(\\d+)\\.(\\d+)\\.(\\d+)"); + private static final int COMMAND_TIMEOUT = 30 * 1000; @NotNull @Override public Version getVersion() throws SvnBindException { - return parseVersion(runCommand()); + return parseVersion(runCommand(true)); } - private static ProcessOutput runCommand() throws SvnBindException { - // TODO: Seems CommandRuntime should be used here when its api is more robust (to specify timeout or so). + @NotNull + public ProcessOutput runCommand(boolean quiet) throws SvnBindException { Command command = new Command(SvnCommandName.version); + if (quiet) { command.put("--quiet"); + } - SvnApplicationSettings settings = SvnApplicationSettings.getInstance(); - CommandExecutor executor = new CommandExecutor(settings.getCommandLinePath(), settings.getExecutableLocale(), command); - executor.run(30 * 1000); - - return executor.getProcessOutput(); + return newRuntime(myVcs).runLocal(command, COMMAND_TIMEOUT).getProcessOutput(); } @NotNull private static Version parseVersion(@NotNull ProcessOutput output) throws SvnBindException { - if (output.isTimeout() || (output.getExitCode() != 0) || !output.getStderr().isEmpty()) { - throw new SvnBindException( - String.format("Exit code: %d, Error: %s, Timeout: %b", output.getExitCode(), output.getStderr(), output.isTimeout())); + // TODO: This or similar check should likely go to CommandRuntime - to be applied for all commands + if (output.isTimeout()) { + throw new SvnBindException(String.format("Exit code: %d, Error: %s", output.getExitCode(), output.getStderr())); } return parseVersion(output.getStdout()); diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandRuntime.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandRuntime.java index a64821e24aad..ec9a504d966d 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandRuntime.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandRuntime.java @@ -18,6 +18,7 @@ package org.jetbrains.idea.svn.commandLine; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; @@ -51,7 +52,7 @@ public class CommandRuntime { SvnApplicationSettings settings = SvnApplicationSettings.getInstance(); exePath = settings.getCommandLinePath(); - executableLocale = settings.getExecutableLocale(); + executableLocale = Registry.stringValue(SvnExecutableChecker.SVN_EXECUTABLE_LOCALE_REGISTRY_KEY); myModules = ContainerUtil.newArrayList(); myModules.add(new CommandParametersResolutionModule(this)); @@ -77,6 +78,16 @@ public class CommandRuntime { } } + @NotNull + public CommandExecutor runLocal(@NotNull Command command, int timeout) throws SvnBindException { + CommandExecutor executor = newExecutor(command); + + executor.run(timeout); + onAfterCommand(executor, command); + + return executor; + } + private void onStart(@NotNull Command command) throws SvnBindException { // TODO: Actually command handler should be used as canceller, but currently all handlers use same cancel logic - // TODO: - just check progress indicator diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnExecutableChecker.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnExecutableChecker.java index d9b952e21cf4..f9f409e66397 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnExecutableChecker.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnExecutableChecker.java @@ -16,13 +16,23 @@ package org.jetbrains.idea.svn.commandLine; import com.intellij.execution.ExecutableValidator; +import com.intellij.execution.process.ProcessOutput; import com.intellij.notification.Notification; +import com.intellij.notification.NotificationType; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Version; +import com.intellij.openapi.util.registry.Registry; +import com.intellij.openapi.util.registry.RegistryValue; +import com.intellij.openapi.util.registry.RegistryValueListener; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.svn.*; +import org.jetbrains.idea.svn.api.CmdVersionClient; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * Created with IntelliJ IDEA. @@ -34,8 +44,24 @@ public class SvnExecutableChecker extends ExecutableValidator { private static final Logger LOG = Logger.getInstance(SvnExecutableChecker.class); - public SvnExecutableChecker(Project project) { - super(project, getNotificationTitle(), getWrongPathMessage()); + public static final String SVN_EXECUTABLE_LOCALE_REGISTRY_KEY = "svn.executable.locale"; + private static final String SVN_VERSION_ENGLISH_OUTPUT = "The following repository access (RA) modules are available"; + private static final Pattern INVALID_LOCALE_WARNING_PATTERN = Pattern.compile( + "^.*cannot set .* locale.*please check that your locale name is correct$", + Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); + + @NotNull private final SvnVcs myVcs; + + public SvnExecutableChecker(@NotNull SvnVcs vcs) { + super(vcs.getProject(), getNotificationTitle(), getWrongPathMessage()); + + myVcs = vcs; + Registry.get(SVN_EXECUTABLE_LOCALE_REGISTRY_KEY).addListener(new RegistryValueListener.Adapter() { + @Override + public void afterValueChanged(@NotNull RegistryValue value) { + myVcs.checkCommandLineVersion(); + } + }, myProject); } @Override @@ -49,9 +75,17 @@ public class SvnExecutableChecker extends ExecutableValidator { return SvnConfigurable.DISPLAY_NAME; } - @NotNull - private SvnVcs getVcs() { - return SvnVcs.getInstance(myProject); + @Override + protected boolean notify(@Nullable Notification notification) { + expireAll(); + + return super.notify(notification); + } + + public void expireAll() { + for (Notification notification : myNotificationManager.getNotificationsOfType(ExecutableNotValidNotification.class, myProject)) { + notification.expire(); + } } @Override @@ -60,31 +94,57 @@ public class SvnExecutableChecker extends ExecutableValidator { // always expire notification as different message could be detected notification.expire(); - getVcs().checkCommandLineVersion(); + myVcs.checkCommandLineVersion(); } @Override - protected boolean isExecutableValid(@NotNull String executable) { - setNotificationErrorDescription(getWrongPathMessage()); + @Nullable + protected Notification validate(@NotNull String executable) { + Notification result = createDefaultNotification(); // Necessary executable path will be taken from settings while command execution final Version version = getConfiguredClientVersion(); - try { - return version != null && validateVersion(version); - } - catch (Throwable e) { - LOG.info(e); - return false; + if (version != null) { + try { + result = validateVersion(version); + + if (result == null) { + result = validateLocale(); + } + } + catch (Throwable e) { + LOG.info(e); + } } + + return result; } - private boolean validateVersion(@NotNull Version version) { - if (!getVcs().isSupportedByCommandLine(WorkingCopyFormat.from(version))) { - setNotificationErrorDescription(getOldExecutableMessage(version)); - return false; + @Nullable + private Notification validateVersion(@NotNull Version version) { + return !myVcs.isSupportedByCommandLine(WorkingCopyFormat.from(version)) ? new ExecutableNotValidNotification( + getOldExecutableMessage(version)) : null; + } + + @Nullable + private Notification validateLocale() throws SvnBindException { + ProcessOutput versionOutput = getVersionClient().runCommand(false); + Notification result = null; + + Matcher matcher = INVALID_LOCALE_WARNING_PATTERN.matcher(versionOutput.getStderr()); + if (matcher.find()) { + LOG.info(matcher.group()); + + result = new ExecutableNotValidNotification(prepareDescription(UIUtil.getHtmlBody(matcher.group()), false), NotificationType.WARNING); + } + else if (!isEnglishOutput(versionOutput.getStdout())) { + LOG.info("\"svn --version\" command contains non-English output " + versionOutput.getStdout()); + + result = new ExecutableNotValidNotification(prepareDescription(SvnBundle.message("non.english.locale.detected.warning"), false), + NotificationType.WARNING); } - return true; + return result; } @Nullable @@ -92,7 +152,7 @@ public class SvnExecutableChecker extends ExecutableValidator { Version result = null; try { - result = getVcs().getCommandLineFactory().createVersionClient().getVersion(); + result = getVersionClient().getVersion(); } catch (Throwable e) { LOG.info(e); @@ -101,6 +161,15 @@ public class SvnExecutableChecker extends ExecutableValidator { return result; } + @NotNull + private CmdVersionClient getVersionClient() { + return (CmdVersionClient)myVcs.getCommandLineFactory().createVersionClient(); + } + + public static boolean isEnglishOutput(@NotNull String versionOutput) { + return StringUtil.containsIgnoreCase(versionOutput, SVN_VERSION_ENGLISH_OUTPUT); + } + private static String getWrongPathMessage() { return SvnBundle.message("subversion.executable.notification.description"); } diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/TaskBundle.properties b/plugins/tasks/tasks-core/src/com/intellij/tasks/TaskBundle.properties index 11d842bf0d91..0154b2989ff0 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/TaskBundle.properties +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/TaskBundle.properties @@ -19,3 +19,7 @@ jira.failure.captcha=Login failed. Enter captcha in web-interface. ## YouTrack youtrack.default.query=for: me sort by: updated #Unresolved +## Bugzilla +bugzilla.failure.malformed.response=Cannot decode server response. Check that XMLRPC plugin is enabled. +bugzilla.failure.no.version=Cannot find Bugzilla version. Check that URL ends with "xmlrpc.cgi". + diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/bugzilla/BugzillaRepository.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/bugzilla/BugzillaRepository.java index f583be334cfc..af3df55b5397 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/bugzilla/BugzillaRepository.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/bugzilla/BugzillaRepository.java @@ -6,10 +6,7 @@ import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Version; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.tasks.LocalTask; -import com.intellij.tasks.Task; -import com.intellij.tasks.TaskRepositoryType; -import com.intellij.tasks.TaskState; +import com.intellij.tasks.*; import com.intellij.tasks.impl.BaseRepository; import com.intellij.tasks.impl.BaseRepositoryImpl; import com.intellij.tasks.impl.RequestFailedException; @@ -17,10 +14,7 @@ import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.HashMap; import com.intellij.util.xmlb.annotations.Tag; -import org.apache.xmlrpc.CommonsXmlRpcTransport; -import org.apache.xmlrpc.XmlRpcClient; -import org.apache.xmlrpc.XmlRpcException; -import org.apache.xmlrpc.XmlRpcRequest; +import org.apache.xmlrpc.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -137,6 +131,9 @@ public class BugzillaRepository extends BaseRepositoryImpl { private void ensureVersionDiscovered() throws Exception { if (myVersion == null) { Hashtable result = new BugzillaXmlRpcRequest("Bugzilla.version").execute(); + if (result == null) { + throw new RequestFailedException(TaskBundle.message("bugzilla.failure.no.version")); + } String version = (String)result.get("version"); String[] parts = version.split("\\.", 3); myVersion = new Version(Integer.parseInt(parts[0]), Integer.parseInt(parts[1]), Integer.parseInt(parts[2])); @@ -345,7 +342,15 @@ public class BugzillaRepository extends BaseRepositoryImpl { } Vector> parameters = new Vector>(); parameters.add(new Hashtable(myParameters)); - return (T)new XmlRpcClient(getUrl()).execute(new XmlRpcRequest(myMethodName, parameters), myTransport); + try { + return (T)new XmlRpcClient(getUrl()).execute(new XmlRpcRequest(myMethodName, parameters), myTransport); + } + catch (XmlRpcClientException e) { + if (e.getMessage().contains("Error decoding XML-RPC response")) { + throw new RequestFailedException(TaskBundle.message("bugzilla.failure.malformed.response"), e); + } + throw e; + } } } diff --git a/plugins/tasks/tasks-core/src/icons/clock.png b/plugins/tasks/tasks-core/src/icons/clock.png index 701863c24cd4..6d35d01eee6e 100644 Binary files a/plugins/tasks/tasks-core/src/icons/clock.png and b/plugins/tasks/tasks-core/src/icons/clock.png differ diff --git a/plugins/tasks/tasks-core/src/icons/clock@2x.png b/plugins/tasks/tasks-core/src/icons/clock@2x.png index c2e69d55385e..3b61cec1f02a 100644 Binary files a/plugins/tasks/tasks-core/src/icons/clock@2x.png and b/plugins/tasks/tasks-core/src/icons/clock@2x.png differ diff --git a/python/edu/course-creator/resources/META-INF/plugin.xml b/python/edu/course-creator/resources/META-INF/plugin.xml index f4e0d510a8d8..636927381260 100644 --- a/python/edu/course-creator/resources/META-INF/plugin.xml +++ b/python/edu/course-creator/resources/META-INF/plugin.xml @@ -80,7 +80,7 @@ - + \ No newline at end of file diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCAddTaskWindow.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCAddTaskWindow.java index e423da553d1b..3df30b7a4608 100644 --- a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCAddTaskWindow.java +++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCAddTaskWindow.java @@ -24,7 +24,7 @@ public class CCAddTaskWindow extends DumbAwareAction { private static final Logger LOG = Logger.getInstance(CCAddTaskWindow.class); public CCAddTaskWindow() { - super("Add problem to solve", "Add problem to solve", null); + super("Add Problem to Solve", "Add problem to solve", null); } diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCChangeCourseInfo.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCChangeCourseInfo.java index a556cd1113f1..653af6c691f6 100644 --- a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCChangeCourseInfo.java +++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCChangeCourseInfo.java @@ -21,7 +21,7 @@ import javax.swing.*; public class CCChangeCourseInfo extends DumbAwareAction { public CCChangeCourseInfo() { - super("Change Course information", "Change Course Information", null); + super("Change Course Information", "Change Course Information", null); } @Override diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCDeleteTaskWindow.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCDeleteTaskWindow.java index cae8393c8a37..c7d8cd91cf4b 100644 --- a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCDeleteTaskWindow.java +++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCDeleteTaskWindow.java @@ -18,7 +18,7 @@ public class CCDeleteTaskWindow extends CCTaskWindowAction { private static final Logger LOG = Logger.getInstance(CCDeleteTaskWindow.class); public CCDeleteTaskWindow() { - super("Delete problem","Delete problem", null); + super("Delete Problem","Delete problem", null); } @Override diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCShowPreview.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCShowPreview.java index 5c9cf6d1e323..97a1b0300688 100644 --- a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCShowPreview.java +++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCShowPreview.java @@ -50,7 +50,7 @@ public class CCShowPreview extends DumbAwareAction { private static final Logger LOG = Logger.getInstance(CCShowPreview.class.getName()); public CCShowPreview() { - super("Show preview","Show preview", null); + super("Show Preview","Show preview", null); } @Override diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCShowTaskWindowDetails.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCShowTaskWindowDetails.java index e08743fc6941..30ba802dbedc 100644 --- a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCShowTaskWindowDetails.java +++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCShowTaskWindowDetails.java @@ -11,7 +11,7 @@ import org.jetbrains.plugins.coursecreator.ui.CreateTaskWindowDialog; public class CCShowTaskWindowDetails extends CCTaskWindowAction { public CCShowTaskWindowDetails() { - super("Show problem details", "Show problem details", null); + super("Show Problem Details", "Show problem details", null); } @Override diff --git a/python/edu/learn-python/resources/META-INF/plugin.xml b/python/edu/learn-python/resources/META-INF/plugin.xml index 01c0b4b9a6a8..62f5bdc6ef85 100644 --- a/python/edu/learn-python/resources/META-INF/plugin.xml +++ b/python/edu/learn-python/resources/META-INF/plugin.xml @@ -22,8 +22,6 @@ com.intellij.modules.lang com.intellij.modules.python - - @@ -40,27 +38,33 @@ - + - + - - + - - - + + - - - + + + + + + diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/StudyInstructionPainter.java b/python/edu/learn-python/src/com/jetbrains/python/edu/StudyInstructionPainter.java index b78111b442c8..87f1f7a35454 100644 --- a/python/edu/learn-python/src/com/jetbrains/python/edu/StudyInstructionPainter.java +++ b/python/edu/learn-python/src/com/jetbrains/python/edu/StudyInstructionPainter.java @@ -1,14 +1,20 @@ package com.jetbrains.python.edu; +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.KeyboardShortcut; import com.intellij.openapi.fileEditor.impl.EditorEmptyTextPainter; import com.intellij.openapi.fileEditor.impl.EditorsSplitters; +import com.intellij.openapi.keymap.KeymapUtil; import com.intellij.openapi.util.Couple; import com.intellij.ui.Gray; import com.intellij.ui.JBColor; import com.intellij.util.PairFunction; import com.intellij.util.ui.GraphicsUtil; import com.intellij.util.ui.UIUtil; +import com.jetbrains.python.edu.actions.*; +import javax.swing.*; import java.awt.*; /** @@ -27,13 +33,19 @@ public class StudyInstructionPainter extends EditorEmptyTextPainter { UIUtil.TextPainter painter = new UIUtil.TextPainter().withLineSpacing(1.5f); painter.appendLine("PyCharm Educational Edition").underlined(new JBColor(Gray._150, Gray._180)); - painter.appendLine("Navigate to the next task window with Ctrl + Enter").smaller().withBullet(); - painter.appendLine("Navigate between task windows with Ctrl + Shift + < and Ctrl + Shift + >").smaller().withBullet(); - painter.appendLine("Navigate between tasks with Ctrl + < and Ctrl + >").smaller().withBullet(); - painter.appendLine("Reset current task file with Ctrl + Shift + X").smaller().withBullet(); - painter.appendLine("Check task with Alt + Ctrl + Enter").smaller().withBullet(); - painter.appendLine("Get hint for the task window using Ctrl + 7").smaller().withBullet(); - painter.appendLine("To see your progress, open the 'Course Description' panel").smaller().withBullet(); + addAction(painter, "Navigate to the next task window", StudyNextWindowAction.ACTION_ID, StudyNextWindowAction.SHORTCUT2, true); + String shortcut1 = getShortcutText(StudyPrevWindowAction.ACTION_ID, StudyPrevWindowAction.SHORTCUT, false, false); + String shortcut2 = getShortcutText(StudyNextWindowAction.ACTION_ID, StudyNextWindowAction.SHORTCUT, false, false); + String text = "Navigate between task windows with " + shortcut1 + + " and " + shortcut2; + painter.appendLine(text).smaller().withBullet(); + shortcut1 = getShortcutText(StudyPreviousStudyTaskAction.ACTION_ID, StudyPreviousStudyTaskAction.SHORTCUT, false, false); + shortcut2 = getShortcutText(StudyNextStudyTaskAction.ACTION_ID, StudyNextStudyTaskAction.SHORTCUT, false, false); + painter.appendLine("Navigate between tasks with " + shortcut1 + " and " + shortcut2).smaller().withBullet(); + addAction(painter, "Reset current task file", StudyRefreshTaskFileAction.ACTION_ID, StudyRefreshTaskFileAction.SHORTCUT, false); + addAction(painter, "Check task", StudyCheckAction.ACTION_ID, StudyCheckAction.SHORTCUT, false); + addAction(painter, "Get hint for the task window", StudyShowHintAction.ACTION_ID, StudyShowHintAction.SHORTCUT, false); + painter.appendLine("To see your progress open the 'Course Description' panel").smaller().withBullet(); painter.draw(g, new PairFunction>() { @Override public Couple fun(Integer width, Integer height) { @@ -42,4 +54,25 @@ public class StudyInstructionPainter extends EditorEmptyTextPainter { } }); } + private static void addAction(UIUtil.TextPainter painter, String text, String actionId, String defaultShortcutString, boolean useDefault) { + String shortcut = getShortcutText(actionId, defaultShortcutString, useDefault, true); + String actionText = text + " with " + shortcut; + painter.appendLine(actionText).smaller().withBullet(); + } + + private static String getShortcutText(String actionId, String defaultShortcutString, boolean useDefault, boolean wrapTag) { + AnAction action = ActionManager.getInstance().getAction(actionId); + String shortcut = ""; + if (!useDefault) { + shortcut = KeymapUtil.getFirstKeyboardShortcutText(action); + } + if (shortcut.isEmpty() && defaultShortcutString != null) { + KeyboardShortcut keyboardShortcut = new KeyboardShortcut(KeyStroke.getKeyStroke(defaultShortcutString), null); + shortcut = KeymapUtil.getShortcutText(keyboardShortcut); + } + if (!wrapTag) { + return shortcut; + } + return "" + shortcut + ""; + } } diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/StudyTaskManager.java b/python/edu/learn-python/src/com/jetbrains/python/edu/StudyTaskManager.java index 9b935504bd5c..f37adf0b19f6 100644 --- a/python/edu/learn-python/src/com/jetbrains/python/edu/StudyTaskManager.java +++ b/python/edu/learn-python/src/com/jetbrains/python/edu/StudyTaskManager.java @@ -1,6 +1,12 @@ package com.jetbrains.python.edu; +import com.intellij.ide.BrowserUtil; import com.intellij.ide.ui.UISettings; +import com.intellij.ide.util.PropertiesComponent; +import com.intellij.notification.Notification; +import com.intellij.notification.NotificationListener; +import com.intellij.notification.NotificationType; +import com.intellij.notification.Notifications; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.actionSystem.ex.AnActionListener; import com.intellij.openapi.application.ApplicationManager; @@ -14,11 +20,15 @@ import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.DumbAwareRunnable; import com.intellij.openapi.project.Project; import com.intellij.openapi.startup.StartupManager; +import com.intellij.openapi.ui.popup.Balloon; +import com.intellij.openapi.ui.popup.JBPopupAdapter; +import com.intellij.openapi.ui.popup.LightweightWindowEvent; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileAdapter; import com.intellij.openapi.vfs.VirtualFileEvent; import com.intellij.openapi.vfs.VirtualFileManager; import com.intellij.openapi.wm.*; +import com.intellij.util.ui.update.UiNotifyConnector; import com.intellij.util.xmlb.XmlSerializer; import com.jetbrains.python.edu.actions.*; import com.jetbrains.python.edu.course.Course; @@ -32,7 +42,9 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import javax.swing.event.HyperlinkEvent; import java.lang.reflect.Method; +import java.net.URL; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -145,9 +157,65 @@ public class StudyTaskManager implements ProjectComponent, PersistentStateCompon } final ToolWindow studyToolWindow = toolWindowManager.getToolWindow(toolWindowId); + class UrlOpeningListener implements NotificationListener { + private final boolean myExpireNotification; + + public UrlOpeningListener(boolean expireNotification) { + myExpireNotification = expireNotification; + } + + protected void hyperlinkActivated(@NotNull Notification notification, @NotNull HyperlinkEvent event) { + URL url = event.getURL(); + if (url == null) { + BrowserUtil.browse(event.getDescription()); + } + else { + BrowserUtil.browse(url); + } + if (myExpireNotification) { + notification.expire(); + } + } + + @Override + public void hyperlinkUpdate(@NotNull Notification notification, @NotNull HyperlinkEvent event) { + if (event.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { + hyperlinkActivated(notification, event); + } + } + } if (studyToolWindow != null) { StudyUtils.updateStudyToolWindow(myProject); studyToolWindow.show(null); + UiNotifyConnector.doWhenFirstShown(studyToolWindow.getComponent(), new Runnable() { + @Override + public void run() { + if (PropertiesComponent.getInstance().getBoolean("StudyShowPopup", true)) { + String content = "If you'd like to learn" + + " more about PyCharm " + + "Educational Edition, " + + "click here to watch a tutorial"; + final Notification notification = + new Notification("Watch Tutorials!", "", content, NotificationType.INFORMATION, new UrlOpeningListener(true)); + Notifications.Bus.notify(notification); + Balloon balloon = notification.getBalloon(); + if (balloon != null) { + balloon.addListener(new JBPopupAdapter() { + @Override + public void onClosed(LightweightWindowEvent event) { + notification.expire(); + } + }); + } + notification.whenExpired(new Runnable() { + @Override + public void run() { + PropertiesComponent.getInstance().setValue("StudyShowPopup", String.valueOf(false)); + } + }); + } + } + }); } addShortcut(StudyNextWindowAction.SHORTCUT, StudyNextWindowAction.ACTION_ID); addShortcut(StudyPrevWindowAction.SHORTCUT, StudyPrevWindowAction.ACTION_ID); @@ -167,6 +235,10 @@ public class StudyTaskManager implements ProjectComponent, PersistentStateCompon private static void addShortcut(@NotNull final String shortcutString, @NotNull final String actionIdString) { Keymap keymap = KeymapManager.getInstance().getActiveKeymap(); + Shortcut[] shortcuts = keymap.getShortcuts(actionIdString); + if (shortcuts.length > 0) { + return; + } Shortcut studyActionShortcut = new KeyboardShortcut(KeyStroke.getKeyStroke(shortcutString), null); String[] actionsIds = keymap.getActionIds(studyActionShortcut); for (String actionId : actionsIds) { diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyWatchTutorialAction.java b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyWatchTutorialAction.java new file mode 100644 index 000000000000..abe38b9708cb --- /dev/null +++ b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyWatchTutorialAction.java @@ -0,0 +1,17 @@ +package com.jetbrains.python.edu.actions; + +import com.intellij.ide.BrowserUtil; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.project.DumbAwareAction; +import org.jetbrains.annotations.NotNull; + +public class StudyWatchTutorialAction extends DumbAwareAction { + public StudyWatchTutorialAction() { + super("Learn more about PyCharm Educational Edition", null, null); + } + + @Override + public void actionPerformed(@NotNull AnActionEvent e) { + BrowserUtil.browse("http://www.jetbrains.com/pycharm-educational/quickstart/"); + } +} diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/editor/StudyEditor.java b/python/edu/learn-python/src/com/jetbrains/python/edu/editor/StudyEditor.java index ec661f8f0b88..b497b5216c26 100644 --- a/python/edu/learn-python/src/com/jetbrains/python/edu/editor/StudyEditor.java +++ b/python/edu/learn-python/src/com/jetbrains/python/edu/editor/StudyEditor.java @@ -4,6 +4,8 @@ import com.intellij.codeHighlighting.BackgroundEditorHighlighter; import com.intellij.icons.AllIcons; import com.intellij.ide.structureView.StructureViewBuilder; import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.KeyboardShortcut; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; @@ -16,6 +18,7 @@ import com.intellij.openapi.fileEditor.*; import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; import com.intellij.openapi.fileEditor.impl.text.PsiAwareTextEditorImpl; import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider; +import com.intellij.openapi.keymap.KeymapUtil; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Key; @@ -48,8 +51,9 @@ import java.awt.*; import java.awt.datatransfer.StringSelection; import java.awt.event.*; import java.beans.PropertyChangeListener; -import java.util.*; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * Implementation of StudyEditor which has panel with special buttons and task text @@ -79,7 +83,14 @@ public class StudyEditor implements TextEditor { return myTaskFile; } - private static JButton addButton(@NotNull final JComponent parentComponent, String toolTipText, Icon icon) { + private static JButton addButton(@NotNull final JComponent parentComponent, String actionID, Icon icon, + @Nullable String defaultShortcutString) { + AnAction action = ActionManager.getInstance().getAction(actionID); + String toolTipText = KeymapUtil.createTooltipText(action.getTemplatePresentation().getText(), action); + if (!toolTipText.contains("(") && defaultShortcutString != null) { + KeyboardShortcut shortcut = new KeyboardShortcut(KeyStroke.getKeyStroke(defaultShortcutString), null); + toolTipText += " (" + KeymapUtil.getShortcutText(shortcut) + ")"; + } JButton newButton = new JButton(); newButton.setToolTipText(toolTipText); newButton.setIcon(icon); @@ -192,13 +203,13 @@ public class StudyEditor implements TextEditor { } private void initializeButtons(@NotNull final JPanel taskActionsPanel, @NotNull final TaskFile taskFile) { - myCheckButton = addButton(taskActionsPanel, "Check task (Ctrl + Alt + Enter)", StudyIcons.Resolve); - myPrevTaskButton = addButton(taskActionsPanel, "Previous task (Ctrl + <)", StudyIcons.Prev); - myNextTaskButton = addButton(taskActionsPanel, "Next task (Ctrl + >)", AllIcons.Actions.Forward); - myRefreshButton = addButton(taskActionsPanel, "Reset task file (Ctrl + Shift + X)", AllIcons.Actions.Refresh); - JButton myShowHintButton = addButton(taskActionsPanel, "Show hint for task window (Ctrl + 7)", StudyIcons.ShowHint); + myCheckButton = addButton(taskActionsPanel, StudyCheckAction.ACTION_ID, StudyIcons.Resolve, StudyCheckAction.SHORTCUT); + myPrevTaskButton = addButton(taskActionsPanel, StudyPreviousStudyTaskAction.ACTION_ID, StudyIcons.Prev, StudyPreviousStudyTaskAction.SHORTCUT); + myNextTaskButton = addButton(taskActionsPanel, StudyNextStudyTaskAction.ACTION_ID, AllIcons.Actions.Forward, StudyNextStudyTaskAction.SHORTCUT); + myRefreshButton = addButton(taskActionsPanel, StudyRefreshTaskFileAction.ACTION_ID, AllIcons.Actions.Refresh, StudyRefreshTaskFileAction.SHORTCUT); + JButton myShowHintButton = addButton(taskActionsPanel, StudyShowHintAction.ACTION_ID, StudyIcons.ShowHint, StudyShowHintAction.SHORTCUT); if (!taskFile.getTask().getUserTests().isEmpty()) { - JButton runButton = addButton(taskActionsPanel, "Run", AllIcons.General.Run); + JButton runButton = addButton(taskActionsPanel, StudyRunAction.ACTION_ID, AllIcons.General.Run, null); runButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { @@ -206,7 +217,7 @@ public class StudyEditor implements TextEditor { studyRunAction.run(myProject); } }); - JButton watchInputButton = addButton(taskActionsPanel, "Watch test input", StudyIcons.WatchInput); + JButton watchInputButton = addButton(taskActionsPanel, "WatchInputAction", StudyIcons.WatchInput, null); watchInputButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { diff --git a/python/helpers/pydev/pydevd_attach_to_process/add_code_to_python_process.py b/python/helpers/pydev/pydevd_attach_to_process/add_code_to_python_process.py index 51264ceea75e..cf698e5230da 100644 --- a/python/helpers/pydev/pydevd_attach_to_process/add_code_to_python_process.py +++ b/python/helpers/pydev/pydevd_attach_to_process/add_code_to_python_process.py @@ -418,10 +418,7 @@ def run_python_code_linux(pid, python_code, connect_debugger_tracing=False, show if not os.path.exists(target_dll): raise RuntimeError('Could not find dll file to inject: %s' % target_dll) - gdb_threads_settrace_file = os.path.join(filedir, 'linux', 'gdb_threads_settrace.py') - gdb_threads_settrace_file = os.path.normpath(gdb_threads_settrace_file) - if not os.path.exists(gdb_threads_settrace_file): - raise RuntimeError('Could not find file to settrace: %s' % gdb_threads_settrace_file) + gdb_threads_settrace_file = find_helper_script(filedir, 'gdb_threads_settrace.py') # Note: we currently don't support debug builds is_debug = 0 @@ -476,6 +473,15 @@ def run_python_code_linux(pid, python_code, connect_debugger_tracing=False, show return out, err +def find_helper_script(filedir, script_name): + lldb_threads_settrace_file = os.path.join(filedir, 'linux', script_name) + lldb_threads_settrace_file = os.path.normpath(lldb_threads_settrace_file) + if not os.path.exists(lldb_threads_settrace_file): + raise RuntimeError('Could not find file to settrace: %s' % lldb_threads_settrace_file) + + return lldb_threads_settrace_file + + def run_python_code_mac(pid, python_code, connect_debugger_tracing=False, show_debug_info=0): assert '\'' not in python_code, 'Having a single quote messes with our command.' filedir = os.path.dirname(__file__) @@ -498,12 +504,10 @@ def run_python_code_mac(pid, python_code, connect_debugger_tracing=False, show_d if not os.path.exists(target_dll): raise RuntimeError('Could not find dll file to inject: %s' % target_dll) - lldb_threads_settrace_file = os.path.join(filedir, 'linux', 'lldb_threads_settrace.py') - lldb_threads_settrace_file = os.path.normpath(lldb_threads_settrace_file) - if not os.path.exists(lldb_threads_settrace_file): - raise RuntimeError('Could not find file to settrace: %s' % lldb_threads_settrace_file) - + lldb_threads_settrace_file = find_helper_script(filedir, 'lldb_threads_settrace.py') + lldb_threads_prepare_file = find_helper_script(filedir, 'lldb_threads_prepare.py') # Note: we currently don't support debug builds + is_debug = 0 # Note that the space in the beginning of each line in the multi-line is important! cmd = [ @@ -521,8 +525,9 @@ def run_python_code_mac(pid, python_code, connect_debugger_tracing=False, show_d cmd.extend([ "-o 'process attach --pid %d'"%pid, + "-o 'command script import \'%s\''" % (lldb_threads_prepare_file,), "-o 'expr (void*)dlopen(\"%s\", 2);'" % target_dll, - "-o 'expr (int)hello();'", + # "-o 'expr (int)hello();'", "-o 'expr (int)DoAttach(%s, \"%s\", %s);'" % ( is_debug, python_code, show_debug_info), ]) @@ -531,7 +536,7 @@ def run_python_code_mac(pid, python_code, connect_debugger_tracing=False, show_d if connect_debugger_tracing: cmd.extend([ # "-o 'expr (int) SetSysTraceFunc(0, 0);'", - "-o 'command script import %s'" % (lldb_threads_settrace_file,), + "-o 'command script import \'%s\''" % (lldb_threads_settrace_file,), ]) cmd.extend([ diff --git a/python/helpers/pydev/pydevd_attach_to_process/linux/lldb_threads_prepare.py b/python/helpers/pydev/pydevd_attach_to_process/linux/lldb_threads_prepare.py new file mode 100644 index 000000000000..21025d7e2097 --- /dev/null +++ b/python/helpers/pydev/pydevd_attach_to_process/linux/lldb_threads_prepare.py @@ -0,0 +1,18 @@ +# This file is meant to be run inside lldb as a command before +# attaching the debugger to mark process threads as suspended +# to distinguish them from debugger threads later + +def __lldb_init_module(debugger, internal_dict): + import lldb + + try: + target = debugger.GetSelectedTarget() + if target: + process = target.GetProcess() + if process: + for thread in process: + # print('Marking process thread %d'%thread.GetThreadID()) + internal_dict['_thread_%d' % thread.GetThreadID()] = True + # thread.Suspend() + except: + import traceback;traceback.print_exc() diff --git a/python/helpers/pydev/pydevd_attach_to_process/linux/lldb_threads_settrace.py b/python/helpers/pydev/pydevd_attach_to_process/linux/lldb_threads_settrace.py index b457e1547cd2..e315d6ea80cd 100644 --- a/python/helpers/pydev/pydevd_attach_to_process/linux/lldb_threads_settrace.py +++ b/python/helpers/pydev/pydevd_attach_to_process/linux/lldb_threads_settrace.py @@ -2,11 +2,11 @@ # the attach_linux.dylib dll has already been loaded to settrace for all threads. def __lldb_init_module(debugger, internal_dict): # Command Initialization code goes here - print('Startup LLDB in Python!') + # print('Startup LLDB in Python!') import lldb try: - show_debug_info = 1 + show_debug_info = 0 is_debug = 0 target = debugger.GetSelectedTarget() if target: @@ -14,15 +14,11 @@ def __lldb_init_module(debugger, internal_dict): if process: for thread in process: # Get the first frame - print('Thread %s, suspended %s\n'%(thread, thread.IsStopped())) + # print('Thread %s, suspended %s\n'%(thread, thread.IsStopped())) process.SetSelectedThread(thread) - if not thread.IsStopped(): - error = process.Stop() - print(error) - - if thread: + if internal_dict.get('_thread_%d' % thread.GetThreadID(), False): frame = thread.GetSelectedFrame() if frame: print('Will settrace in: %s' % (frame,)) @@ -31,6 +27,6 @@ def __lldb_init_module(debugger, internal_dict): error = res.GetError() if error: print(error) - thread.Resume() + thread.Resume() except: import traceback;traceback.print_exc() diff --git a/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibTypeProvider.java b/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibTypeProvider.java index 8dacfd3ec597..e333e864cfa2 100644 --- a/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibTypeProvider.java +++ b/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibTypeProvider.java @@ -135,7 +135,40 @@ public class PyStdlibTypeProvider extends PyTypeProviderBase { } } else if ("__builtin__.tuple.__add__".equals(qname) && callSite instanceof PyBinaryExpression) { - return getTupleConcatenationResultType(((PyBinaryExpression)callSite), context); + return getTupleConcatenationResultType((PyBinaryExpression)callSite, context); + } + else if ("__builtin__.tuple.__mul__".equals(qname) && callSite instanceof PyBinaryExpression) { + return getTupleMultiplicationResultType((PyBinaryExpression)callSite, context); + } + } + return null; + } + + @Nullable + private static PyType getTupleMultiplicationResultType(@NotNull PyBinaryExpression multiplication, @NotNull TypeEvalContext context) { + final PyTupleType leftTupleType = as(context.getType(multiplication.getLeftExpression()), PyTupleType.class); + if (leftTupleType == null) { + return null; + } + PyExpression rightExpression = multiplication.getRightExpression(); + if (rightExpression instanceof PyReferenceExpression) { + final PsiElement target = ((PyReferenceExpression)rightExpression).getReference().resolve(); + if (target instanceof PyTargetExpression) { + rightExpression = ((PyTargetExpression)target).findAssignedValue(); + } + } + if (rightExpression instanceof PyNumericLiteralExpression && ((PyNumericLiteralExpression)rightExpression).isIntegerLiteral()) { + final int multiplier = ((PyNumericLiteralExpression)rightExpression).getBigIntegerValue().intValue(); + final int originalSize = leftTupleType.getElementCount(); + // Heuristic + if (originalSize * multiplier <= 20) { + final PyType[] elementTypes = new PyType[leftTupleType.getElementCount() * multiplier]; + for (int i = 0; i < multiplier; i++) { + for (int j = 0; j < originalSize; j++) { + elementTypes[i * originalSize + j] = leftTupleType.getElementType(j); + } + } + return PyTupleType.create(multiplication, elementTypes); } } return null; diff --git a/python/src/com/jetbrains/python/inspections/PyStringFormatInspection.java b/python/src/com/jetbrains/python/inspections/PyStringFormatInspection.java index 9e61faabdc65..187803f4cfa3 100644 --- a/python/src/com/jetbrains/python/inspections/PyStringFormatInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyStringFormatInspection.java @@ -102,39 +102,25 @@ public class PyStringFormatInspection extends PyInspection { final PyBuiltinCache builtinCache = PyBuiltinCache.getInstance(problemTarget); final PyResolveContext resolveContext = PyResolveContext.noImplicits().withTypeEvalContext(myTypeEvalContext); - //in case tuple multiplies integer PY-4647 - if (rightExpression instanceof PyBinaryExpression) { - PyBinaryExpression binaryExpression = (PyBinaryExpression)rightExpression; - if (binaryExpression.getOperator() == PyTokenTypes.MULT && binaryExpression.getLeftExpression() instanceof PyParenthesizedExpression - && binaryExpression.getRightExpression() instanceof PyNumericLiteralExpression) { - PyParenthesizedExpression parenthesizedExpression = (PyParenthesizedExpression)binaryExpression.getLeftExpression(); - if (parenthesizedExpression.getContainedExpression() instanceof PyTupleExpression) { - PyExpression[] tupleElements = ((PyTupleExpression)parenthesizedExpression.getContainedExpression()).getElements(); - final PyExpression expression = ((PyBinaryExpression)rightExpression).getRightExpression(); - if (expression != null) { - return ((PyNumericLiteralExpression)expression).getBigIntegerValue().intValue() * tupleElements.length; - } - } - } - } final String s = myFormatSpec.get("1"); if (PyUtil.instanceOf(rightExpression, SIMPLE_RHS_EXPRESSIONS)) { if (s != null) { - assert rightExpression != null; - PyType right_type = myTypeEvalContext.getType(rightExpression); - if (right_type instanceof PySubscriptableType) { - PySubscriptableType tuple_type = (PySubscriptableType)right_type; - for (int i=0; i <= tuple_type.getElementCount(); i += 1) { - PyType elementType = tuple_type.getElementType(i); + final PyType rightType = myTypeEvalContext.getType(rightExpression); + if (rightType instanceof PySubscriptableType) { + final PySubscriptableType tupleType = (PySubscriptableType)rightType; + for (int i = 0; i <= tupleType.getElementCount(); i += 1) { + final PyType elementType = tupleType.getElementType(i); if (elementType != null) { final String typeName = myFormatSpec.get(String.valueOf(i + 1)); final PyType type = typeName != null ? PyTypeParser.getTypeByName(problemTarget, typeName) : null; checkTypeCompatible(problemTarget, elementType, type); } } - return tuple_type.getElementCount(); + return tupleType.getElementCount(); + } + else { + checkExpressionType(rightExpression, s, problemTarget); } - else checkExpressionType(rightExpression, s, problemTarget); } return 1; } diff --git a/python/src/com/jetbrains/python/refactoring/inline/PyInlineLocalHandler.java b/python/src/com/jetbrains/python/refactoring/inline/PyInlineLocalHandler.java index ed8380da4a6e..1bbd98c500aa 100644 --- a/python/src/com/jetbrains/python/refactoring/inline/PyInlineLocalHandler.java +++ b/python/src/com/jetbrains/python/refactoring/inline/PyInlineLocalHandler.java @@ -31,10 +31,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.wm.WindowManager; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; -import com.intellij.psi.PsiReference; -import com.intellij.psi.PsiWhiteSpace; +import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.searches.ReferencesSearch; @@ -101,7 +98,10 @@ public class PyInlineLocalHandler extends InlineActionHandler { invoke(project, editor, (PyTargetExpression)element, refExpr); } - public static void invoke(final Project project, final Editor editor, final PyTargetExpression local, PyReferenceExpression refExpr) { + private static void invoke(@NotNull final Project project, + @NotNull final Editor editor, + @NotNull final PyTargetExpression local, + @Nullable PyReferenceExpression refExpr) { if (!CommonRefactoringUtil.checkReadOnlyStatus(project, local)) return; final HighlightManager highlightManager = HighlightManager.getInstance(project); @@ -136,7 +136,7 @@ public class PyInlineLocalHandler extends InlineActionHandler { } final TextAttributes attributes = EditorColorsManager.getInstance().getGlobalScheme().getAttributes(EditorColors.SEARCH_RESULT_ATTRIBUTES); - if (editor != null && !ApplicationManager.getApplication().isUnitTestMode()) { + if (!ApplicationManager.getApplication().isUnitTestMode()) { highlightManager.addOccurrenceHighlights(editor, refsToInline, attributes, true, null); final int occurrencesCount = refsToInline.length; final String occurrencesString = RefactoringBundle.message("occurrences.string", occurrencesCount); @@ -171,13 +171,11 @@ public class PyInlineLocalHandler extends InlineActionHandler { isSameDefinition &= isSameDefinition(def, otherDef); } if (!isSameDefinition) { - if (editor != null) { - highlightManager.addOccurrenceHighlights(editor, defs, writeAttributes, true, null); - highlightManager.addOccurrenceHighlights(editor, new PsiElement[]{ref}, attributes, true, null); - final String message = RefactoringBundle.getCannotRefactorMessage( - RefactoringBundle.message("variable.is.accessed.for.writing.and.used.with.inlined", localName)); - CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HELP_ID); - } + highlightManager.addOccurrenceHighlights(editor, defs, writeAttributes, true, null); + highlightManager.addOccurrenceHighlights(editor, new PsiElement[]{ref}, attributes, true, null); + final String message = RefactoringBundle.getCannotRefactorMessage( + RefactoringBundle.message("variable.is.accessed.for.writing.and.used.with.inlined", localName)); + CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HELP_ID); WindowManager.getInstance().getStatusBar(project).setInfo(RefactoringBundle.message("press.escape.to.remove.the.highlighting")); return; } @@ -218,9 +216,10 @@ public class PyInlineLocalHandler extends InlineActionHandler { return parentalStatement != null ? parentalStatement.getTextRange() : null; } }); + PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument()); CodeStyleManager.getInstance(project).reformatText(workingFile, ranges); - if (editor != null && !ApplicationManager.getApplication().isUnitTestMode()) { + if (!ApplicationManager.getApplication().isUnitTestMode()) { highlightManager.addOccurrenceHighlights(editor, exprs, attributes, true, null); WindowManager.getInstance().getStatusBar(project) .setInfo(RefactoringBundle.message("press.escape.to.remove.the.highlighting")); diff --git a/python/testData/inspections/PyStringFormatInspection1/test.py b/python/testData/inspections/PyStringFormatInspection1/test.py index 3ed0e3edb65f..92212324a230 100644 --- a/python/testData/inspections/PyStringFormatInspection1/test.py +++ b/python/testData/inspections/PyStringFormatInspection1/test.py @@ -10,4 +10,7 @@ my_dict['tmp'] = 'classes %(claz)s' % t * num) \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/PyTypeTest.java b/python/testSrc/com/jetbrains/python/PyTypeTest.java index 4877cbcb6d7e..d4f6acda8fd3 100644 --- a/python/testSrc/com/jetbrains/python/PyTypeTest.java +++ b/python/testSrc/com/jetbrains/python/PyTypeTest.java @@ -848,6 +848,11 @@ public class PyTypeTest extends PyTestCase { "expr = (1,) + (True, 'spam') + ()"); } + public void testTupleMultiplication() { + doTest("(int, bool, int, bool)", + "expr = (1, False) * 2"); + } + public void testConstructorUnification() { doTest("C[int]", "class C(object):\n" + diff --git a/xml/impl/src/com/intellij/codeInsight/template/emmet/EmmetPreviewHint.java b/xml/impl/src/com/intellij/codeInsight/template/emmet/EmmetPreviewHint.java index f9777958e689..01c809e6a459 100644 --- a/xml/impl/src/com/intellij/codeInsight/template/emmet/EmmetPreviewHint.java +++ b/xml/impl/src/com/intellij/codeInsight/template/emmet/EmmetPreviewHint.java @@ -157,6 +157,7 @@ public class EmmetPreviewHint extends LightweightHint implements Disposable { settings.setIndentGuidesShown(false); settings.setVirtualSpace(false); settings.setWheelFontChangeEnabled(false); + settings.setAdditionalPageAtBottom(false); previewEditor.setCaretEnabled(false); previewEditor.setBorder(IdeBorderFactory.createEmptyBorder()); diff --git a/xml/impl/src/com/intellij/codeInsight/template/emmet/ZenCodingTemplate.java b/xml/impl/src/com/intellij/codeInsight/template/emmet/ZenCodingTemplate.java index 433e7c680304..4b22ccf7e3db 100644 --- a/xml/impl/src/com/intellij/codeInsight/template/emmet/ZenCodingTemplate.java +++ b/xml/impl/src/com/intellij/codeInsight/template/emmet/ZenCodingTemplate.java @@ -132,7 +132,7 @@ public class ZenCodingTemplate extends CustomLiveTemplateBase { @Nullable private static ZenCodingGenerator findApplicableGenerator(ZenCodingNode node, PsiElement context, boolean wrapping) { ZenCodingGenerator defaultGenerator = null; - List generators = ZenCodingGenerator.getInstances(); + ZenCodingGenerator[] generators = ZenCodingGenerator.getInstances(); for (ZenCodingGenerator generator : generators) { if (defaultGenerator == null && generator.isMyContext(context, wrapping) && generator.isAppliedByDefault(context)) { defaultGenerator = generator; diff --git a/xml/impl/src/com/intellij/codeInsight/template/emmet/generators/ZenCodingGenerator.java b/xml/impl/src/com/intellij/codeInsight/template/emmet/generators/ZenCodingGenerator.java index 846eb867d844..fd3706df1036 100644 --- a/xml/impl/src/com/intellij/codeInsight/template/emmet/generators/ZenCodingGenerator.java +++ b/xml/impl/src/com/intellij/codeInsight/template/emmet/generators/ZenCodingGenerator.java @@ -30,8 +30,6 @@ import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.Collections; import java.util.List; @@ -39,7 +37,7 @@ import java.util.List; * @author Eugene.Kudelevsky */ public abstract class ZenCodingGenerator { - private static final ExtensionPointName EP_NAME = new ExtensionPointName("com.intellij.xml.zenCodingGenerator"); + public static final ExtensionPointName EP_NAME = new ExtensionPointName("com.intellij.xml.zenCodingGenerator"); public abstract TemplateImpl generateTemplate(@NotNull TemplateToken token, boolean hasChildren, @NotNull PsiElement context); @@ -59,11 +57,8 @@ public abstract class ZenCodingGenerator { public abstract boolean isEnabled(); - public static List getInstances() { - List generators = new ArrayList(); - Collections.addAll(generators, EP_NAME.getExtensions()); - generators.add(XmlZenCodingGeneratorImpl.INSTANCE); - return generators; + public static ZenCodingGenerator[] getInstances() { + return EP_NAME.getExtensions(); } @Nullable diff --git a/xml/xml-psi-impl/src/com/intellij/ide/highlighter/HtmlFileHighlighter.java b/xml/xml-psi-impl/src/com/intellij/ide/highlighter/HtmlFileHighlighter.java index 715c068d80ae..9496604413e5 100644 --- a/xml/xml-psi-impl/src/com/intellij/ide/highlighter/HtmlFileHighlighter.java +++ b/xml/xml-psi-impl/src/com/intellij/ide/highlighter/HtmlFileHighlighter.java @@ -96,16 +96,18 @@ public class HtmlFileHighlighter extends SyntaxHighlighterBase { public static void registerEmbeddedTokenAttributes(Map _keys1, Map _keys2) { if (_keys1 != null) { - for (Iterator iterator = _keys1.keySet().iterator(); iterator.hasNext();) { - IElementType iElementType = iterator.next(); - keys1.put(iElementType,_keys1.get(iElementType)); + for (IElementType iElementType : _keys1.keySet()) { + if (!keys1.containsKey(iElementType)) { + keys1.put(iElementType, _keys1.get(iElementType)); + } } } if (_keys2 != null) { - for (Iterator iterator = _keys2.keySet().iterator(); iterator.hasNext();) { - IElementType iElementType = iterator.next(); - keys2.put(iElementType,_keys2.get(iElementType)); + for (IElementType iElementType : _keys2.keySet()) { + if (!keys2.containsKey(iElementType)) { + keys2.put(iElementType, _keys2.get(iElementType)); + } } } }