mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
VCS: todo checkin handler - visualization (merge)
This commit is contained in:
Generated
+3
@@ -41,6 +41,9 @@
|
||||
<property name="text" value="CheckBox" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="com.intellij.ui.components.JBLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="true" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="0" />
|
||||
</item>
|
||||
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.intellij.lang.regexp;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public enum RegExpCapability {
|
||||
XML_SCHEMA_MODE,
|
||||
DANGLING_METACHARACTERS,
|
||||
NESTED_CHARACTER_CLASSES,
|
||||
OCTAL_NO_LEADING_ZERO,
|
||||
OMIT_NUMBERS_IN_QUANTIFIERS,
|
||||
COMMENT_MODE
|
||||
}
|
||||
@@ -30,7 +30,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
class RegExpHighlighter extends SyntaxHighlighterBase {
|
||||
public class RegExpHighlighter extends SyntaxHighlighterBase {
|
||||
private static final Map<IElementType, TextAttributesKey> keys1;
|
||||
private static final Map<IElementType, TextAttributesKey> keys2;
|
||||
|
||||
|
||||
@@ -17,16 +17,20 @@ package org.intellij.lang.regexp;
|
||||
|
||||
import com.intellij.lexer.FlexAdapter;
|
||||
|
||||
import java.util.EnumSet;
|
||||
|
||||
public class RegExpLexer extends FlexAdapter {
|
||||
|
||||
private static final int COMMENT_MODE = 1 << 14;
|
||||
private final EnumSet<RegExpCapability> myCapabilities;
|
||||
|
||||
public RegExpLexer(boolean xmlSchemaMode, boolean allowDanglingMetacharacters) {
|
||||
super(new _RegExLexer(xmlSchemaMode, allowDanglingMetacharacters));
|
||||
}
|
||||
public RegExpLexer(EnumSet<RegExpCapability> capabilities) {
|
||||
super(new _RegExLexer(capabilities));
|
||||
myCapabilities = capabilities;
|
||||
}
|
||||
|
||||
public void start(CharSequence buffer, int startOffset, int endOffset, int initialState) {
|
||||
getFlex().commentMode = (initialState & COMMENT_MODE) != 0;
|
||||
getFlex().commentMode = (initialState & COMMENT_MODE) != 0 || myCapabilities.contains(RegExpCapability.COMMENT_MODE);
|
||||
super.start(buffer, startOffset, endOffset, initialState & ~COMMENT_MODE);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,17 +23,18 @@ import com.intellij.psi.tree.IElementType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.EnumSet;
|
||||
|
||||
@SuppressWarnings({"RedundantIfStatement"})
|
||||
public class RegExpParser implements PsiParser {
|
||||
private boolean myAllowDanglingMetacharacters;
|
||||
private boolean myAllowOmitNumbersInQuantifiers;
|
||||
private final EnumSet<RegExpCapability> myCapabilities;
|
||||
|
||||
public void setAllowDanglingMetacharacters(boolean allowDanglingMetacharacters) {
|
||||
myAllowDanglingMetacharacters = allowDanglingMetacharacters;
|
||||
public RegExpParser() {
|
||||
myCapabilities = EnumSet.noneOf(RegExpCapability.class);
|
||||
}
|
||||
|
||||
public void setAllowOmitNumbersInQuantifiers(boolean allowOmitNumbersInQuantifiers) {
|
||||
myAllowOmitNumbersInQuantifiers = allowOmitNumbersInQuantifiers;
|
||||
public RegExpParser(EnumSet<RegExpCapability> capabilities) {
|
||||
myCapabilities = capabilities;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -136,11 +137,11 @@ public class RegExpParser implements PsiParser {
|
||||
if (builder.getTokenType() == RegExpTT.LBRACE) {
|
||||
builder.advanceLexer();
|
||||
boolean minOmitted = false;
|
||||
if (builder.getTokenType() == RegExpTT.COMMA && myAllowOmitNumbersInQuantifiers) {
|
||||
if (builder.getTokenType() == RegExpTT.COMMA && myCapabilities.contains(RegExpCapability.OMIT_NUMBERS_IN_QUANTIFIERS)) {
|
||||
minOmitted = true;
|
||||
builder.advanceLexer();
|
||||
}
|
||||
else if (builder.getTokenType() != RegExpTT.NUMBER && myAllowDanglingMetacharacters) {
|
||||
else if (builder.getTokenType() != RegExpTT.NUMBER && myCapabilities.contains(RegExpCapability.DANGLING_METACHARACTERS)) {
|
||||
marker.done(RegExpTT.CHARACTER);
|
||||
return true;
|
||||
}
|
||||
@@ -432,7 +433,7 @@ public class RegExpParser implements PsiParser {
|
||||
marker.drop();
|
||||
return parseClass(builder);
|
||||
}
|
||||
else if (type == RegExpTT.LBRACE && myAllowDanglingMetacharacters) {
|
||||
else if (type == RegExpTT.LBRACE && myCapabilities.contains(RegExpCapability.DANGLING_METACHARACTERS)) {
|
||||
builder.advanceLexer();
|
||||
marker.done(RegExpElementTypes.CHAR);
|
||||
}
|
||||
|
||||
@@ -31,12 +31,14 @@ import com.intellij.psi.tree.TokenSet;
|
||||
import org.intellij.lang.regexp.psi.impl.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.EnumSet;
|
||||
|
||||
public class RegExpParserDefinition implements ParserDefinition {
|
||||
private static final TokenSet COMMENT_TOKENS = TokenSet.create(RegExpTT.COMMENT);
|
||||
|
||||
@NotNull
|
||||
public Lexer createLexer(Project project) {
|
||||
return new RegExpLexer(false, false);
|
||||
return new RegExpLexer(EnumSet.of(RegExpCapability.NESTED_CHARACTER_CLASSES));
|
||||
}
|
||||
|
||||
public PsiParser createParser(Project project) {
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
/* The following code was generated by JFlex 1.4.3 on 01.06.10 15:51 */
|
||||
/* The following code was generated by JFlex 1.4.3 on 21.02.11 20:37 */
|
||||
|
||||
/* It's an automatically generated code. Do not modify it. */
|
||||
package org.intellij.lang.regexp;
|
||||
|
||||
import com.intellij.lexer.FlexLexer;
|
||||
import com.intellij.psi.StringEscapesTokenTypes;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.EnumSet;
|
||||
import com.intellij.psi.StringEscapesTokenTypes;
|
||||
|
||||
// IDEADEV-11055
|
||||
@SuppressWarnings({ "ALL", "SameParameterValue", "WeakerAccess", "SameReturnValue", "RedundantThrows", "UnusedDeclaration", "UnusedDeclaration" })
|
||||
@@ -15,8 +15,8 @@ import java.util.LinkedList;
|
||||
/**
|
||||
* This class is a scanner generated by
|
||||
* <a href="http://www.jflex.de/">JFlex</a> 1.4.3
|
||||
* on 01.06.10 15:51 from the specification file
|
||||
* <tt>C:/JetBrains/idea.branches/maia/tools/lexer/../../community/RegExpSupport/src/org/intellij/lang/regexp/regexp-lexer.flex</tt>
|
||||
* on 21.02.11 20:37 from the specification file
|
||||
* <tt>C:/JetBrains/IDEA/tools/lexer/../../community/RegExpSupport/src/org/intellij/lang/regexp/regexp-lexer.flex</tt>
|
||||
*/
|
||||
class _RegExLexer implements FlexLexer {
|
||||
/** initial size of the lookahead buffer */
|
||||
@@ -24,17 +24,18 @@ class _RegExLexer implements FlexLexer {
|
||||
|
||||
/** lexical states */
|
||||
public static final int EMBRACED = 4;
|
||||
public static final int PY_NAMED_GROUP_REF = 20;
|
||||
public static final int CLASS1PY = 8;
|
||||
public static final int PY_NAMED_GROUP_REF = 22;
|
||||
public static final int QUOTED = 2;
|
||||
public static final int OPTIONS = 12;
|
||||
public static final int PY_COND_REF = 22;
|
||||
public static final int OPTIONS = 14;
|
||||
public static final int PY_COND_REF = 24;
|
||||
public static final int YYINITIAL = 0;
|
||||
public static final int NAMED_GROUP = 16;
|
||||
public static final int CLASS2 = 8;
|
||||
public static final int NAMED_GROUP = 18;
|
||||
public static final int CLASS2 = 10;
|
||||
public static final int CLASS1 = 6;
|
||||
public static final int COMMENT = 14;
|
||||
public static final int QUOTED_NAMED_GROUP = 18;
|
||||
public static final int PROP = 10;
|
||||
public static final int COMMENT = 16;
|
||||
public static final int QUOTED_NAMED_GROUP = 20;
|
||||
public static final int PROP = 12;
|
||||
|
||||
/**
|
||||
* ZZ_LEXSTATE[l] is the state in the DFA for the lexical state l
|
||||
@@ -44,7 +45,7 @@ class _RegExLexer implements FlexLexer {
|
||||
*/
|
||||
private static final int ZZ_LEXSTATE[] = {
|
||||
0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7,
|
||||
8, 8, 9, 9, 10, 10, 11, 11
|
||||
8, 8, 9, 9, 10, 10, 11, 11, 12, 12
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -130,20 +131,21 @@ class _RegExLexer implements FlexLexer {
|
||||
private static final int [] ZZ_ACTION = zzUnpackAction();
|
||||
|
||||
private static final String ZZ_ACTION_PACKED_0 =
|
||||
"\6\0\1\1\1\2\4\0\1\3\1\4\1\5\1\6"+
|
||||
"\7\0\1\1\1\2\4\0\1\3\1\4\1\5\1\6"+
|
||||
"\1\7\1\10\1\11\1\12\1\13\1\14\1\15\1\16"+
|
||||
"\1\17\1\20\1\21\1\22\1\23\1\3\1\24\1\25"+
|
||||
"\1\26\1\27\1\30\1\31\1\32\1\33\1\34\1\3"+
|
||||
"\1\35\1\36\1\35\1\37\1\40\1\1\1\41\1\42"+
|
||||
"\1\2\1\43\1\44\1\45\1\46\1\47\1\50\1\51"+
|
||||
"\1\52\1\53\1\54\1\55\1\56\2\57\1\60\1\11"+
|
||||
"\1\61\1\62\1\63\1\64\1\65\1\66\1\0\1\67"+
|
||||
"\1\70\1\71\1\72\1\0\1\73\1\74\1\75\2\62"+
|
||||
"\2\63\1\76\1\77\1\100\1\101\1\0\1\74\1\62"+
|
||||
"\1\102\2\63\1\103\1\74\3\63\1\104";
|
||||
"\1\26\1\27\1\30\1\31\1\32\1\33\1\34\1\35"+
|
||||
"\1\11\1\36\1\3\1\37\1\40\1\37\1\41\1\42"+
|
||||
"\1\1\1\43\1\44\1\2\1\45\1\46\1\47\1\50"+
|
||||
"\1\0\1\51\1\52\1\53\1\54\1\55\1\56\1\57"+
|
||||
"\1\60\2\61\1\62\1\11\1\63\1\64\1\65\1\52"+
|
||||
"\1\66\1\67\1\70\1\71\1\72\1\0\1\73\1\74"+
|
||||
"\1\75\1\76\1\0\1\77\1\100\1\101\1\102\2\64"+
|
||||
"\2\65\1\52\1\103\1\104\1\105\1\106\1\0\1\101"+
|
||||
"\1\64\1\107\2\65\1\110\1\111\1\101\3\65\1\112";
|
||||
|
||||
private static int [] zzUnpackAction() {
|
||||
int [] result = new int[100];
|
||||
int [] result = new int[111];
|
||||
int offset = 0;
|
||||
offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result);
|
||||
return result;
|
||||
@@ -169,21 +171,22 @@ class _RegExLexer implements FlexLexer {
|
||||
|
||||
private static final String ZZ_ROWMAP_PACKED_0 =
|
||||
"\0\0\0\63\0\146\0\231\0\314\0\377\0\u0132\0\u0165"+
|
||||
"\0\u0198\0\u01cb\0\u01fe\0\u0231\0\u0264\0\u0264\0\u0297\0\u0264"+
|
||||
"\0\u0264\0\u02ca\0\u02fd\0\u0264\0\u0264\0\u0264\0\u0264\0\u0264"+
|
||||
"\0\u0264\0\u0264\0\u0264\0\u0264\0\u0264\0\u0330\0\u0264\0\u0363"+
|
||||
"\0\u0264\0\u0396\0\u0264\0\u0264\0\u0264\0\u0264\0\u0264\0\u03c9"+
|
||||
"\0\u0264\0\u0264\0\u02ca\0\u0264\0\u0264\0\u03fc\0\u042f\0\u0264"+
|
||||
"\0\u0264\0\u0264\0\u0264\0\u0462\0\u0264\0\u0264\0\u0495\0\u04c8"+
|
||||
"\0\u0264\0\u0264\0\u0264\0\u0264\0\u0264\0\u0264\0\u04fb\0\u0264"+
|
||||
"\0\u0264\0\u0264\0\u052e\0\u0561\0\u0264\0\u0264\0\u0264\0\u0594"+
|
||||
"\0\u0264\0\u0264\0\u0264\0\u05c7\0\u05fa\0\u0264\0\u062d\0\u0264"+
|
||||
"\0\u0660\0\u0693\0\u06c6\0\u06f9\0\u0264\0\u0264\0\u0264\0\u0264"+
|
||||
"\0\u072c\0\u075f\0\u0264\0\u0264\0\u0792\0\u07c5\0\u0264\0\u0264"+
|
||||
"\0\u07f8\0\u082b\0\u0264\0\u0264";
|
||||
"\0\u0198\0\u01cb\0\u01fe\0\u0231\0\u0264\0\u0297\0\u0297\0\u02ca"+
|
||||
"\0\u0297\0\u0297\0\u02fd\0\u0330\0\u0297\0\u0297\0\u0297\0\u0297"+
|
||||
"\0\u0297\0\u0297\0\u0297\0\u0297\0\u0297\0\u0297\0\u0363\0\u0297"+
|
||||
"\0\u0396\0\u0297\0\u03c9\0\u0297\0\u0297\0\u0297\0\u0297\0\u03fc"+
|
||||
"\0\u0297\0\u042f\0\u0297\0\u0462\0\u0297\0\u0297\0\u02fd\0\u0297"+
|
||||
"\0\u0297\0\u0495\0\u04c8\0\u0297\0\u0297\0\u0297\0\u0297\0\u04fb"+
|
||||
"\0\u0297\0\u052e\0\u0297\0\u0561\0\u0594\0\u0297\0\u0297\0\u0297"+
|
||||
"\0\u0297\0\u0297\0\u0297\0\u05c7\0\u0297\0\u0297\0\u0297\0\u05fa"+
|
||||
"\0\u062d\0\u0660\0\u0297\0\u0297\0\u0297\0\u0297\0\u0297\0\u0693"+
|
||||
"\0\u0297\0\u0297\0\u0297\0\u06c6\0\u06f9\0\u0297\0\u0297\0\u072c"+
|
||||
"\0\u0297\0\u075f\0\u0792\0\u07c5\0\u07f8\0\u082b\0\u0297\0\u0297"+
|
||||
"\0\u0297\0\u0297\0\u085e\0\u0891\0\u0297\0\u0297\0\u08c4\0\u08f7"+
|
||||
"\0\u0561\0\u0297\0\u0297\0\u092a\0\u095d\0\u0297\0\u0297";
|
||||
|
||||
private static int [] zzUnpackRowMap() {
|
||||
int [] result = new int[100];
|
||||
int [] result = new int[111];
|
||||
int offset = 0;
|
||||
offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result);
|
||||
return result;
|
||||
@@ -206,47 +209,53 @@ class _RegExLexer implements FlexLexer {
|
||||
private static final int [] ZZ_TRANS = zzUnpackTrans();
|
||||
|
||||
private static final String ZZ_TRANS_PACKED_0 =
|
||||
"\3\15\1\16\1\17\1\20\1\21\1\15\1\22\1\15"+
|
||||
"\1\23\1\24\1\25\1\26\1\27\1\30\1\31\1\32"+
|
||||
"\21\15\1\33\1\15\1\34\4\15\1\24\5\15\1\35"+
|
||||
"\1\15\1\24\12\15\1\36\1\0\47\15\1\37\2\40"+
|
||||
"\4\37\1\41\12\37\20\42\1\40\1\37\1\42\2\37"+
|
||||
"\1\40\1\43\12\37\11\44\1\45\1\44\1\0\47\44"+
|
||||
"\6\15\1\21\1\15\1\22\1\46\1\23\1\47\1\25"+
|
||||
"\26\15\1\33\5\15\1\50\1\47\7\15\1\47\6\51"+
|
||||
"\1\52\1\51\1\53\1\51\1\23\50\51\5\54\1\55"+
|
||||
"\14\54\20\56\1\54\1\57\1\56\6\54\1\60\7\54"+
|
||||
"\13\10\1\61\46\10\1\61\22\54\20\42\2\54\1\42"+
|
||||
"\7\54\1\62\30\54\20\42\2\54\1\42\14\54\1\63"+
|
||||
"\6\54\1\55\14\54\20\42\2\54\1\42\17\54\2\40"+
|
||||
"\2\54\1\55\14\54\20\42\1\40\1\54\1\42\2\54"+
|
||||
"\1\40\13\54\101\0\1\64\55\0\1\65\51\0\1\66"+
|
||||
"\1\67\1\70\4\71\1\66\1\71\1\66\1\71\1\72"+
|
||||
"\6\71\2\73\2\74\2\75\1\76\1\77\1\76\2\100"+
|
||||
"\1\101\1\102\1\101\1\103\1\104\1\67\1\71\1\101"+
|
||||
"\1\72\4\66\1\72\7\66\1\72\37\0\1\105\24\0"+
|
||||
"\2\40\37\0\1\40\4\0\1\40\14\0\2\42\17\0"+
|
||||
"\21\42\1\0\1\42\1\0\2\42\64\0\1\106\33\0"+
|
||||
"\20\56\2\0\1\56\40\0\20\57\2\0\1\57\22\0"+
|
||||
"\1\107\27\0\1\110\16\0\2\111\1\112\1\113\1\114"+
|
||||
"\1\115\1\116\2\0\2\67\37\0\1\67\22\0\1\117"+
|
||||
"\37\0\1\117\20\0\63\120\1\121\2\122\20\121\2\122"+
|
||||
"\2\121\3\122\3\121\1\122\1\121\1\122\2\121\1\122"+
|
||||
"\20\121\1\123\2\124\20\123\2\124\2\123\3\124\3\123"+
|
||||
"\1\124\1\123\1\124\2\123\1\124\20\123\55\0\1\125"+
|
||||
"\1\0\1\126\60\0\1\127\1\130\4\0\5\131\1\0"+
|
||||
"\55\131\2\0\1\132\37\0\1\132\20\0\64\133\2\134"+
|
||||
"\20\133\2\134\2\133\3\134\3\133\1\134\1\133\1\134"+
|
||||
"\2\133\1\134\20\133\64\135\2\136\20\135\2\136\2\135"+
|
||||
"\3\136\3\135\1\136\1\135\1\136\2\135\1\136\20\135"+
|
||||
"\5\131\1\137\55\131\2\0\1\140\37\0\1\140\20\0"+
|
||||
"\64\141\2\142\20\141\2\142\2\141\3\142\3\141\1\142"+
|
||||
"\1\141\1\142\2\141\1\142\20\141\64\143\2\144\20\143"+
|
||||
"\2\144\2\143\3\144\3\143\1\144\1\143\1\144\2\143"+
|
||||
"\1\144\20\143";
|
||||
"\3\16\1\17\1\20\1\21\1\22\1\16\1\23\1\16"+
|
||||
"\1\24\1\25\1\26\1\27\1\30\1\31\1\32\1\33"+
|
||||
"\21\16\1\34\1\16\1\35\4\16\1\25\5\16\1\36"+
|
||||
"\1\16\1\25\12\16\1\37\1\0\47\16\1\40\2\41"+
|
||||
"\4\40\1\42\12\40\20\43\1\41\1\40\1\43\2\40"+
|
||||
"\1\41\1\44\12\40\11\45\1\46\1\45\1\0\62\45"+
|
||||
"\1\0\1\47\46\45\6\16\1\22\1\16\1\50\1\51"+
|
||||
"\1\52\1\53\1\26\26\16\1\34\5\16\1\54\1\53"+
|
||||
"\7\16\1\53\6\55\1\56\1\55\1\57\1\55\1\24"+
|
||||
"\50\55\5\60\1\61\14\60\20\62\1\60\1\63\1\62"+
|
||||
"\6\60\1\64\7\60\13\11\1\65\46\11\1\65\22\60"+
|
||||
"\20\43\2\60\1\43\7\60\1\66\30\60\20\43\2\60"+
|
||||
"\1\43\14\60\1\67\6\60\1\61\14\60\20\43\2\60"+
|
||||
"\1\43\17\60\2\41\2\60\1\61\14\60\20\43\1\41"+
|
||||
"\1\60\1\43\2\60\1\41\13\60\101\0\1\70\55\0"+
|
||||
"\1\71\2\0\1\72\46\0\1\73\1\74\1\75\4\76"+
|
||||
"\1\73\1\76\1\73\1\76\1\77\6\76\2\100\2\101"+
|
||||
"\2\102\1\103\1\104\1\103\2\105\1\106\1\107\1\106"+
|
||||
"\1\110\1\111\1\112\1\76\1\106\1\77\4\73\1\77"+
|
||||
"\7\73\1\77\37\0\1\113\24\0\2\41\37\0\1\41"+
|
||||
"\4\0\1\41\14\0\2\43\17\0\21\43\1\0\1\43"+
|
||||
"\1\0\2\43\24\0\1\114\2\0\1\72\46\0\1\73"+
|
||||
"\1\74\1\75\4\76\1\73\1\76\1\115\1\76\1\77"+
|
||||
"\6\76\2\100\2\101\2\102\1\103\1\104\1\103\2\105"+
|
||||
"\1\106\1\107\1\106\1\110\1\111\1\112\1\76\1\106"+
|
||||
"\1\77\4\73\1\77\7\73\1\77\51\0\1\116\33\0"+
|
||||
"\20\62\2\0\1\62\40\0\20\63\2\0\1\63\22\0"+
|
||||
"\1\117\27\0\1\120\16\0\2\121\1\122\1\123\1\124"+
|
||||
"\1\125\1\126\12\0\1\127\52\0\2\74\37\0\1\74"+
|
||||
"\22\0\1\130\37\0\1\130\20\0\63\131\1\132\2\133"+
|
||||
"\20\132\2\133\2\132\3\133\3\132\1\133\1\132\1\133"+
|
||||
"\2\132\1\133\20\132\1\134\2\135\20\134\2\135\2\134"+
|
||||
"\3\135\3\134\1\135\1\134\1\135\2\134\1\135\20\134"+
|
||||
"\1\0\1\74\1\136\37\0\1\136\75\0\1\137\1\0"+
|
||||
"\1\140\60\0\1\141\1\142\4\0\5\143\1\0\55\143"+
|
||||
"\2\0\1\144\37\0\1\144\20\0\64\145\2\146\20\145"+
|
||||
"\2\146\2\145\3\146\3\145\1\146\1\145\1\146\2\145"+
|
||||
"\1\146\20\145\64\147\2\150\20\147\2\150\2\147\3\150"+
|
||||
"\3\147\1\150\1\147\1\150\2\147\1\150\20\147\1\0"+
|
||||
"\1\74\1\151\37\0\1\151\20\0\5\143\1\152\55\143"+
|
||||
"\2\0\1\153\37\0\1\153\20\0\64\154\2\155\20\154"+
|
||||
"\2\155\2\154\3\155\3\154\1\155\1\154\1\155\2\154"+
|
||||
"\1\155\20\154\64\156\2\157\20\156\2\157\2\156\3\157"+
|
||||
"\3\156\1\157\1\156\1\157\2\156\1\157\20\156";
|
||||
|
||||
private static int [] zzUnpackTrans() {
|
||||
int [] result = new int[2142];
|
||||
int [] result = new int[2448];
|
||||
int offset = 0;
|
||||
offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result);
|
||||
return result;
|
||||
@@ -287,15 +296,16 @@ class _RegExLexer implements FlexLexer {
|
||||
private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute();
|
||||
|
||||
private static final String ZZ_ATTRIBUTE_PACKED_0 =
|
||||
"\6\0\2\1\4\0\2\11\1\1\2\11\2\1\12\11"+
|
||||
"\1\1\1\11\1\1\1\11\1\1\5\11\1\1\2\11"+
|
||||
"\1\1\2\11\2\1\4\11\1\1\2\11\2\1\6\11"+
|
||||
"\1\1\3\11\2\1\3\11\1\0\3\11\1\1\1\0"+
|
||||
"\1\11\1\1\1\11\4\1\4\11\1\0\1\1\2\11"+
|
||||
"\2\1\2\11\2\1\2\11";
|
||||
"\7\0\2\1\4\0\2\11\1\1\2\11\2\1\12\11"+
|
||||
"\1\1\1\11\1\1\1\11\1\1\4\11\1\1\1\11"+
|
||||
"\1\1\1\11\1\1\2\11\1\1\2\11\2\1\4\11"+
|
||||
"\1\1\1\11\1\0\1\11\2\1\6\11\1\1\3\11"+
|
||||
"\3\1\5\11\1\0\3\11\1\1\1\0\2\11\1\1"+
|
||||
"\1\11\5\1\4\11\1\0\1\1\2\11\3\1\2\11"+
|
||||
"\2\1\2\11";
|
||||
|
||||
private static int [] zzUnpackAttribute() {
|
||||
int [] result = new int[100];
|
||||
int [] result = new int[111];
|
||||
int offset = 0;
|
||||
offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result);
|
||||
return result;
|
||||
@@ -358,15 +368,21 @@ class _RegExLexer implements FlexLexer {
|
||||
private final LinkedList<Integer> states = new LinkedList();
|
||||
|
||||
// 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.
|
||||
// as well, but is currently unfinished as it requires to tweak more places than just the lexer.
|
||||
private boolean xmlSchemaMode;
|
||||
|
||||
private boolean allowDanglingMetacharacters;
|
||||
|
||||
_RegExLexer(boolean xmlSchemaMode, boolean allowDanglingMetacharacters) {
|
||||
private boolean allowDanglingMetacharacters;
|
||||
private boolean allowNestedCharacterClasses;
|
||||
private boolean allowOctalNoLeadingZero;
|
||||
|
||||
_RegExLexer(EnumSet<RegExpCapability> capabilities) {
|
||||
this((java.io.Reader)null);
|
||||
this.xmlSchemaMode = xmlSchemaMode;
|
||||
this.allowDanglingMetacharacters = allowDanglingMetacharacters;
|
||||
this.xmlSchemaMode = capabilities.contains(RegExpCapability.XML_SCHEMA_MODE);
|
||||
this.allowDanglingMetacharacters = capabilities.contains(RegExpCapability.DANGLING_METACHARACTERS);
|
||||
this.allowNestedCharacterClasses = capabilities.contains(RegExpCapability.NESTED_CHARACTER_CLASSES);
|
||||
this.allowOctalNoLeadingZero = capabilities.contains(RegExpCapability.OCTAL_NO_LEADING_ZERO);
|
||||
this.commentMode = capabilities.contains(RegExpCapability.COMMENT_MODE);
|
||||
}
|
||||
|
||||
private void yypushstate(int state) {
|
||||
@@ -636,272 +652,219 @@ class _RegExLexer implements FlexLexer {
|
||||
zzMarkedPos = zzMarkedPosL;
|
||||
|
||||
switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) {
|
||||
case 7:
|
||||
{ if (yystate() != CLASS2) yypushstate(EMBRACED); return RegExpTT.LBRACE;
|
||||
}
|
||||
case 69: break;
|
||||
case 6:
|
||||
{ return RegExpTT.GROUP_END;
|
||||
}
|
||||
case 70: break;
|
||||
case 38:
|
||||
// lookahead expression with fixed base length
|
||||
zzMarkedPos = zzStartRead + 1;
|
||||
{ yypushstate(CLASS1); return RegExpTT.CLASS_BEGIN;
|
||||
}
|
||||
case 71: break;
|
||||
case 14:
|
||||
{ return RegExpTT.STAR;
|
||||
}
|
||||
case 72: break;
|
||||
case 42:
|
||||
{ return RegExpTT.ESC_CHARACTER;
|
||||
}
|
||||
case 73: break;
|
||||
case 28:
|
||||
{ return commentMode ? com.intellij.psi.TokenType.WHITE_SPACE : RegExpTT.ESC_CHARACTER;
|
||||
}
|
||||
case 74: break;
|
||||
case 43:
|
||||
{ return commentMode ? RegExpTT.CHARACTER : RegExpTT.REDUNDANT_ESCAPE;
|
||||
case 74:
|
||||
{ return RegExpTT.UNICODE_CHAR;
|
||||
}
|
||||
case 75: break;
|
||||
case 39:
|
||||
{ return RegExpTT.REDUNDANT_ESCAPE;
|
||||
case 7:
|
||||
{ if (yystate() != CLASS2) yypushstate(EMBRACED); return RegExpTT.LBRACE;
|
||||
}
|
||||
case 76: break;
|
||||
case 24:
|
||||
{ return RegExpTT.COMMA;
|
||||
}
|
||||
case 77: break;
|
||||
case 58:
|
||||
{ yybegin(NAMED_GROUP); return RegExpTT.RUBY_NAMED_GROUP;
|
||||
}
|
||||
case 78: break;
|
||||
case 64:
|
||||
{ return RegExpTT.POS_LOOKBEHIND;
|
||||
}
|
||||
case 79: break;
|
||||
case 41:
|
||||
{ return RegExpTT.BAD_OCT_VALUE;
|
||||
}
|
||||
case 80: break;
|
||||
case 10:
|
||||
{ return commentMode ? com.intellij.psi.TokenType.WHITE_SPACE : RegExpTT.CTRL_CHARACTER;
|
||||
}
|
||||
case 81: break;
|
||||
case 30:
|
||||
{ yypopstate(); yypushstate(EMBRACED); return RegExpTT.LBRACE;
|
||||
}
|
||||
case 82: break;
|
||||
case 51:
|
||||
{ return StringEscapesTokenTypes.INVALID_UNICODE_ESCAPE_TOKEN;
|
||||
}
|
||||
case 83: break;
|
||||
case 65:
|
||||
{ return RegExpTT.NEG_LOOKBEHIND;
|
||||
}
|
||||
case 84: break;
|
||||
case 68:
|
||||
{ return RegExpTT.UNICODE_CHAR;
|
||||
}
|
||||
case 85: break;
|
||||
case 61:
|
||||
{ if (xmlSchemaMode) { yypushback(1); return RegExpTT.CHAR_CLASS; } else return RegExpTT.CTRL;
|
||||
}
|
||||
case 86: break;
|
||||
case 37:
|
||||
{ yybegin(OPTIONS); return RegExpTT.SET_OPTIONS;
|
||||
}
|
||||
case 87: break;
|
||||
case 12:
|
||||
{ return RegExpTT.DOLLAR;
|
||||
}
|
||||
case 88: break;
|
||||
case 52:
|
||||
{ yypopstate(); return RegExpTT.QUOTE_END;
|
||||
}
|
||||
case 89: break;
|
||||
case 56:
|
||||
case 60:
|
||||
{ return RegExpTT.POS_LOOKAHEAD;
|
||||
}
|
||||
case 90: break;
|
||||
case 22:
|
||||
{ yypopstate(); return RegExpTT.RBRACE;
|
||||
}
|
||||
case 91: break;
|
||||
case 3:
|
||||
{ return RegExpTT.CHARACTER;
|
||||
}
|
||||
case 92: break;
|
||||
case 57:
|
||||
{ return RegExpTT.NEG_LOOKAHEAD;
|
||||
}
|
||||
case 93: break;
|
||||
case 44:
|
||||
{ return RegExpTT.ESC_CTRL_CHARACTER;
|
||||
}
|
||||
case 94: break;
|
||||
case 23:
|
||||
{ return RegExpTT.NAME;
|
||||
}
|
||||
case 95: break;
|
||||
case 53:
|
||||
{ return RegExpTT.ANDAND;
|
||||
}
|
||||
case 96: break;
|
||||
case 13:
|
||||
{ return RegExpTT.QUEST;
|
||||
}
|
||||
case 97: break;
|
||||
case 46:
|
||||
{ return RegExpTT.CHAR_CLASS;
|
||||
}
|
||||
case 98: break;
|
||||
case 17:
|
||||
{ return RegExpTT.MINUS;
|
||||
}
|
||||
case 99: break;
|
||||
case 67:
|
||||
case 78: break;
|
||||
case 73:
|
||||
{ return RegExpTT.COMMENT;
|
||||
}
|
||||
case 100: break;
|
||||
case 40:
|
||||
{ return yystate() != CLASS2 ? RegExpTT.BACKREF : RegExpTT.ESC_CHARACTER;
|
||||
}
|
||||
case 101: break;
|
||||
case 16:
|
||||
{ return RegExpTT.UNION;
|
||||
}
|
||||
case 102: break;
|
||||
case 47:
|
||||
{ if (xmlSchemaMode) return RegExpTT.CHAR_CLASS; else return StringEscapesTokenTypes.INVALID_CHARACTER_ESCAPE_TOKEN;
|
||||
}
|
||||
case 103: break;
|
||||
case 60:
|
||||
{ return RegExpTT.OCT_CHAR;
|
||||
}
|
||||
case 104: break;
|
||||
case 4:
|
||||
{ return RegExpTT.DOT;
|
||||
}
|
||||
case 105: break;
|
||||
case 32:
|
||||
{ yybegin(YYINITIAL); return RegExpTT.GROUP_END;
|
||||
}
|
||||
case 106: break;
|
||||
case 21:
|
||||
{ return RegExpTT.NUMBER;
|
||||
}
|
||||
case 107: break;
|
||||
case 35:
|
||||
{ yybegin(YYINITIAL); return RegExpTT.GT;
|
||||
}
|
||||
case 108: break;
|
||||
case 59:
|
||||
{ yybegin(QUOTED_NAMED_GROUP); return RegExpTT.RUBY_QUOTED_NAMED_GROUP;
|
||||
}
|
||||
case 109: break;
|
||||
case 54:
|
||||
{ yybegin(PY_COND_REF); return RegExpTT.PYTHON_COND_REF;
|
||||
}
|
||||
case 110: break;
|
||||
case 48:
|
||||
{ yypushstate(PROP); return RegExpTT.PROPERTY;
|
||||
}
|
||||
case 111: break;
|
||||
case 18:
|
||||
{ return commentMode ? com.intellij.psi.TokenType.WHITE_SPACE : RegExpTT.CHARACTER;
|
||||
}
|
||||
case 112: break;
|
||||
case 33:
|
||||
{ handleOptions(); return RegExpTT.OPTIONS_OFF;
|
||||
}
|
||||
case 113: break;
|
||||
case 34:
|
||||
{ yybegin(YYINITIAL); return RegExpTT.COLON;
|
||||
}
|
||||
case 114: break;
|
||||
case 25:
|
||||
{ assert false : yytext();
|
||||
}
|
||||
case 115: break;
|
||||
case 62:
|
||||
{ yybegin(PY_NAMED_GROUP_REF); return RegExpTT.PYTHON_NAMED_GROUP_REF;
|
||||
}
|
||||
case 116: break;
|
||||
case 27:
|
||||
{ yypopstate(); return RegExpTT.CLASS_END;
|
||||
}
|
||||
case 117: break;
|
||||
case 11:
|
||||
{ return RegExpTT.CARET;
|
||||
}
|
||||
case 118: break;
|
||||
case 1:
|
||||
{ handleOptions(); return RegExpTT.OPTIONS_ON;
|
||||
}
|
||||
case 119: break;
|
||||
case 29:
|
||||
{ yypopstate(); yypushback(1);
|
||||
}
|
||||
case 120: break;
|
||||
case 45:
|
||||
{ return yystate() != CLASS2 ? RegExpTT.BOUNDARY : RegExpTT.ESC_CHARACTER;
|
||||
}
|
||||
case 121: break;
|
||||
case 63:
|
||||
case 79: break;
|
||||
case 68:
|
||||
{ yybegin(NAMED_GROUP); return RegExpTT.PYTHON_NAMED_GROUP;
|
||||
}
|
||||
case 122: break;
|
||||
case 19:
|
||||
{ if (commentMode) { yypushstate(COMMENT); return RegExpTT.COMMENT; } else return RegExpTT.CHARACTER;
|
||||
case 80: break;
|
||||
case 14:
|
||||
{ return RegExpTT.STAR;
|
||||
}
|
||||
case 123: break;
|
||||
case 66:
|
||||
{ return RegExpTT.HEX_CHAR;
|
||||
case 81: break;
|
||||
case 58:
|
||||
{ yybegin(PY_COND_REF); return RegExpTT.PYTHON_COND_REF;
|
||||
}
|
||||
case 124: break;
|
||||
case 82: break;
|
||||
case 48:
|
||||
{ return RegExpTT.CHAR_CLASS;
|
||||
}
|
||||
case 83: break;
|
||||
case 35:
|
||||
{ handleOptions(); return RegExpTT.OPTIONS_OFF;
|
||||
}
|
||||
case 84: break;
|
||||
case 54:
|
||||
{ yypopstate(); return RegExpTT.QUOTE_END;
|
||||
}
|
||||
case 85: break;
|
||||
case 34:
|
||||
{ yybegin(YYINITIAL); return RegExpTT.GROUP_END;
|
||||
}
|
||||
case 86: break;
|
||||
case 5:
|
||||
{ return RegExpTT.GROUP_BEGIN;
|
||||
}
|
||||
case 125: break;
|
||||
case 8:
|
||||
{ yypushstate(CLASS2); return RegExpTT.CLASS_BEGIN;
|
||||
case 87: break;
|
||||
case 36:
|
||||
{ yybegin(YYINITIAL); return RegExpTT.COLON;
|
||||
}
|
||||
case 126: break;
|
||||
case 55:
|
||||
case 88: break;
|
||||
case 6:
|
||||
{ return RegExpTT.GROUP_END;
|
||||
}
|
||||
case 89: break;
|
||||
case 25:
|
||||
{ assert false : yytext();
|
||||
}
|
||||
case 90: break;
|
||||
case 18:
|
||||
{ return commentMode ? com.intellij.psi.TokenType.WHITE_SPACE : RegExpTT.CHARACTER;
|
||||
}
|
||||
case 91: break;
|
||||
case 45:
|
||||
{ return commentMode ? RegExpTT.CHARACTER : RegExpTT.REDUNDANT_ESCAPE;
|
||||
}
|
||||
case 92: break;
|
||||
case 23:
|
||||
{ return RegExpTT.NAME;
|
||||
}
|
||||
case 93: break;
|
||||
case 72:
|
||||
{ if (allowOctalNoLeadingZero) return RegExpTT.OCT_CHAR;
|
||||
return yystate() != CLASS2 ? RegExpTT.BACKREF : RegExpTT.ESC_CHARACTER;
|
||||
}
|
||||
case 94: break;
|
||||
case 29:
|
||||
{ yypopstate(); return RegExpTT.CLASS_END;
|
||||
}
|
||||
case 95: break;
|
||||
case 33:
|
||||
{ yybegin(YYINITIAL); return RegExpTT.BAD_CHARACTER;
|
||||
}
|
||||
case 96: break;
|
||||
case 51:
|
||||
{ yypushstate(QUOTED); return RegExpTT.QUOTE_BEGIN;
|
||||
}
|
||||
case 97: break;
|
||||
case 21:
|
||||
{ return RegExpTT.NUMBER;
|
||||
}
|
||||
case 98: break;
|
||||
case 4:
|
||||
{ return RegExpTT.DOT;
|
||||
}
|
||||
case 99: break;
|
||||
case 70:
|
||||
{ return RegExpTT.NEG_LOOKBEHIND;
|
||||
}
|
||||
case 100: break;
|
||||
case 40:
|
||||
// lookahead expression with fixed base length
|
||||
zzMarkedPos = zzStartRead + 1;
|
||||
{ yypushstate(CLASS1);
|
||||
return RegExpTT.CLASS_BEGIN;
|
||||
}
|
||||
case 101: break;
|
||||
case 61:
|
||||
{ return RegExpTT.NEG_LOOKAHEAD;
|
||||
}
|
||||
case 102: break;
|
||||
case 10:
|
||||
{ return commentMode ? com.intellij.psi.TokenType.WHITE_SPACE : RegExpTT.CTRL_CHARACTER;
|
||||
}
|
||||
case 103: break;
|
||||
case 59:
|
||||
{ return RegExpTT.NON_CAPT_GROUP;
|
||||
}
|
||||
case 127: break;
|
||||
case 9:
|
||||
{ return StringEscapesTokenTypes.INVALID_CHARACTER_ESCAPE_TOKEN;
|
||||
case 104: break;
|
||||
case 63:
|
||||
{ yybegin(QUOTED_NAMED_GROUP); return RegExpTT.RUBY_QUOTED_NAMED_GROUP;
|
||||
}
|
||||
case 128: break;
|
||||
case 36:
|
||||
{ yybegin(YYINITIAL); return RegExpTT.QUOTE;
|
||||
case 105: break;
|
||||
case 28:
|
||||
{ if (allowNestedCharacterClasses) {
|
||||
yypushstate(CLASS2);
|
||||
return RegExpTT.CLASS_BEGIN;
|
||||
}
|
||||
return RegExpTT.CHARACTER;
|
||||
}
|
||||
case 129: break;
|
||||
case 106: break;
|
||||
case 19:
|
||||
{ if (commentMode) { yypushstate(COMMENT); return RegExpTT.COMMENT; } else return RegExpTT.CHARACTER;
|
||||
}
|
||||
case 107: break;
|
||||
case 50:
|
||||
{ return RegExpTT.BAD_HEX_VALUE;
|
||||
{ yypushstate(PROP); return RegExpTT.PROPERTY;
|
||||
}
|
||||
case 130: break;
|
||||
case 108: break;
|
||||
case 8:
|
||||
{ yypushstate(CLASS2);
|
||||
return RegExpTT.CLASS_BEGIN;
|
||||
}
|
||||
case 109: break;
|
||||
case 69:
|
||||
{ return RegExpTT.POS_LOOKBEHIND;
|
||||
}
|
||||
case 110: break;
|
||||
case 42:
|
||||
{ return yystate() != CLASS2 ? RegExpTT.BACKREF : RegExpTT.ESC_CHARACTER;
|
||||
}
|
||||
case 111: break;
|
||||
case 71:
|
||||
{ return RegExpTT.HEX_CHAR;
|
||||
}
|
||||
case 112: break;
|
||||
case 1:
|
||||
{ handleOptions(); return RegExpTT.OPTIONS_ON;
|
||||
}
|
||||
case 113: break;
|
||||
case 57:
|
||||
{ return allowNestedCharacterClasses ? RegExpTT.ANDAND : RegExpTT.CHARACTER;
|
||||
}
|
||||
case 114: break;
|
||||
case 2:
|
||||
{ yypopstate(); return RegExpTT.COMMENT;
|
||||
}
|
||||
case 131: break;
|
||||
case 49:
|
||||
{ yypushstate(QUOTED); return RegExpTT.QUOTE_BEGIN;
|
||||
case 115: break;
|
||||
case 17:
|
||||
{ return RegExpTT.MINUS;
|
||||
}
|
||||
case 132: break;
|
||||
case 26:
|
||||
{ yybegin(CLASS2); return RegExpTT.CHARACTER;
|
||||
case 116: break;
|
||||
case 46:
|
||||
{ return RegExpTT.ESC_CTRL_CHARACTER;
|
||||
}
|
||||
case 133: break;
|
||||
case 117: break;
|
||||
case 32:
|
||||
{ yypopstate(); yypushstate(EMBRACED); return RegExpTT.LBRACE;
|
||||
}
|
||||
case 118: break;
|
||||
case 13:
|
||||
{ return RegExpTT.QUEST;
|
||||
}
|
||||
case 119: break;
|
||||
case 15:
|
||||
{ return RegExpTT.PLUS;
|
||||
}
|
||||
case 134: break;
|
||||
case 120: break;
|
||||
case 65:
|
||||
{ return RegExpTT.OCT_CHAR;
|
||||
}
|
||||
case 121: break;
|
||||
case 38:
|
||||
{ yybegin(YYINITIAL); return RegExpTT.QUOTE;
|
||||
}
|
||||
case 122: break;
|
||||
case 64:
|
||||
// lookahead expression with fixed base length
|
||||
zzMarkedPos = zzStartRead + 1;
|
||||
{ if (!allowNestedCharacterClasses) {
|
||||
yypushstate(CLASS1PY);
|
||||
}
|
||||
else {
|
||||
yypushstate(CLASS2);
|
||||
}
|
||||
return RegExpTT.CLASS_BEGIN;
|
||||
}
|
||||
case 123: break;
|
||||
case 20:
|
||||
{ if (allowDanglingMetacharacters) {
|
||||
yypopstate(); yypushback(1);
|
||||
@@ -909,11 +872,110 @@ class _RegExLexer implements FlexLexer {
|
||||
return RegExpTT.BAD_CHARACTER;
|
||||
}
|
||||
}
|
||||
case 135: break;
|
||||
case 124: break;
|
||||
case 31:
|
||||
{ yybegin(YYINITIAL); return RegExpTT.BAD_CHARACTER;
|
||||
{ yypopstate(); yypushback(1);
|
||||
}
|
||||
case 125: break;
|
||||
case 27:
|
||||
{ yybegin(CLASS1); return RegExpTT.CARET;
|
||||
}
|
||||
case 126: break;
|
||||
case 55:
|
||||
// lookahead expression with fixed base length
|
||||
zzMarkedPos = zzStartRead + 1;
|
||||
{ if (allowNestedCharacterClasses) {
|
||||
yypushstate(CLASS1);
|
||||
return RegExpTT.CLASS_BEGIN;
|
||||
}
|
||||
return RegExpTT.CHARACTER;
|
||||
}
|
||||
case 127: break;
|
||||
case 56:
|
||||
{ if (!allowNestedCharacterClasses) return RegExpTT.CHARACTER;
|
||||
return RegExpTT.REDUNDANT_ESCAPE;
|
||||
}
|
||||
case 128: break;
|
||||
case 37:
|
||||
{ yybegin(YYINITIAL); return RegExpTT.GT;
|
||||
}
|
||||
case 129: break;
|
||||
case 67:
|
||||
{ yybegin(PY_NAMED_GROUP_REF); return RegExpTT.PYTHON_NAMED_GROUP_REF;
|
||||
}
|
||||
case 130: break;
|
||||
case 16:
|
||||
{ return RegExpTT.UNION;
|
||||
}
|
||||
case 131: break;
|
||||
case 3:
|
||||
{ return RegExpTT.CHARACTER;
|
||||
}
|
||||
case 132: break;
|
||||
case 62:
|
||||
{ yybegin(NAMED_GROUP); return RegExpTT.RUBY_NAMED_GROUP;
|
||||
}
|
||||
case 133: break;
|
||||
case 39:
|
||||
{ yybegin(OPTIONS); return RegExpTT.SET_OPTIONS;
|
||||
}
|
||||
case 134: break;
|
||||
case 26:
|
||||
{ yybegin(CLASS2); return RegExpTT.CHARACTER;
|
||||
}
|
||||
case 135: break;
|
||||
case 66:
|
||||
{ if (xmlSchemaMode) { yypushback(1); return RegExpTT.CHAR_CLASS; } else return RegExpTT.CTRL;
|
||||
}
|
||||
case 136: break;
|
||||
case 30:
|
||||
{ return commentMode ? com.intellij.psi.TokenType.WHITE_SPACE : RegExpTT.ESC_CHARACTER;
|
||||
}
|
||||
case 137: break;
|
||||
case 12:
|
||||
{ return RegExpTT.DOLLAR;
|
||||
}
|
||||
case 138: break;
|
||||
case 49:
|
||||
{ if (xmlSchemaMode) return RegExpTT.CHAR_CLASS; else return StringEscapesTokenTypes.INVALID_CHARACTER_ESCAPE_TOKEN;
|
||||
}
|
||||
case 139: break;
|
||||
case 41:
|
||||
{ return RegExpTT.REDUNDANT_ESCAPE;
|
||||
}
|
||||
case 140: break;
|
||||
case 47:
|
||||
{ return yystate() != CLASS2 ? RegExpTT.BOUNDARY : RegExpTT.ESC_CHARACTER;
|
||||
}
|
||||
case 141: break;
|
||||
case 22:
|
||||
{ yypopstate(); return RegExpTT.RBRACE;
|
||||
}
|
||||
case 142: break;
|
||||
case 53:
|
||||
{ return StringEscapesTokenTypes.INVALID_UNICODE_ESCAPE_TOKEN;
|
||||
}
|
||||
case 143: break;
|
||||
case 43:
|
||||
{ return RegExpTT.BAD_OCT_VALUE;
|
||||
}
|
||||
case 144: break;
|
||||
case 52:
|
||||
{ return RegExpTT.BAD_HEX_VALUE;
|
||||
}
|
||||
case 145: break;
|
||||
case 9:
|
||||
{ return StringEscapesTokenTypes.INVALID_CHARACTER_ESCAPE_TOKEN;
|
||||
}
|
||||
case 146: break;
|
||||
case 11:
|
||||
{ return RegExpTT.CARET;
|
||||
}
|
||||
case 147: break;
|
||||
case 44:
|
||||
{ return RegExpTT.ESC_CHARACTER;
|
||||
}
|
||||
case 148: break;
|
||||
default:
|
||||
if (zzInput == YYEOF && zzStartRead == zzCurrentPos) {
|
||||
zzAtEOF = true;
|
||||
|
||||
@@ -4,6 +4,7 @@ package org.intellij.lang.regexp;
|
||||
import com.intellij.lexer.FlexLexer;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import java.util.LinkedList;
|
||||
import java.util.EnumSet;
|
||||
import com.intellij.psi.StringEscapesTokenTypes;
|
||||
|
||||
// IDEADEV-11055
|
||||
@@ -23,15 +24,21 @@ import com.intellij.psi.StringEscapesTokenTypes;
|
||||
private final LinkedList<Integer> states = new LinkedList();
|
||||
|
||||
// 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.
|
||||
// as well, but is currently unfinished as it requires to tweak more places than just the lexer.
|
||||
private boolean xmlSchemaMode;
|
||||
|
||||
private boolean allowDanglingMetacharacters;
|
||||
|
||||
_RegExLexer(boolean xmlSchemaMode, boolean allowDanglingMetacharacters) {
|
||||
private boolean allowDanglingMetacharacters;
|
||||
private boolean allowNestedCharacterClasses;
|
||||
private boolean allowOctalNoLeadingZero;
|
||||
|
||||
_RegExLexer(EnumSet<RegExpCapability> capabilities) {
|
||||
this((java.io.Reader)null);
|
||||
this.xmlSchemaMode = xmlSchemaMode;
|
||||
this.allowDanglingMetacharacters = allowDanglingMetacharacters;
|
||||
this.xmlSchemaMode = capabilities.contains(RegExpCapability.XML_SCHEMA_MODE);
|
||||
this.allowDanglingMetacharacters = capabilities.contains(RegExpCapability.DANGLING_METACHARACTERS);
|
||||
this.allowNestedCharacterClasses = capabilities.contains(RegExpCapability.NESTED_CHARACTER_CLASSES);
|
||||
this.allowOctalNoLeadingZero = capabilities.contains(RegExpCapability.OCTAL_NO_LEADING_ZERO);
|
||||
this.commentMode = capabilities.contains(RegExpCapability.COMMENT_MODE);
|
||||
}
|
||||
|
||||
private void yypushstate(int state) {
|
||||
@@ -58,6 +65,7 @@ import com.intellij.psi.StringEscapesTokenTypes;
|
||||
%xstate QUOTED
|
||||
%xstate EMBRACED
|
||||
%xstate CLASS1
|
||||
%xstate CLASS1PY
|
||||
%state CLASS2
|
||||
%state PROP
|
||||
%xstate OPTIONS
|
||||
@@ -133,7 +141,10 @@ HEX_CHAR=[0-9a-fA-F]
|
||||
So, for 100% compatibility, backrefs > 9 should be resolved by the parser, but
|
||||
I'm not sure if it's worth the effort - at least not atm.
|
||||
*/
|
||||
|
||||
{ESCAPE} [0-7]{3} { if (allowOctalNoLeadingZero) return RegExpTT.OCT_CHAR;
|
||||
return yystate() != CLASS2 ? RegExpTT.BACKREF : RegExpTT.ESC_CHARACTER;
|
||||
}
|
||||
|
||||
{ESCAPE} {DIGITS} { return yystate() != CLASS2 ? RegExpTT.BACKREF : RegExpTT.ESC_CHARACTER; }
|
||||
|
||||
{ESCAPE} "-" { return RegExpTT.ESC_CHARACTER; }
|
||||
@@ -146,7 +157,15 @@ HEX_CHAR=[0-9a-fA-F]
|
||||
|
||||
{ESCAPE} [:letter:] { return StringEscapesTokenTypes.INVALID_CHARACTER_ESCAPE_TOKEN; }
|
||||
{ESCAPE} [\n\b\t\r\f ] { return commentMode ? RegExpTT.CHARACTER : RegExpTT.REDUNDANT_ESCAPE; }
|
||||
|
||||
<CLASS2> {
|
||||
{ESCAPE} {RBRACKET} { if (!allowNestedCharacterClasses) return RegExpTT.CHARACTER;
|
||||
return RegExpTT.REDUNDANT_ESCAPE; }
|
||||
}
|
||||
|
||||
{ESCAPE} {ANY} { return RegExpTT.REDUNDANT_ESCAPE; }
|
||||
|
||||
|
||||
{ESCAPE} { return StringEscapesTokenTypes.INVALID_CHARACTER_ESCAPE_TOKEN; }
|
||||
|
||||
<PROP> {
|
||||
@@ -175,8 +194,37 @@ HEX_CHAR=[0-9a-fA-F]
|
||||
"-" { return RegExpTT.MINUS; }
|
||||
"^" { return RegExpTT.CARET; }
|
||||
|
||||
{LBRACKET} / {RBRACKET} { yypushstate(CLASS1); return RegExpTT.CLASS_BEGIN; }
|
||||
{LBRACKET} { yypushstate(CLASS2); return RegExpTT.CLASS_BEGIN; }
|
||||
<CLASS2> {
|
||||
{LBRACKET} { if (allowNestedCharacterClasses) {
|
||||
yypushstate(CLASS2);
|
||||
return RegExpTT.CLASS_BEGIN;
|
||||
}
|
||||
return RegExpTT.CHARACTER;
|
||||
}
|
||||
|
||||
{LBRACKET} / {RBRACKET} { if (allowNestedCharacterClasses) {
|
||||
yypushstate(CLASS1);
|
||||
return RegExpTT.CLASS_BEGIN;
|
||||
}
|
||||
return RegExpTT.CHARACTER;
|
||||
}
|
||||
}
|
||||
|
||||
{LBRACKET} / {RBRACKET} { yypushstate(CLASS1);
|
||||
return RegExpTT.CLASS_BEGIN; }
|
||||
|
||||
/* Python understands that, Java doesn't */
|
||||
{LBRACKET} / "^" {RBRACKET} { if (!allowNestedCharacterClasses) {
|
||||
yypushstate(CLASS1PY);
|
||||
}
|
||||
else {
|
||||
yypushstate(CLASS2);
|
||||
}
|
||||
return RegExpTT.CLASS_BEGIN;
|
||||
}
|
||||
|
||||
{LBRACKET} { yypushstate(CLASS2);
|
||||
return RegExpTT.CLASS_BEGIN; }
|
||||
|
||||
/* []abc] is legal. The first ] is treated as literal character */
|
||||
<CLASS1> {
|
||||
@@ -184,14 +232,20 @@ HEX_CHAR=[0-9a-fA-F]
|
||||
. { assert false : yytext(); }
|
||||
}
|
||||
|
||||
<CLASS1PY> {
|
||||
"^" { yybegin(CLASS1); return RegExpTT.CARET; }
|
||||
. { assert false : yytext(); }
|
||||
}
|
||||
|
||||
<CLASS2> {
|
||||
{RBRACKET} { yypopstate(); return RegExpTT.CLASS_END; }
|
||||
|
||||
"&&" { return RegExpTT.ANDAND; }
|
||||
"&&" { return allowNestedCharacterClasses ? RegExpTT.ANDAND : RegExpTT.CHARACTER; }
|
||||
[\n\b\t\r\f] { return commentMode ? com.intellij.psi.TokenType.WHITE_SPACE : RegExpTT.ESC_CHARACTER; }
|
||||
{ANY} { return RegExpTT.CHARACTER; }
|
||||
}
|
||||
|
||||
|
||||
<YYINITIAL> {
|
||||
{LPAREN} { return RegExpTT.GROUP_BEGIN; }
|
||||
{RPAREN} { return RegExpTT.GROUP_END; }
|
||||
|
||||
@@ -15,9 +15,8 @@
|
||||
*/
|
||||
package com.intellij.debugger.ui.tree.render;
|
||||
|
||||
import com.intellij.ui.classFilter.ClassFilter;
|
||||
import com.intellij.debugger.DebuggerContext;
|
||||
import com.intellij.debugger.DebuggerBundle;
|
||||
import com.intellij.debugger.DebuggerContext;
|
||||
import com.intellij.debugger.engine.DebugProcessImpl;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluateException;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluationContext;
|
||||
@@ -29,6 +28,7 @@ import com.intellij.openapi.util.InvalidDataException;
|
||||
import com.intellij.openapi.util.JDOMExternalizerUtil;
|
||||
import com.intellij.openapi.util.WriteExternalException;
|
||||
import com.intellij.psi.PsiExpression;
|
||||
import com.intellij.ui.classFilter.ClassFilter;
|
||||
import com.intellij.xdebugger.impl.ui.XDebuggerUIConstants;
|
||||
import com.sun.jdi.*;
|
||||
import org.jdom.Element;
|
||||
@@ -73,7 +73,7 @@ public class ToStringRenderer extends NodeRendererImpl {
|
||||
final Value value = valueDescriptor.getValue();
|
||||
BatchEvaluator.getBatchEvaluator(evaluationContext.getDebugProcess()).invoke(new ToStringCommand(evaluationContext, value) {
|
||||
public void evaluationResult(String message) {
|
||||
valueDescriptor.setValueLabel(message != null ? "\"" + message + "\"" : "");
|
||||
valueDescriptor.setValueLabel(message != null ? "\"" + DebuggerUtilsEx.truncateString(message) + "\"" : "");
|
||||
labelListener.labelChanged();
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.refactoring.listeners.RefactoringElementAdapter;
|
||||
import com.intellij.refactoring.listeners.RefactoringElementListener;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -85,7 +86,7 @@ public class RefactoringListeners {
|
||||
}
|
||||
}
|
||||
|
||||
private static abstract class RenameElement<T extends PsiElement> implements RefactoringElementListener {
|
||||
private static abstract class RenameElement<T extends PsiElement> extends RefactoringElementAdapter {
|
||||
private final Accessor<T> myAccessor;
|
||||
private final String myPath;
|
||||
|
||||
@@ -94,22 +95,15 @@ public class RefactoringListeners {
|
||||
myPath = path;
|
||||
}
|
||||
|
||||
public void elementMoved(@NotNull final PsiElement newElement) {
|
||||
setName((T)newElement);
|
||||
}
|
||||
|
||||
public void elementRenamed(@NotNull final PsiElement newElement) {
|
||||
setName((T)newElement);
|
||||
}
|
||||
|
||||
private void setName(@NotNull T newElement) {
|
||||
String qualifiedName = getQualifiedName(newElement);
|
||||
public void elementRenamedOrMoved(@NotNull final PsiElement newElement) {
|
||||
T newElement1 = (T)newElement;
|
||||
String qualifiedName = getQualifiedName(newElement1);
|
||||
if (myPath.length() > 0) {
|
||||
qualifiedName = qualifiedName + "." + myPath;
|
||||
newElement = findNewElement(newElement, qualifiedName);
|
||||
newElement1 = findNewElement(newElement1, qualifiedName);
|
||||
}
|
||||
if (newElement != null) {
|
||||
myAccessor.setPsiElement(newElement);
|
||||
if (newElement1 != null) {
|
||||
myAccessor.setPsiElement(newElement1);
|
||||
}
|
||||
else {
|
||||
myAccessor.setName(qualifiedName);
|
||||
|
||||
+2
-14
@@ -18,13 +18,10 @@ package com.intellij.execution.ui;
|
||||
import com.intellij.execution.ExecutionBundle;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.ide.CopyPasteManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.ui.PopupHandler;
|
||||
import com.intellij.util.ui.EmptyClipboardOwner;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.datatransfer.Clipboard;
|
||||
import java.awt.datatransfer.StringSelection;
|
||||
|
||||
public class ConfigurationArgumentsHelpArea extends JPanel {
|
||||
@@ -68,17 +65,8 @@ public class ConfigurationArgumentsHelpArea extends JPanel {
|
||||
}
|
||||
|
||||
public void actionPerformed(final AnActionEvent e) {
|
||||
try {
|
||||
final StringSelection contents = new StringSelection(myHelpArea.getText().trim());
|
||||
final Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext());
|
||||
if (project == null) {
|
||||
final Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
|
||||
clipboard.setContents(contents, EmptyClipboardOwner.INSTANCE);
|
||||
} else {
|
||||
CopyPasteManager.getInstance().setContents(contents);
|
||||
}
|
||||
} catch(Exception ex) {
|
||||
}
|
||||
final StringSelection contents = new StringSelection(myHelpArea.getText().trim());
|
||||
CopyPasteManager.getInstance().setContents(contents);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.intellij.ide.palette.impl;
|
||||
import com.intellij.ide.IdeBundle;
|
||||
import com.intellij.ide.palette.PaletteDragEventListener;
|
||||
import com.intellij.ide.palette.PaletteItem;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.components.ProjectComponent;
|
||||
import com.intellij.openapi.fileEditor.FileEditorManager;
|
||||
import com.intellij.openapi.fileEditor.FileEditorManagerEvent;
|
||||
@@ -60,20 +61,22 @@ public class PaletteManager implements ProjectComponent {
|
||||
}
|
||||
|
||||
public void projectOpened() {
|
||||
StartupManager.getInstance(myProject).registerPostStartupActivity(new Runnable() {
|
||||
public void run() {
|
||||
myPaletteWindow = new PaletteWindow(myProject);
|
||||
myPaletteToolWindow = ToolWindowManager.getInstance(myProject).registerToolWindow(IdeBundle.message("toolwindow.palette"),
|
||||
myPaletteWindow,
|
||||
ToolWindowAnchor.RIGHT,
|
||||
myProject,
|
||||
true, false);
|
||||
myPaletteToolWindow.setIcon(IconLoader.getIcon("/general/toolWindowPalette.png"));
|
||||
myPaletteToolWindow.setAvailable(false, null);
|
||||
final MyFileEditorManagerListener myListener = new MyFileEditorManagerListener();
|
||||
myFileEditorManager.addFileEditorManagerListener(myListener, myProject);
|
||||
}
|
||||
});
|
||||
if (!ApplicationManager.getApplication().isHeadlessEnvironment()) {
|
||||
StartupManager.getInstance(myProject).registerPostStartupActivity(new Runnable() {
|
||||
public void run() {
|
||||
myPaletteWindow = new PaletteWindow(myProject);
|
||||
myPaletteToolWindow = ToolWindowManager.getInstance(myProject).registerToolWindow(IdeBundle.message("toolwindow.palette"),
|
||||
myPaletteWindow,
|
||||
ToolWindowAnchor.RIGHT,
|
||||
myProject,
|
||||
true);
|
||||
myPaletteToolWindow.setIcon(IconLoader.getIcon("/general/toolWindowPalette.png"));
|
||||
myPaletteToolWindow.setAvailable(false, null);
|
||||
final MyFileEditorManagerListener myListener = new MyFileEditorManagerListener();
|
||||
myFileEditorManager.addFileEditorManagerListener(myListener, myProject);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void projectClosed() {
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/testSrc" isTestSource="true" />
|
||||
</content>
|
||||
<orderEntry type="module" module-name="boot" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
|
||||
@@ -206,10 +206,10 @@ public class ExceptionUtil {
|
||||
PsiClassType exception = getUnhandledException(statement, topElement);
|
||||
unhandledExceptions = exception == null ? Collections.<PsiClassType>emptyList() : Collections.singletonList(exception);
|
||||
}
|
||||
else if (element instanceof PsiCodeBlock
|
||||
&& element.getParent() instanceof PsiMethod
|
||||
&& ((PsiMethod)element.getParent()).isConstructor()
|
||||
&& !firstStatementIsConstructorCall((PsiCodeBlock)element)) {
|
||||
else if (element instanceof PsiCodeBlock &&
|
||||
element.getParent() instanceof PsiMethod &&
|
||||
((PsiMethod)element.getParent()).isConstructor() &&
|
||||
!firstStatementIsConstructorCall((PsiCodeBlock)element)) {
|
||||
// there is implicit parent constructor call
|
||||
final PsiMethod constructor = (PsiMethod)element.getParent();
|
||||
final PsiClass aClass = constructor.getContainingClass();
|
||||
@@ -246,6 +246,16 @@ public class ExceptionUtil {
|
||||
unhandledExceptions = unhandled;
|
||||
}
|
||||
|
||||
if (element instanceof PsiResource) {
|
||||
final List<PsiClassType> unhandled = getUnhandledCloserExceptions((PsiResource)element, topElement);
|
||||
if (unhandledExceptions == null) {
|
||||
unhandledExceptions = unhandled;
|
||||
}
|
||||
else {
|
||||
unhandledExceptions.addAll(unhandled);
|
||||
}
|
||||
}
|
||||
|
||||
if (unhandledExceptions != null) {
|
||||
if (foundExceptions == null) {
|
||||
foundExceptions = new THashSet<PsiClassType>();
|
||||
@@ -309,19 +319,36 @@ public class ExceptionUtil {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static List<PsiClassType> getUnhandledExceptions(PsiCallExpression methodCall, PsiElement topElement) {
|
||||
public static List<PsiClassType> getUnhandledExceptions(final PsiCallExpression methodCall, final PsiElement topElement) {
|
||||
final JavaResolveResult result = methodCall.resolveMethodGenerics();
|
||||
PsiMethod method = (PsiMethod)result.getElement();
|
||||
return getUnhandledExceptions(method, methodCall, topElement,
|
||||
ApplicationManager.getApplication().runReadAction(new Computable<PsiSubstitutor>() {
|
||||
public PsiSubstitutor compute() {
|
||||
return result.getSubstitutor();
|
||||
}
|
||||
}));
|
||||
final PsiMethod method = (PsiMethod)result.getElement();
|
||||
final PsiSubstitutor substitutor = ApplicationManager.getApplication().runReadAction(new Computable<PsiSubstitutor>() {
|
||||
public PsiSubstitutor compute() {
|
||||
return result.getSubstitutor();
|
||||
}
|
||||
});
|
||||
return getUnhandledExceptions(method, methodCall, topElement, substitutor);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static List<PsiClassType> getUnhandledCloserExceptions(final PsiResource resource, final PsiElement topElement) {
|
||||
final PsiType resourceType = resource.getType();
|
||||
if (resourceType instanceof PsiClassType) {
|
||||
final PsiClass resourceClass = ((PsiClassType)resourceType).resolve();
|
||||
if (resourceClass != null) {
|
||||
final PsiMethod[] closers = resourceClass.findMethodsByName("close", false);
|
||||
for (final PsiMethod method : closers) {
|
||||
if (method.getParameterList().getParametersCount() == 0) {
|
||||
return getUnhandledExceptions(method, resource, topElement, PsiSubstitutor.EMPTY);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiClassType getUnhandledException(PsiThrowStatement throwStatement, PsiElement topElement){
|
||||
public static PsiClassType getUnhandledException(PsiThrowStatement throwStatement, PsiElement topElement) {
|
||||
final PsiExpression exception = throwStatement.getException();
|
||||
if (exception != null) {
|
||||
final PsiType type = exception.getType();
|
||||
@@ -335,7 +362,6 @@ public class ExceptionUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
private static List<PsiClassType> getUnhandledExceptions(PsiMethod method,
|
||||
PsiElement element,
|
||||
|
||||
@@ -953,7 +953,7 @@ public class ExpectedTypesProvider {
|
||||
if (index >= params.length) {
|
||||
return TailType.NONE;
|
||||
}
|
||||
if (index == params.length - 1) {
|
||||
if (index == params.length - 1 || index == params.length - 2 && params[index + 1].isVarArgs()) {
|
||||
//myTailType = CompletionUtil.NONE_TAIL;
|
||||
final PsiElement call = argument.getParent().getParent();
|
||||
if (call instanceof JspMethodCall) return TailType.NONE;
|
||||
|
||||
+22
-31
@@ -31,7 +31,6 @@ import com.intellij.psi.scope.util.PsiScopesUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -39,16 +38,15 @@ import java.util.Map;
|
||||
|
||||
import static com.intellij.patterns.PsiJavaPatterns.psiClass;
|
||||
import static com.intellij.patterns.PsiJavaPatterns.psiElement;
|
||||
import static com.intellij.patterns.StandardPatterns.not;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class BasicExpressionCompletionContributor extends ExpressionSmartCompletionContributor{
|
||||
public class BasicExpressionCompletionContributor {
|
||||
public static final ElementPattern<PsiElement> AFTER_DOT = psiElement().afterLeaf(".");
|
||||
|
||||
private static void addKeyword(final CompletionResultSet result, final PsiElement element, final String s) {
|
||||
result.addElement(createKeywordLookupItem(element, s));
|
||||
private static void addKeyword(final Consumer<LookupElement> result, final PsiElement element, final String s) {
|
||||
result.consume(createKeywordLookupItem(element, s));
|
||||
}
|
||||
|
||||
public static LookupElement createKeywordLookupItem(final PsiElement element, final String s) {
|
||||
@@ -61,31 +59,29 @@ public class BasicExpressionCompletionContributor extends ExpressionSmartComplet
|
||||
}
|
||||
}
|
||||
|
||||
public static void fillCompletionVariants(JavaSmartCompletionParameters parameters,
|
||||
final Consumer<LookupElement> result,
|
||||
PrefixMatcher matcher) {
|
||||
final PsiElement element = parameters.getPosition();
|
||||
if (PsiJavaPatterns.psiElement().afterLeaf(
|
||||
PsiJavaPatterns.psiElement().withText(".").afterLeaf(
|
||||
PsiJavaPatterns.psiElement().withParent(
|
||||
PsiJavaPatterns.psiElement().referencing(psiClass())))).accepts(element)) {
|
||||
addKeyword(result, element, PsiKeyword.CLASS);
|
||||
addKeyword(result, element, PsiKeyword.THIS);
|
||||
|
||||
public BasicExpressionCompletionContributor() {
|
||||
extend(PsiJavaPatterns.psiElement().afterLeaf(
|
||||
PsiJavaPatterns.psiElement().withText(".").afterLeaf(
|
||||
PsiJavaPatterns.psiElement().withParent(
|
||||
PsiJavaPatterns.psiElement().referencing(psiClass())))), new CompletionProvider<JavaSmartCompletionParameters>() {
|
||||
public void addCompletions(@NotNull final JavaSmartCompletionParameters parameters, final ProcessingContext context, @NotNull final CompletionResultSet result) {
|
||||
final PsiElement element = parameters.getPosition();
|
||||
addKeyword(result, element, PsiKeyword.CLASS);
|
||||
addKeyword(result, element, PsiKeyword.THIS);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
if (!AFTER_DOT.accepts(element)) {
|
||||
CollectionsUtilityMethodsProvider.addCompletions(parameters, result);
|
||||
ClassLiteralGetter.addCompletions(parameters, result, matcher);
|
||||
|
||||
extend(not(AFTER_DOT), new CollectionsUtilityMethodsProvider());
|
||||
extend(not(AFTER_DOT), new ClassLiteralGetter());
|
||||
|
||||
extend(not(AFTER_DOT), new CompletionProvider<JavaSmartCompletionParameters>() {
|
||||
protected void addCompletions(@NotNull final JavaSmartCompletionParameters parameters, final ProcessingContext context, @NotNull final CompletionResultSet result) {
|
||||
final PsiElement position = parameters.getPosition();
|
||||
final PsiElement position = parameters.getPosition();
|
||||
final PsiType expectedType = parameters.getExpectedType();
|
||||
|
||||
for (final TemplateImpl template : TemplateSettings.getInstance().getTemplates()) {
|
||||
if (!template.isDeactivated() && template.getTemplateContext().isEnabled(new SmartCompletionContextType())) {
|
||||
result.addElement(new SmartCompletionTemplateItem(template, position));
|
||||
result.consume(new SmartCompletionTemplateItem(template, position));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,17 +96,12 @@ public class BasicExpressionCompletionContributor extends ExpressionSmartComplet
|
||||
}
|
||||
|
||||
for (final PsiExpression expression : ThisGetter.getThisExpressionVariants(position)) {
|
||||
result.addElement(new ExpressionLookupItem(expression));
|
||||
result.consume(new ExpressionLookupItem(expression));
|
||||
}
|
||||
}
|
||||
|
||||
processDataflowExpressionTypes(position, expectedType, result.getPrefixMatcher(), new Consumer<LookupElement>() {
|
||||
public void consume(LookupElement decorator) {
|
||||
result.addElement(decorator);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
processDataflowExpressionTypes(position, expectedType, matcher, result);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
+13
-11
@@ -15,19 +15,21 @@
|
||||
*/
|
||||
package com.intellij.codeInsight.completion;
|
||||
|
||||
import com.intellij.codeInsight.lookup.LookupItem;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import com.intellij.psi.*;
|
||||
import static com.intellij.psi.CommonClassNames.*;
|
||||
import com.intellij.codeInsight.lookup.AutoCompletionPolicy;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.util.Consumer;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import static com.intellij.psi.CommonClassNames.*;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
class CollectionsUtilityMethodsProvider extends CompletionProvider<JavaSmartCompletionParameters> {
|
||||
public void addCompletions(@NotNull final JavaSmartCompletionParameters parameters, final ProcessingContext context, @NotNull final CompletionResultSet result) {
|
||||
class CollectionsUtilityMethodsProvider {
|
||||
public static void addCompletions(@NotNull final JavaSmartCompletionParameters parameters,
|
||||
@NotNull final Consumer<LookupElement> result) {
|
||||
final PsiElement element = parameters.getPosition();
|
||||
|
||||
final PsiElement parent = element.getParent();
|
||||
@@ -63,7 +65,7 @@ class CollectionsUtilityMethodsProvider extends CompletionProvider<JavaSmartComp
|
||||
|
||||
}
|
||||
|
||||
private static void addCollectionMethod(final CompletionResultSet result, final PsiType expectedType,
|
||||
private static void addCollectionMethod(final Consumer<LookupElement> result, final PsiType expectedType,
|
||||
final PsiType defaultType, final String baseClassName,
|
||||
@NonNls final String method, @NotNull final PsiClass collectionsClass) {
|
||||
if (isClassType(expectedType, baseClassName) || isClassType(expectedType, JAVA_UTIL_COLLECTION)) {
|
||||
@@ -73,7 +75,7 @@ class CollectionsUtilityMethodsProvider extends CompletionProvider<JavaSmartComp
|
||||
}
|
||||
}
|
||||
|
||||
private static void addMethodItem(CompletionResultSet result, PsiType expectedType, String methodName, PsiClass containingClass) {
|
||||
private static void addMethodItem(Consumer<LookupElement> result, PsiType expectedType, String methodName, PsiClass containingClass) {
|
||||
final PsiMethod[] methods = containingClass.findMethodsByName(methodName, false);
|
||||
if (methods.length == 0) {
|
||||
return;
|
||||
@@ -83,7 +85,7 @@ class CollectionsUtilityMethodsProvider extends CompletionProvider<JavaSmartComp
|
||||
final JavaMethodCallElement item = new JavaMethodCallElement(method);
|
||||
JavaCompletionUtil.qualify(item).setAutoCompletionPolicy(AutoCompletionPolicy.NEVER_AUTOCOMPLETE);
|
||||
item.setInferenceSubstitutor(SmartCompletionDecorator.calculateMethodReturnTypeSubstitutor(method, expectedType));
|
||||
result.addElement(item);
|
||||
result.consume(item);
|
||||
}
|
||||
|
||||
private static boolean isClassType(final PsiType type, final String className) {
|
||||
|
||||
@@ -21,7 +21,6 @@ import com.intellij.codeInsight.TailType;
|
||||
import com.intellij.codeInsight.TailTypes;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.LookupItem;
|
||||
import com.intellij.featureStatistics.FeatureUsageTracker;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
@@ -31,7 +30,6 @@ import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -73,20 +71,6 @@ public class DefaultInsertHandler extends TemplateInsertHandler implements Clone
|
||||
handleParentheses(false, false, tailType, context, state);
|
||||
handleBrackets(item, document, state);
|
||||
|
||||
if (item.getObject() instanceof PsiVariable) {
|
||||
if (completionChar == '!' && PsiType.BOOLEAN.isAssignableFrom(((PsiVariable) item.getObject()).getType())) {
|
||||
PsiDocumentManager.getInstance(project).commitDocument(document);
|
||||
final PsiReferenceExpression ref =
|
||||
PsiTreeUtil.findElementOfClassAtOffset(file, state.tailOffset - 1, PsiReferenceExpression.class, false);
|
||||
if (ref != null) {
|
||||
FeatureUsageTracker.getInstance().triggerFeatureUsed(CodeCompletionFeatures.EXCLAMATION_FINISH);
|
||||
document.insertString(ref.getTextRange().getStartOffset(), "!");
|
||||
state.caretOffset++;
|
||||
state.tailOffset++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
context.setTailOffset(state.tailOffset);
|
||||
state.caretOffset = processTail(tailType, state.caretOffset, state.tailOffset, editor);
|
||||
editor.getSelectionModel().removeSelection();
|
||||
|
||||
-47
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInsight.completion;
|
||||
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.patterns.ElementPattern;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public abstract class ExpressionSmartCompletionContributor extends AbstractCompletionContributor<JavaSmartCompletionParameters> {
|
||||
|
||||
private final List<Pair<ElementPattern<? extends PsiElement>, CompletionProvider<JavaSmartCompletionParameters>>> myList =
|
||||
new ArrayList<Pair<ElementPattern<? extends PsiElement>, CompletionProvider<JavaSmartCompletionParameters>>>();
|
||||
|
||||
public final void extend(final ElementPattern<? extends PsiElement> place, CompletionProvider<JavaSmartCompletionParameters> provider) {
|
||||
myList.add(new Pair<ElementPattern<? extends PsiElement>, CompletionProvider<JavaSmartCompletionParameters>>(place, provider));
|
||||
}
|
||||
|
||||
public void fillCompletionVariants(final JavaSmartCompletionParameters parameters, CompletionResultSet result) {
|
||||
for (final Pair<ElementPattern<? extends PsiElement>, CompletionProvider<JavaSmartCompletionParameters>> pair : myList) {
|
||||
final ProcessingContext context = new ProcessingContext();
|
||||
if (pair.first.accepts(parameters.getPosition(), context)) {
|
||||
pair.second.addCompletionVariants(parameters, context, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -56,7 +56,7 @@ public class JavaClassNameCompletionContributor extends CompletionContributor {
|
||||
CompletionService.getCompletionService().setAdvertisementText(CompletionBundle.message("completion.class.name.hint.2", getActionShortcut(IdeActions.ACTION_CLASS_NAME_COMPLETION)));
|
||||
}
|
||||
|
||||
final CompletionResultSet result = JavaCompletionContributor.addJavaSorting(parameters, _result);
|
||||
final CompletionResultSet result = JavaCompletionSorting.addJavaSorting(parameters, _result);
|
||||
|
||||
final PsiElement insertedElement = parameters.getPosition();
|
||||
|
||||
|
||||
+1
-14
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package com.intellij.codeInsight.completion;
|
||||
|
||||
import com.intellij.codeInsight.ExpectedTypeInfo;
|
||||
import com.intellij.codeInsight.TailType;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.ImportClassFix;
|
||||
import com.intellij.codeInsight.hint.ShowParameterInfoHandler;
|
||||
@@ -182,7 +181,7 @@ public class JavaCompletionContributor extends CompletionContributor {
|
||||
}
|
||||
|
||||
|
||||
final CompletionResultSet result = addJavaSorting(parameters, _result);
|
||||
final CompletionResultSet result = JavaCompletionSorting.addJavaSorting(parameters, _result);
|
||||
|
||||
if (ANNOTATION_ATTRIBUTE_NAME.accepts(position)) {
|
||||
completeAnnotationAttributeName(result, position, parameters);
|
||||
@@ -207,18 +206,6 @@ public class JavaCompletionContributor extends CompletionContributor {
|
||||
result.stopHere();
|
||||
}
|
||||
|
||||
public static CompletionResultSet addJavaSorting(CompletionParameters parameters, CompletionResultSet result) {
|
||||
final boolean afterNew = JavaSmartCompletionContributor.AFTER_NEW.accepts(parameters.getPosition());
|
||||
final ExpectedTypeInfo[] expectedTypes = afterNew ? JavaSmartCompletionContributor.getExpectedTypes(parameters) : ExpectedTypeInfo.EMPTY_ARRAY;
|
||||
return result.withRelevanceSorter(CompletionSorter.defaultSorter(parameters).weighBefore("liftShorter", new LookupElementWeigher("expectedAfterNew") {
|
||||
@NotNull
|
||||
@Override
|
||||
public Comparable weigh(@NotNull LookupElement element) {
|
||||
return -((Enum)PreferExpectedTypeWeigher.weigh(element, expectedTypes)).ordinal();
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
public static void addAllClasses(CompletionParameters parameters,
|
||||
final CompletionResultSet result,
|
||||
PsiElement position,
|
||||
|
||||
@@ -39,6 +39,7 @@ import com.intellij.psi.jsp.JspElementType;
|
||||
import com.intellij.psi.scope.ElementClassFilter;
|
||||
import com.intellij.psi.templateLanguages.OuterLanguageElement;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
@@ -503,8 +504,9 @@ public class JavaCompletionData extends JavaAwareCompletionData{
|
||||
new ParentElementFilter(new ClassFilter(PsiSwitchLabelStatement.class)),
|
||||
new LeftNeighbour(new OrFilter(
|
||||
new ParentElementFilter(new ClassFilter(PsiSwitchStatement.class), 2),
|
||||
new AndFilter(new TextFilter(";", "}", ":"),new ParentElementFilter(new ClassFilter(PsiSwitchStatement.class), 3)
|
||||
))))));
|
||||
new AndFilter(new TextFilter(";", ":"),new ParentElementFilter(new ClassFilter(PsiSwitchStatement.class), 3)),
|
||||
new AndFilter(new TextFilter("}"), new ParentElementFilter(new ClassFilter(PsiSwitchStatement.class), 4))
|
||||
)))));
|
||||
variant.includeScopeClass(PsiElement.class, false);
|
||||
variant.addCompletion(PsiKeyword.CASE, TailType.SPACE);
|
||||
variant.addCompletion(PsiKeyword.DEFAULT, TailType.CASE_COLON);
|
||||
@@ -549,12 +551,19 @@ public class JavaCompletionData extends JavaAwareCompletionData{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillCompletions(CompletionParameters parameters, CompletionResultSet result) {
|
||||
public void fillCompletions(CompletionParameters parameters, final CompletionResultSet result) {
|
||||
final PsiElement position = parameters.getPosition();
|
||||
if (PsiTreeUtil.getParentOfType(position, PsiComment.class, false) != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final PsiExpressionStatement expressionStatement = PsiTreeUtil.getParentOfType(position, PsiExpressionStatement.class);
|
||||
if (expressionStatement != null && expressionStatement.getTextRange().getStartOffset() == position.getTextRange().getStartOffset()) {
|
||||
if (!psiElement().withSuperParent(2, PsiSwitchStatement.class).accepts(expressionStatement)) {
|
||||
result.addElement(createKeyword(position, PsiKeyword.FINAL));
|
||||
}
|
||||
}
|
||||
|
||||
if (SUPER_OR_THIS_PATTERN.accepts(position)) {
|
||||
if (AFTER_DOT.accepts(position) && !isInsideQualifierClass(position)) return;
|
||||
|
||||
@@ -605,7 +614,7 @@ public class JavaCompletionData extends JavaAwareCompletionData{
|
||||
if (!PsiKeyword.VOID.equals(primitiveType)) {
|
||||
result.addElement(TailTypeDecorator.withTail(createKeyword(position, primitiveType), TailType.SPACE));
|
||||
}
|
||||
result.addElement(TailTypeDecorator.withTail(createKeyword(position, PsiKeyword.FINAL), TailType.SPACE));
|
||||
//result.addElement(TailTypeDecorator.withTail(createKeyword(position, PsiKeyword.FINAL), TailType.SPACE));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -630,7 +639,12 @@ public class JavaCompletionData extends JavaAwareCompletionData{
|
||||
!(position.getParent() instanceof PsiLiteralExpression) &&
|
||||
!(position.getParent().getParent() instanceof PsiSwitchLabelStatement)) {
|
||||
for (final ExpectedTypeInfo info : JavaSmartCompletionContributor.getExpectedTypes(parameters)) {
|
||||
MembersGetter.addMembers(position, info.getDefaultType(), result);
|
||||
MembersGetter.addMembers(position, info.getDefaultType(), new Consumer<LookupElement>() {
|
||||
@Override
|
||||
public void consume(LookupElement element) {
|
||||
result.addElement(element);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,592 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.completion;
|
||||
|
||||
import com.intellij.codeInsight.ExpectedTypeInfo;
|
||||
import com.intellij.codeInsight.ExpectedTypeInfoImpl;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.LookupElementWeigher;
|
||||
import com.intellij.codeInsight.lookup.PsiTypeLookupItem;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.patterns.PsiJavaPatterns;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.codeStyle.NameUtil;
|
||||
import com.intellij.psi.codeStyle.VariableKind;
|
||||
import com.intellij.psi.filters.ElementFilter;
|
||||
import com.intellij.psi.javadoc.PsiDocComment;
|
||||
import com.intellij.psi.search.searches.DeepestSuperMethodsSearch;
|
||||
import com.intellij.psi.util.PropertyUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class JavaCompletionSorting {
|
||||
private JavaCompletionSorting() {
|
||||
}
|
||||
|
||||
public static CompletionResultSet addJavaSorting(final CompletionParameters parameters, CompletionResultSet result) {
|
||||
final PsiElement position = parameters.getPosition();
|
||||
final ExpectedTypeInfo[] expectedTypes = PsiJavaPatterns.psiElement().beforeLeaf(PsiJavaPatterns.psiElement().withText(".")).accepts(position) ? ExpectedTypeInfo.EMPTY_ARRAY : JavaSmartCompletionContributor.getExpectedTypes(parameters);
|
||||
final CompletionType type = parameters.getCompletionType();
|
||||
final boolean smart = type == CompletionType.SMART;
|
||||
final boolean afterNew = JavaSmartCompletionContributor.AFTER_NEW.accepts(position);
|
||||
|
||||
List<LookupElementWeigher> afterNegativeStats = new ArrayList<LookupElementWeigher>();
|
||||
ContainerUtil.addIfNotNull(afterNegativeStats, smart ? new PreferDefaultTypeWeigher(expectedTypes, parameters) : preferStatics(position));
|
||||
afterNegativeStats.add(new PreferLocalVariablesLiteralsAndAnnoMethodsWeigher(type));
|
||||
ContainerUtil.addIfNotNull(afterNegativeStats, recursion(parameters, expectedTypes));
|
||||
if (!smart && !afterNew) {
|
||||
afterNegativeStats.add(new PreferExpected(false, expectedTypes));
|
||||
}
|
||||
afterNegativeStats.add(new PreferSimilarlyEnding(expectedTypes));
|
||||
|
||||
List<LookupElementWeigher> afterProximity = new ArrayList<LookupElementWeigher>();
|
||||
afterProximity.add(new PreferContainingSameWords(expectedTypes));
|
||||
if (smart) {
|
||||
afterProximity.add(new PreferFieldsAndGetters());
|
||||
}
|
||||
afterProximity.add(new PreferShorter(expectedTypes));
|
||||
|
||||
CompletionSorter sorter = CompletionSorter.defaultSorter(parameters);
|
||||
if (!smart && afterNew) {
|
||||
sorter = sorter.weighBefore("liftShorter", new PreferExpected(true, expectedTypes));
|
||||
}
|
||||
sorter = sorter.weighAfter("negativeStats", afterNegativeStats.toArray(new LookupElementWeigher[afterNegativeStats.size()]));
|
||||
sorter = sorter.weighAfter("prefix", new PreferNonGeneric(), new PreferAccessible(position), new PreferSimple(), new PreferEnumConstants(parameters));
|
||||
sorter = sorter.weighAfter("proximity", afterProximity.toArray(new LookupElementWeigher[afterProximity.size()]));
|
||||
return result.withRelevanceSorter(sorter);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static LookupElementWeigher recursion(CompletionParameters parameters, final ExpectedTypeInfo[] expectedInfos) {
|
||||
|
||||
final PsiElement position = parameters.getPosition();
|
||||
final PsiMethod positionMethod = PsiTreeUtil.getParentOfType(position, PsiMethod.class, false);
|
||||
final ElementFilter filter = JavaCompletionUtil.recursionFilter(position);
|
||||
final PsiMethodCallExpression expression = PsiTreeUtil.getParentOfType(position, PsiMethodCallExpression.class, true, PsiClass.class);
|
||||
final PsiReferenceExpression reference = expression != null ? expression.getMethodExpression() : PsiTreeUtil.getParentOfType(position, PsiReferenceExpression.class);
|
||||
if (reference == null) return null;
|
||||
|
||||
return new RecursionWeigher(filter, position, reference, expression, positionMethod, expectedInfos);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static LookupElementWeigher preferStatics(PsiElement position) {
|
||||
if (PsiTreeUtil.getParentOfType(position, PsiDocComment.class) != null) {
|
||||
return null;
|
||||
}
|
||||
if (position.getParent() instanceof PsiReferenceExpression) {
|
||||
final PsiReferenceExpression refExpr = (PsiReferenceExpression)position.getParent();
|
||||
final PsiElement qualifier = refExpr.getQualifier();
|
||||
if (qualifier == null) {
|
||||
return null;
|
||||
}
|
||||
if (!(qualifier instanceof PsiJavaCodeReferenceElement) || !(((PsiJavaCodeReferenceElement)qualifier).resolve() instanceof PsiClass)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return new LookupElementWeigher("statics") {
|
||||
@NotNull
|
||||
@Override
|
||||
public Comparable weigh(@NotNull LookupElement element) {
|
||||
final Object o = element.getObject();
|
||||
if (!(o instanceof PsiMember)) return 0;
|
||||
|
||||
if (((PsiMember)o).hasModifierProperty(PsiModifier.STATIC)) {
|
||||
if (o instanceof PsiMethod) return -5;
|
||||
if (o instanceof PsiField) return -4;
|
||||
}
|
||||
|
||||
if (o instanceof PsiClass) return -3;
|
||||
|
||||
//instance method or field
|
||||
return -5;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static ExpectedTypeMatching getExpectedTypeMatching(LookupElement item, ExpectedTypeInfo[] expectedInfos) {
|
||||
PsiType itemType = JavaCompletionUtil.getLookupElementType(item);
|
||||
if (itemType == null) return ExpectedTypeMatching.normal;
|
||||
|
||||
for (final ExpectedTypeInfo expectedInfo : expectedInfos) {
|
||||
final PsiType defaultType = expectedInfo.getDefaultType();
|
||||
final PsiType expectedType = expectedInfo.getType();
|
||||
if (!expectedType.isValid()) {
|
||||
return ExpectedTypeMatching.normal;
|
||||
}
|
||||
|
||||
if (defaultType != expectedType && defaultType.isAssignableFrom(itemType)) {
|
||||
return ExpectedTypeMatching.ofDefaultType;
|
||||
}
|
||||
if (expectedType.isAssignableFrom(itemType)) {
|
||||
return ExpectedTypeMatching.expected;
|
||||
}
|
||||
}
|
||||
|
||||
return ExpectedTypeMatching.normal;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String getLookupObjectName(Object o) {
|
||||
if (o instanceof PsiVariable) {
|
||||
final PsiVariable variable = (PsiVariable)o;
|
||||
JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(variable.getProject());
|
||||
VariableKind variableKind = codeStyleManager.getVariableKind(variable);
|
||||
return codeStyleManager.variableNameToPropertyName(variable.getName(), variableKind);
|
||||
}
|
||||
if (o instanceof PsiMethod) {
|
||||
return ((PsiMethod)o).getName();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static int getNameEndMatchingDegree(final String name, ExpectedTypeInfo[] expectedInfos, String prefix) {
|
||||
int res = 0;
|
||||
if (name != null && expectedInfos != null) {
|
||||
if (prefix.equals(name)) {
|
||||
res = Integer.MAX_VALUE;
|
||||
} else {
|
||||
final List<String> words = NameUtil.nameToWordsLowerCase(name);
|
||||
final List<String> wordsNoDigits = NameUtil.nameToWordsLowerCase(truncDigits(name));
|
||||
int max1 = calcMatch(words, 0, expectedInfos);
|
||||
max1 = calcMatch(wordsNoDigits, max1, expectedInfos);
|
||||
res = max1;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
private static String truncDigits(String name){
|
||||
int count = name.length() - 1;
|
||||
while (count >= 0) {
|
||||
char c = name.charAt(count);
|
||||
if (!Character.isDigit(c)) break;
|
||||
count--;
|
||||
}
|
||||
return name.substring(0, count + 1);
|
||||
}
|
||||
|
||||
private static int calcMatch(final List<String> words, int max, ExpectedTypeInfo[] myExpectedInfos) {
|
||||
for (ExpectedTypeInfo myExpectedInfo : myExpectedInfos) {
|
||||
String expectedName = ((ExpectedTypeInfoImpl)myExpectedInfo).expectedName;
|
||||
if (expectedName == null) continue;
|
||||
max = calcMatch(expectedName, words, max);
|
||||
max = calcMatch(truncDigits(expectedName), words, max);
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
private static int calcMatch(final String expectedName, final List<String> words, int max) {
|
||||
if (expectedName == null) return max;
|
||||
|
||||
String[] expectedWords = NameUtil.nameToWords(expectedName);
|
||||
int limit = Math.min(words.size(), expectedWords.length);
|
||||
for (int i = 0; i < limit; i++) {
|
||||
String word = words.get(words.size() - i - 1);
|
||||
String expectedWord = expectedWords[expectedWords.length - i - 1];
|
||||
if (word.equalsIgnoreCase(expectedWord)) {
|
||||
max = Math.max(max, i + 1);
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
private static class PreferDefaultTypeWeigher extends LookupElementWeigher {
|
||||
private final PsiTypeParameter myTypeParameter;
|
||||
private final ExpectedTypeInfo[] myExpectedTypes;
|
||||
private final CompletionParameters myParameters;
|
||||
private final CompletionLocation myLocation;
|
||||
|
||||
public PreferDefaultTypeWeigher(ExpectedTypeInfo[] expectedTypes, CompletionParameters parameters) {
|
||||
super("defaultType");
|
||||
myExpectedTypes = expectedTypes;
|
||||
myParameters = parameters;
|
||||
|
||||
final Pair<PsiClass,Integer> pair = JavaSmartCompletionContributor.getTypeParameterInfo(parameters.getPosition());
|
||||
myTypeParameter = pair == null ? null : pair.first.getTypeParameters()[pair.second.intValue()];
|
||||
myLocation = new CompletionLocation(myParameters);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Comparable weigh(@NotNull LookupElement item) {
|
||||
final Object object = item.getObject();
|
||||
|
||||
if (object instanceof PsiClass) {
|
||||
if (myTypeParameter != null && object.equals(PsiUtil.resolveClassInType(TypeConversionUtil.typeParameterErasure(myTypeParameter)))) {
|
||||
return MyResult.exactlyExpected;
|
||||
}
|
||||
}
|
||||
|
||||
if (myExpectedTypes == null) return MyResult.normal;
|
||||
|
||||
PsiType itemType = JavaCompletionUtil.getLookupElementType(item);
|
||||
if (itemType == null || !itemType.isValid()) return MyResult.normal;
|
||||
|
||||
if (object instanceof PsiClass) {
|
||||
for (final ExpectedTypeInfo info : myExpectedTypes) {
|
||||
if (TypeConversionUtil.erasure(info.getType().getDeepComponentType()).equals(TypeConversionUtil.erasure(itemType))) {
|
||||
return AbstractExpectedTypeSkipper.skips(item, myLocation) ? MyResult.expectedNoSelect : MyResult.exactlyExpected;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (final ExpectedTypeInfo expectedInfo : myExpectedTypes) {
|
||||
final PsiType defaultType = expectedInfo.getDefaultType();
|
||||
final PsiType expectedType = expectedInfo.getType();
|
||||
if (!expectedType.isValid()) {
|
||||
return MyResult.normal;
|
||||
}
|
||||
|
||||
if (defaultType != expectedType) {
|
||||
if (defaultType.equals(itemType)) {
|
||||
return MyResult.exactlyDefault;
|
||||
}
|
||||
|
||||
if (defaultType.isAssignableFrom(itemType)) {
|
||||
return MyResult.ofDefaultType;
|
||||
}
|
||||
}
|
||||
if (PsiType.VOID.equals(itemType) && PsiType.VOID.equals(expectedType)) {
|
||||
return MyResult.exactlyExpected;
|
||||
}
|
||||
}
|
||||
|
||||
return MyResult.normal;
|
||||
}
|
||||
|
||||
private enum MyResult {
|
||||
expectedNoSelect,
|
||||
exactlyDefault,
|
||||
ofDefaultType,
|
||||
exactlyExpected,
|
||||
normal,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class RecursionWeigher extends LookupElementWeigher {
|
||||
private final ElementFilter myFilter;
|
||||
private final PsiElement myPosition;
|
||||
private final PsiReferenceExpression myReference;
|
||||
private final PsiMethodCallExpression myExpression;
|
||||
private final PsiMethod myPositionMethod;
|
||||
private final ExpectedTypeInfo[] myExpectedInfos;
|
||||
private final PsiExpression myQualifier;
|
||||
private final boolean myDelegate;
|
||||
|
||||
public RecursionWeigher(ElementFilter filter,
|
||||
PsiElement position,
|
||||
@NotNull PsiReferenceExpression reference,
|
||||
PsiMethodCallExpression expression,
|
||||
PsiMethod positionMethod, ExpectedTypeInfo[] expectedInfos) {
|
||||
super("recursion");
|
||||
myFilter = filter;
|
||||
myPosition = position;
|
||||
myReference = reference;
|
||||
myExpression = expression;
|
||||
myPositionMethod = positionMethod;
|
||||
myExpectedInfos = expectedInfos;
|
||||
myQualifier = myReference.getQualifierExpression();
|
||||
myDelegate = myQualifier != null && !(myQualifier instanceof PsiThisExpression);
|
||||
}
|
||||
|
||||
private enum Result {
|
||||
delegation,
|
||||
normal,
|
||||
passingObjectToItself,
|
||||
recursive,
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Result weigh(@NotNull LookupElement element) {
|
||||
final Object object = element.getObject();
|
||||
if (!(object instanceof PsiMethod || object instanceof PsiVariable || object instanceof PsiExpression)) return Result.normal;
|
||||
|
||||
if (myFilter != null && !myFilter.isAcceptable(object, myPosition)) {
|
||||
return Result.recursive;
|
||||
}
|
||||
|
||||
if (isPassingObjectToItself(object)) {
|
||||
return Result.passingObjectToItself;
|
||||
}
|
||||
|
||||
if (myExpression != null && myPositionMethod != null) {
|
||||
if (myExpectedInfos != null) {
|
||||
final PsiType itemType = JavaCompletionUtil.getLookupElementType(element);
|
||||
if (itemType != null) {
|
||||
for (final ExpectedTypeInfo expectedInfo : myExpectedInfos) {
|
||||
if (myPositionMethod.equals(expectedInfo.getCalledMethod()) && expectedInfo.getType().isAssignableFrom(itemType)) {
|
||||
return myDelegate ? Result.delegation : Result.recursive;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return Result.normal;
|
||||
}
|
||||
|
||||
if (object instanceof PsiMethod && myPositionMethod != null) {
|
||||
final PsiMethod method = (PsiMethod)object;
|
||||
if (PsiTreeUtil.isAncestor(myReference, myPosition, false) &&
|
||||
Comparing.equal(method.getName(), myPositionMethod.getName())) {
|
||||
if (!myDelegate && findDeepestSuper(method).equals(findDeepestSuper(myPositionMethod))) {
|
||||
return Result.recursive;
|
||||
}
|
||||
return Result.delegation;
|
||||
}
|
||||
}
|
||||
|
||||
return Result.normal;
|
||||
}
|
||||
|
||||
private boolean isPassingObjectToItself(Object object) {
|
||||
if (object instanceof PsiThisExpression) {
|
||||
return !myDelegate || myQualifier instanceof PsiSuperExpression;
|
||||
}
|
||||
return myQualifier instanceof PsiReferenceExpression &&
|
||||
object.equals(((PsiReferenceExpression)myQualifier).advancedResolve(true).getElement());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static PsiMethod findDeepestSuper(@NotNull final PsiMethod method) {
|
||||
final PsiMethod first = DeepestSuperMethodsSearch.search(method).findFirst();
|
||||
return first == null ? method : first;
|
||||
}
|
||||
}
|
||||
|
||||
private enum ExpectedTypeMatching {
|
||||
ofDefaultType,
|
||||
expected,
|
||||
normal,
|
||||
}
|
||||
|
||||
private static class PreferAccessible extends LookupElementWeigher {
|
||||
private final PsiElement myPosition;
|
||||
|
||||
public PreferAccessible(PsiElement position) {
|
||||
super("accessible");
|
||||
myPosition = position;
|
||||
}
|
||||
|
||||
private enum MyEnum {
|
||||
NORMAL,
|
||||
DEPRECATED,
|
||||
INACCESSIBLE,
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Comparable weigh(@NotNull LookupElement element) {
|
||||
final Object object = element.getObject();
|
||||
if (object instanceof PsiDocCommentOwner) {
|
||||
final PsiDocCommentOwner member = (PsiDocCommentOwner)object;
|
||||
if (!member.isValid()) {
|
||||
return MyEnum.NORMAL;
|
||||
}
|
||||
|
||||
if (!JavaPsiFacade.getInstance(member.getProject()).getResolveHelper().isAccessible(member, myPosition, null)) return MyEnum.INACCESSIBLE;
|
||||
if (member.isDeprecated()) return MyEnum.DEPRECATED;
|
||||
}
|
||||
return MyEnum.NORMAL;
|
||||
}
|
||||
}
|
||||
|
||||
private static class PreferNonGeneric extends LookupElementWeigher {
|
||||
public PreferNonGeneric() {
|
||||
super("nonGeneric");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Comparable weigh(@NotNull LookupElement element) {
|
||||
final Object object = element.getObject();
|
||||
if (object instanceof PsiMethod) {
|
||||
PsiType type = ((PsiMethod)object).getReturnType();
|
||||
final JavaMethodCallElement callItem = element.as(JavaMethodCallElement.CLASS_CONDITION_KEY);
|
||||
if (callItem != null) {
|
||||
type = callItem.getSubstitutor().substitute(type);
|
||||
}
|
||||
|
||||
if (type instanceof PsiClassType && ((PsiClassType) type).resolve() instanceof PsiTypeParameter) return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private static class PreferSimple extends LookupElementWeigher {
|
||||
public PreferSimple() {
|
||||
super("simple");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Comparable weigh(@NotNull LookupElement element) {
|
||||
final PsiTypeLookupItem lookupItem = element.as(PsiTypeLookupItem.CLASS_CONDITION_KEY);
|
||||
if (lookupItem != null) {
|
||||
return lookupItem.getBracketsCount();
|
||||
}
|
||||
if (element.as(CastingLookupElementDecorator.CLASS_CONDITION_KEY) != null) {
|
||||
return 239;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private static class PreferEnumConstants extends LookupElementWeigher {
|
||||
private final CompletionParameters myParameters;
|
||||
|
||||
public PreferEnumConstants(CompletionParameters parameters) {
|
||||
super("constants");
|
||||
myParameters = parameters;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Comparable weigh(@NotNull LookupElement element) {
|
||||
if (element.getObject() instanceof PsiEnumConstant) return -2;
|
||||
|
||||
if (!(myParameters.getOriginalFile() instanceof PsiJavaFile)) return -1;
|
||||
|
||||
if (PsiKeyword.TRUE.equals(element.getLookupString()) || PsiKeyword.FALSE.equals(element.getLookupString())) {
|
||||
boolean inReturn = PsiTreeUtil.getParentOfType(myParameters.getPosition(), PsiReturnStatement.class, false, PsiMember.class) != null;
|
||||
return inReturn ? -2 : 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
private static class PreferExpected extends LookupElementWeigher {
|
||||
private final boolean myAcceptClasses;
|
||||
private final ExpectedTypeInfo[] myExpectedTypes;
|
||||
|
||||
public PreferExpected(boolean acceptClasses, ExpectedTypeInfo[] expectedTypes) {
|
||||
super("expectedType");
|
||||
myAcceptClasses = acceptClasses;
|
||||
myExpectedTypes = expectedTypes;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Comparable weigh(@NotNull LookupElement item) {
|
||||
return item.getObject() instanceof PsiClass && !myAcceptClasses
|
||||
? ExpectedTypeMatching.normal : getExpectedTypeMatching(item, myExpectedTypes);
|
||||
}
|
||||
}
|
||||
|
||||
private static class PreferSimilarlyEnding extends LookupElementWeigher {
|
||||
private final ExpectedTypeInfo[] myExpectedTypes;
|
||||
|
||||
public PreferSimilarlyEnding(ExpectedTypeInfo[] expectedTypes) {
|
||||
super("nameEnd");
|
||||
myExpectedTypes = expectedTypes;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Comparable weigh(@NotNull LookupElement element) {
|
||||
final String name = getLookupObjectName(element.getObject());
|
||||
return -getNameEndMatchingDegree(name, myExpectedTypes, element.getPrefixMatcher().getPrefix());
|
||||
}
|
||||
}
|
||||
|
||||
private static class PreferContainingSameWords extends LookupElementWeigher {
|
||||
private final ExpectedTypeInfo[] myExpectedTypes;
|
||||
|
||||
public PreferContainingSameWords(ExpectedTypeInfo[] expectedTypes) {
|
||||
super("sameWords");
|
||||
myExpectedTypes = expectedTypes;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Comparable weigh(@NotNull LookupElement element) {
|
||||
final Object object = element.getObject();
|
||||
|
||||
final String name = getLookupObjectName(object);
|
||||
if (name != null) {
|
||||
int max = 0;
|
||||
final List<String> wordsNoDigits = NameUtil.nameToWordsLowerCase(truncDigits(name));
|
||||
for (ExpectedTypeInfo myExpectedInfo : myExpectedTypes) {
|
||||
String expectedName = ((ExpectedTypeInfoImpl)myExpectedInfo).expectedName;
|
||||
if (expectedName != null) {
|
||||
final THashSet<String> set = new THashSet<String>(NameUtil.nameToWordsLowerCase(truncDigits(expectedName)));
|
||||
set.retainAll(wordsNoDigits);
|
||||
max = Math.max(max, set.size());
|
||||
}
|
||||
}
|
||||
return -max;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private static class PreferFieldsAndGetters extends LookupElementWeigher {
|
||||
public PreferFieldsAndGetters() {
|
||||
super("fieldsAndGetters");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Comparable weigh(@NotNull LookupElement element) {
|
||||
final Object object = element.getObject();
|
||||
if (object instanceof PsiField) return -2;
|
||||
if (object instanceof PsiMethod && PropertyUtil.isSimplePropertyGetter((PsiMethod)object)) return -1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private static class PreferShorter extends LookupElementWeigher {
|
||||
private final ExpectedTypeInfo[] myExpectedTypes;
|
||||
|
||||
public PreferShorter(ExpectedTypeInfo[] expectedTypes) {
|
||||
super("shorter");
|
||||
myExpectedTypes = expectedTypes;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Comparable weigh(@NotNull LookupElement element) {
|
||||
final Object object = element.getObject();
|
||||
final String name = getLookupObjectName(object);
|
||||
|
||||
if (name != null && getNameEndMatchingDegree(name, myExpectedTypes, element.getPrefixMatcher().getPrefix()) != 0) {
|
||||
return NameUtil.nameToWords(name).length - 1000;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -105,23 +105,15 @@ public class JavaCompletionUtil {
|
||||
public static Set<PsiType> getExpectedTypes(final CompletionParameters parameters) {
|
||||
final PsiExpression expr = PsiTreeUtil.getContextOfType(parameters.getPosition(), PsiExpression.class, true);
|
||||
if (expr != null) {
|
||||
final ExpectedTypeInfo[] expectedInfos = JavaSmartCompletionContributor.getExpectedTypes(parameters);
|
||||
if(expectedInfos != null){
|
||||
final Set<PsiType> set = new THashSet<PsiType>();
|
||||
for (final ExpectedTypeInfo expectedInfo : expectedInfos) {
|
||||
set.add(expectedInfo.getType());
|
||||
}
|
||||
return set;
|
||||
final Set<PsiType> set = new THashSet<PsiType>();
|
||||
for (final ExpectedTypeInfo expectedInfo : JavaSmartCompletionContributor.getExpectedTypes(parameters)) {
|
||||
set.add(expectedInfo.getType());
|
||||
}
|
||||
return set;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static final NullableLazyKey<PsiMethod, CompletionLocation> POSITION_METHOD = NullableLazyKey.create("positionMethod", new NullableFunction<CompletionLocation, PsiMethod>() {
|
||||
public PsiMethod fun(final CompletionLocation location) {
|
||||
return PsiTreeUtil.getParentOfType(location.getCompletionParameters().getPosition(), PsiMethod.class, false);
|
||||
}
|
||||
});
|
||||
public static final Key<List<PsiMethod>> ALL_METHODS_ATTRIBUTE = Key.create("allMethods");
|
||||
|
||||
public static PsiType getQualifierType(LookupItem item) {
|
||||
@@ -323,26 +315,12 @@ public class JavaCompletionUtil {
|
||||
|
||||
final PsiReference reference = file.findReferenceAt(selectionEndOffset);
|
||||
if(reference != null) {
|
||||
/*
|
||||
if(reference instanceof PsiJavaCodeReferenceElement){
|
||||
offsetMap.addOffset(CompletionInitializationContext.IDENTIFIER_END_OFFSET, element.getParent().getTextRange().getEndOffset());
|
||||
}
|
||||
else{
|
||||
}
|
||||
*/
|
||||
offsetMap.addOffset(CompletionInitializationContext.IDENTIFIER_END_OFFSET,
|
||||
reference.getElement().getTextRange().getStartOffset() + reference.getRangeInElement().getEndOffset());
|
||||
|
||||
element = file.findElementAt(offsetMap.getOffset(CompletionInitializationContext.IDENTIFIER_END_OFFSET));
|
||||
}
|
||||
else if (isWord(element)){
|
||||
/*
|
||||
if(element instanceof PsiIdentifier && element.getParent() instanceof PsiJavaCodeReferenceElement){
|
||||
offsetMap.addOffset(CompletionInitializationContext.IDENTIFIER_END_OFFSET, element.getParent().getTextRange().getEndOffset());
|
||||
}
|
||||
else{
|
||||
}
|
||||
*/
|
||||
offsetMap.addOffset(CompletionInitializationContext.IDENTIFIER_END_OFFSET, element.getTextRange().getEndOffset());
|
||||
|
||||
element = file.findElementAt(offsetMap.getOffset(CompletionInitializationContext.IDENTIFIER_END_OFFSET));
|
||||
@@ -432,75 +410,6 @@ public class JavaCompletionUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static int getNameEndMatchingDegree(final String name, ExpectedTypeInfo[] expectedInfos, String prefix) {
|
||||
int res = 0;
|
||||
if (name != null && expectedInfos != null) {
|
||||
if (prefix.equals(name)) {
|
||||
res = Integer.MAX_VALUE;
|
||||
} else {
|
||||
final List<String> words = NameUtil.nameToWordsLowerCase(name);
|
||||
final List<String> wordsNoDigits = NameUtil.nameToWordsLowerCase(truncDigits(name));
|
||||
int max1 = calcMatch(words, 0, expectedInfos);
|
||||
max1 = calcMatch(wordsNoDigits, max1, expectedInfos);
|
||||
res = max1;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static String truncDigits(String name){
|
||||
int count = name.length() - 1;
|
||||
while (count >= 0) {
|
||||
char c = name.charAt(count);
|
||||
if (!Character.isDigit(c)) break;
|
||||
count--;
|
||||
}
|
||||
return name.substring(0, count + 1);
|
||||
}
|
||||
|
||||
private static int calcMatch(final List<String> words, int max, ExpectedTypeInfo[] myExpectedInfos) {
|
||||
for (ExpectedTypeInfo myExpectedInfo : myExpectedInfos) {
|
||||
String expectedName = ((ExpectedTypeInfoImpl)myExpectedInfo).expectedName;
|
||||
if (expectedName == null) continue;
|
||||
max = calcMatch(expectedName, words, max);
|
||||
max = calcMatch(truncDigits(expectedName), words, max);
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
static int calcMatch(final String expectedName, final List<String> words, int max) {
|
||||
if (expectedName == null) return max;
|
||||
|
||||
String[] expectedWords = NameUtil.nameToWords(expectedName);
|
||||
int limit = Math.min(words.size(), expectedWords.length);
|
||||
for (int i = 0; i < limit; i++) {
|
||||
String word = words.get(words.size() - i - 1);
|
||||
String expectedWord = expectedWords[expectedWords.length - i - 1];
|
||||
if (word.equalsIgnoreCase(expectedWord)) {
|
||||
max = Math.max(max, i + 1);
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static String getLookupObjectName(Object o) {
|
||||
if (o instanceof PsiVariable) {
|
||||
final PsiVariable variable = (PsiVariable)o;
|
||||
JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(variable.getProject());
|
||||
VariableKind variableKind = codeStyleManager.getVariableKind(variable);
|
||||
return codeStyleManager.variableNameToPropertyName(variable.getName(), variableKind);
|
||||
}
|
||||
if (o instanceof PsiMethod) {
|
||||
return ((PsiMethod)o).getName();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiType getLookupElementType(final LookupElement element) {
|
||||
TypedLookupItem typed = element.as(TypedLookupItem.CLASS_CONDITION_KEY);
|
||||
@@ -573,7 +482,7 @@ public class JavaCompletionUtil {
|
||||
return matcher.prefixMatches(s);
|
||||
}
|
||||
};
|
||||
final JavaCompletionProcessor processor = new JavaCompletionProcessor(element, elementFilter, checkAccess, nameCondition);
|
||||
final JavaCompletionProcessor processor = new JavaCompletionProcessor(element, elementFilter, checkAccess, parameters.getInvocationCount() <= 1, nameCondition);
|
||||
javaReference.processVariants(processor);
|
||||
final Collection<CompletionElement> plainResults = processor.getResults();
|
||||
|
||||
|
||||
+1
-1
@@ -77,7 +77,7 @@ public class JavaDocCompletionContributor extends CompletionContributor {
|
||||
if (ref instanceof PsiJavaReference) {
|
||||
result.stopHere();
|
||||
|
||||
final JavaCompletionProcessor processor = new JavaCompletionProcessor(position, TrueFilter.INSTANCE, false, null);
|
||||
final JavaCompletionProcessor processor = new JavaCompletionProcessor(position, TrueFilter.INSTANCE, false, false, null);
|
||||
((PsiJavaReference) ref).processVariants(processor);
|
||||
|
||||
for (final CompletionElement _item : processor.getResults()) {
|
||||
|
||||
@@ -135,8 +135,11 @@ public class JavaInheritorsGetter extends CompletionProvider<CompletionParameter
|
||||
final PsiStatement statement = elementFactory
|
||||
.createStatementFromText(psiType.getCanonicalText() + " v = new " + canonicalText + "<>()", parameters.getOriginalFile());
|
||||
final PsiVariable declaredVar = (PsiVariable)((PsiDeclarationStatement)statement).getDeclaredElements()[0];
|
||||
final PsiExpression initializer = declaredVar.getInitializer();
|
||||
psiType = initializer.getType();
|
||||
final PsiNewExpression initializer = (PsiNewExpression)declaredVar.getInitializer();
|
||||
final boolean hasDefaultConstructorOrNoGenericsOne = PsiDiamondType.hasDefaultConstructor(psiClass) || !PsiDiamondType.haveConstructorsGenericsParameters(psiClass);
|
||||
if (hasDefaultConstructorOrNoGenericsOne && PsiDiamondType.resolveInferredTypes(initializer).getErrorMessage() == null) {
|
||||
psiType = initializer.getType();
|
||||
}
|
||||
}
|
||||
}
|
||||
final LookupItem item = PsiTypeLookupItem.createLookupItem(psiType, parameters.getPosition());
|
||||
|
||||
@@ -141,6 +141,12 @@ public class JavaMethodCallElement extends LookupItem<PsiMethod> implements Type
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (leaf != null) {
|
||||
final PsiElement parent = leaf.getParent();
|
||||
if (parent instanceof PsiReferenceExpression && ((PsiReferenceExpression)parent).getTypeParameters().length > 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return SmartCompletionDecorator.hasUnboundTypeParams(getObject());
|
||||
}
|
||||
|
||||
+12
-6
@@ -197,9 +197,9 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
|
||||
final JavaSmartCompletionParameters parameters = new JavaSmartCompletionParameters(params, info);
|
||||
final PsiType type = info.getType();
|
||||
|
||||
final CompletionService service = CompletionService.getCompletionService();
|
||||
new BasicExpressionCompletionContributor().fillCompletionVariants(parameters, service.createResultSet(parameters, new Consumer<LookupElement>() {
|
||||
public void consume(final LookupElement lookupElement) {
|
||||
BasicExpressionCompletionContributor.fillCompletionVariants(parameters, new Consumer<LookupElement>() {
|
||||
@Override
|
||||
public void consume(LookupElement lookupElement) {
|
||||
final TypedLookupItem typed = lookupElement.as(TypedLookupItem.CLASS_CONDITION_KEY);
|
||||
if (typed != null) {
|
||||
final PsiType psiType = typed.getType();
|
||||
@@ -208,12 +208,12 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
|
||||
}
|
||||
}
|
||||
}
|
||||
}, JavaSmartCompletionContributor.this));
|
||||
ReferenceExpressionCompletionContributor.fillCompletionVariants(parameters, service.createResultSet(parameters, new Consumer<LookupElement>() {
|
||||
}, result.getPrefixMatcher());
|
||||
ReferenceExpressionCompletionContributor.fillCompletionVariants(parameters, new Consumer<LookupElement>() {
|
||||
public void consume(final LookupElement lookupElement) {
|
||||
result.addElement(decorate(lookupElement, _infos));
|
||||
}
|
||||
}, JavaSmartCompletionContributor.this));
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
@@ -335,6 +335,11 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
|
||||
extend(CompletionType.SMART, AFTER_NEW, new JavaInheritorsGetter(ConstructorInsertHandler.SMART_INSTANCE));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillCompletionVariants(CompletionParameters parameters, CompletionResultSet result) {
|
||||
super.fillCompletionVariants(parameters, JavaCompletionSorting.addJavaSorting(parameters, result));
|
||||
}
|
||||
|
||||
public static SmartCompletionDecorator decorate(LookupElement lookupElement, Collection<ExpectedTypeInfo> infos) {
|
||||
if (lookupElement instanceof LookupItem) {
|
||||
final LookupItem lookupItem = (LookupItem)lookupElement;
|
||||
@@ -397,6 +402,7 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
public static ExpectedTypeInfo[] getExpectedTypes(final CompletionParameters parameters) {
|
||||
final PsiElement position = parameters.getPosition();
|
||||
if (psiElement().withParent(psiElement(PsiReferenceExpression.class).withParent(PsiThrowStatement.class)).accepts(position)) {
|
||||
|
||||
-36
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInsight.completion;
|
||||
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class NameEndMatchingDegreeWeigher extends CompletionWeigher {
|
||||
|
||||
public Integer weigh(@NotNull final LookupElement element, @NotNull final CompletionLocation location) {
|
||||
if (location == null) {
|
||||
return null;
|
||||
}
|
||||
final String name = JavaCompletionUtil.getLookupObjectName(element.getObject());
|
||||
return JavaCompletionUtil.getNameEndMatchingDegree(name, JavaCompletionUtil.EXPECTED_TYPES.getValue(location),
|
||||
element.getPrefixMatcher().getPrefix());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInsight.completion;
|
||||
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.psi.JavaPsiFacade;
|
||||
import com.intellij.psi.PsiDocCommentOwner;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class PreferAccessibleWeigher extends CompletionWeigher {
|
||||
|
||||
public MyEnum weigh(@NotNull final LookupElement item, @NotNull final CompletionLocation location) {
|
||||
if (location == null) {
|
||||
return null;
|
||||
}
|
||||
final Object object = item.getObject();
|
||||
if (object instanceof PsiDocCommentOwner) {
|
||||
final PsiDocCommentOwner member = (PsiDocCommentOwner)object;
|
||||
if (!member.isValid()) {
|
||||
return MyEnum.NORMAL;
|
||||
}
|
||||
|
||||
if (!JavaPsiFacade.getInstance(member.getProject()).getResolveHelper().isAccessible(member, location.getCompletionParameters().getPosition(), null)) return MyEnum.INACCESSIBLE;
|
||||
if (member.isDeprecated()) return MyEnum.DEPRECATED;
|
||||
}
|
||||
return MyEnum.NORMAL;
|
||||
}
|
||||
|
||||
private enum MyEnum {
|
||||
INACCESSIBLE,
|
||||
DEPRECATED,
|
||||
NORMAL
|
||||
}
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInsight.completion;
|
||||
|
||||
import com.intellij.codeInsight.ExpectedTypeInfo;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.openapi.util.NullableLazyKey;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiType;
|
||||
import com.intellij.psi.PsiTypeParameter;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.util.NullableFunction;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class PreferDefaultTypeWeigher extends CompletionWeigher {
|
||||
private static final NullableLazyKey<PsiTypeParameter, CompletionLocation> TYPE_PARAMETER = NullableLazyKey.create("expectedTypes", new NullableFunction<CompletionLocation, PsiTypeParameter>() {
|
||||
@Nullable
|
||||
public PsiTypeParameter fun(final CompletionLocation location) {
|
||||
final Pair<PsiClass,Integer> pair =
|
||||
JavaSmartCompletionContributor.getTypeParameterInfo(location.getCompletionParameters().getPosition());
|
||||
if (pair == null) return null;
|
||||
return pair.first.getTypeParameters()[pair.second.intValue()];
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
private enum MyResult {
|
||||
normal,
|
||||
exactlyExpected,
|
||||
ofDefaultType,
|
||||
exactlyDefault,
|
||||
expectedNoSelect
|
||||
}
|
||||
|
||||
public MyResult weigh(@NotNull final LookupElement item, @NotNull final CompletionLocation location) {
|
||||
if (location == null) {
|
||||
return null;
|
||||
}
|
||||
final Object object = item.getObject();
|
||||
if (location.getCompletionType() != CompletionType.SMART) return MyResult.normal;
|
||||
|
||||
if (object instanceof PsiClass) {
|
||||
final PsiTypeParameter parameter = TYPE_PARAMETER.getValue(location);
|
||||
if (parameter != null && object.equals(PsiUtil.resolveClassInType(TypeConversionUtil.typeParameterErasure(parameter)))) {
|
||||
return MyResult.exactlyExpected;
|
||||
}
|
||||
}
|
||||
|
||||
ExpectedTypeInfo[] expectedInfos = JavaCompletionUtil.EXPECTED_TYPES.getValue(location);
|
||||
if (expectedInfos == null) return MyResult.normal;
|
||||
|
||||
PsiType itemType = JavaCompletionUtil.getLookupElementType(item);
|
||||
if (itemType == null || !itemType.isValid()) return MyResult.normal;
|
||||
|
||||
if (object instanceof PsiClass) {
|
||||
for (final ExpectedTypeInfo info : expectedInfos) {
|
||||
if (TypeConversionUtil.erasure(info.getType().getDeepComponentType()).equals(TypeConversionUtil.erasure(itemType))) {
|
||||
return AbstractExpectedTypeSkipper.skips(item, location) ? MyResult.expectedNoSelect : MyResult.exactlyExpected;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (final ExpectedTypeInfo expectedInfo : expectedInfos) {
|
||||
final PsiType defaultType = expectedInfo.getDefaultType();
|
||||
final PsiType expectedType = expectedInfo.getType();
|
||||
if (!expectedType.isValid()) {
|
||||
return MyResult.normal;
|
||||
}
|
||||
|
||||
if (defaultType != expectedType) {
|
||||
if (defaultType.equals(itemType)) {
|
||||
return MyResult.exactlyDefault;
|
||||
}
|
||||
|
||||
if (defaultType.isAssignableFrom(itemType)) {
|
||||
return MyResult.ofDefaultType;
|
||||
}
|
||||
}
|
||||
if (PsiType.VOID.equals(itemType) && PsiType.VOID.equals(expectedType)) {
|
||||
return MyResult.exactlyExpected;
|
||||
}
|
||||
}
|
||||
|
||||
return MyResult.normal;
|
||||
}
|
||||
}
|
||||
-45
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInsight.completion;
|
||||
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class PreferEnumConstantsWeigher extends CompletionWeigher {
|
||||
|
||||
public Comparable weigh(@NotNull final LookupElement item, @NotNull final CompletionLocation location) {
|
||||
if (location == null) {
|
||||
return null;
|
||||
}
|
||||
if (item.getObject() instanceof PsiEnumConstant) return 2;
|
||||
|
||||
final CompletionParameters parameters = location.getCompletionParameters();
|
||||
if (!(parameters.getOriginalFile() instanceof PsiJavaFile)) return 1;
|
||||
|
||||
if (PsiKeyword.TRUE.equals(item.getLookupString()) || PsiKeyword.FALSE.equals(item.getLookupString())) {
|
||||
boolean inReturn = PsiTreeUtil.getParentOfType(parameters.getPosition(), PsiReturnStatement.class, false, PsiMember.class) != null;
|
||||
return inReturn ? 2 : 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInsight.completion;
|
||||
|
||||
import com.intellij.codeInsight.ExpectedTypeInfo;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class PreferExpectedTypeWeigher extends CompletionWeigher {
|
||||
|
||||
private enum MyResult {
|
||||
normal,
|
||||
expected,
|
||||
ofDefaultType,
|
||||
}
|
||||
|
||||
public MyResult weigh(@NotNull final LookupElement item, @NotNull final CompletionLocation location) {
|
||||
if (location.getCompletionType() != CompletionType.BASIC) return MyResult.normal;
|
||||
if (item.getObject() instanceof PsiClass) {
|
||||
if (!JavaSmartCompletionContributor.AFTER_NEW.accepts(location.getCompletionParameters().getPosition())) {
|
||||
return MyResult.normal;
|
||||
}
|
||||
}
|
||||
|
||||
ExpectedTypeInfo[] expectedInfos = JavaCompletionUtil.EXPECTED_TYPES.getValue(location);
|
||||
if (expectedInfos == null) return MyResult.normal;
|
||||
|
||||
return weigh(item, expectedInfos);
|
||||
}
|
||||
|
||||
public static MyResult weigh(LookupElement item, ExpectedTypeInfo[] expectedInfos) {
|
||||
PsiType itemType = JavaCompletionUtil.getLookupElementType(item);
|
||||
if (itemType == null) return MyResult.normal;
|
||||
|
||||
for (final ExpectedTypeInfo expectedInfo : expectedInfos) {
|
||||
final PsiType defaultType = expectedInfo.getDefaultType();
|
||||
final PsiType expectedType = expectedInfo.getType();
|
||||
if (!expectedType.isValid()) {
|
||||
return MyResult.normal;
|
||||
}
|
||||
|
||||
if (defaultType != expectedType && defaultType.isAssignableFrom(itemType)) {
|
||||
return MyResult.ofDefaultType;
|
||||
}
|
||||
if (expectedType.isAssignableFrom(itemType)) {
|
||||
return MyResult.expected;
|
||||
}
|
||||
}
|
||||
|
||||
return MyResult.normal;
|
||||
}
|
||||
}
|
||||
-41
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInsight.completion;
|
||||
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.psi.PsiField;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.util.PropertyUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class PreferFieldsAndGettersWeigher extends CompletionWeigher {
|
||||
|
||||
public Comparable weigh(@NotNull final LookupElement item, @NotNull final CompletionLocation location) {
|
||||
if (location == null) {
|
||||
return null;
|
||||
}
|
||||
if (location.getCompletionType() != CompletionType.SMART) return 0;
|
||||
|
||||
final Object object = item.getObject();
|
||||
if (object instanceof PsiField) return 2;
|
||||
if (object instanceof PsiMethod && PropertyUtil.isSimplePropertyGetter((PsiMethod)object)) return 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
+20
-11
@@ -16,38 +16,47 @@
|
||||
package com.intellij.codeInsight.completion;
|
||||
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.LookupElementWeigher;
|
||||
import com.intellij.psi.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class PreferLocalVariablesLiteralsAndAnnoMethodsWeigher extends CompletionWeigher {
|
||||
public class PreferLocalVariablesLiteralsAndAnnoMethodsWeigher extends LookupElementWeigher {
|
||||
private final CompletionType myCompletionType;
|
||||
|
||||
enum MyResult {
|
||||
className,
|
||||
classLiteral,
|
||||
normal,
|
||||
superMethodParameters,
|
||||
localOrParameter,
|
||||
annoMethod,
|
||||
public PreferLocalVariablesLiteralsAndAnnoMethodsWeigher(CompletionType completionType) {
|
||||
super("local");
|
||||
myCompletionType = completionType;
|
||||
}
|
||||
|
||||
public MyResult weigh(@NotNull final LookupElement item, @NotNull final CompletionLocation location) {
|
||||
enum MyResult {
|
||||
annoMethod,
|
||||
localOrParameter,
|
||||
superMethodParameters,
|
||||
normal,
|
||||
classLiteral,
|
||||
className,
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Comparable weigh(@NotNull LookupElement item) {
|
||||
final Object object = item.getObject();
|
||||
|
||||
if (object instanceof PsiLocalVariable || object instanceof PsiParameter || object instanceof PsiThisExpression) {
|
||||
return MyResult.localOrParameter;
|
||||
}
|
||||
|
||||
if (location.getCompletionType() == CompletionType.SMART) {
|
||||
if (myCompletionType == CompletionType.SMART) {
|
||||
if (object instanceof String && item.getUserData(JavaCompletionUtil.SUPER_METHOD_PARAMETERS) == Boolean.TRUE) {
|
||||
return MyResult.superMethodParameters;
|
||||
}
|
||||
return MyResult.normal;
|
||||
}
|
||||
|
||||
if (location.getCompletionType() == CompletionType.BASIC) {
|
||||
if (myCompletionType == CompletionType.BASIC) {
|
||||
if (object instanceof PsiKeyword && PsiKeyword.CLASS.equals(item.getLookupString())) {
|
||||
return MyResult.classLiteral;
|
||||
}
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInsight.completion;
|
||||
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.psi.PsiClassType;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.PsiType;
|
||||
import com.intellij.psi.PsiTypeParameter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class PreferNonGenericWeigher extends CompletionWeigher {
|
||||
|
||||
public Comparable weigh(@NotNull final LookupElement item, @NotNull final CompletionLocation location) {
|
||||
final Object object = item.getObject();
|
||||
if (object instanceof PsiMethod) {
|
||||
PsiType type = ((PsiMethod)object).getReturnType();
|
||||
final JavaMethodCallElement callItem = item.as(JavaMethodCallElement.CLASS_CONDITION_KEY);
|
||||
if (callItem != null) {
|
||||
type = callItem.getSubstitutor().substitute(type);
|
||||
}
|
||||
|
||||
if (type instanceof PsiClassType && ((PsiClassType) type).resolve() instanceof PsiTypeParameter) return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInsight.completion;
|
||||
|
||||
import com.intellij.codeInsight.ExpectedTypeInfo;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.psi.codeStyle.NameUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class PreferShorterWeigher extends CompletionWeigher {
|
||||
|
||||
public Comparable weigh(@NotNull final LookupElement item, @NotNull final CompletionLocation location) {
|
||||
if (location == null) {
|
||||
return null;
|
||||
}
|
||||
final Object object = item.getObject();
|
||||
final String name = JavaCompletionUtil.getLookupObjectName(object);
|
||||
final ExpectedTypeInfo[] expectedInfos = JavaCompletionUtil.EXPECTED_TYPES.getValue(location);
|
||||
|
||||
if (name != null && expectedInfos != null && JavaCompletionUtil.getNameEndMatchingDegree(name, expectedInfos,
|
||||
item.getPrefixMatcher().getPrefix()) != 0) {
|
||||
return 239 - NameUtil.nameToWords(name).length;
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInsight.completion;
|
||||
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.PsiTypeLookupItem;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class PreferSimpleWeigher extends CompletionWeigher {
|
||||
|
||||
public Comparable weigh(@NotNull final LookupElement item, @NotNull final CompletionLocation location) {
|
||||
final PsiTypeLookupItem lookupItem = item.as(PsiTypeLookupItem.CLASS_CONDITION_KEY);
|
||||
if (lookupItem != null) {
|
||||
return -lookupItem.getBracketsCount();
|
||||
}
|
||||
if (item.as(CastingLookupElementDecorator.CLASS_CONDITION_KEY) != null) {
|
||||
return -239;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1,106 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInsight.completion;
|
||||
|
||||
import com.intellij.codeInsight.ExpectedTypeInfo;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.filters.ElementFilter;
|
||||
import com.intellij.psi.search.searches.DeepestSuperMethodsSearch;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class RecursionWeigher extends CompletionWeigher {
|
||||
|
||||
private enum Result {
|
||||
recursive,
|
||||
passingObjectToItself,
|
||||
normal,
|
||||
delegation,
|
||||
}
|
||||
|
||||
public Result weigh(@NotNull final LookupElement element, @NotNull final CompletionLocation location) {
|
||||
if (location.getCompletionType() != CompletionType.BASIC && location.getCompletionType() != CompletionType.SMART) return Result.normal;
|
||||
|
||||
final Object object = element.getObject();
|
||||
if (!(object instanceof PsiMethod || object instanceof PsiVariable || object instanceof PsiExpression)) return Result.normal;
|
||||
|
||||
final PsiMethod positionMethod = JavaCompletionUtil.POSITION_METHOD.getValue(location);
|
||||
|
||||
final PsiElement position = location.getCompletionParameters().getPosition();
|
||||
final ElementFilter filter = JavaCompletionUtil.recursionFilter(position);
|
||||
if (filter != null && !filter.isAcceptable(object, position)) {
|
||||
return Result.recursive;
|
||||
}
|
||||
|
||||
final PsiMethodCallExpression expression = PsiTreeUtil.getParentOfType(position, PsiMethodCallExpression.class, true, PsiClass.class);
|
||||
final PsiReferenceExpression reference = expression != null ? expression.getMethodExpression() : PsiTreeUtil.getParentOfType(position, PsiReferenceExpression.class);
|
||||
if (reference == null) return Result.normal;
|
||||
|
||||
final PsiExpression qualifier = reference.getQualifierExpression();
|
||||
boolean isDelegate = qualifier != null && !(qualifier instanceof PsiThisExpression);
|
||||
|
||||
if (isPassingObjectToItself(object, qualifier, isDelegate)) {
|
||||
return Result.passingObjectToItself;
|
||||
}
|
||||
|
||||
if (expression != null && positionMethod != null) {
|
||||
final ExpectedTypeInfo[] expectedInfos = JavaCompletionUtil.EXPECTED_TYPES.getValue(location);
|
||||
if (expectedInfos != null) {
|
||||
final PsiType itemType = JavaCompletionUtil.getLookupElementType(element);
|
||||
if (itemType != null) {
|
||||
for (final ExpectedTypeInfo expectedInfo : expectedInfos) {
|
||||
if (positionMethod.equals(expectedInfo.getCalledMethod()) && expectedInfo.getType().isAssignableFrom(itemType)) {
|
||||
return isDelegate ? Result.delegation : Result.recursive;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return Result.normal;
|
||||
}
|
||||
|
||||
if (object instanceof PsiMethod && positionMethod != null) {
|
||||
final PsiMethod method = (PsiMethod)object;
|
||||
if (PsiTreeUtil.isAncestor(reference, position, false) &&
|
||||
Comparing.equal(method.getName(), positionMethod.getName()) &&
|
||||
method.getParameterList().getParametersCount() == positionMethod.getParameterList().getParametersCount()) {
|
||||
if (findDeepestSuper(method).equals(findDeepestSuper(positionMethod))) {
|
||||
return isDelegate ? Result.delegation : Result.recursive;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Result.normal;
|
||||
}
|
||||
|
||||
private static boolean isPassingObjectToItself(Object object, PsiExpression qualifier, boolean delegate) {
|
||||
if (object instanceof PsiThisExpression) {
|
||||
return !delegate || qualifier instanceof PsiSuperExpression;
|
||||
}
|
||||
return qualifier instanceof PsiReferenceExpression &&
|
||||
object.equals(((PsiReferenceExpression)qualifier).advancedResolve(true).getElement());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static PsiMethod findDeepestSuper(@NotNull final PsiMethod method) {
|
||||
final PsiMethod first = DeepestSuperMethodsSearch.search(method).findFirst();
|
||||
return first == null ? method : first;
|
||||
}
|
||||
}
|
||||
+14
-14
@@ -104,7 +104,7 @@ public class ReferenceExpressionCompletionContributor {
|
||||
return TrueFilter.INSTANCE;
|
||||
}
|
||||
|
||||
public static void fillCompletionVariants(final JavaSmartCompletionParameters parameters, final CompletionResultSet result) {
|
||||
public static void fillCompletionVariants(final JavaSmartCompletionParameters parameters, final Consumer<LookupElement> result) {
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
public void run() {
|
||||
final PsiElement element = parameters.getPosition();
|
||||
@@ -115,7 +115,7 @@ public class ReferenceExpressionCompletionContributor {
|
||||
if (reference != null) {
|
||||
final ElementFilter filter = getReferenceFilter(element, false);
|
||||
for (final LookupElement item : completeFinalReference(element, reference, filter, parameters)) {
|
||||
result.addElement(item);
|
||||
result.consume(item);
|
||||
}
|
||||
|
||||
final boolean secondTime = parameters.getInvocationCount() >= 2;
|
||||
@@ -180,7 +180,7 @@ public class ReferenceExpressionCompletionContributor {
|
||||
}
|
||||
|
||||
private static void addSingleArrayElementAccess(PsiElement element, LookupElement item, JavaSmartCompletionParameters parameters,
|
||||
CompletionResultSet result) {
|
||||
Consumer<LookupElement> result) {
|
||||
if (item.getObject() instanceof PsiLocalVariable) {
|
||||
final PsiLocalVariable variable = (PsiLocalVariable)item.getObject();
|
||||
final PsiType type = variable.getType();
|
||||
@@ -192,7 +192,7 @@ public class ReferenceExpressionCompletionContributor {
|
||||
if (dimensions.length == 1 && "1".equals(dimensions[0].getText()) && newExpression.getArrayInitializer() == null) {
|
||||
final String text = variable.getName() + "[0]";
|
||||
final PsiExpression conversion = createExpression(text, element);
|
||||
result.addElement(new ExpressionLookupItem(conversion).setIcon(variable.getIcon(Iconable.ICON_FLAG_VISIBILITY)));
|
||||
result.consume(new ExpressionLookupItem(conversion).setIcon(variable.getIcon(Iconable.ICON_FLAG_VISIBILITY)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -204,7 +204,7 @@ public class ReferenceExpressionCompletionContributor {
|
||||
}
|
||||
|
||||
private static void addSecondCompletionVariants(PsiElement element, PsiReference reference, LookupElement baseItem,
|
||||
JavaSmartCompletionParameters parameters, CompletionResultSet result) {
|
||||
JavaSmartCompletionParameters parameters, Consumer<LookupElement> result) {
|
||||
final Object object = baseItem.getObject();
|
||||
|
||||
try {
|
||||
@@ -236,7 +236,7 @@ public class ReferenceExpressionCompletionContributor {
|
||||
}
|
||||
|
||||
private static void addArrayMemberAccessors(final PsiElement element, final String prefix, final PsiType itemType,
|
||||
final PsiElement qualifier, final CompletionResultSet result, PsiModifierListOwner object,
|
||||
final PsiElement qualifier, final Consumer<LookupElement> result, PsiModifierListOwner object,
|
||||
final PsiType expectedType)
|
||||
throws IncorrectOperationException {
|
||||
if (itemType instanceof PsiArrayType && expectedType.isAssignableFrom(((PsiArrayType)itemType).getComponentType())) {
|
||||
@@ -262,7 +262,7 @@ public class ReferenceExpressionCompletionContributor {
|
||||
editor.getCaretModel().moveToOffset(tailOffset + 1 + callSpace.length());
|
||||
}
|
||||
});
|
||||
result.addElement(item);
|
||||
result.consume(item);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -276,7 +276,7 @@ public class ReferenceExpressionCompletionContributor {
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void addArraysAsListConversions(final PsiElement element, final String prefix, final PsiType itemType, final CompletionResultSet result,
|
||||
private static void addArraysAsListConversions(final PsiElement element, final String prefix, final PsiType itemType, final Consumer<LookupElement> result,
|
||||
@Nullable PsiElement qualifier,
|
||||
final PsiType expectedType) throws IncorrectOperationException {
|
||||
PsiType componentType = PsiUtil.extractIterableTypeParameter(expectedType, true);
|
||||
@@ -321,11 +321,11 @@ public class ReferenceExpressionCompletionContributor {
|
||||
PostprocessReformattingAspect.getInstance(project).doPostponedFormatting();
|
||||
}
|
||||
});
|
||||
result.addElement(item);
|
||||
result.consume(item);
|
||||
}
|
||||
|
||||
private static void addToArrayConversions(final PsiElement element, final Object object, final String prefix, final PsiType itemType,
|
||||
final CompletionResultSet result, @Nullable final PsiElement qualifier,
|
||||
final Consumer<LookupElement> result, @Nullable final PsiElement qualifier,
|
||||
final PsiType expectedType) {
|
||||
final String callSpace = getSpace(CodeStyleSettingsManager.getSettings(element.getProject()).SPACE_WITHIN_METHOD_CALL_PARENTHESES);
|
||||
final PsiType componentType = PsiUtil.extractIterableTypeParameter(itemType, true);
|
||||
@@ -380,7 +380,7 @@ public class ReferenceExpressionCompletionContributor {
|
||||
}
|
||||
|
||||
private static void addChainedCallVariants(final PsiElement place, LookupElement qualifierItem,
|
||||
final CompletionResultSet result,
|
||||
final Consumer<LookupElement> result,
|
||||
PsiType qualifierType,
|
||||
final PsiType expectedType, JavaSmartCompletionParameters parameters) throws IncorrectOperationException {
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(place.getProject()).getElementFactory();
|
||||
@@ -404,7 +404,7 @@ public class ReferenceExpressionCompletionContributor {
|
||||
final ElementFilter filter = getReferenceFilter(place, true);
|
||||
for (final LookupElement item : completeFinalReference(place, mockRef, filter, parameters)) {
|
||||
if (shoudChain(place, varType, expectedType, item)) {
|
||||
result.addElement(JavaChainLookupElement.chainElements(qualifierItem, item));
|
||||
result.consume(JavaChainLookupElement.chainElements(qualifierItem, item));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -454,7 +454,7 @@ public class ReferenceExpressionCompletionContributor {
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void addToArrayConversion(final PsiElement element, final String prefix, @NonNls final String expressionString, @NonNls String presentableString, final CompletionResultSet result, PsiElement qualifier) {
|
||||
private static void addToArrayConversion(final PsiElement element, final String prefix, @NonNls final String expressionString, @NonNls String presentableString, final Consumer<LookupElement> result, PsiElement qualifier) {
|
||||
final boolean callSpace = CodeStyleSettingsManager.getSettings(element.getProject()).SPACE_WITHIN_METHOD_CALL_PARENTHESES;
|
||||
final PsiExpression conversion;
|
||||
try {
|
||||
@@ -490,7 +490,7 @@ public class ReferenceExpressionCompletionContributor {
|
||||
PostprocessReformattingAspect.getInstance(project).doPostponedFormatting();
|
||||
}
|
||||
});
|
||||
result.addElement(item);
|
||||
result.consume(item);
|
||||
}
|
||||
|
||||
private static boolean isEmptyArrayInitializer(@Nullable PsiElement element) {
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInsight.completion;
|
||||
|
||||
import com.intellij.codeInsight.ExpectedTypeInfo;
|
||||
import com.intellij.codeInsight.ExpectedTypeInfoImpl;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.psi.codeStyle.NameUtil;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class SameWordsWeigher extends CompletionWeigher {
|
||||
|
||||
public Comparable weigh(@NotNull final LookupElement item, @NotNull final CompletionLocation location) {
|
||||
if (location == null) {
|
||||
return null;
|
||||
}
|
||||
final Object object = item.getObject();
|
||||
|
||||
final String name = JavaCompletionUtil.getLookupObjectName(object);
|
||||
final ExpectedTypeInfo[] myExpectedInfos = JavaCompletionUtil.EXPECTED_TYPES.getValue(location);
|
||||
if (name != null && myExpectedInfos != null) {
|
||||
int max = 0;
|
||||
final List<String> wordsNoDigits = NameUtil.nameToWordsLowerCase(JavaCompletionUtil.truncDigits(name));
|
||||
for (ExpectedTypeInfo myExpectedInfo : myExpectedInfos) {
|
||||
String expectedName = ((ExpectedTypeInfoImpl)myExpectedInfo).expectedName;
|
||||
if (expectedName != null) {
|
||||
final THashSet<String> set = new THashSet<String>(NameUtil.nameToWordsLowerCase(JavaCompletionUtil.truncDigits(expectedName)));
|
||||
set.retainAll(wordsNoDigits);
|
||||
max = Math.max(max, set.size());
|
||||
}
|
||||
}
|
||||
return max;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,6 @@ import com.intellij.featureStatistics.FeatureUsageTracker;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.ScrollType;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.patterns.PlatformPatterns;
|
||||
import com.intellij.patterns.PsiElementPattern;
|
||||
import com.intellij.psi.*;
|
||||
@@ -16,9 +15,11 @@ import com.intellij.psi.codeStyle.CodeStyleManager;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
|
||||
import com.intellij.psi.impl.source.PostprocessReformattingAspect;
|
||||
import com.intellij.psi.impl.source.tree.java.PsiEmptyExpressionImpl;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
@@ -27,58 +28,101 @@ class SmartCastProvider extends CompletionProvider<CompletionParameters> {
|
||||
static final PsiElementPattern.Capture<PsiElement> INSIDE_TYPECAST_TYPE = PlatformPatterns.psiElement().afterLeaf(
|
||||
PlatformPatterns.psiElement().withText("(").withParent(
|
||||
PsiTypeCastExpression.class));
|
||||
public static final Key<Boolean> TYPE_CAST = Key.create("TYPE_CAST");
|
||||
|
||||
protected void addCompletions(@NotNull final CompletionParameters parameters, final ProcessingContext context, @NotNull final CompletionResultSet result) {
|
||||
for (final ExpectedTypeInfo type : JavaSmartCompletionContributor.getExpectedTypes(parameters)) {
|
||||
if (type.getType() == PsiType.VOID) {
|
||||
for (final ExpectedTypeInfo info : JavaSmartCompletionContributor.getExpectedTypes(parameters)) {
|
||||
final PsiElement originalPosition = parameters.getOriginalPosition();
|
||||
final boolean overwrite = INSIDE_TYPECAST_TYPE.accepts(originalPosition);
|
||||
|
||||
PsiType type = info.getDefaultType();
|
||||
if (type instanceof PsiWildcardType) {
|
||||
type = ((PsiWildcardType)type).getBound();
|
||||
}
|
||||
|
||||
if (type == null || type == PsiType.VOID) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final boolean overwrite = INSIDE_TYPECAST_TYPE.accepts(parameters.getOriginalPosition());
|
||||
|
||||
final LookupElement item = AutoCompletionPolicy.ALWAYS_AUTOCOMPLETE.applyPolicy(new LookupElementDecorator<LookupItem>(
|
||||
PsiTypeLookupItem.createLookupItem(type.getDefaultType(), parameters.getPosition())) {
|
||||
|
||||
@Override
|
||||
public void handleInsert(InsertionContext context) {
|
||||
FeatureUsageTracker.getInstance().triggerFeatureUsed("editing.completion.smarttype.casting");
|
||||
|
||||
final Editor editor = context.getEditor();
|
||||
final Document document = editor.getDocument();
|
||||
if (overwrite) {
|
||||
document.deleteString(context.getSelectionEndOffset(),
|
||||
context.getOffsetMap().getOffset(CompletionInitializationContext.IDENTIFIER_END_OFFSET));
|
||||
result.addElement(createSmartCastElement(parameters, overwrite, type));
|
||||
if (type instanceof PsiPrimitiveType) {
|
||||
final PsiType castedType = getCastedExpressionType(originalPosition);
|
||||
if (castedType != null && !(castedType instanceof PsiPrimitiveType)) {
|
||||
final PsiClassType boxedType = ((PsiPrimitiveType)type).getBoxedType(originalPosition);
|
||||
if (boxedType != null) {
|
||||
result.addElement(createSmartCastElement(parameters, overwrite, boxedType));
|
||||
}
|
||||
|
||||
final CodeStyleSettings csSettings = CodeStyleSettingsManager.getSettings(context.getProject());
|
||||
final int oldTail = context.getTailOffset();
|
||||
context.setTailOffset(RParenthTailType.addRParenth(editor, oldTail, csSettings.SPACE_WITHIN_CAST_PARENTHESES));
|
||||
|
||||
//todo let the delegate handle insertion itself
|
||||
final LookupItem typeItem = getDelegate();
|
||||
final InsertionContext typeContext = CompletionUtil.newContext(context, typeItem, context.getStartOffset(), oldTail);
|
||||
new DefaultInsertHandler().handleInsert(typeContext, typeItem);
|
||||
final PsiTypeCastExpression castExpression =
|
||||
PsiTreeUtil.findElementOfClassAtOffset(context.getFile(), context.getStartOffset(), PsiTypeCastExpression.class, false);
|
||||
if (castExpression != null) {
|
||||
final PsiTypeElement typeElement = castExpression.getCastType();
|
||||
if (typeElement != null) {
|
||||
CodeStyleManager.getInstance(context.getProject()).reformat(typeElement);
|
||||
}
|
||||
}
|
||||
|
||||
PostprocessReformattingAspect.getInstance(context.getProject()).doPostponedFormatting();
|
||||
if (csSettings.SPACE_AFTER_TYPE_CAST) {
|
||||
context.setTailOffset(TailType.insertChar(editor, context.getTailOffset(), ' '));
|
||||
}
|
||||
|
||||
editor.getCaretModel().moveToOffset(context.getTailOffset());
|
||||
editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
|
||||
}
|
||||
});
|
||||
item.putUserData(TYPE_CAST, Boolean.TRUE);
|
||||
result.addElement(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiType getCastedExpressionType(PsiElement originalPosition) {
|
||||
if (INSIDE_TYPECAST_TYPE.accepts(originalPosition)) {
|
||||
final PsiTypeCastExpression cast = PsiTreeUtil.getParentOfType(originalPosition, PsiTypeCastExpression.class);
|
||||
if (cast != null) {
|
||||
final PsiExpression operand = cast.getOperand();
|
||||
return operand == null ? null : operand.getType();
|
||||
}
|
||||
}
|
||||
final PsiParenthesizedExpression parens = PsiTreeUtil.getParentOfType(originalPosition, PsiParenthesizedExpression.class, true, PsiStatement.class);
|
||||
if (parens != null) {
|
||||
final PsiExpression rightSide = parens.getExpression();
|
||||
if (rightSide != null) {
|
||||
return rightSide.getType();
|
||||
}
|
||||
PsiElement next = parens.getNextSibling();
|
||||
while (next != null && (next instanceof PsiEmptyExpressionImpl || next instanceof PsiErrorElement || next instanceof PsiWhiteSpace)) {
|
||||
next = next.getNextSibling();
|
||||
}
|
||||
if (next instanceof PsiExpression) {
|
||||
return ((PsiExpression)next).getType();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static LookupElement createSmartCastElement(final CompletionParameters parameters, final boolean overwrite, final PsiType type) {
|
||||
return AutoCompletionPolicy.ALWAYS_AUTOCOMPLETE.applyPolicy(new LookupElementDecorator<LookupItem>(
|
||||
PsiTypeLookupItem.createLookupItem(type, parameters.getPosition())) {
|
||||
|
||||
@Override
|
||||
public void handleInsert(InsertionContext context) {
|
||||
FeatureUsageTracker.getInstance().triggerFeatureUsed("editing.completion.smarttype.casting");
|
||||
|
||||
final Editor editor = context.getEditor();
|
||||
final Document document = editor.getDocument();
|
||||
if (overwrite) {
|
||||
document.deleteString(context.getSelectionEndOffset(),
|
||||
context.getOffsetMap().getOffset(CompletionInitializationContext.IDENTIFIER_END_OFFSET));
|
||||
}
|
||||
|
||||
final CodeStyleSettings csSettings = CodeStyleSettingsManager.getSettings(context.getProject());
|
||||
final int oldTail = context.getTailOffset();
|
||||
context.setTailOffset(RParenthTailType.addRParenth(editor, oldTail, csSettings.SPACE_WITHIN_CAST_PARENTHESES));
|
||||
|
||||
//todo let the delegate handle insertion itself
|
||||
final LookupItem typeItem = getDelegate();
|
||||
final InsertionContext typeContext = CompletionUtil.newContext(context, typeItem, context.getStartOffset(), oldTail);
|
||||
new DefaultInsertHandler().handleInsert(typeContext, typeItem);
|
||||
final PsiTypeCastExpression castExpression =
|
||||
PsiTreeUtil.findElementOfClassAtOffset(context.getFile(), context.getStartOffset(), PsiTypeCastExpression.class, false);
|
||||
if (castExpression != null) {
|
||||
final PsiTypeElement typeElement = castExpression.getCastType();
|
||||
if (typeElement != null) {
|
||||
CodeStyleManager.getInstance(context.getProject()).reformat(typeElement);
|
||||
}
|
||||
}
|
||||
|
||||
PostprocessReformattingAspect.getInstance(context.getProject()).doPostponedFormatting();
|
||||
if (csSettings.SPACE_AFTER_TYPE_CAST) {
|
||||
context.setTailOffset(TailType.insertChar(editor, context.getTailOffset(), ' '));
|
||||
}
|
||||
|
||||
editor.getCaretModel().moveToOffset(context.getTailOffset());
|
||||
editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInsight.completion;
|
||||
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.javadoc.PsiDocComment;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class StaticMembersWeigher extends CompletionWeigher {
|
||||
public Comparable weigh(@NotNull LookupElement element, @NotNull CompletionLocation loc) {
|
||||
if (loc.getCompletionType() != CompletionType.BASIC) return 0;
|
||||
|
||||
// cheap weigher applicability goes first
|
||||
final Object o = element.getObject();
|
||||
if (!(o instanceof PsiMember)) return 0;
|
||||
|
||||
final PsiElement position = loc.getCompletionParameters().getPosition();
|
||||
if (PsiTreeUtil.getParentOfType(position, PsiDocComment.class) != null) return 0;
|
||||
if (position.getParent() instanceof PsiReferenceExpression) {
|
||||
final PsiReferenceExpression refExpr = (PsiReferenceExpression)position.getParent();
|
||||
final PsiElement qualifier = refExpr.getQualifier();
|
||||
if (qualifier == null) {
|
||||
return 0;
|
||||
}
|
||||
if (!(qualifier instanceof PsiJavaCodeReferenceElement) || !(((PsiJavaCodeReferenceElement)qualifier).resolve() instanceof PsiClass)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (((PsiMember)o).hasModifierProperty(PsiModifier.STATIC)) {
|
||||
if (o instanceof PsiMethod) return 5;
|
||||
if (o instanceof PsiField) return 4;
|
||||
}
|
||||
|
||||
if (o instanceof PsiClass) {
|
||||
//if (((PsiClass) o).getContainingClass() != null) return 2;
|
||||
return 3;
|
||||
}
|
||||
|
||||
//instance method or field
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
+76
-12
@@ -26,14 +26,13 @@ import com.intellij.psi.infos.CandidateInfo;
|
||||
import com.intellij.psi.scope.BaseScopeProcessor;
|
||||
import com.intellij.psi.scope.ElementClassHint;
|
||||
import com.intellij.psi.scope.JavaScopeProcessorEvent;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
@@ -58,8 +57,9 @@ public class JavaCompletionProcessor extends BaseScopeProcessor implements Eleme
|
||||
private PsiClass myQualifierClass = null;
|
||||
private final Condition<String> myMatcher;
|
||||
private final boolean myCheckAccess;
|
||||
private final Set<PsiField> myNonInitializedFields = new HashSet<PsiField>();
|
||||
|
||||
public JavaCompletionProcessor(PsiElement element, ElementFilter filter, final boolean checkAccess, @Nullable Condition<String> nameCondition) {
|
||||
public JavaCompletionProcessor(PsiElement element, ElementFilter filter, final boolean checkAccess, boolean checkInitialized, @Nullable Condition<String> nameCondition) {
|
||||
myCheckAccess = checkAccess;
|
||||
mySettings = CodeInsightSettings.getInstance();
|
||||
myResults = new ArrayList<CompletionElement>();
|
||||
@@ -102,6 +102,65 @@ public class JavaCompletionProcessor extends BaseScopeProcessor implements Eleme
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (checkInitialized) {
|
||||
myNonInitializedFields.addAll(getNonInitializedFields(element));
|
||||
}
|
||||
}
|
||||
|
||||
private static Set<PsiField> getNonInitializedFields(PsiElement element) {
|
||||
final PsiStatement statement = PsiTreeUtil.getParentOfType(element, PsiStatement.class);
|
||||
final PsiMethod method = PsiTreeUtil.getParentOfType(element, PsiMethod.class, true, PsiClass.class);
|
||||
if (statement == null || method == null || !method.isConstructor()) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
PsiElement parent = element.getParent();
|
||||
while (parent != statement) {
|
||||
PsiElement next = parent.getParent();
|
||||
if (next instanceof PsiAssignmentExpression && parent == ((PsiAssignmentExpression)next).getLExpression()) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
if (parent instanceof PsiReferenceExpression && next instanceof PsiExpressionStatement) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
parent = next;
|
||||
}
|
||||
|
||||
final Set<PsiField> fields = new HashSet<PsiField>();
|
||||
final PsiClass containingClass = method.getContainingClass();
|
||||
assert containingClass != null;
|
||||
for (PsiField field : containingClass.getFields()) {
|
||||
if (!field.hasModifierProperty(PsiModifier.STATIC) && field.getInitializer() == null) {
|
||||
fields.add(field);
|
||||
}
|
||||
}
|
||||
|
||||
method.accept(new JavaRecursiveElementWalkingVisitor() {
|
||||
@Override
|
||||
public void visitAssignmentExpression(PsiAssignmentExpression expression) {
|
||||
if (expression.getTextRange().getStartOffset() < statement.getTextRange().getStartOffset()) {
|
||||
final PsiExpression lExpression = expression.getLExpression();
|
||||
if (lExpression instanceof PsiReferenceExpression) {
|
||||
//noinspection SuspiciousMethodCalls
|
||||
fields.remove(((PsiReferenceExpression)lExpression).resolve());
|
||||
}
|
||||
}
|
||||
super.visitAssignmentExpression(expression);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitMethodCallExpression(PsiMethodCallExpression expression) {
|
||||
if (expression.getTextRange().getStartOffset() < statement.getTextRange().getStartOffset()) {
|
||||
final PsiReferenceExpression methodExpression = expression.getMethodExpression();
|
||||
if (methodExpression.textMatches("this")) {
|
||||
fields.clear();
|
||||
}
|
||||
}
|
||||
super.visitMethodCallExpression(expression);
|
||||
}
|
||||
});
|
||||
return fields;
|
||||
}
|
||||
|
||||
public void handleEvent(Event event, Object associated){
|
||||
@@ -113,19 +172,24 @@ public class JavaCompletionProcessor extends BaseScopeProcessor implements Eleme
|
||||
}
|
||||
}
|
||||
|
||||
public boolean execute(PsiElement element, ResolveState state){
|
||||
if(!(element instanceof PsiClass) && element instanceof PsiModifierListOwner){
|
||||
public boolean execute(PsiElement element, ResolveState state) {
|
||||
//noinspection SuspiciousMethodCalls
|
||||
if (myNonInitializedFields.contains(element)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(element instanceof PsiClass) && element instanceof PsiModifierListOwner) {
|
||||
PsiModifierListOwner modifierListOwner = (PsiModifierListOwner)element;
|
||||
if(myStatic){
|
||||
if(!modifierListOwner.hasModifierProperty(PsiModifier.STATIC)){
|
||||
if (myStatic) {
|
||||
if (!modifierListOwner.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
// we don't need non static method in static context.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else{
|
||||
if(!mySettings.SHOW_STATIC_AFTER_INSTANCE
|
||||
&& modifierListOwner.hasModifierProperty(PsiModifier.STATIC)
|
||||
&& !myMembersFlag){
|
||||
else {
|
||||
if (!mySettings.SHOW_STATIC_AFTER_INSTANCE
|
||||
&& modifierListOwner.hasModifierProperty(PsiModifier.STATIC)
|
||||
&& !myMembersFlag) {
|
||||
// according settings we don't need to process such fields/methods
|
||||
return true;
|
||||
}
|
||||
|
||||
+47
-2
@@ -16,16 +16,23 @@
|
||||
package com.intellij.codeInsight.daemon.impl.analysis;
|
||||
|
||||
import com.intellij.codeInsight.AnnotationUtil;
|
||||
import com.intellij.codeInsight.CodeInsightUtilBase;
|
||||
import com.intellij.codeInsight.daemon.JavaErrorMessages;
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.QuickFixAction;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -221,7 +228,7 @@ public class AnnotationsHighlightUtil {
|
||||
return HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, typeElement, JavaErrorMessages.message("annotation.invalid.annotation.member.type"));
|
||||
}
|
||||
|
||||
public static HighlightInfo checkApplicability(PsiAnnotation annotation) {
|
||||
public static HighlightInfo checkApplicability(final PsiAnnotation annotation) {
|
||||
PsiAnnotationOwner owner = annotation.getOwner();
|
||||
if (!(owner instanceof PsiModifierList || owner instanceof PsiTypeElement || owner instanceof PsiMethodReceiver || owner instanceof PsiTypeParameter)) return null;
|
||||
PsiElement member = ((PsiElement)owner).getParent();
|
||||
@@ -231,7 +238,9 @@ public class AnnotationsHighlightUtil {
|
||||
String description = JavaErrorMessages.message("annotation.not.applicable",
|
||||
nameRef.getText(),
|
||||
JavaErrorMessages.message("annotation.target." + elementTypeFields[0]));
|
||||
return HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, nameRef, description);
|
||||
final HighlightInfo highlightInfo = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, nameRef, description);
|
||||
QuickFixAction.registerQuickFixAction(highlightInfo, new DeleteNotApplicableAnnotationAction(annotation));
|
||||
return highlightInfo;
|
||||
}
|
||||
|
||||
public static boolean isAnnotationApplicableTo(PsiAnnotation annotation, boolean strict, String... elementTypeFields) {
|
||||
@@ -445,4 +454,40 @@ public class AnnotationsHighlightUtil {
|
||||
return classType.equalsToText("java.lang.Class") || classType.equalsToText("java.lang.String") ? Boolean.TRUE : Boolean.FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
private static class DeleteNotApplicableAnnotationAction implements IntentionAction {
|
||||
private final PsiAnnotation myAnnotation;
|
||||
|
||||
public DeleteNotApplicableAnnotationAction(PsiAnnotation annotation) {
|
||||
myAnnotation = annotation;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
return "Remove";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return getText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
|
||||
if (!CodeInsightUtilBase.prepareFileForWrite(file)) return;
|
||||
myAnnotation.delete();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean startInWriteAction() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+18
-3
@@ -107,6 +107,22 @@ public class GenericsHighlightUtil {
|
||||
}
|
||||
}
|
||||
|
||||
PsiDiamondType.DiamondInferenceResult inferenceResult = null;
|
||||
PsiTypeElement[] referenceElements = null;
|
||||
if (referenceParameterList != null) {
|
||||
referenceElements = referenceParameterList.getTypeParameterElements();
|
||||
if (referenceElements.length == 1 && referenceElements[0].getType() instanceof PsiDiamondType) {
|
||||
if (!typeParameterListOwner.hasTypeParameters()) {
|
||||
return HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, referenceElements[0], "Diamond operator is not applicable for non-parameterized types");
|
||||
}
|
||||
inferenceResult = ((PsiDiamondType)referenceElements[0].getType()).resolveInferredTypes();
|
||||
final String errorMessage = inferenceResult.getErrorMessage();
|
||||
if (errorMessage != null) {
|
||||
return HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, referenceElements[0], errorMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final PsiTypeParameter[] typeParameters = typeParameterListOwner.getTypeParameters();
|
||||
final int targetParametersNum = typeParameters.length;
|
||||
final int refParametersNum = referenceParameterList == null ? 0 : referenceParameterList.getTypeArguments().length;
|
||||
@@ -140,9 +156,8 @@ public class GenericsHighlightUtil {
|
||||
|
||||
// bounds check
|
||||
if (targetParametersNum > 0 && refParametersNum != 0) {
|
||||
final PsiTypeElement[] referenceElements = referenceParameterList.getTypeParameterElements();
|
||||
if (referenceElements.length == 1 && referenceElements[0].getType() instanceof PsiDiamondType) {
|
||||
final PsiType[] types = ((PsiDiamondType)referenceElements[0].getType()).getInferredTypes();
|
||||
if (inferenceResult != null) {
|
||||
final PsiType[] types = inferenceResult.getTypes();
|
||||
for (int i = 0; i < typeParameters.length; i++) {
|
||||
final PsiType type = types[i];
|
||||
final HighlightInfo highlightInfo = checkTypeParameterWithinItsBound(typeParameters[i], substitutor, type, referenceElements[0]);
|
||||
|
||||
+33
-25
@@ -13,15 +13,6 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: cdr
|
||||
* Date: Aug 8, 2002
|
||||
* Time: 5:55:01 PM
|
||||
* To change template for new class use
|
||||
* Code Style | Class Templates options (Tools | IDE Options).
|
||||
*/
|
||||
package com.intellij.codeInsight.daemon.impl.analysis;
|
||||
|
||||
import com.intellij.codeInsight.daemon.JavaErrorMessages;
|
||||
@@ -43,9 +34,14 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author cdr
|
||||
* Date: Aug 8, 2002
|
||||
*/
|
||||
public class HighlightControlFlowUtil {
|
||||
private static final QuickFixFactory QUICK_FIX_FACTORY = QuickFixFactory.getInstance();
|
||||
|
||||
private HighlightControlFlowUtil() { }
|
||||
|
||||
@Nullable
|
||||
public static HighlightInfo checkMissingReturnStatement(PsiMethod method) {
|
||||
@@ -297,7 +293,7 @@ public class HighlightControlFlowUtil {
|
||||
|
||||
topBlock = JspPsiUtil.isInJspFile(scope) && scope instanceof PsiFile ? scope : PsiUtil.getTopLevelEnclosingCodeBlock(expression, scope);
|
||||
if (variable instanceof PsiField) {
|
||||
// non final field already initalized with default value
|
||||
// non final field already initialized with default value
|
||||
if (!variable.hasModifierProperty(PsiModifier.FINAL)) return null;
|
||||
// final field may be initialized in ctor or class initializer only
|
||||
// if we're inside non-ctr method, skip it
|
||||
@@ -314,9 +310,9 @@ public class HighlightControlFlowUtil {
|
||||
if (parent instanceof PsiMethod) {
|
||||
PsiMethod constructor = (PsiMethod)parent;
|
||||
if (!parent.getManager().areElementsEquivalent(constructor.getContainingClass(), ((PsiField)variable).getContainingClass())) return null;
|
||||
// static variables already initalized in class initalizers
|
||||
// static variables already initialized in class initializers
|
||||
if (variable.hasModifierProperty(PsiModifier.STATIC)) return null;
|
||||
// as a last chance, field may be initalized in this() call
|
||||
// as a last chance, field may be initialized in this() call
|
||||
final List<PsiMethod> redirectedConstructors = getChainedConstructors(constructor);
|
||||
for (int j = 0; redirectedConstructors != null && j < redirectedConstructors.size(); j++) {
|
||||
PsiMethod redirectedConstructor = redirectedConstructors.get(j);
|
||||
@@ -338,7 +334,7 @@ public class HighlightControlFlowUtil {
|
||||
aClass = classInitializer.getContainingClass();
|
||||
}
|
||||
else {
|
||||
// field reference outside codeblock
|
||||
// field reference outside code block
|
||||
// check variable initialized before its usage
|
||||
final PsiField field = (PsiField)variable;
|
||||
|
||||
@@ -356,7 +352,7 @@ public class HighlightControlFlowUtil {
|
||||
&& variableDefinitelyAssignedIn(variable, constructor.getBody())) {
|
||||
return null;
|
||||
}
|
||||
// as a last chance, field may be initalized in this() call
|
||||
// as a last chance, field may be initialized in this() call
|
||||
final List<PsiMethod> redirectedConstructors = getChainedConstructors(constructor);
|
||||
for (int j = 0; redirectedConstructors != null && j < redirectedConstructors.size(); j++) {
|
||||
PsiMethod redirectedConstructor = redirectedConstructors.get(j);
|
||||
@@ -371,13 +367,13 @@ public class HighlightControlFlowUtil {
|
||||
}
|
||||
|
||||
if (aClass != null) {
|
||||
// field may be initialized in class initalizer
|
||||
// field may be initialized in class initializer
|
||||
final PsiClassInitializer[] initializers = aClass.getInitializers();
|
||||
for (PsiClassInitializer initializer : initializers) {
|
||||
PsiCodeBlock body = initializer.getBody();
|
||||
if (body == block) break;
|
||||
// variable referenced in initializer must be initialized in initializer preceding assignment
|
||||
// varaibel refernced in field initializer or in class initializier
|
||||
// variable referenced in field initializer or in class initializer
|
||||
boolean shouldCheckInitializerOrder = block == null || block.getParent() instanceof PsiClassInitializer;
|
||||
if (shouldCheckInitializerOrder && startOffset < initializer.getTextRange().getStartOffset()) continue;
|
||||
if (initializer.hasModifierProperty(PsiModifier.STATIC)
|
||||
@@ -449,6 +445,7 @@ public class HighlightControlFlowUtil {
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
public static HighlightInfo checkFinalVariableMightAlreadyHaveBeenAssignedTo(PsiVariable variable,
|
||||
PsiReferenceExpression expression,
|
||||
Map<PsiElement, Collection<ControlFlowUtil.VariableInfo>> finalVarProblems) {
|
||||
@@ -473,7 +470,7 @@ public class HighlightControlFlowUtil {
|
||||
final PsiField field = (PsiField)variable;
|
||||
final PsiClass aClass = field.getContainingClass();
|
||||
if (aClass == null) return null;
|
||||
// field can get assigned in other field inititializers
|
||||
// field can get assigned in other field initializers
|
||||
final PsiField[] fields = aClass.getFields();
|
||||
boolean isFieldStatic = field.hasModifierProperty(PsiModifier.STATIC);
|
||||
for (PsiField psiField : fields) {
|
||||
@@ -565,7 +562,8 @@ public class HighlightControlFlowUtil {
|
||||
}
|
||||
|
||||
|
||||
public static HighlightInfo checkFinalVariableInitalizedInLoop(PsiReferenceExpression expression, PsiElement resolved) {
|
||||
@Nullable
|
||||
public static HighlightInfo checkFinalVariableInitializedInLoop(PsiReferenceExpression expression, PsiElement resolved) {
|
||||
if (ControlFlowUtil.isVariableAssignedInLoop(expression, resolved)) {
|
||||
String description = JavaErrorMessages.message("variable.assigned.in.loop", ((PsiVariable)resolved).getName());
|
||||
final HighlightInfo highlightInfo = HighlightInfo.createHighlightInfo(
|
||||
@@ -580,6 +578,7 @@ public class HighlightControlFlowUtil {
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
public static HighlightInfo checkCannotWriteToFinal(PsiExpression expression) {
|
||||
PsiReferenceExpression reference = null;
|
||||
if (expression instanceof PsiAssignmentExpression) {
|
||||
@@ -659,6 +658,7 @@ public class HighlightControlFlowUtil {
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
static HighlightInfo checkVariableMustBeFinal(PsiVariable variable, PsiJavaCodeReferenceElement context) {
|
||||
if (variable.hasModifierProperty(PsiModifier.FINAL)) return null;
|
||||
final PsiClass innerClass = getInnerClassVariableReferencedFrom(variable, context);
|
||||
@@ -672,23 +672,30 @@ public class HighlightControlFlowUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiClass getInnerClassVariableReferencedFrom(PsiVariable variable, PsiElement context) {
|
||||
PsiElement scope;
|
||||
if (variable instanceof PsiLocalVariable) {
|
||||
scope = variable.getParent().getParent(); // code block or for statement
|
||||
PsiElement[] scope;
|
||||
if (variable instanceof PsiScopedLocalVariable) {
|
||||
scope = ((PsiScopedLocalVariable)variable).getDeclarationScope();
|
||||
}
|
||||
else if (variable instanceof PsiLocalVariable) {
|
||||
scope = new PsiElement[]{variable.getParent().getParent()}; // code block or for statement
|
||||
}
|
||||
else if (variable instanceof PsiParameter) {
|
||||
scope = ((PsiParameter)variable).getDeclarationScope();
|
||||
scope = new PsiElement[]{((PsiParameter)variable).getDeclarationScope()};
|
||||
}
|
||||
else {
|
||||
scope = variable.getParent();
|
||||
scope = new PsiElement[]{variable.getParent()};
|
||||
}
|
||||
if (scope.getContainingFile() != context.getContainingFile()) return null;
|
||||
if (scope.length < 1 || scope[0].getContainingFile() != context.getContainingFile()) return null;
|
||||
|
||||
PsiElement parent = context.getParent();
|
||||
PsiElement prevParent = context;
|
||||
outer:
|
||||
while (parent != null) {
|
||||
if (parent.equals(scope)) break;
|
||||
for (PsiElement scopeElement : scope) {
|
||||
if (parent.equals(scopeElement)) break outer;
|
||||
}
|
||||
if (parent instanceof PsiClass && !(prevParent instanceof PsiExpressionList && parent instanceof PsiAnonymousClass)) {
|
||||
return (PsiClass)parent;
|
||||
}
|
||||
@@ -699,6 +706,7 @@ public class HighlightControlFlowUtil {
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
public static HighlightInfo checkInitializerCompleteNormally(PsiClassInitializer initializer) {
|
||||
final PsiCodeBlock body = initializer.getBody();
|
||||
// unhandled exceptions already reported
|
||||
|
||||
+97
-54
@@ -36,6 +36,7 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.jsp.jspJava.JspHolderMethod;
|
||||
import com.intellij.psi.javadoc.PsiDocComment;
|
||||
@@ -45,6 +46,7 @@ import com.intellij.psi.scope.util.PsiScopesUtil;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.*;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.xml.util.XmlStringUtil;
|
||||
import gnu.trove.THashMap;
|
||||
@@ -73,8 +75,7 @@ public class HighlightUtil {
|
||||
@NonNls private static final String SERIAL_PERSISTENT_FIELDS_FIELD_NAME = "serialPersistentFields";
|
||||
private static final QuickFixFactory QUICK_FIX_FACTORY = QuickFixFactory.getInstance();
|
||||
|
||||
private HighlightUtil() {
|
||||
}
|
||||
private HighlightUtil() { }
|
||||
|
||||
static {
|
||||
ourClassIncompatibleModifiers = new THashMap<String, Set<String>>(8);
|
||||
@@ -345,6 +346,7 @@ public class HighlightUtil {
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
static HighlightInfo checkVariableExpected(PsiExpression expression) {
|
||||
PsiExpression lValue;
|
||||
if (expression instanceof PsiAssignmentExpression) {
|
||||
@@ -543,33 +545,39 @@ public class HighlightUtil {
|
||||
return errorResult;
|
||||
}
|
||||
|
||||
public static String getUnhandledExceptionsDescriptor(Collection<PsiClassType> unhandledExceptions) {
|
||||
StringBuilder exceptionsText = new StringBuilder();
|
||||
for (PsiClassType unhandledException : unhandledExceptions) {
|
||||
if (exceptionsText.length() != 0) exceptionsText.append(", ");
|
||||
exceptionsText.append(formatType(unhandledException));
|
||||
}
|
||||
|
||||
return JavaErrorMessages.message("unhandled.exceptions", exceptionsText.toString(), unhandledExceptions.size());
|
||||
public static String getUnhandledExceptionsDescriptor(final Collection<PsiClassType> unhandled) {
|
||||
return getUnhandledExceptionsDescriptor(unhandled, null);
|
||||
}
|
||||
|
||||
private static String getUnhandledExceptionsDescriptor(final Collection<PsiClassType> unhandled, final String source) {
|
||||
final String exceptions = StringUtil.join(unhandled, new Function<PsiClassType, String>() {
|
||||
@Override public String fun(PsiClassType type) { return formatType(type); }
|
||||
}, ", ");
|
||||
return source != null ? JavaErrorMessages.message("unhandled.close.exceptions", exceptions, unhandled.size(), source)
|
||||
: JavaErrorMessages.message("unhandled.exceptions", exceptions, unhandled.size());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static HighlightInfo checkVariableAlreadyDefined(PsiVariable variable) {
|
||||
if (variable instanceof ExternallyDefinedPsiElement) return null;
|
||||
boolean isIncorrect = false;
|
||||
PsiIdentifier identifier = variable.getNameIdentifier();
|
||||
assert identifier != null : variable;
|
||||
String name = variable.getName();
|
||||
if (variable instanceof PsiLocalVariable ||
|
||||
variable instanceof PsiParameter && ((PsiParameter)variable).getDeclarationScope() instanceof PsiCatchSection ||
|
||||
variable instanceof PsiParameter && ((PsiParameter)variable).getDeclarationScope() instanceof PsiForeachStatement) {
|
||||
PsiElement scope = PsiTreeUtil.getParentOfType(variable, PsiFile.class, PsiMethod.class, PsiClassInitializer.class);
|
||||
VariablesNotProcessor proc = new VariablesNotProcessor(variable, false){
|
||||
PsiElement scope = PsiTreeUtil.getParentOfType(variable, PsiFile.class, PsiMethod.class, PsiClassInitializer.class, PsiResourceList.class);
|
||||
VariablesNotProcessor proc = new VariablesNotProcessor(variable, false) {
|
||||
protected boolean check(final PsiVariable var, final ResolveState state) {
|
||||
return (var instanceof PsiLocalVariable || var instanceof PsiParameter) && super.check(var, state);
|
||||
}
|
||||
};
|
||||
PsiScopesUtil.treeWalkUp(proc, identifier, scope);
|
||||
if (scope instanceof PsiResourceList && proc.size() == 0) {
|
||||
scope = PsiTreeUtil.getParentOfType(variable, PsiFile.class, PsiMethod.class, PsiClassInitializer.class);
|
||||
PsiScopesUtil.treeWalkUp(proc, identifier, scope);
|
||||
}
|
||||
if (proc.size() > 0) {
|
||||
isIncorrect = true;
|
||||
}
|
||||
@@ -631,26 +639,47 @@ public class HighlightUtil {
|
||||
}
|
||||
|
||||
|
||||
public static HighlightInfo checkUnhandledExceptions(PsiElement element, TextRange fixRange) {
|
||||
List<PsiClassType> unhandledExceptions = ExceptionUtil.getUnhandledExceptions(element);
|
||||
HighlightInfo errorResult = null;
|
||||
if (!unhandledExceptions.isEmpty()) {
|
||||
if (fixRange == null) {
|
||||
fixRange = element.getTextRange();
|
||||
}
|
||||
HighlightInfoType highlightType = getUnhandledExceptionHighlightType(element);
|
||||
if (highlightType == null) return null;
|
||||
errorResult = HighlightInfo.createHighlightInfo(highlightType, fixRange, getUnhandledExceptionsDescriptor(unhandledExceptions));
|
||||
QuickFixAction.registerQuickFixAction(errorResult, new AddExceptionToCatchFix());
|
||||
QuickFixAction.registerQuickFixAction(errorResult, new AddExceptionToThrowsFix(element));
|
||||
QuickFixAction.registerQuickFixAction(errorResult, new SurroundWithTryCatchFix(element));
|
||||
if (unhandledExceptions.size() == 1) {
|
||||
QuickFixAction.registerQuickFixAction(errorResult, new GeneralizeCatchFix(element, unhandledExceptions.get(0)));
|
||||
}
|
||||
}
|
||||
@Nullable
|
||||
public static HighlightInfo checkUnhandledExceptions(final PsiElement element, TextRange fixRange) {
|
||||
final List<PsiClassType> unhandledExceptions = ExceptionUtil.getUnhandledExceptions(element);
|
||||
if (unhandledExceptions.isEmpty()) return null;
|
||||
|
||||
final HighlightInfoType highlightType = getUnhandledExceptionHighlightType(element);
|
||||
if (highlightType == null) return null;
|
||||
|
||||
if (fixRange == null) fixRange = element.getTextRange();
|
||||
final String description = getUnhandledExceptionsDescriptor(unhandledExceptions);
|
||||
final HighlightInfo errorResult = HighlightInfo.createHighlightInfo(highlightType, fixRange, description);
|
||||
registerUnhandledExceptionFixes(element, errorResult, unhandledExceptions);
|
||||
return errorResult;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static HighlightInfo checkUnhandledCloserExceptions(final PsiResource resource) {
|
||||
final List<PsiClassType> unhandled = ExceptionUtil.getUnhandledCloserExceptions(resource, null);
|
||||
if (unhandled.isEmpty()) return null;
|
||||
|
||||
final HighlightInfoType highlightType = getUnhandledExceptionHighlightType(resource);
|
||||
if (highlightType == null) return null;
|
||||
|
||||
final String description = getUnhandledExceptionsDescriptor(unhandled, "auto-closeable resource");
|
||||
final HighlightInfo highlight = HighlightInfo.createHighlightInfo(highlightType, resource, description);
|
||||
registerUnhandledExceptionFixes(resource, highlight, unhandled);
|
||||
return highlight;
|
||||
}
|
||||
|
||||
private static void registerUnhandledExceptionFixes(final PsiElement element,
|
||||
final HighlightInfo errorResult,
|
||||
final List<PsiClassType> unhandled) {
|
||||
QuickFixAction.registerQuickFixAction(errorResult, new AddExceptionToCatchFix());
|
||||
QuickFixAction.registerQuickFixAction(errorResult, new AddExceptionToThrowsFix(element));
|
||||
QuickFixAction.registerQuickFixAction(errorResult, new SurroundWithTryCatchFix(element));
|
||||
if (unhandled.size() == 1) {
|
||||
QuickFixAction.registerQuickFixAction(errorResult, new GeneralizeCatchFix(element, unhandled.get(0)));
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static HighlightInfoType getUnhandledExceptionHighlightType(final PsiElement element) {
|
||||
if (!JspPsiUtil.isInJspFile(element)) {
|
||||
return HighlightInfoType.UNHANDLED_EXCEPTION;
|
||||
@@ -697,6 +726,7 @@ public class HighlightUtil {
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
static HighlightInfo checkIllegalModifierCombination(PsiKeyword keyword, PsiModifierList modifierList) {
|
||||
@Modifier String modifier = keyword.getText();
|
||||
String incompatible = getIncompatibleModifier(modifier, modifierList);
|
||||
@@ -864,13 +894,11 @@ public class HighlightUtil {
|
||||
assert tryBlock != null : statement;
|
||||
thrownTypes.addAll(ExceptionUtil.collectUnhandledExceptions(tryBlock, tryBlock));
|
||||
|
||||
final PsiParameterList resources = statement.getResourceList();
|
||||
final PsiResourceList resources = statement.getResourceList();
|
||||
if (resources != null) {
|
||||
thrownTypes.addAll(ExceptionUtil.collectUnhandledExceptions(resources, resources));
|
||||
}
|
||||
|
||||
// todo: add exceptions from resource's close() method
|
||||
|
||||
final PsiType caughtType = parameter.getType();
|
||||
if (caughtType instanceof PsiClassType) {
|
||||
return checkSimpleCatchParameter(parameter, thrownTypes, (PsiClassType)caughtType);
|
||||
@@ -950,6 +978,7 @@ public class HighlightUtil {
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
public static HighlightInfo checkSwitchSelectorType(PsiSwitchStatement statement) {
|
||||
PsiExpression expression = statement.getExpression();
|
||||
HighlightInfo errorResult = null;
|
||||
@@ -1110,19 +1139,32 @@ public class HighlightUtil {
|
||||
|
||||
|
||||
@Nullable
|
||||
public static HighlightInfo checkCatchParameterIsThrowable(PsiParameter parameter) {
|
||||
public static HighlightInfo checkCatchParameterIsThrowable(final PsiParameter parameter) {
|
||||
if (parameter.getDeclarationScope() instanceof PsiCatchSection) {
|
||||
PsiType type = parameter.getType();
|
||||
final PsiType type = parameter.getType();
|
||||
return checkMustBeThrowable(type, parameter, true);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void checkArrayInitalizer(final PsiExpression initializer, final HighlightInfoHolder holder) {
|
||||
if (! (initializer instanceof PsiArrayInitializerExpression)) return;
|
||||
@Nullable
|
||||
public static HighlightInfo checkTryResourceIsAutoCloseable(@NotNull final PsiResource resource) {
|
||||
final PsiType type = resource.getType();
|
||||
if (type == null) return null;
|
||||
|
||||
final PsiElementFactory factory = JavaPsiFacade.getInstance(resource.getProject()).getElementFactory();
|
||||
final PsiClassType autoCloseable = factory.createTypeByFQClassName("java.lang.AutoCloseable", resource.getResolveScope());
|
||||
if (TypeConversionUtil.isAssignable(autoCloseable, type)) return null;
|
||||
|
||||
return createIncompatibleTypeHighlightInfo(autoCloseable, type, resource.getTextRange());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Collection<HighlightInfo> checkArrayInitializer(final PsiExpression initializer) {
|
||||
if (! (initializer instanceof PsiArrayInitializerExpression)) return null;
|
||||
|
||||
final PsiType arrayInitializerType = initializer.getType();
|
||||
if (! (arrayInitializerType instanceof PsiArrayType)) return;
|
||||
if (! (arrayInitializerType instanceof PsiArrayType)) return null;
|
||||
|
||||
final PsiType componentType = ((PsiArrayType) arrayInitializerType).getComponentType();
|
||||
final PsiArrayInitializerExpression arrayInitializer = (PsiArrayInitializerExpression) initializer;
|
||||
@@ -1130,11 +1172,12 @@ public class HighlightUtil {
|
||||
boolean arrayTypeFixChecked = false;
|
||||
VariableArrayTypeFix fix = null;
|
||||
|
||||
final Collection<HighlightInfo> result = Lists.newArrayList();
|
||||
final PsiExpression[] initializers = arrayInitializer.getInitializers();
|
||||
for (PsiExpression expression : initializers) {
|
||||
final HighlightInfo info = checkArrayInitalizerCompatibleTypes(expression, componentType);
|
||||
final HighlightInfo info = checkArrayInitializerCompatibleTypes(expression, componentType);
|
||||
if (info != null) {
|
||||
holder.add(info);
|
||||
result.add(info);
|
||||
|
||||
if (!arrayTypeFixChecked) {
|
||||
final PsiType checkResult = sameType(initializers);
|
||||
@@ -1146,6 +1189,7 @@ public class HighlightUtil {
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -1157,6 +1201,7 @@ public class HighlightUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiType sameType(PsiExpression[] expressions) {
|
||||
PsiType type = null;
|
||||
for (PsiExpression expression : expressions) {
|
||||
@@ -1178,7 +1223,7 @@ public class HighlightUtil {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static HighlightInfo checkArrayInitalizerCompatibleTypes(PsiExpression initializer, final PsiType componentType) {
|
||||
private static HighlightInfo checkArrayInitializerCompatibleTypes(PsiExpression initializer, final PsiType componentType) {
|
||||
PsiType initializerType = initializer.getType();
|
||||
if (initializerType == null) {
|
||||
return HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, initializer,
|
||||
@@ -1212,16 +1257,12 @@ public class HighlightUtil {
|
||||
PsiVariable variable = (PsiVariable)parent;
|
||||
if (variable.getType() instanceof PsiArrayType) return null;
|
||||
}
|
||||
else if (parent instanceof PsiNewExpression) {
|
||||
else if (parent instanceof PsiNewExpression || parent instanceof PsiArrayInitializerExpression) {
|
||||
return null;
|
||||
}
|
||||
else if (parent instanceof PsiArrayInitializerExpression) {
|
||||
return null;
|
||||
}
|
||||
HighlightInfo info =
|
||||
HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, expression, JavaErrorMessages.message("expression.expected"));
|
||||
QuickFixAction.registerQuickFixAction(info, new AddNewArrayExpressionFix(expression));
|
||||
|
||||
HighlightInfo info = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, expression, JavaErrorMessages.message("expression.expected"));
|
||||
QuickFixAction.registerQuickFixAction(info, new AddNewArrayExpressionFix(expression));
|
||||
return info;
|
||||
}
|
||||
|
||||
@@ -1393,13 +1434,11 @@ public class HighlightUtil {
|
||||
if (typeOwner instanceof PsiMethod) {
|
||||
if (((PsiMethod)typeOwner).getReturnTypeElement() == parent) return null;
|
||||
}
|
||||
else if (typeOwner instanceof PsiClassObjectAccessExpression &&
|
||||
TypeConversionUtil.isVoidType(((PsiClassObjectAccessExpression)typeOwner).getOperand().getType())) {
|
||||
// like in Class c = void.class;
|
||||
return null;
|
||||
}
|
||||
else if (typeOwner != null && PsiUtilBase.hasErrorElementChild(typeOwner)) {
|
||||
// do not highlight incomplete declarations
|
||||
else if (// like in Class c = void.class;
|
||||
typeOwner instanceof PsiClassObjectAccessExpression &&
|
||||
TypeConversionUtil.isVoidType(((PsiClassObjectAccessExpression)typeOwner).getOperand().getType()) ||
|
||||
// do not highlight incomplete declarations
|
||||
typeOwner != null && PsiUtilBase.hasErrorElementChild(typeOwner)) {
|
||||
return null;
|
||||
}
|
||||
else if (typeOwner instanceof JavaCodeFragment) {
|
||||
@@ -1510,6 +1549,7 @@ public class HighlightUtil {
|
||||
return checkReferenceToOurInstanceInsideThisOrSuper(expression, referencedClass, resolvedName);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static HighlightInfo checkReferenceToOurInstanceInsideThisOrSuper(final PsiElement expression,
|
||||
final PsiClass referencedClass,
|
||||
final String resolvedName) {
|
||||
@@ -1551,6 +1591,7 @@ public class HighlightUtil {
|
||||
return HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, textRange, description);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static HighlightInfo checkImplicitThisReferenceBeforeSuper(PsiClass aClass) {
|
||||
if (aClass instanceof PsiAnonymousClass) return null;
|
||||
PsiClass superClass = aClass.getSuperClass();
|
||||
@@ -1589,6 +1630,7 @@ public class HighlightUtil {
|
||||
return element != null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String getMethodExpressionName(PsiElement element) {
|
||||
if (!(element instanceof PsiMethodCallExpression)) return null;
|
||||
PsiReferenceExpression methodExpression = ((PsiMethodCallExpression)element).getMethodExpression();
|
||||
@@ -2082,6 +2124,7 @@ public class HighlightUtil {
|
||||
return aClass == null || isSerializable(aClass);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static HighlightInfo checkClassReferenceAfterQualifier(final PsiReferenceExpression expression, final PsiElement resolved) {
|
||||
if (!(resolved instanceof PsiClass)) return null;
|
||||
final PsiExpression qualifier = expression.getQualifierExpression();
|
||||
|
||||
+11
-4
@@ -342,7 +342,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
}
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightControlFlowUtil.checkCannotWriteToFinal(expression));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkVariableExpected(expression));
|
||||
if (!myHolder.hasErrorResults()) HighlightUtil.checkArrayInitalizer(expression, myHolder);
|
||||
if (!myHolder.hasErrorResults()) myHolder.addAll(HighlightUtil.checkArrayInitializer(expression));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkTernaryOperatorConditionIsBoolean(expression));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkAssertOperatorTypes(expression));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkSynchronizedExpressionType(expression));
|
||||
@@ -820,7 +820,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
if (!myHolder.hasErrorResults()) {
|
||||
myHolder.add(HighlightControlFlowUtil.checkFinalVariableMightAlreadyHaveBeenAssignedTo(variable, expression, myFinalVarProblems));
|
||||
}
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightControlFlowUtil.checkFinalVariableInitalizedInLoop(expression, resolved));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightControlFlowUtil.checkFinalVariableInitializedInLoop(expression, resolved));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -897,8 +897,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
@Override public void visitTryStatement(PsiTryStatement statement) {
|
||||
super.visitTryStatement(statement);
|
||||
if (!myHolder.hasErrorResults()) {
|
||||
PsiParameter[] parameters = statement.getCatchBlockParameters();
|
||||
for (PsiParameter parameter : parameters) {
|
||||
for (PsiParameter parameter : statement.getCatchBlockParameters()) {
|
||||
myHolder.addAll(HighlightUtil.checkExceptionThrownInTry(parameter));
|
||||
myHolder.add(HighlightUtil.checkCatchParameterIsThrowable(parameter));
|
||||
myHolder.add(GenericsHighlightUtil.checkCatchParameterIsClass(parameter));
|
||||
@@ -906,6 +905,14 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitResource(final PsiResource resource) {
|
||||
myHolder.add(HighlightUtil.checkTryResourceIsAutoCloseable(resource));
|
||||
if (!myHolder.hasErrorResults()) {
|
||||
myHolder.add(HighlightUtil.checkUnhandledCloserExceptions(resource));
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void visitTypeElement(PsiTypeElement type) {
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkIllegalType(type));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkReferenceTypeUsedAsTypeArgument(type));
|
||||
|
||||
+10
-16
@@ -24,7 +24,6 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.impl.JavaPsiFacadeEx;
|
||||
import com.intellij.psi.util.PsiFormatUtil;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
@@ -61,23 +60,18 @@ public class CreateMethodQuickFix implements LocalQuickFix {
|
||||
}
|
||||
|
||||
public void applyFix(@NotNull final Project project, @NotNull final ProblemDescriptor descriptor) {
|
||||
try {
|
||||
if (!CodeInsightUtilBase.preparePsiElementForWrite(myTargetClass.getContainingFile())) return;
|
||||
if (!CodeInsightUtilBase.preparePsiElementForWrite(myTargetClass.getContainingFile())) return;
|
||||
|
||||
PsiMethod method = createMethod(project);
|
||||
List<Pair<PsiExpression, PsiType>> arguments =
|
||||
ContainerUtil.map2List(method.getParameterList().getParameters(), new Function<PsiParameter, Pair<PsiExpression, PsiType>>() {
|
||||
public Pair<PsiExpression, PsiType> fun(PsiParameter psiParameter) {
|
||||
return Pair.create(null, psiParameter.getType());
|
||||
}
|
||||
});
|
||||
PsiMethod method = createMethod(project);
|
||||
List<Pair<PsiExpression, PsiType>> arguments =
|
||||
ContainerUtil.map2List(method.getParameterList().getParameters(), new Function<PsiParameter, Pair<PsiExpression, PsiType>>() {
|
||||
public Pair<PsiExpression, PsiType> fun(PsiParameter psiParameter) {
|
||||
return Pair.create(null, psiParameter.getType());
|
||||
}
|
||||
});
|
||||
|
||||
method = (PsiMethod)JavaCodeStyleManager.getInstance(project).shortenClassReferences((PsiMethod)myTargetClass.add(method));
|
||||
CreateMethodFromUsageFix.doCreate(myTargetClass, method, arguments, PsiSubstitutor.EMPTY, ExpectedTypeInfo.EMPTY_ARRAY, method);
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
method = (PsiMethod)JavaCodeStyleManager.getInstance(project).shortenClassReferences((PsiMethod)myTargetClass.add(method));
|
||||
CreateMethodFromUsageFix.doCreate(myTargetClass, method, arguments, PsiSubstitutor.EMPTY, ExpectedTypeInfo.EMPTY_ARRAY, method);
|
||||
}
|
||||
|
||||
private PsiMethod createMethod(Project project) {
|
||||
|
||||
@@ -22,6 +22,7 @@ import com.intellij.codeInsight.daemon.impl.actions.AddImportAction;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.codeInspection.LocalQuickFix;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.compiler.ModuleCompilerUtil;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.openapi.application.Result;
|
||||
@@ -42,8 +43,6 @@ import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.compiler.ModuleCompilerUtil;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -72,12 +71,7 @@ public abstract class OrderEntryFix implements IntentionAction, LocalQuickFix {
|
||||
}
|
||||
|
||||
public void applyFix(@NotNull final Project project, @NotNull final ProblemDescriptor descriptor) {
|
||||
try {
|
||||
invoke(project, null, descriptor.getPsiElement().getContainingFile());
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
invoke(project, null, descriptor.getPsiElement().getContainingFile());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
+45
-39
@@ -27,21 +27,19 @@ import com.intellij.psi.scope.processor.VariablesNotProcessor;
|
||||
import com.intellij.psi.scope.util.PsiScopesUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: cdr
|
||||
* @author cdr
|
||||
* Date: Nov 20, 2002
|
||||
* Time: 3:01:25 PM
|
||||
* To change this template use Options | File Templates.
|
||||
*/
|
||||
public class ReuseVariableDeclarationFix implements IntentionAction {
|
||||
private final PsiVariable variable;
|
||||
private final PsiIdentifier identifier;
|
||||
private final PsiVariable myVariable;
|
||||
private final PsiIdentifier myIdentifier;
|
||||
|
||||
public ReuseVariableDeclarationFix(PsiVariable variable, PsiIdentifier identifier) {
|
||||
this.variable = variable;
|
||||
this.identifier = identifier;
|
||||
public ReuseVariableDeclarationFix(final PsiVariable variable, final PsiIdentifier identifier) {
|
||||
this.myVariable = variable;
|
||||
this.myIdentifier = identifier;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -51,55 +49,63 @@ public class ReuseVariableDeclarationFix implements IntentionAction {
|
||||
|
||||
@NotNull
|
||||
public String getText() {
|
||||
return QuickFixBundle.message("reuse.variable.declaration.text", variable.getName());
|
||||
return QuickFixBundle.message("reuse.variable.declaration.text", myVariable.getName());
|
||||
}
|
||||
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
|
||||
|
||||
PsiVariable previousVariable = findPreviousVariable();
|
||||
return
|
||||
variable != null
|
||||
&& variable.isValid()
|
||||
&& variable instanceof PsiLocalVariable
|
||||
&& previousVariable != null
|
||||
&& Comparing.equal(previousVariable.getType(), variable.getType())
|
||||
&& identifier != null
|
||||
&& identifier.isValid()
|
||||
&& variable.getManager().isInProject(variable);
|
||||
public boolean isAvailable(@NotNull final Project project, final Editor editor, final PsiFile file) {
|
||||
final PsiVariable previousVariable = findPreviousVariable();
|
||||
return myVariable != null &&
|
||||
myVariable.isValid() &&
|
||||
myVariable instanceof PsiLocalVariable &&
|
||||
!(myVariable.getParent() instanceof PsiResource && myVariable.getInitializer() == null) &&
|
||||
previousVariable != null &&
|
||||
Comparing.equal(previousVariable.getType(), myVariable.getType()) &&
|
||||
myIdentifier != null &&
|
||||
myIdentifier.isValid() &&
|
||||
myVariable.getManager().isInProject(myVariable);
|
||||
}
|
||||
|
||||
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
|
||||
PsiVariable refVariable = findPreviousVariable();
|
||||
public void invoke(@NotNull final Project project, final Editor editor, final PsiFile file) throws IncorrectOperationException {
|
||||
final PsiVariable refVariable = findPreviousVariable();
|
||||
if (refVariable == null) return;
|
||||
if (!CodeInsightUtil.preparePsiElementsForWrite(variable, refVariable)) return;
|
||||
PsiUtil.setModifierProperty(refVariable, PsiModifier.FINAL, false);
|
||||
if (variable.getInitializer() == null) {
|
||||
variable.delete();
|
||||
|
||||
if (!CodeInsightUtil.preparePsiElementsForWrite(myVariable, refVariable)) return;
|
||||
|
||||
final PsiExpression initializer = myVariable.getInitializer();
|
||||
if (initializer == null) {
|
||||
myVariable.delete();
|
||||
return;
|
||||
}
|
||||
PsiDeclarationStatement declaration = (PsiDeclarationStatement) variable.getParent();
|
||||
PsiElementFactory factory = JavaPsiFacade.getInstance(variable.getProject()).getElementFactory();
|
||||
PsiStatement statement = factory.createStatementFromText(variable.getName() + " = " + variable.getInitializer().getText()+";", variable);
|
||||
declaration.replace(statement);
|
||||
|
||||
PsiUtil.setModifierProperty(refVariable, PsiModifier.FINAL, false);
|
||||
|
||||
final PsiElementFactory factory = JavaPsiFacade.getInstance(myVariable.getProject()).getElementFactory();
|
||||
final PsiElement replacement;
|
||||
final PsiElement parent = myVariable.getParent();
|
||||
if (parent instanceof PsiResource) {
|
||||
replacement = factory.createResourceFromText(myVariable.getName() + " = " + initializer.getText(), null);
|
||||
}
|
||||
else {
|
||||
replacement = factory.createStatementFromText(myVariable.getName() + " = " + initializer.getText() + ";", null);
|
||||
}
|
||||
parent.replace(replacement);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PsiVariable findPreviousVariable() {
|
||||
PsiElement scope = variable.getParent();
|
||||
PsiElement scope = myVariable.getParent();
|
||||
while (scope != null) {
|
||||
if (scope instanceof PsiFile || scope instanceof PsiMethod || scope instanceof PsiClassInitializer) break;
|
||||
scope = scope.getParent();
|
||||
}
|
||||
if (scope == null) return null;
|
||||
VariablesNotProcessor proc = new VariablesNotProcessor(variable, false);
|
||||
PsiScopesUtil.treeWalkUp(proc, identifier, scope);
|
||||
|
||||
if(proc.size() > 0)
|
||||
return proc.getResult(0);
|
||||
return null;
|
||||
final VariablesNotProcessor proc = new VariablesNotProcessor(myVariable, false);
|
||||
PsiScopesUtil.treeWalkUp(proc, myIdentifier, scope);
|
||||
return proc.size() > 0 ? proc.getResult(0) : null;
|
||||
}
|
||||
|
||||
public boolean startInWriteAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -117,6 +117,11 @@ public class JavadocTypedHandler extends TypedHandlerDelegate {
|
||||
return null;
|
||||
}
|
||||
return text.subSequence(i + 1, endOffset).toString();
|
||||
|
||||
// There is a possible case that opening tag has attributes, e.g. <a href='bla-bla-bla'>[offset]. We want to extract
|
||||
// only tag name then.
|
||||
case ' ':
|
||||
case '\t': endOffset = i;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -221,6 +221,11 @@ public class JavaDocInfoGenerator {
|
||||
else if (myElement instanceof PsiVariable) {
|
||||
generateVariableJavaDoc(buffer, (PsiVariable)myElement);
|
||||
}
|
||||
else if (myElement instanceof PsiDirectory) {
|
||||
final PsiPackage aPackage = JavaDirectoryService.getInstance().getPackage((PsiDirectory)myElement);
|
||||
if (aPackage == null) return null;
|
||||
generatePackageJavaDoc(buffer, aPackage);
|
||||
}
|
||||
else if (myElement instanceof PsiPackage) {
|
||||
generatePackageJavaDoc(buffer, (PsiPackage) myElement);
|
||||
} else {
|
||||
|
||||
@@ -2,10 +2,11 @@ package com.intellij.codeInsight.lookup;
|
||||
|
||||
import com.intellij.codeInsight.AutoPopupController;
|
||||
import com.intellij.codeInsight.TailType;
|
||||
import com.intellij.codeInsight.completion.CodeCompletionFeatures;
|
||||
import com.intellij.codeInsight.completion.InsertionContext;
|
||||
import com.intellij.psi.PsiSubstitutor;
|
||||
import com.intellij.psi.PsiType;
|
||||
import com.intellij.psi.PsiVariable;
|
||||
import com.intellij.featureStatistics.FeatureUsageTracker;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@@ -34,17 +35,27 @@ public class VariableLookupItem extends LookupItem<PsiVariable> implements Typed
|
||||
public void handleInsert(InsertionContext context) {
|
||||
super.handleInsert(context);
|
||||
|
||||
if (context.getCompletionChar() == '=') {
|
||||
final char completionChar = context.getCompletionChar();
|
||||
if (completionChar == '=') {
|
||||
context.setAddCompletionChar(false);
|
||||
TailType.EQ.processTail(context.getEditor(), context.getTailOffset());
|
||||
}
|
||||
else if (context.getCompletionChar() == ',' && getAttribute(LookupItem.TAIL_TYPE_ATTR) != TailType.UNKNOWN) {
|
||||
else if (completionChar == ',' && getAttribute(LookupItem.TAIL_TYPE_ATTR) != TailType.UNKNOWN) {
|
||||
context.setAddCompletionChar(false);
|
||||
TailType.COMMA.processTail(context.getEditor(), context.getTailOffset());
|
||||
}
|
||||
else if (context.getCompletionChar() == '.') {
|
||||
else if (completionChar == '.') {
|
||||
AutoPopupController.getInstance(context.getProject()).autoPopupMemberLookup(context.getEditor(), null);
|
||||
}
|
||||
else if (completionChar == '!' && PsiType.BOOLEAN.isAssignableFrom(getObject().getType())) {
|
||||
context.setAddCompletionChar(false);
|
||||
final PsiReferenceExpression ref = PsiTreeUtil.findElementOfClassAtOffset(context.getFile(), context.getTailOffset() - 1, PsiReferenceExpression.class, false);
|
||||
if (ref != null) {
|
||||
FeatureUsageTracker.getInstance().triggerFeatureUsed(CodeCompletionFeatures.EXCLAMATION_FINISH);
|
||||
context.getDocument().insertString(ref.getTextRange().getStartOffset(), "!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+30
-3
@@ -15,12 +15,14 @@
|
||||
*/
|
||||
package com.intellij.codeInspection;
|
||||
|
||||
import com.intellij.codeInsight.CodeInsightUtilBase;
|
||||
import com.intellij.codeInsight.daemon.GroupNames;
|
||||
import com.intellij.codeInsight.intention.HighPriorityAction;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -65,15 +67,39 @@ public class ExplicitTypeCanBeDiamondInspection extends BaseJavaLocalInspectionT
|
||||
@Override
|
||||
public void visitNewExpression(PsiNewExpression expression) {
|
||||
if (PsiUtil.getLanguageLevel(expression).isAtLeast(LanguageLevel.JDK_1_7)) {
|
||||
final PsiJavaCodeReferenceElement classReference = expression.getClassReference();
|
||||
final PsiJavaCodeReferenceElement classReference = expression.getClassOrAnonymousClassReference();
|
||||
if (classReference != null) {
|
||||
final PsiReferenceParameterList parameterList = classReference.getParameterList();
|
||||
if (parameterList != null) {
|
||||
final PsiTypeElement[] typeElements = parameterList.getTypeParameterElements();
|
||||
if (typeElements.length > 0) {
|
||||
if (typeElements.length == 1 && typeElements[0].getType() instanceof PsiDiamondType) return;
|
||||
holder.registerProblem(parameterList, "Redundant type argument #ref #loc",
|
||||
ProblemHighlightType.LIKE_UNUSED_SYMBOL, new ReplaceWithDiamondFix());
|
||||
final PsiDiamondType.DiamondInferenceResult inferenceResult = PsiDiamondType.resolveInferredTypes(expression);
|
||||
if (inferenceResult.getErrorMessage() == null) {
|
||||
final PsiType[] types = inferenceResult.getTypes();
|
||||
final PsiType[] typeArguments = parameterList.getTypeArguments();
|
||||
if (types.length == typeArguments.length) {
|
||||
for (int i = 0, typeArgumentsLength = typeArguments.length; i < typeArgumentsLength; i++) {
|
||||
PsiType typeArgument = typeArguments[i];
|
||||
if (types[i] instanceof PsiWildcardType) {
|
||||
final PsiWildcardType wildcardType = (PsiWildcardType)types[i];
|
||||
final PsiType bound = wildcardType.getBound();
|
||||
if (bound != null) {
|
||||
if (wildcardType.isExtends()) {
|
||||
if (bound.isAssignableFrom(typeArgument)) continue;
|
||||
} else {
|
||||
if (typeArgument.isAssignableFrom(bound)) continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!typeArgument.equals(types[i])) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
holder.registerProblem(parameterList, "Redundant type argument #ref #loc",
|
||||
ProblemHighlightType.LIKE_UNUSED_SYMBOL, new ReplaceWithDiamondFix());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -99,6 +125,7 @@ public class ExplicitTypeCanBeDiamondInspection extends BaseJavaLocalInspectionT
|
||||
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
|
||||
final PsiElement psiElement = descriptor.getPsiElement();
|
||||
if (psiElement instanceof PsiReferenceParameterList) {
|
||||
if (!CodeInsightUtilBase.prepareFileForWrite(psiElement.getContainingFile())) return;
|
||||
final PsiTypeElement[] parameterElements = ((PsiReferenceParameterList)psiElement).getTypeParameterElements();
|
||||
psiElement.deleteChildRange(parameterElements[0], parameterElements[parameterElements.length - 1]);
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ public class DefUseInspection extends BaseLocalInspectionTool {
|
||||
PsiElement context = info.getContext();
|
||||
PsiVariable psiVariable = info.getVariable();
|
||||
|
||||
if (context instanceof PsiDeclarationStatement) {
|
||||
if (context instanceof PsiDeclarationStatement || context instanceof PsiResource) {
|
||||
if (!info.isRead()) {
|
||||
if (!isOnTheFly) {
|
||||
holder.registerProblem(psiVariable.getNameIdentifier(),
|
||||
|
||||
@@ -220,7 +220,10 @@ public class JavaLanguageCodeStyleSettingsProvider extends LanguageCodeStyleSett
|
||||
" throws Exception { \n" +
|
||||
" foo.foo().bar(\"arg1\", \n" +
|
||||
" \"arg2\"); \n" +
|
||||
" new Object() {};" +
|
||||
" } \n" +
|
||||
" class TestInnerClass {}\n" +
|
||||
" interface TestInnerInterface {}\n" +
|
||||
"}\n" +
|
||||
"\n" +
|
||||
"enum Breed {\n" +
|
||||
|
||||
@@ -23,6 +23,7 @@ import com.intellij.openapi.roots.ui.util.ModifiableCellAppearance;
|
||||
import com.intellij.openapi.util.Iconable;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiFormatUtil;
|
||||
import com.intellij.psi.util.PsiFormatUtilBase;
|
||||
import com.intellij.ui.ColoredTreeCellRenderer;
|
||||
import com.intellij.ui.SimpleTextAttributes;
|
||||
|
||||
@@ -51,7 +52,8 @@ public class StructureNodeRenderer extends ColoredTreeCellRenderer {
|
||||
ModifiableCellAppearance result;
|
||||
if (psiElement instanceof PsiElement && !((PsiElement)psiElement).isValid()) {
|
||||
result = CompositeAppearance.single(name);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
PsiClass psiClass = getContainingClass(psiElement);
|
||||
if (isInheritedMember(node, psiClass) && psiClass != null) {
|
||||
CompositeAppearance.DequeEnd ending = new CompositeAppearance().getEnding();
|
||||
@@ -84,13 +86,13 @@ public class StructureNodeRenderer extends ColoredTreeCellRenderer {
|
||||
}
|
||||
}
|
||||
|
||||
public static String getNameOf(PsiElement psiElement) {
|
||||
private static String getNameOf(PsiElement psiElement) {
|
||||
if (psiElement instanceof PsiMethod)
|
||||
return PsiFormatUtil.formatMethod((PsiMethod)psiElement,
|
||||
PsiSubstitutor.EMPTY,
|
||||
PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_TYPE | PsiFormatUtil.TYPE_AFTER |
|
||||
PsiFormatUtil.SHOW_PARAMETERS,
|
||||
PsiFormatUtil.SHOW_TYPE
|
||||
PsiFormatUtilBase.SHOW_NAME | PsiFormatUtilBase.SHOW_TYPE | PsiFormatUtilBase.TYPE_AFTER |
|
||||
PsiFormatUtilBase.SHOW_PARAMETERS,
|
||||
PsiFormatUtilBase.SHOW_TYPE
|
||||
);
|
||||
return psiElement.toString();
|
||||
}
|
||||
@@ -109,23 +111,17 @@ public class StructureNodeRenderer extends ColoredTreeCellRenderer {
|
||||
return new SimpleTextAttributes(nameAttributes.getStyle() | SimpleTextAttributes.STYLE_STRIKEOUT, nameAttributes.getFgColor());
|
||||
}
|
||||
|
||||
public static boolean isDeprecated(Object psiElement) {
|
||||
if (psiElement instanceof PsiDocCommentOwner)
|
||||
return ((PsiDocCommentOwner) psiElement).isDeprecated();
|
||||
return false;
|
||||
private static boolean isDeprecated(Object psiElement) {
|
||||
return psiElement instanceof PsiDocCommentOwner && ((PsiDocCommentOwner)psiElement).isDeprecated();
|
||||
}
|
||||
|
||||
public static PsiClass getContainingClass(Object element) {
|
||||
private static PsiClass getContainingClass(Object element) {
|
||||
if (element instanceof PsiMember)
|
||||
return ((PsiMember) element).getContainingClass();
|
||||
if (element instanceof PsiClass) {
|
||||
PsiElement parent = ((PsiClass) element).getParent();
|
||||
return (PsiClass) (parent instanceof PsiClass ? parent : null);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static PsiClass getTreeParentClass(Object value) {
|
||||
private static PsiClass getTreeParentClass(Object value) {
|
||||
if (!(value instanceof TreeNode))
|
||||
return null;
|
||||
for (TreeNode treeNode = ((TreeNode) value).getParent(); treeNode != null; treeNode = treeNode.getParent()) {
|
||||
|
||||
+2
-3
@@ -35,10 +35,8 @@ public class JavaClassTreeElement extends JavaClassTreeElementBase<PsiClass> {
|
||||
}
|
||||
|
||||
private Collection<StructureViewTreeElement> getClassChildren() {
|
||||
ArrayList<StructureViewTreeElement> array = new ArrayList<StructureViewTreeElement>();
|
||||
|
||||
final PsiClass aClass = getElement();
|
||||
if (aClass == null) return array;
|
||||
if (aClass == null) return Collections.emptyList();
|
||||
|
||||
List<PsiElement> children = Arrays.asList(aClass.getChildren());
|
||||
Collection<PsiElement> ownChildren = new THashSet<PsiElement>();
|
||||
@@ -47,6 +45,7 @@ public class JavaClassTreeElement extends JavaClassTreeElementBase<PsiClass> {
|
||||
ContainerUtil.addAll(ownChildren, aClass.getInnerClasses());
|
||||
ContainerUtil.addAll(ownChildren, aClass.getInitializers());
|
||||
Collection<PsiElement> inherited = new LinkedHashSet<PsiElement>(children);
|
||||
List<StructureViewTreeElement> array = new ArrayList<StructureViewTreeElement>(inherited.size());
|
||||
|
||||
aClass.processDeclarations(new AddAllMembersProcessor(inherited, aClass), ResolveState.initial(), null, aClass);
|
||||
|
||||
|
||||
@@ -26,7 +26,6 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
public class JavaFileTreeElement extends PsiTreeElementBase<PsiJavaFile> implements ItemPresentation {
|
||||
|
||||
public JavaFileTreeElement(PsiJavaFile file) {
|
||||
super(file);
|
||||
}
|
||||
|
||||
@@ -31,11 +31,12 @@ import org.jetbrains.annotations.Nullable;
|
||||
import static com.intellij.lang.PsiBuilderUtil.expect;
|
||||
import static com.intellij.lang.PsiBuilderUtil.nextTokenType;
|
||||
import static com.intellij.lang.java.parser.JavaParserUtil.*;
|
||||
import static com.intellij.lang.java.parser.JavaParserUtil.exprType;
|
||||
|
||||
|
||||
public class DeclarationParser {
|
||||
public enum Context {
|
||||
FILE, CLASS, CODE_BLOCK, ANNOTATION_INTERFACE
|
||||
FILE, CLASS, CODE_BLOCK, ANNOTATION_INTERFACE, RESOURCE_LIST
|
||||
}
|
||||
|
||||
private static final TokenSet AFTER_END_DECLARATION_SET = TokenSet.create(JavaElementType.FIELD, JavaElementType.METHOD);
|
||||
@@ -222,7 +223,7 @@ public class DeclarationParser {
|
||||
if (tokenType == null) return null;
|
||||
|
||||
if (tokenType == JavaTokenType.LBRACE) {
|
||||
if (context == Context.FILE || context == Context.CODE_BLOCK) return null;
|
||||
if (context == Context.FILE || context == Context.CODE_BLOCK || context == Context.RESOURCE_LIST) return null;
|
||||
}
|
||||
else if (tokenType == JavaTokenType.IDENTIFIER || ElementType.PRIMITIVE_TYPE_BIT_SET.contains(tokenType)) {
|
||||
if (context == Context.FILE) return null;
|
||||
@@ -234,7 +235,7 @@ public class DeclarationParser {
|
||||
else if (!ElementType.MODIFIER_BIT_SET.contains(tokenType) &&
|
||||
!ElementType.CLASS_KEYWORD_BIT_SET.contains(tokenType) &&
|
||||
tokenType != JavaTokenType.AT &&
|
||||
(context == Context.CODE_BLOCK || tokenType != JavaTokenType.LT)) {
|
||||
(context == Context.CODE_BLOCK || context == Context.RESOURCE_LIST || tokenType != JavaTokenType.LT)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -278,7 +279,7 @@ public class DeclarationParser {
|
||||
final PsiBuilder.Marker idPos = builder.mark();
|
||||
type = parseTypeNotNull(builder);
|
||||
if (builder.getTokenType() == JavaTokenType.LPARENTH) { // constructor
|
||||
if (context == Context.CODE_BLOCK) {
|
||||
if (context == Context.CODE_BLOCK || context == Context.RESOURCE_LIST) {
|
||||
declaration.rollbackTo();
|
||||
return null;
|
||||
}
|
||||
@@ -301,6 +302,10 @@ public class DeclarationParser {
|
||||
declaration.drop();
|
||||
return modList;
|
||||
}
|
||||
else if (context == Context.RESOURCE_LIST) {
|
||||
declaration.rollbackTo();
|
||||
return null;
|
||||
}
|
||||
|
||||
final PsiBuilder.Marker codeBlock = StatementParser.parseCodeBlock(builder);
|
||||
assert codeBlock != null : builder.getOriginalText();
|
||||
@@ -326,7 +331,7 @@ public class DeclarationParser {
|
||||
}
|
||||
|
||||
if (!expect(builder, JavaTokenType.IDENTIFIER)) {
|
||||
if (context == Context.CODE_BLOCK && modListInfo.second) {
|
||||
if ((context == Context.CODE_BLOCK || context == Context.RESOURCE_LIST) && modListInfo.second) {
|
||||
declaration.rollbackTo();
|
||||
return null;
|
||||
}
|
||||
@@ -447,33 +452,33 @@ public class DeclarationParser {
|
||||
|
||||
@NotNull
|
||||
public static PsiBuilder.Marker parseParameterList(final PsiBuilder builder) {
|
||||
return parseParameterList(builder, false);
|
||||
return parseElementList(builder, false);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static PsiBuilder.Marker parseResourceList(final PsiBuilder builder) {
|
||||
return parseParameterList(builder, true);
|
||||
return parseElementList(builder, true);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static PsiBuilder.Marker parseParameterList(final PsiBuilder builder, final boolean resources) {
|
||||
private static PsiBuilder.Marker parseElementList(final PsiBuilder builder, final boolean resources) {
|
||||
assert builder.getTokenType() == JavaTokenType.LPARENTH : builder.getTokenType();
|
||||
final PsiBuilder.Marker paramList = builder.mark();
|
||||
final PsiBuilder.Marker elementList = builder.mark();
|
||||
builder.advanceLexer();
|
||||
|
||||
final IElementType delimiter = resources ? JavaTokenType.SEMICOLON : JavaTokenType.COMMA;
|
||||
final String noDelimiterMsg = JavaErrorMessages.message(resources ? "expected.semicolon" : "expected.comma");
|
||||
final String noParameterMsg = JavaErrorMessages.message(resources ? "expected.resource" : "expected.parameter");
|
||||
final String noElementMsg = JavaErrorMessages.message(resources ? "expected.resource" : "expected.parameter");
|
||||
|
||||
PsiBuilder.Marker invalidElements = null;
|
||||
String errorMessage = null;
|
||||
boolean delimiterExpected = false;
|
||||
int paramCount = 0;
|
||||
int elementCount = 0;
|
||||
while (true) {
|
||||
final IElementType tokenType = builder.getTokenType();
|
||||
if (tokenType == null || tokenType == JavaTokenType.RPARENTH || tokenType == JavaTokenType.LBRACE) {
|
||||
boolean noLastParam = !delimiterExpected && paramCount > 0;
|
||||
if (noLastParam) {
|
||||
boolean noLastElement = !delimiterExpected && elementCount > 0;
|
||||
if (noLastElement) {
|
||||
error(builder, JavaErrorMessages.message("expected.identifier.or.type"));
|
||||
}
|
||||
if (tokenType == JavaTokenType.RPARENTH) {
|
||||
@@ -481,13 +486,13 @@ public class DeclarationParser {
|
||||
invalidElements.error(errorMessage);
|
||||
invalidElements = null;
|
||||
}
|
||||
else if (resources && paramCount == 0) {
|
||||
else if (resources && elementCount == 0) {
|
||||
error(builder, JavaErrorMessages.message("expected.resource"));
|
||||
}
|
||||
builder.advanceLexer();
|
||||
}
|
||||
else {
|
||||
if (!noLastParam) {
|
||||
if (!noLastElement) {
|
||||
if (invalidElements != null) {
|
||||
invalidElements.error(errorMessage);
|
||||
}
|
||||
@@ -510,27 +515,27 @@ public class DeclarationParser {
|
||||
}
|
||||
}
|
||||
else {
|
||||
final PsiBuilder.Marker param = parseParameter(builder, true, false, resources);
|
||||
if (param != null) {
|
||||
final PsiBuilder.Marker listElement = resources ? parseResource(builder) : parseParameter(builder, true, false);
|
||||
if (listElement != null) {
|
||||
delimiterExpected = true;
|
||||
if (invalidElements != null) {
|
||||
invalidElements.errorBefore(errorMessage, param);
|
||||
invalidElements.errorBefore(errorMessage, listElement);
|
||||
invalidElements = null;
|
||||
}
|
||||
paramCount++;
|
||||
elementCount++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (invalidElements == null) {
|
||||
if (builder.getTokenType() == delimiter) {
|
||||
error(builder, noParameterMsg);
|
||||
error(builder, noElementMsg);
|
||||
builder.advanceLexer();
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
invalidElements = builder.mark();
|
||||
errorMessage = delimiterExpected ? noDelimiterMsg : noParameterMsg;
|
||||
errorMessage = delimiterExpected ? noDelimiterMsg : noElementMsg;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -545,19 +550,19 @@ public class DeclarationParser {
|
||||
invalidElements.error(errorMessage);
|
||||
}
|
||||
|
||||
done(paramList, JavaElementType.PARAMETER_LIST);
|
||||
return paramList;
|
||||
done(elementList, resources ? JavaElementType.RESOURCE_LIST : JavaElementType.PARAMETER_LIST);
|
||||
return elementList;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiBuilder.Marker parseParameter(final PsiBuilder builder, final boolean ellipsis, final boolean disjunction, final boolean value) {
|
||||
public static PsiBuilder.Marker parseParameter(final PsiBuilder builder, final boolean ellipsis, final boolean disjunctiveType) {
|
||||
final PsiBuilder.Marker param = builder.mark();
|
||||
|
||||
final Pair<PsiBuilder.Marker, Boolean> modListInfo = parseModifierList(builder);
|
||||
|
||||
int flags = ReferenceParser.EAT_LAST_DOT | ReferenceParser.WILDCARD;
|
||||
if (ellipsis) flags |= ReferenceParser.ELLIPSIS;
|
||||
if (disjunction) flags |= ReferenceParser.DISJUNCTIONS;
|
||||
if (disjunctiveType) flags |= ReferenceParser.DISJUNCTIONS;
|
||||
final ReferenceParser.TypeInfo typeInfo = ReferenceParser.parseTypeInfo(builder, flags);
|
||||
|
||||
if (typeInfo == null) {
|
||||
@@ -572,23 +577,34 @@ public class DeclarationParser {
|
||||
}
|
||||
|
||||
if (expect(builder, JavaTokenType.IDENTIFIER)) {
|
||||
eatBrackets(builder, typeInfo != null && typeInfo.isVarArg || value, JavaErrorMessages.message("expected.rparen"));
|
||||
if (value) {
|
||||
if (expectOrError(builder, JavaTokenType.EQ, JavaErrorMessages.message("expected.eq"))) {
|
||||
if (ExpressionParser.parse(builder) == null) {
|
||||
error(builder, JavaErrorMessages.message("expected.expression"));
|
||||
}
|
||||
}
|
||||
}
|
||||
eatBrackets(builder, typeInfo != null && typeInfo.isVarArg, JavaErrorMessages.message("expected.rparen"));
|
||||
done(param, JavaElementType.PARAMETER);
|
||||
return param;
|
||||
}
|
||||
else {
|
||||
error(builder, JavaErrorMessages.message("expected.identifier"));
|
||||
param.drop();
|
||||
return modListInfo.first;
|
||||
}
|
||||
}
|
||||
|
||||
done(param, JavaElementType.PARAMETER);
|
||||
return param;
|
||||
@Nullable
|
||||
public static PsiBuilder.Marker parseResource(final PsiBuilder builder) {
|
||||
PsiBuilder.Marker element = parse(builder, Context.RESOURCE_LIST);
|
||||
if (exprType(element) == JavaElementType.MODIFIER_LIST) {
|
||||
return element;
|
||||
}
|
||||
else if (element == null) {
|
||||
element = ExpressionParser.parse(builder);
|
||||
}
|
||||
|
||||
if (element != null) {
|
||||
final PsiBuilder.Marker resource = element.precede();
|
||||
done(resource, JavaElementType.RESOURCE);
|
||||
return resource;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -598,7 +614,7 @@ public class DeclarationParser {
|
||||
if (context == Context.CLASS || context == Context.ANNOTATION_INTERFACE) {
|
||||
varType = JavaElementType.FIELD;
|
||||
}
|
||||
else if (context == Context.CODE_BLOCK) {
|
||||
else if (context == Context.CODE_BLOCK || context == Context.RESOURCE_LIST) {
|
||||
varType = JavaElementType.LOCAL_VARIABLE;
|
||||
}
|
||||
else {
|
||||
@@ -629,6 +645,11 @@ public class DeclarationParser {
|
||||
unclosed = true;
|
||||
break;
|
||||
}
|
||||
if (context == Context.RESOURCE_LIST) break;
|
||||
}
|
||||
else if (context == Context.RESOURCE_LIST) {
|
||||
error(builder, JavaErrorMessages.message("expected.eq"));
|
||||
break;
|
||||
}
|
||||
|
||||
if (builder.getTokenType() != JavaTokenType.COMMA) break;
|
||||
@@ -647,26 +668,28 @@ public class DeclarationParser {
|
||||
builder.advanceLexer();
|
||||
}
|
||||
|
||||
if (builder.getTokenType() == JavaTokenType.SEMICOLON && eatSemicolon) {
|
||||
builder.advanceLexer();
|
||||
}
|
||||
else {
|
||||
// special treatment (see DeclarationParserTest.testMultiLineUnclosed())
|
||||
if (!builder.eof() && shouldRollback) {
|
||||
final CharSequence text = builder.getOriginalText();
|
||||
final int spaceEnd = builder.getCurrentOffset();
|
||||
final int spaceStart = CharArrayUtil.shiftBackward(text, spaceEnd-1, WHITESPACES);
|
||||
final int lineStart = CharArrayUtil.shiftBackwardUntil(text, spaceEnd, LINE_ENDS);
|
||||
|
||||
if (declarationStart < lineStart && lineStart < spaceStart) {
|
||||
final int newBufferEnd = CharArrayUtil.shiftForward(text, lineStart, WHITESPACES);
|
||||
declaration.rollbackTo();
|
||||
return parse(stoppingBuilder(builder, newBufferEnd), context);
|
||||
}
|
||||
if (context != Context.RESOURCE_LIST) {
|
||||
if (builder.getTokenType() == JavaTokenType.SEMICOLON && eatSemicolon) {
|
||||
builder.advanceLexer();
|
||||
}
|
||||
else {
|
||||
// special treatment (see DeclarationParserTest.testMultiLineUnclosed())
|
||||
if (!builder.eof() && shouldRollback) {
|
||||
final CharSequence text = builder.getOriginalText();
|
||||
final int spaceEnd = builder.getCurrentOffset();
|
||||
final int spaceStart = CharArrayUtil.shiftBackward(text, spaceEnd-1, WHITESPACES);
|
||||
final int lineStart = CharArrayUtil.shiftBackwardUntil(text, spaceEnd, LINE_ENDS);
|
||||
|
||||
if (!unclosed) {
|
||||
error(builder, JavaErrorMessages.message("expected.semicolon"));
|
||||
if (declarationStart < lineStart && lineStart < spaceStart) {
|
||||
final int newBufferEnd = CharArrayUtil.shiftForward(text, lineStart, WHITESPACES);
|
||||
declaration.rollbackTo();
|
||||
return parse(stoppingBuilder(builder, newBufferEnd), context);
|
||||
}
|
||||
}
|
||||
|
||||
if (!unclosed) {
|
||||
error(builder, JavaErrorMessages.message("expected.semicolon"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -375,7 +375,7 @@ public class StatementParser {
|
||||
}
|
||||
|
||||
final PsiBuilder.Marker afterParenth = builder.mark();
|
||||
final PsiBuilder.Marker param = DeclarationParser.parseParameter(builder, false, false, false);
|
||||
final PsiBuilder.Marker param = DeclarationParser.parseParameter(builder, false, false);
|
||||
if (param == null || JavaParserUtil.exprType(param) != JavaElementType.PARAMETER || builder.getTokenType() != JavaTokenType.COLON) {
|
||||
afterParenth.rollbackTo();
|
||||
return parseForLoopFromInitialization(builder, statement);
|
||||
@@ -657,7 +657,7 @@ public class StatementParser {
|
||||
return false;
|
||||
}
|
||||
|
||||
final PsiBuilder.Marker param = DeclarationParser.parseParameter(builder, false, areMultiCatchSupported(builder), false);
|
||||
final PsiBuilder.Marker param = DeclarationParser.parseParameter(builder, false, areMultiCatchSupported(builder));
|
||||
if (param == null) {
|
||||
error(builder, JavaErrorMessages.message("expected.parameter"));
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ public class PomJavaAspectImpl extends PomJavaAspect implements ProjectComponent
|
||||
if(changeSet == null) return;
|
||||
final PsiFile containingFile = changeSet.getRootElement().getPsi().getContainingFile();
|
||||
if(!(containingFile.getLanguage() instanceof JavaLanguage)) return;
|
||||
final PomJavaAspectChangeSet set = new PomJavaAspectChangeSet(myPomModel, containingFile);
|
||||
final PomJavaAspectChangeSet set = new PomJavaAspectChangeSet(myPomModel);
|
||||
set.addChange(new JavaTreeChanged(containingFile));
|
||||
event.registerChangeSet(this, set);
|
||||
}
|
||||
|
||||
@@ -268,7 +268,6 @@ class ControlFlowAnalyzer extends JavaJspElementVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// generate jump to the top finally block
|
||||
if (!myFinallyBlocks.isEmpty()) {
|
||||
final PsiElement finallyBlock = myFinallyBlocks.peek();
|
||||
@@ -278,13 +277,10 @@ class ControlFlowAnalyzer extends JavaJspElementVisitor {
|
||||
addElementOffsetLater(finallyBlock, true);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void generateCheckedExceptionJumps(PsiElement element) {
|
||||
//generate jumps to all handled exception handlers
|
||||
//if (myCatchBlocks.size() != 0) {
|
||||
//}
|
||||
Collection<PsiClassType> unhandledExceptions = ExceptionUtil.collectUnhandledExceptions(element, element.getParent());
|
||||
for (PsiClassType unhandledException : unhandledExceptions) {
|
||||
ProgressManager.checkCanceled();
|
||||
@@ -478,7 +474,8 @@ class ControlFlowAnalyzer extends JavaJspElementVisitor {
|
||||
finishElement(statement);
|
||||
}
|
||||
|
||||
@Override public void visitDeclarationStatement(PsiDeclarationStatement statement) {
|
||||
@Override
|
||||
public void visitDeclarationStatement(PsiDeclarationStatement statement) {
|
||||
startElement(statement);
|
||||
int pc = myCurrentFlow.getSize();
|
||||
PsiElement[] elements = statement.getDeclaredElements();
|
||||
@@ -488,28 +485,7 @@ class ControlFlowAnalyzer extends JavaJspElementVisitor {
|
||||
element.accept(this);
|
||||
}
|
||||
else if (element instanceof PsiVariable) {
|
||||
PsiExpression initializer = ((PsiVariable)element).getInitializer();
|
||||
if (initializer != null) {
|
||||
myStartStatementStack.pushStatement(initializer, false);
|
||||
myEndStatementStack.pushStatement(initializer, false);
|
||||
initializer.accept(this);
|
||||
myStartStatementStack.popStatement();
|
||||
myEndStatementStack.popStatement();
|
||||
}
|
||||
if (element instanceof PsiLocalVariable && initializer != null
|
||||
|| element instanceof PsiField) {
|
||||
if (element instanceof PsiLocalVariable && !myPolicy.isLocalVariableAccepted((PsiLocalVariable)element)) continue;
|
||||
|
||||
if (myAssignmentTargetsAreElements) {
|
||||
startElement(element);
|
||||
}
|
||||
|
||||
generateWriteInstruction((PsiVariable)element);
|
||||
|
||||
if (myAssignmentTargetsAreElements) {
|
||||
finishElement(element);
|
||||
}
|
||||
}
|
||||
processVariable((PsiVariable)element);
|
||||
}
|
||||
}
|
||||
if (pc == myCurrentFlow.getSize()) {
|
||||
@@ -519,6 +495,31 @@ class ControlFlowAnalyzer extends JavaJspElementVisitor {
|
||||
finishElement(statement);
|
||||
}
|
||||
|
||||
private void processVariable(final PsiVariable element) {
|
||||
final PsiExpression initializer = element.getInitializer();
|
||||
if (initializer != null) {
|
||||
myStartStatementStack.pushStatement(initializer, false);
|
||||
myEndStatementStack.pushStatement(initializer, false);
|
||||
initializer.accept(this);
|
||||
myStartStatementStack.popStatement();
|
||||
myEndStatementStack.popStatement();
|
||||
}
|
||||
if (element instanceof PsiLocalVariable && initializer != null ||
|
||||
element instanceof PsiField) {
|
||||
if (element instanceof PsiLocalVariable && !myPolicy.isLocalVariableAccepted((PsiLocalVariable)element)) return;
|
||||
|
||||
if (myAssignmentTargetsAreElements) {
|
||||
startElement(element);
|
||||
}
|
||||
|
||||
generateWriteInstruction(element);
|
||||
|
||||
if (myAssignmentTargetsAreElements) {
|
||||
finishElement(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void visitDoWhileStatement(PsiDoWhileStatement statement) {
|
||||
startElement(statement);
|
||||
myStartStatementStack.pushStatement(statement.getBody() == null ? statement : statement.getBody(), true);
|
||||
@@ -1034,6 +1035,11 @@ class ControlFlowAnalyzer extends JavaJspElementVisitor {
|
||||
myFinallyBlocks.push(finallyBlock);
|
||||
}
|
||||
|
||||
PsiResourceList resourceList = statement.getResourceList();
|
||||
if (resourceList != null) {
|
||||
generateCheckedExceptionJumps(resourceList);
|
||||
resourceList.accept(this);
|
||||
}
|
||||
PsiCodeBlock tryBlock = statement.getTryBlock();
|
||||
if (tryBlock != null) {
|
||||
// javac works as if all checked exceptions can occur at the top of the block
|
||||
@@ -1156,8 +1162,36 @@ class ControlFlowAnalyzer extends JavaJspElementVisitor {
|
||||
finishElement(statement);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitResourceList(final PsiResourceList resourceList) {
|
||||
startElement(resourceList);
|
||||
|
||||
@Override public void visitWhileStatement(PsiWhileStatement statement) {
|
||||
final List<PsiResource> resources = resourceList.getResources();
|
||||
for (PsiResource resource : resources) {
|
||||
ProgressManager.checkCanceled();
|
||||
resource.accept(this);
|
||||
}
|
||||
|
||||
finishElement(resourceList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitResource(final PsiResource resource) {
|
||||
startElement(resource);
|
||||
|
||||
final PsiElement resourceElement = resource.getResourceElement();
|
||||
if (resourceElement instanceof PsiLocalVariable) {
|
||||
processVariable((PsiLocalVariable)resourceElement);
|
||||
}
|
||||
else if (resourceElement instanceof PsiExpression) {
|
||||
resourceElement.accept(this);
|
||||
}
|
||||
|
||||
finishElement(resource);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitWhileStatement(PsiWhileStatement statement) {
|
||||
startElement(statement);
|
||||
if (statement.getBody() == null) {
|
||||
myStartStatementStack.pushStatement(statement, false);
|
||||
|
||||
@@ -13,15 +13,6 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: max
|
||||
* Date: Mar 22, 2002
|
||||
* Time: 7:25:02 PM
|
||||
* To change template for new class use
|
||||
* Code Style | Class Templates options (Tools | IDE Options).
|
||||
*/
|
||||
package com.intellij.psi.controlFlow;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
@@ -34,16 +25,20 @@ import com.intellij.util.containers.IntArrayList;
|
||||
import com.intellij.util.containers.Queue;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author max
|
||||
* Date: Mar 22, 2002
|
||||
*/
|
||||
public class DefUseUtil {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.defUse.DefUseUtil");
|
||||
|
||||
private DefUseUtil() {
|
||||
}
|
||||
private DefUseUtil() { }
|
||||
|
||||
public static class Info {
|
||||
private final PsiVariable myVariable;
|
||||
@@ -132,6 +127,7 @@ public class DefUseUtil {
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static List<Info> getUnusedDefs(PsiCodeBlock body, Set<PsiVariable> outUsedVariables) {
|
||||
if (body == null) {
|
||||
return null;
|
||||
@@ -232,12 +228,13 @@ public class DefUseUtil {
|
||||
if (instruction instanceof WriteVariableInstruction) {
|
||||
WriteVariableInstruction writeInstruction = (WriteVariableInstruction)instruction;
|
||||
if (!defsArmed[i]) {
|
||||
PsiElement context = flow.getElement(i);
|
||||
context = PsiTreeUtil.getNonStrictParentOfType(context, PsiStatement.class, PsiAssignmentExpression.class,
|
||||
PsiPostfixExpression.class, PsiPrefixExpression.class);
|
||||
PsiElement context = PsiTreeUtil.getNonStrictParentOfType(flow.getElement(i),
|
||||
PsiStatement.class, PsiAssignmentExpression.class,
|
||||
PsiPostfixExpression.class, PsiPrefixExpression.class,
|
||||
PsiResource.class);
|
||||
PsiVariable psiVariable = writeInstruction.variable;
|
||||
if (context != null && !(context instanceof PsiTryStatement)) {
|
||||
if (context instanceof PsiDeclarationStatement && psiVariable.getInitializer() == null) {
|
||||
if (isDeclaration(context) && psiVariable.getInitializer() == null) {
|
||||
if (!assignedVariables.contains(psiVariable)) {
|
||||
unusedDefs.add(new Info(psiVariable, context, false));
|
||||
}
|
||||
@@ -251,7 +248,11 @@ public class DefUseUtil {
|
||||
}
|
||||
|
||||
return unusedDefs;
|
||||
}
|
||||
|
||||
private static boolean isDeclaration(final PsiElement context) {
|
||||
return context instanceof PsiDeclarationStatement ||
|
||||
context instanceof PsiResource && ((PsiResource)context).getResourceElement() instanceof PsiLocalVariable;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -476,5 +477,4 @@ public class DefUseUtil {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -39,7 +39,12 @@ public class ExcludeSillyAssignment implements ElementFilter {
|
||||
final PsiExpression left = ((PsiAssignmentExpression)each).getLExpression();
|
||||
if (left instanceof PsiReferenceExpression) {
|
||||
final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)left;
|
||||
if (referenceExpression.isQualified()) return true;
|
||||
final PsiElement qualifier = referenceExpression.getQualifier();
|
||||
if (qualifier != null) {
|
||||
if (!(qualifier instanceof PsiThisExpression) || ((PsiThisExpression)qualifier).getQualifier() != null) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return !referenceExpression.isReferenceTo((PsiElement)element);
|
||||
}
|
||||
|
||||
@@ -16,30 +16,26 @@
|
||||
package com.intellij.psi.filters.getters;
|
||||
|
||||
import com.intellij.codeInsight.CodeInsightUtil;
|
||||
import com.intellij.codeInsight.completion.CompletionProvider;
|
||||
import com.intellij.codeInsight.completion.CompletionResultSet;
|
||||
import com.intellij.codeInsight.completion.JavaSmartCompletionParameters;
|
||||
import com.intellij.codeInsight.completion.PrefixMatcher;
|
||||
import com.intellij.codeInsight.lookup.AutoCompletionPolicy;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class ClassLiteralGetter extends CompletionProvider<JavaSmartCompletionParameters> {
|
||||
public class ClassLiteralGetter {
|
||||
private static final Logger LOG = Logger.getInstance("com.intellij.psi.filters.getters.ClassLiteralGetter");
|
||||
|
||||
@Override
|
||||
protected void addCompletions(@NotNull final JavaSmartCompletionParameters parameters,
|
||||
ProcessingContext context,
|
||||
@NotNull CompletionResultSet result) {
|
||||
public static void addCompletions(@NotNull final JavaSmartCompletionParameters parameters,
|
||||
@NotNull Consumer<LookupElement> result, final PrefixMatcher matcher) {
|
||||
|
||||
final PrefixMatcher matcher = result.getPrefixMatcher();
|
||||
final Condition<String> shortNameCondition = new Condition<String>() {
|
||||
public boolean value(String s) {
|
||||
return matcher.prefixMatches(s);
|
||||
@@ -61,7 +57,7 @@ public class ClassLiteralGetter extends CompletionProvider<JavaSmartCompletionPa
|
||||
PsiFile file = parameters.getPosition().getContainingFile();
|
||||
addClassLiteralLookupElement(classParameter, result, file);
|
||||
if (addInheritors) {
|
||||
addInheritorClassLiterals(file, shortNameCondition, classParameter, result);
|
||||
addInheritorClassLiterals(file, shortNameCondition, classParameter, result, matcher);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -69,9 +65,9 @@ public class ClassLiteralGetter extends CompletionProvider<JavaSmartCompletionPa
|
||||
private static void addInheritorClassLiterals(PsiFile context,
|
||||
Condition<String> shortNameCondition,
|
||||
final PsiType classParameter,
|
||||
CompletionResultSet result) {
|
||||
Consumer<LookupElement> result, PrefixMatcher matcher) {
|
||||
final String canonicalText = classParameter.getCanonicalText();
|
||||
if (CommonClassNames.JAVA_LANG_OBJECT.equals(canonicalText) && StringUtil.isEmpty(result.getPrefixMatcher().getPrefix())) {
|
||||
if (CommonClassNames.JAVA_LANG_OBJECT.equals(canonicalText) && StringUtil.isEmpty(matcher.getPrefix())) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -80,13 +76,13 @@ public class ClassLiteralGetter extends CompletionProvider<JavaSmartCompletionPa
|
||||
}
|
||||
}
|
||||
|
||||
private static void addClassLiteralLookupElement(@Nullable final PsiType type, final CompletionResultSet resultSet, final PsiFile context) {
|
||||
private static void addClassLiteralLookupElement(@Nullable final PsiType type, final Consumer<LookupElement> resultSet, final PsiFile context) {
|
||||
if (type instanceof PsiClassType &&
|
||||
PsiUtil.resolveClassInType(type) != null &&
|
||||
!((PsiClassType)type).hasParameters() &&
|
||||
!(((PsiClassType)type).resolve() instanceof PsiTypeParameter)) {
|
||||
try {
|
||||
resultSet.addElement(AutoCompletionPolicy.NEVER_AUTOCOMPLETE.applyPolicy(new ClassLiteralLookupElement((PsiClassType)type, context)));
|
||||
resultSet.consume(AutoCompletionPolicy.NEVER_AUTOCOMPLETE.applyPolicy(new ClassLiteralLookupElement((PsiClassType)type, context)));
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.error(e);
|
||||
|
||||
@@ -15,10 +15,9 @@
|
||||
*/
|
||||
package com.intellij.psi.filters.getters;
|
||||
|
||||
import com.intellij.codeInsight.completion.CompletionResultSet;
|
||||
import com.intellij.codeInsight.completion.JavaCompletionUtil;
|
||||
import com.intellij.codeInsight.completion.JavaMethodCallElement;
|
||||
import com.intellij.codeInsight.completion.SmartCompletionDecorator;
|
||||
import com.intellij.codeInsight.completion.JavaCompletionUtil;
|
||||
import com.intellij.codeInsight.lookup.*;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.filters.TrueFilter;
|
||||
@@ -27,6 +26,7 @@ import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.Consumer;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
@@ -38,7 +38,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
*/
|
||||
public class MembersGetter {
|
||||
|
||||
public static void addMembers(PsiElement position, PsiType expectedType, CompletionResultSet results) {
|
||||
public static void addMembers(PsiElement position, PsiType expectedType, Consumer<LookupElement> results) {
|
||||
final PsiClass psiClass = PsiUtil.resolveClassInType(expectedType);
|
||||
processMembers(position, results, psiClass, PsiTreeUtil.getParentOfType(position, PsiAnnotation.class) != null, expectedType);
|
||||
|
||||
@@ -47,7 +47,7 @@ public class MembersGetter {
|
||||
}
|
||||
}
|
||||
|
||||
private static void addConstantsFromTargetClass(PsiElement position, PsiType expectedType, CompletionResultSet results) {
|
||||
private static void addConstantsFromTargetClass(PsiElement position, PsiType expectedType, Consumer<LookupElement> results) {
|
||||
PsiElement parent = position.getParent();
|
||||
if (!(parent instanceof PsiReferenceExpression)) {
|
||||
return;
|
||||
@@ -99,7 +99,7 @@ public class MembersGetter {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void processMembers(final PsiElement context, final CompletionResultSet results, @Nullable final PsiClass where,
|
||||
private static void processMembers(final PsiElement context, final Consumer<LookupElement> results, @Nullable final PsiClass where,
|
||||
final boolean acceptMethods, PsiType expectedType) {
|
||||
if (where == null) return;
|
||||
|
||||
@@ -132,7 +132,7 @@ public class MembersGetter {
|
||||
}
|
||||
final PsiType itemType = ((TypedLookupItem)item).getType();
|
||||
if (itemType != null && expectedType.isAssignableFrom(itemType)) {
|
||||
results.addElement(item);
|
||||
results.consume(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -213,6 +213,10 @@ public class JavaSpacePropertyProcessor extends JavaElementVisitor {
|
||||
if (aClass.isEnum()) {
|
||||
createParenSpace(true, false);
|
||||
}
|
||||
else if (myRole2 == ChildRole.RBRACE && mySettings.KEEP_SIMPLE_CLASSES_IN_ONE_LINE) {
|
||||
int spaces = mySettings.SPACE_WITHIN_BRACES ? 1 : 0;
|
||||
myResult = Spacing.createSpacing(spaces, spaces, 0, mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_IN_DECLARATIONS);
|
||||
}
|
||||
else if (aClass instanceof PsiAnonymousClass) {
|
||||
if (myRole2 == ChildRole.CLASS_INITIALIZER && isTheOnlyClassMember(myChild2)) {
|
||||
myResult = Spacing.createSpacing(0, 0, 0,
|
||||
|
||||
@@ -185,35 +185,30 @@ public class PsiImplUtil {
|
||||
if (list != null && !list.processDeclarations(processor, state, null, place)) return false;
|
||||
}
|
||||
if (lastParent instanceof PsiCodeBlock) {
|
||||
final PsiParameterList parameterList = method.getParameterList();
|
||||
if (processDeclarationsInParameterList(parameterList, processor, state)) return false;
|
||||
final PsiParameter[] parameters = method.getParameterList().getParameters();
|
||||
for (PsiParameter parameter : parameters) {
|
||||
if (!processor.execute(parameter, state)) return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean processDeclarationsInTryStatement(@NotNull final PsiTryStatement statement,
|
||||
public static boolean processDeclarationsInResourceList(@NotNull final PsiResourceList resourceList,
|
||||
@NotNull final PsiScopeProcessor processor,
|
||||
@NotNull final ResolveState state,
|
||||
final PsiElement lastParent) {
|
||||
if (lastParent instanceof PsiCodeBlock) {
|
||||
final PsiParameterList parameterList = statement.getResourceList();
|
||||
if (parameterList != null && processDeclarationsInParameterList(parameterList, processor, state)) return false;
|
||||
final List<PsiResource> resources = resourceList.getResources();
|
||||
for (PsiResource resource : resources) {
|
||||
final PsiElement resourceElement = resource.getResourceElement();
|
||||
if (resourceElement instanceof PsiLocalVariable &&
|
||||
!resourceElement.equals(lastParent) &&
|
||||
!processor.execute(resourceElement, state)) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean processDeclarationsInParameterList(@NotNull final PsiParameterList parameterList,
|
||||
@NotNull final PsiScopeProcessor processor,
|
||||
@NotNull final ResolveState state) {
|
||||
final PsiParameter[] parameters = parameterList.getParameters();
|
||||
for (PsiParameter parameter : parameters) {
|
||||
if (!processor.execute(parameter, state)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean hasTypeParameters(@NotNull PsiTypeParameterListOwner owner) {
|
||||
final PsiTypeParameterList typeParameterList = owner.getTypeParameterList();
|
||||
return typeParameterList != null && typeParameterList.getTypeParameters().length != 0;
|
||||
@@ -233,7 +228,7 @@ public class PsiImplUtil {
|
||||
types[i] = typeElements[i].getType();
|
||||
}
|
||||
if (types.length == 1 && types[0] instanceof PsiDiamondType) {
|
||||
return ((PsiDiamondType)types[0]).getInferredTypes();
|
||||
return ((PsiDiamondType)types[0]).resolveInferredTypes().getTypes();
|
||||
}
|
||||
return types;
|
||||
}
|
||||
|
||||
@@ -60,14 +60,14 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ
|
||||
private static final JavaParserUtil.ParserWrapper PARAMETER = new JavaParserUtil.ParserWrapper() {
|
||||
@Override
|
||||
public void parse(final PsiBuilder builder) {
|
||||
DeclarationParser.parseParameter(builder, true, false, false);
|
||||
DeclarationParser.parseParameter(builder, true, false);
|
||||
}
|
||||
};
|
||||
|
||||
private static final JavaParserUtil.ParserWrapper RESOURCE = new JavaParserUtil.ParserWrapper() {
|
||||
@Override
|
||||
public void parse(final PsiBuilder builder) {
|
||||
DeclarationParser.parseParameter(builder, true, false, true);
|
||||
DeclarationParser.parseResource(builder);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -169,6 +169,7 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiAnnotation createAnnotationFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException {
|
||||
final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, ANNOTATION, false), context);
|
||||
final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode());
|
||||
@@ -179,16 +180,19 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiDocTag createDocTagFromText(@NotNull final String text) throws IncorrectOperationException {
|
||||
return createDocCommentFromText(join("/**\n", text, "\n */")).getTags()[0];
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiDocTag createDocTagFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException {
|
||||
return createDocTagFromText(text);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiDocComment createDocCommentFromText(@NotNull final String text) throws IncorrectOperationException {
|
||||
final PsiMethod method = createMethodFromText(join(text, "void m();"), null);
|
||||
final PsiDocComment comment = method.getDocComment();
|
||||
@@ -197,11 +201,13 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiDocComment createDocCommentFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException {
|
||||
return createDocCommentFromText(text);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiClass createClassFromText(@NotNull final String body, final PsiElement context) throws IncorrectOperationException {
|
||||
final PsiJavaFile aFile = createDummyJavaFile(join("class _Dummy_ { ", body, " }"));
|
||||
final PsiClass[] classes = aFile.getClasses();
|
||||
@@ -212,6 +218,7 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiField createFieldFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException {
|
||||
final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, DECLARATION, false), context);
|
||||
final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode());
|
||||
@@ -222,6 +229,7 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiMethod createMethodFromText(@NotNull final String text, final PsiElement context, final LanguageLevel level) throws IncorrectOperationException {
|
||||
final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, DECLARATION, false, level), context);
|
||||
final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode());
|
||||
@@ -232,17 +240,16 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public final PsiMethod createMethodFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException {
|
||||
final LanguageLevel level = LanguageLevelProjectExtension.getInstance(myManager.getProject()).getLanguageLevel();
|
||||
return createMethodFromText(text, context, level);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiParameter createParameterFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException {
|
||||
final boolean resource = context instanceof PsiParameterList &&
|
||||
context.getParent() instanceof PsiTryStatement;
|
||||
final JavaParserUtil.ParserWrapper wrapper = resource ? RESOURCE : PARAMETER;
|
||||
final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, wrapper, false), context);
|
||||
final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, PARAMETER, false), context);
|
||||
final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode());
|
||||
if (!(element instanceof PsiParameter)) {
|
||||
throw new IncorrectOperationException("Incorrect parameter \"" + text + "\".");
|
||||
@@ -251,11 +258,24 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiResource createResourceFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException {
|
||||
final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, RESOURCE, false), context);
|
||||
final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode());
|
||||
if (!(element instanceof PsiResource)) {
|
||||
throw new IncorrectOperationException("Incorrect resource \"" + text + "\".");
|
||||
}
|
||||
return (PsiResource)element;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiType createTypeFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException {
|
||||
return createTypeInner(text, context, false);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiTypeElement createTypeElementFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException {
|
||||
final boolean multiCatch = context instanceof PsiParameter &&
|
||||
context.getParent() instanceof PsiCatchSection &&
|
||||
@@ -281,6 +301,7 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiJavaCodeReferenceElement createReferenceFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException {
|
||||
final boolean isStaticImport = context instanceof PsiImportStaticStatement &&
|
||||
!((PsiImportStaticStatement)context).isOnDemand();
|
||||
@@ -294,6 +315,7 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiCodeBlock createCodeBlockFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException {
|
||||
final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, CODE_BLOCK, true), context);
|
||||
final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode());
|
||||
@@ -304,6 +326,7 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiStatement createStatementFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException {
|
||||
final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, STATEMENT, false), context);
|
||||
final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode());
|
||||
@@ -314,6 +337,7 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiExpression createExpressionFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException {
|
||||
final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, EXPRESSION, false), context);
|
||||
final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode());
|
||||
@@ -330,6 +354,7 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiTypeParameter createTypeParameterFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException {
|
||||
final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, TYPE_PARAMETER, false), context);
|
||||
final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode());
|
||||
@@ -340,6 +365,7 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiComment createCommentFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException {
|
||||
final PsiJavaFile aFile = createDummyJavaFile(text);
|
||||
for (PsiElement aChildren : aFile.getChildren()) {
|
||||
@@ -357,6 +383,7 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiEnumConstant createEnumConstantFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException {
|
||||
final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, ENUM_CONSTANT, false), context);
|
||||
final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode());
|
||||
@@ -367,6 +394,7 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiCatchSection createCatchSection(@NotNull final PsiClassType exceptionType, @NotNull final String exceptionName,
|
||||
final PsiElement context) throws IncorrectOperationException {
|
||||
final String text = join("catch (", exceptionType.getCanonicalText(), " ", exceptionName, ") {}");
|
||||
@@ -406,6 +434,7 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ
|
||||
psiCatchSection.getCatchBlock().replace(codeBlockFromText);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiType createPrimitiveType(@NotNull final String text, @NotNull final PsiAnnotation[] annotations) throws IncorrectOperationException {
|
||||
final PsiPrimitiveType primitiveType = getPrimitiveType(text);
|
||||
if (primitiveType == null) {
|
||||
|
||||
@@ -177,7 +177,7 @@ public class PsiSubstitutorImpl implements PsiSubstitutor {
|
||||
final List<PsiType> substituted = ContainerUtil.map(disjunctionType.getDisjunctions(), new Function<PsiType, PsiType>() {
|
||||
@Override public PsiType fun(PsiType psiType) { return psiType.accept(SubstitutionVisitorBase.this); }
|
||||
});
|
||||
return new PsiDisjunctionType(substituted, disjunctionType.getManager());
|
||||
return disjunctionType.newDisjunctionType(substituted);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-3
@@ -755,7 +755,7 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme
|
||||
}
|
||||
else {
|
||||
while (superParent != null) {
|
||||
if (superParent instanceof PsiCodeBlock || superParent instanceof PsiVariable) {
|
||||
if (superParent instanceof PsiCodeBlock || superParent instanceof PsiLocalVariable) {
|
||||
smartCompletion = false;
|
||||
break;
|
||||
}
|
||||
@@ -763,8 +763,6 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme
|
||||
}
|
||||
}
|
||||
if (!smartCompletion && !isCodeFragmentType(getTreeParent().getElementType()) && !(getParent() instanceof PsiAnnotation)) {
|
||||
/*filter.addFilter(ElementClassFilter.CLASS);
|
||||
filter.addFilter(ElementClassFilter.PACKAGE);*/
|
||||
filter.addFilter(new AndFilter(ElementClassFilter.METHOD, new NotFilter(new ConstructorFilter())));
|
||||
filter.addFilter(ElementClassFilter.VARIABLE);
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ public class PsiModifierListImpl extends JavaStubPsiElement<PsiModifierListStub>
|
||||
super(node);
|
||||
}
|
||||
|
||||
public boolean hasModifierProperty(@NotNull String name){
|
||||
public boolean hasModifierProperty(@NotNull String name) {
|
||||
final PsiModifierListStub stub = getStub();
|
||||
if (stub != null) {
|
||||
int flag = NAME_TO_MODIFIER_FLAG_MAP.get(name);
|
||||
@@ -93,34 +93,34 @@ public class PsiModifierListImpl extends JavaStubPsiElement<PsiModifierListStub>
|
||||
IElementType type = NAME_TO_KEYWORD_TYPE_MAP.get(name);
|
||||
|
||||
PsiElement parent = getParent();
|
||||
if (parent instanceof PsiClass){
|
||||
PsiElement pparent = parent.getParent();
|
||||
if (pparent instanceof PsiClass && ((PsiClass)pparent).isInterface()){
|
||||
if (type == JavaTokenType.PUBLIC_KEYWORD){
|
||||
if (parent instanceof PsiClass) {
|
||||
PsiElement grandParent = parent.getParent();
|
||||
if (grandParent instanceof PsiClass && ((PsiClass)grandParent).isInterface()) {
|
||||
if (type == JavaTokenType.PUBLIC_KEYWORD) {
|
||||
return true;
|
||||
}
|
||||
if (type == null){ // package local
|
||||
if (type == null) { // package local
|
||||
return false;
|
||||
}
|
||||
if (type == JavaTokenType.STATIC_KEYWORD){
|
||||
if (type == JavaTokenType.STATIC_KEYWORD) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (((PsiClass)parent).isInterface()){
|
||||
if (type == JavaTokenType.ABSTRACT_KEYWORD){
|
||||
if (((PsiClass)parent).isInterface()) {
|
||||
if (type == JavaTokenType.ABSTRACT_KEYWORD) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// nested interface is implicitly static
|
||||
if (pparent instanceof PsiClass) {
|
||||
if (type == JavaTokenType.STATIC_KEYWORD){
|
||||
if (grandParent instanceof PsiClass) {
|
||||
if (type == JavaTokenType.STATIC_KEYWORD) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (((PsiClass)parent).isEnum()){
|
||||
if (((PsiClass)parent).isEnum()) {
|
||||
if (type == JavaTokenType.STATIC_KEYWORD) {
|
||||
if (!(pparent instanceof PsiFile)) return true;
|
||||
if (!(grandParent instanceof PsiFile)) return true;
|
||||
}
|
||||
else if (type == JavaTokenType.FINAL_KEYWORD) {
|
||||
final PsiField[] fields = ((PsiClass)parent).getFields();
|
||||
@@ -138,37 +138,37 @@ public class PsiModifierListImpl extends JavaStubPsiElement<PsiModifierListStub>
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (parent instanceof PsiMethod){
|
||||
else if (parent instanceof PsiMethod) {
|
||||
PsiClass aClass = ((PsiMethod)parent).getContainingClass();
|
||||
if (aClass != null && aClass.isInterface()){
|
||||
if (type == JavaTokenType.PUBLIC_KEYWORD){
|
||||
if (aClass != null && aClass.isInterface()) {
|
||||
if (type == JavaTokenType.PUBLIC_KEYWORD) {
|
||||
return true;
|
||||
}
|
||||
if (type == null){ // package local
|
||||
if (type == null) { // package local
|
||||
return false;
|
||||
}
|
||||
if (type == JavaTokenType.ABSTRACT_KEYWORD){
|
||||
if (type == JavaTokenType.ABSTRACT_KEYWORD) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (parent instanceof PsiField){
|
||||
else if (parent instanceof PsiField) {
|
||||
if (parent instanceof PsiEnumConstant) {
|
||||
return type == JavaTokenType.PUBLIC_KEYWORD || type == JavaTokenType.STATIC_KEYWORD || type == JavaTokenType.FINAL_KEYWORD;
|
||||
}
|
||||
else {
|
||||
PsiClass aClass = ((PsiField)parent).getContainingClass();
|
||||
if (aClass != null && aClass.isInterface()){
|
||||
if (type == JavaTokenType.PUBLIC_KEYWORD){
|
||||
if (aClass != null && aClass.isInterface()) {
|
||||
if (type == JavaTokenType.PUBLIC_KEYWORD) {
|
||||
return true;
|
||||
}
|
||||
if (type == null){ // package local
|
||||
if (type == null) { // package local
|
||||
return false;
|
||||
}
|
||||
if (type == JavaTokenType.STATIC_KEYWORD){
|
||||
if (type == JavaTokenType.STATIC_KEYWORD) {
|
||||
return true;
|
||||
}
|
||||
if (type == JavaTokenType.FINAL_KEYWORD){
|
||||
if (type == JavaTokenType.FINAL_KEYWORD) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -177,9 +177,15 @@ public class PsiModifierListImpl extends JavaStubPsiElement<PsiModifierListStub>
|
||||
else if (parent instanceof PsiParameter) {
|
||||
if (type == JavaTokenType.FINAL_KEYWORD && ((PsiParameter)parent).getType() instanceof PsiDisjunctionType) return true;
|
||||
}
|
||||
else if (parent instanceof PsiLocalVariable) {
|
||||
PsiElement grandParent = parent.getParent();
|
||||
if (type == JavaTokenType.FINAL_KEYWORD && grandParent instanceof PsiResource) return true;
|
||||
}
|
||||
|
||||
if (type == null){ // package local
|
||||
return !hasModifierProperty(PsiModifier.PUBLIC) && !hasModifierProperty(PsiModifier.PRIVATE) && !hasModifierProperty(PsiModifier.PROTECTED);
|
||||
if (type == null) { // package local
|
||||
return !hasModifierProperty(PsiModifier.PUBLIC) &&
|
||||
!hasModifierProperty(PsiModifier.PRIVATE) &&
|
||||
!hasModifierProperty(PsiModifier.PROTECTED);
|
||||
}
|
||||
|
||||
return getNode().findChildByType(type) != null;
|
||||
|
||||
@@ -403,8 +403,8 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
|
||||
final boolean forCompletion) {
|
||||
PsiTypeParameterListOwner owner = typeParameter.getOwner();
|
||||
Pair<PsiType, ConstraintType> substitution = null;
|
||||
if (owner instanceof PsiMethod && parent instanceof PsiMethodCallExpression) {
|
||||
PsiMethodCallExpression methodCall = (PsiMethodCallExpression)parent;
|
||||
if (owner instanceof PsiMethod && parent instanceof PsiCallExpression) {
|
||||
PsiCallExpression methodCall = (PsiCallExpression)parent;
|
||||
substitution = inferMethodTypeParameterFromParent(methodCall.getParent(), methodCall, typeParameter, substitutor, forCompletion);
|
||||
}
|
||||
return substitution;
|
||||
@@ -604,7 +604,7 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
|
||||
}
|
||||
|
||||
private static Pair<PsiType, ConstraintType> inferMethodTypeParameterFromParent(PsiElement parent,
|
||||
PsiMethodCallExpression methodCall,
|
||||
PsiCallExpression methodCall,
|
||||
final PsiTypeParameter typeParameter,
|
||||
PsiSubstitutor substitutor,
|
||||
final boolean forCompletion) {
|
||||
@@ -701,13 +701,13 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
|
||||
return result;
|
||||
}
|
||||
|
||||
private static final ThreadLocal<List<PsiMethodCallExpression>> myBlockedForInferenceMethodCalls = new ThreadLocal<List<PsiMethodCallExpression>>() {
|
||||
protected List<PsiMethodCallExpression> initialValue() {
|
||||
return new ArrayList<PsiMethodCallExpression>(2);
|
||||
private static final ThreadLocal<List<PsiCallExpression>> myBlockedForInferenceMethodCalls = new ThreadLocal<List<PsiCallExpression>>() {
|
||||
protected List<PsiCallExpression> initialValue() {
|
||||
return new ArrayList<PsiCallExpression>(2);
|
||||
}
|
||||
};
|
||||
|
||||
private static Pair<PsiType, ConstraintType> inferTypeForCompletionFromCallContext(final PsiMethodCallExpression innerMethodCall,
|
||||
private static Pair<PsiType, ConstraintType> inferTypeForCompletionFromCallContext(final PsiCallExpression innerMethodCall,
|
||||
final PsiExpressionList expressionList,
|
||||
final PsiCallExpression contextCall,
|
||||
final PsiTypeParameter typeParameter) {
|
||||
|
||||
@@ -127,9 +127,11 @@ public interface JavaElementType {
|
||||
IElementType THROW_STATEMENT = new JavaCompositeElementType("THROW_STATEMENT", PsiThrowStatementImpl.class);
|
||||
IElementType SYNCHRONIZED_STATEMENT = new JavaCompositeElementType("SYNCHRONIZED_STATEMENT", PsiSynchronizedStatementImpl.class);
|
||||
IElementType TRY_STATEMENT = new JavaCompositeElementType("TRY_STATEMENT", PsiTryStatementImpl.class);
|
||||
IElementType RESOURCE_LIST = new JavaCompositeElementType("RESOURCE_LIST", PsiResourceListImpl.class);
|
||||
IElementType RESOURCE = new JavaCompositeElementType("RESOURCE", PsiResourceImpl.class);
|
||||
IElementType CATCH_SECTION = new JavaCompositeElementType("CATCH_SECTION", PsiCatchSectionImpl.class);
|
||||
IElementType LABELED_STATEMENT = new JavaCompositeElementType("LABELED_STATEMENT", PsiLabeledStatementImpl.class);
|
||||
IElementType ASSERT_STATEMENT = new JavaCompositeElementType("ASSERT_STATEMENT", PsiAssertStatementImpl.class);
|
||||
IElementType CATCH_SECTION = new JavaCompositeElementType("CATCH_SECTION", PsiCatchSectionImpl.class);
|
||||
IElementType ANNOTATION_ARRAY_INITIALIZER = new JavaCompositeElementType("ANNOTATION_ARRAY_INITIALIZER", PsiArrayInitializerMemberValueImpl.class);
|
||||
IElementType NAME_VALUE_PAIR = new JavaCompositeElementType("NAME_VALUE_PAIR", PsiNameValuePairImpl.class, true);
|
||||
IElementType ANNOTATION_PARAMETER_LIST = new JavaCompositeElementType("ANNOTATION_PARAMETER_LIST", PsiAnnotationParameterListImpl.class, true);
|
||||
|
||||
+23
-6
@@ -49,7 +49,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import javax.swing.*;
|
||||
import java.util.Set;
|
||||
|
||||
public class PsiLocalVariableImpl extends CompositePsiElement implements PsiLocalVariable, PsiVariableEx, Constants {
|
||||
public class PsiLocalVariableImpl extends CompositePsiElement implements PsiScopedLocalVariable, PsiVariableEx, Constants {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiLocalVariableImpl");
|
||||
|
||||
private volatile String myCachedName = null;
|
||||
@@ -94,7 +94,7 @@ public class PsiLocalVariableImpl extends CompositePsiElement implements PsiLoca
|
||||
@NotNull
|
||||
public PsiTypeElement getTypeElement() {
|
||||
ASTNode first = getTreeParent().findChildByType(LOCAL_VARIABLE);
|
||||
return (PsiTypeElement)SourceTreeToPsiMap.treeElementToPsi(first.findChildByType(TYPE));
|
||||
return SourceTreeToPsiMap.treeToPsiNotNull(first.findChildByType(TYPE));
|
||||
}
|
||||
|
||||
public PsiModifierList getModifierList() {
|
||||
@@ -105,7 +105,8 @@ public class PsiLocalVariableImpl extends CompositePsiElement implements PsiLoca
|
||||
}
|
||||
|
||||
public boolean hasModifierProperty(@NotNull String name) {
|
||||
return getModifierList().hasModifierProperty(name);
|
||||
final PsiModifierList modifierList = getModifierList();
|
||||
return modifierList != null && modifierList.hasModifierProperty(name);
|
||||
}
|
||||
|
||||
public PsiExpression getInitializer() {
|
||||
@@ -278,6 +279,21 @@ public class PsiLocalVariableImpl extends CompositePsiElement implements PsiLoca
|
||||
return "PsiLocalVariable:" + getName();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public PsiElement[] getDeclarationScope() {
|
||||
final PsiElement parentElement = getParent();
|
||||
if (parentElement instanceof PsiDeclarationStatement) {
|
||||
return new PsiElement[]{parentElement.getParent()};
|
||||
}
|
||||
else if (parentElement instanceof PsiResource) {
|
||||
final PsiResourceList resourceList = (PsiResourceList)parentElement.getParent();
|
||||
final PsiTryStatement tryStatement = (PsiTryStatement)resourceList.getParent();
|
||||
final PsiCodeBlock tryBlock = tryStatement.getTryBlock();
|
||||
return tryBlock != null ? new PsiElement[]{resourceList, tryBlock} : new PsiElement[]{resourceList};
|
||||
}
|
||||
return new PsiElement[]{parentElement.getParent()};
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public SearchScope getUseScope() {
|
||||
if (JspPsiUtil.isInJspFile(this)) {
|
||||
@@ -304,9 +320,9 @@ public class PsiLocalVariableImpl extends CompositePsiElement implements PsiLoca
|
||||
}
|
||||
}
|
||||
|
||||
PsiElement parentElement = getParent();
|
||||
if (parentElement instanceof PsiDeclarationStatement) {
|
||||
return new LocalSearchScope(parentElement.getParent());
|
||||
final PsiElement parentElement = getParent();
|
||||
if (parentElement instanceof PsiDeclarationStatement || parentElement instanceof PsiResource) {
|
||||
return new LocalSearchScope(getDeclarationScope());
|
||||
}
|
||||
else {
|
||||
return getManager().getFileManager().getUseScope(this);
|
||||
@@ -317,6 +333,7 @@ public class PsiLocalVariableImpl extends CompositePsiElement implements PsiLoca
|
||||
final RowIcon baseIcon = createLayeredIcon(Icons.VARIABLE_ICON, ElementPresentationUtil.getFlags(this, false));
|
||||
return ElementPresentationUtil.addVisibilityIcon(this, flags, baseIcon);
|
||||
}
|
||||
|
||||
public PsiType getTypeNoResolve() {
|
||||
return getType();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.psi.impl.source.tree.java;
|
||||
|
||||
import com.intellij.openapi.diagnostic.LogUtil;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.tree.CompositePsiElement;
|
||||
import com.intellij.psi.impl.source.tree.JavaElementType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class PsiResourceImpl extends CompositePsiElement implements PsiResource {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiResourceImpl");
|
||||
|
||||
public PsiResourceImpl() {
|
||||
super(JavaElementType.RESOURCE);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiElement getResourceElement() {
|
||||
final PsiElement element = getFirstChild();
|
||||
assert element != null : this;
|
||||
return element;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiType getType() {
|
||||
final PsiElement element = getResourceElement();
|
||||
if (element instanceof PsiLocalVariable) {
|
||||
return ((PsiLocalVariable)element).getType();
|
||||
}
|
||||
else if (element instanceof PsiExpression) {
|
||||
return ((PsiExpression)element).getType();
|
||||
}
|
||||
LOG.error("Unexpected resource type: " + LogUtil.objectAndClass(element));
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(@NotNull final PsiElementVisitor visitor) {
|
||||
if (visitor instanceof JavaElementVisitor) {
|
||||
((JavaElementVisitor)visitor).visitResource(this);
|
||||
}
|
||||
else {
|
||||
visitor.visitElement(this);
|
||||
}
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
final PsiElement element = getFirstChild();
|
||||
if (element instanceof PsiLocalVariable) return ((PsiLocalVariable)element).getName();
|
||||
if (element instanceof PsiAssignmentExpression) return ((PsiAssignmentExpression)element).getLExpression().toString();
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PsiResource:" + getName();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.psi.impl.source.tree.java;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.PsiImplUtil;
|
||||
import com.intellij.psi.impl.source.tree.CompositePsiElement;
|
||||
import com.intellij.psi.impl.source.tree.JavaElementType;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PsiResourceListImpl extends CompositePsiElement implements PsiResourceList {
|
||||
public PsiResourceListImpl() {
|
||||
super(JavaElementType.RESOURCE_LIST);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<PsiResource> getResources() {
|
||||
return PsiTreeUtil.getChildrenOfTypeAsList(this, PsiResource.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(@NotNull final PsiElementVisitor visitor) {
|
||||
if (visitor instanceof JavaElementVisitor) {
|
||||
((JavaElementVisitor)visitor).visitResourceList(this);
|
||||
}
|
||||
else {
|
||||
visitor.visitElement(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean processDeclarations(@NotNull final PsiScopeProcessor processor,
|
||||
@NotNull final ResolveState state,
|
||||
final PsiElement lastParent,
|
||||
@NotNull final PsiElement place) {
|
||||
return PsiImplUtil.processDeclarationsInResourceList(this, processor, state, lastParent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PsiResourceList:" + getText();
|
||||
}
|
||||
}
|
||||
@@ -93,8 +93,8 @@ public class PsiTryStatementImpl extends CompositePsiElement implements PsiTrySt
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiParameterList getResourceList() {
|
||||
return PsiTreeUtil.findChildOfType(this, PsiParameterList.class);
|
||||
public PsiResourceList getResourceList() {
|
||||
return PsiTreeUtil.findChildOfType(this, PsiResourceList.class);
|
||||
}
|
||||
|
||||
public ASTNode findChildByRole(int role) {
|
||||
@@ -164,7 +164,12 @@ public class PsiTryStatementImpl extends CompositePsiElement implements PsiTrySt
|
||||
@NotNull final ResolveState state,
|
||||
final PsiElement lastParent,
|
||||
@NotNull final PsiElement place) {
|
||||
return PsiImplUtil.processDeclarationsInTryStatement(this, processor, state, lastParent);
|
||||
final PsiResourceList resourceList = getResourceList();
|
||||
if (resourceList != null && lastParent instanceof PsiCodeBlock && lastParent == getTryBlock()) {
|
||||
return PsiImplUtil.processDeclarationsInResourceList(resourceList, processor, state, lastParent);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
|
||||
+7
@@ -26,11 +26,13 @@ import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.RangeMarker;
|
||||
import com.intellij.openapi.editor.SelectionModel;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.keymap.Keymap;
|
||||
import com.intellij.openapi.keymap.KeymapManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
@@ -131,6 +133,11 @@ class VariableInplaceIntroducer extends VariableInplaceRenamer {
|
||||
return super.createLookupItems(lookupItems, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TextRange preserveSelectedRange(SelectionModel selectionModel) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void moveOffsetAfter(boolean success) {
|
||||
try {
|
||||
|
||||
+6
@@ -37,6 +37,12 @@ public class JavadocTypedHandlerTest {
|
||||
doTest("<t\nag><caret>", null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void tagWithAttribute() {
|
||||
doTest("<a href='www'><caret>", "a");
|
||||
//TODO den implement
|
||||
}
|
||||
|
||||
private static void doTest(String text, String expected) {
|
||||
StringBuilder normalized = new StringBuilder();
|
||||
int offset = text.indexOf(CARET_MARKER);
|
||||
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
class A {
|
||||
final boolean aboo;
|
||||
A() {
|
||||
abo<caret>
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
class A {
|
||||
final boolean aboo;
|
||||
A() {
|
||||
aboo<caret>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
public class ConstConfig {
|
||||
{
|
||||
switch (a) {
|
||||
case Foooo: {}
|
||||
def<caret>
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
public class ConstConfig {
|
||||
{
|
||||
switch (a) {
|
||||
case Foooo: {}
|
||||
default:<caret>
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
public class ConstConfig {
|
||||
public static boolean testMode = false;
|
||||
|
||||
{
|
||||
if (test<caret>x)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
public class ConstConfig {
|
||||
public static boolean testMode = false;
|
||||
|
||||
{
|
||||
if (!testMode<caret>x)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
class A {
|
||||
private lo<caret> localizedStringManager;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
class A {
|
||||
private long <caret>localizedStringManager;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
class A {
|
||||
A() {
|
||||
fin<caret>this.toString();
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ public class Aaaaaaa {
|
||||
private final String aaa;
|
||||
|
||||
Aaaaaaa(String aabbb) {
|
||||
aaa = "";
|
||||
aaa = true ? null : aa<caret>
|
||||
}
|
||||
|
||||
|
||||
+1
@@ -2,6 +2,7 @@ public class Aaaaaaa {
|
||||
private final String aaa;
|
||||
|
||||
Aaaaaaa(Object aabbb) {
|
||||
aaa = "";
|
||||
aaa = true ? null : aa<caret>
|
||||
}
|
||||
|
||||
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
class Goo {
|
||||
int boo() {}
|
||||
int doo() {}
|
||||
int foo() {}
|
||||
}
|
||||
|
||||
class Foooo {
|
||||
Goo g;
|
||||
|
||||
int foo() {
|
||||
return g.<caret>
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
class A {
|
||||
public abstract void zoo(int y);
|
||||
|
||||
{
|
||||
Object x;
|
||||
zoo((Integer) <caret>x);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
class A {
|
||||
public abstract void zoo(int y);
|
||||
|
||||
{
|
||||
Object x;
|
||||
zoo((<caret>x);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
class A {
|
||||
public abstract void zoo(int y);
|
||||
|
||||
{
|
||||
Object x;
|
||||
zoo((Integer) <caret>x);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
class A {
|
||||
public abstract void zoo(int y);
|
||||
|
||||
{
|
||||
Object x;
|
||||
zoo((<caret>) x);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
class A {
|
||||
public abstract void zoo(int y);
|
||||
|
||||
{
|
||||
Object x;
|
||||
zoo((Integer) <caret>x);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user